#!/usr/bin/env python3 """Unsupported YAML must fail before any runtime call.""" import os, pathlib, subprocess, sys, tempfile binary = str(pathlib.Path(sys.argv[1]).resolve()) with tempfile.TemporaryDirectory(prefix='container-compose-compat-', dir=os.environ.get('CONTAINER_COMPOSE_TEST_TMPDIR', '/Volumes/ChatGPT' if pathlib.Path('/Volumes/ChatGPT').is_dir() else tempfile.gettempdir())) as d: root = pathlib.Path(d) runtime = root/'container' runtime.write_text('#!/bin/sh\necho called >> "$CALLS"\nexit 99\n') runtime.chmod(0o755) calls=root/'calls'; source=root/'compose.yaml' env=dict(os.environ, PATH=str(root)+':'+os.environ['PATH'], CALLS=str(calls)) fixtures = [ 'secrets: {}\nservices:\n web:\n image: nginx\n', 'volumes:\n data:\n external: true\nservices:\n web:\n image: nginx\n', 'networks:\n lan:\n driver: overlay\nservices:\n web:\n image: nginx\n', 'services:\n web:\n image: nginx\n ports: [{target: 80, published: 8080}]\n', 'services:\n web:\n image: nginx\n volumes: [{type: bind, source: ., target: /app}]\n', 'services:\n web:\n image: nginx\n networks:\n lan:\n aliases: [web]\n', 'services:\n web:\n image: nginx\n depends_on:\n db:\n condition: service_healthy\n db:\n image: postgres\n', 'services:\n web:\n build:\n context: .\n target: production\n', 'services:\n web:\n image: nginx\n profiles: [dev]\n', 'services:\n web:\n image: nginx\n deploy: {replicas: 3}\n', ] for fixture in fixtures: source.write_text(fixture) result=subprocess.run([binary,'-f',str(source),'up','-d'],env=env,capture_output=True,timeout=5) assert result.returncode != 0, result.stdout assert not calls.exists(), 'Unexpected runtime mutation' source.write_text('services:\n web:\n image: nginx\n') for command in [['down','--bogus'],['logs','--follow'],['stop','unknown']]: result=subprocess.run([binary,'-f',str(source)]+command,env=env,capture_output=True,timeout=5) assert result.returncode != 0 assert not calls.exists() result=subprocess.run([binary,'monitor','--demo','start','demo-web-1'],env=env,capture_output=True,timeout=5) assert result.returncode != 0 and not calls.exists() print('PASS: 14 compatibility and read-only demo checks')