diff --git a/docs/TESTING.md b/docs/TESTING.md index e0824de..8a544f9 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -41,7 +41,9 @@ python3 tools/riot-urlsession-check.py ``` The runner starts a loopback-only HTTP fixture, reserves a second non-listening -port for the transport-error case, and creates a fresh private DPREFIX. It runs +port for the transport-error case, and reserves a private parent directory with +an initially absent DPREFIX. Darling must create DPREFIX itself to initialize +guest accounts and configuration; an existing empty directory skips that setup. It runs only the independent probe, then shuts down that private prefix. It never starts Riot/League, queries their APIs, sends game input or shuts down the normal prefix. The fixture delays its response so session invalidation is @@ -61,6 +63,12 @@ suspended custom delegate queue. Expected output includes `URLSESSION_PASS`, `LIFECYCLE_PASS`, `SHARED_SESSION_PASS` and `QUEUE_PASS`. The original runtime aborts on missing data-task initialization or session invalidation. +Native validation on 2026-10-18 passed all four markers using a staged, patched +CFNetwork framework and the installed Darling base runtime. No installed SDK +libraries were replaced. Darling shutdown may leave a root-owned overlay work +directory; the runner reports retained private artifacts if cleanup cannot +remove it. + These checks do not establish full NSURLSession conformance or transport-level interruption of an already-running request. diff --git a/tests/test_urlsession_runner.py b/tests/test_urlsession_runner.py index dc4abf0..ac7d900 100644 --- a/tests/test_urlsession_runner.py +++ b/tests/test_urlsession_runner.py @@ -23,6 +23,10 @@ with open(TRACE, 'a') as stream: stream.write(json.dumps({'args':sys.argv[1:], 'prefix':os.environ['DPREFIX']}) + '\\n') if sys.argv[1] == 'shutdown': raise SystemExit(0) +from pathlib import Path +prefix = Path(os.environ['DPREFIX']) +assert not prefix.exists(), 'Darling must receive an absent prefix for first-time initialization' +prefix.mkdir() assert sys.argv[1:3] == ['shell', 'env'] assert 'DYLD_FRAMEWORK_PATH' not in os.environ and 'DYLD_LIBRARY_PATH' not in os.environ urls = [arg for arg in sys.argv[1:] if arg.startswith('http://')] @@ -53,7 +57,7 @@ print('QUEUE_PASS: fixture') self.assertEqual(calls[1]['args'], ['shutdown']) self.assertEqual(calls[0]['prefix'], calls[1]['prefix']) self.assertNotEqual(Path(calls[0]['prefix']), Path.home() / '.darling') - self.assertFalse(Path(calls[0]['prefix']).exists()) + self.assertFalse(Path(calls[0]['prefix']).parent.exists()) self.assertEqual(stat.S_IMODE(log.stat().st_mode), 0o600) diff --git a/tools/riot-urlsession-check.py b/tools/riot-urlsession-check.py index 1f974af..dddcf77 100644 --- a/tools/riot-urlsession-check.py +++ b/tools/riot-urlsession-check.py @@ -51,7 +51,10 @@ reserved = socket.socket() reserved.bind(('127.0.0.1', 0)) # Reserved but not listening: deterministic connection refusal. Thread(target=server.serve_forever, daemon=True).start() (root / 'build').mkdir(exist_ok=True) -prefix = Path(tempfile.mkdtemp(prefix='urlsession-prefix-', dir=root / 'build')) +# Darling initializes account/configuration files only for an absent prefix. +# Reserve its private parent, not DPREFIX itself. +private_root = Path(tempfile.mkdtemp(prefix='urlsession-', dir=root / 'build')) +prefix = private_root / 'prefix' env = {key: os.environ[key] for key in ('PATH', 'HOME', 'USER', 'LOGNAME', 'DISPLAY', 'XAUTHORITY', 'XDG_RUNTIME_DIR', 'DBUS_SESSION_BUS_ADDRESS', 'LANG') if key in os.environ} env.update(DPREFIX=str(prefix), EGL_PLATFORM='x11', LC_ALL='en_US.UTF-8') @@ -84,8 +87,8 @@ finally: try: stopped = subprocess.run(['darling', 'shutdown'], env=env, capture_output=True, timeout=25) if stopped.returncode == 0: - shutil.rmtree(prefix) + shutil.rmtree(private_root) else: - print('Private test prefix retained for inspection:', prefix) + print('Private test artifacts retained for inspection:', private_root) except (OSError, subprocess.SubprocessError): - print('Private test prefix retained for inspection:', prefix) + print('Private test artifacts retained for inspection:', private_root)