← Files Codex ReplayARCHIVED FILE
tests/test_node_runtime.py
8.58 KB · Nov 3, 2026 · 18:31 UTC
"""Node runtime discovery under restricted MCP server environments."""
from __future__ import annotations
import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock
from test_mcp_server import load_server
class NodeRuntimeTests(unittest.TestCase):
def test_packaged_worker_preserves_selected_node_for_its_wrapper(self) -> None:
server = load_server()
node_runtime = server._node_runtime()
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
host_bin = root / "host-bin"
host_bin.mkdir()
stale_bin = root / "stale-bin"
stale_bin.mkdir()
stale_node = stale_bin / "node"
stale_node.write_text(
"#!/bin/sh\nprintf 'stale node selected\\n' >&2\nexit 91\n", encoding="utf-8"
)
stale_node.chmod(0o700)
fake_codex = host_bin / "codex"
fake_codex.write_text(
"\n".join(
[
f"#!{sys.executable}",
"import json, os, sys",
"if sys.argv[1:] == ['--version']:",
" print('codex fixture')",
" raise SystemExit(0)",
"if sys.argv[1] == 'app-server':",
" for line in sys.stdin:",
" message = json.loads(line)",
" if 'id' in message:",
" print(json.dumps({'id': message['id'], 'result': {'config': {}, 'requirements': None}}), flush=True)",
" raise SystemExit(0)",
"sys.stdin.read()",
"print(json.dumps({'type': 'thread.started', 'thread_id': 'runtime-thread'}))",
"environment = {name: os.environ[name] for name in ('PATH', 'GIT_EXEC_PATH')}",
"assert 'REPLAY_SECRET_CANARY' not in os.environ",
"environment['CLI_EXECUTABLE'] = sys.argv[0]",
"print(json.dumps({'type': 'item.completed', 'item': {'type': 'agent_message', 'text': json.dumps(environment)}}))",
"print(json.dumps({'type': 'turn.completed', 'usage': {'input_tokens': 1, 'output_tokens': 1}}))",
"",
]
),
encoding="utf-8",
)
fake_codex.chmod(0o700)
selected_bin = root / "selected-node-bin"
selected_bin.mkdir()
selected_node = selected_bin / "node"
selected_node.symlink_to(node_runtime)
alternate_codex = selected_bin / "codex"
alternate_codex.write_text(fake_codex.read_text(encoding="utf-8"), encoding="utf-8")
alternate_codex.chmod(0o700)
node_directory = str(selected_bin)
cases = {
"missing-node": [str(host_bin)],
"stale-node": [str(stale_bin), str(host_bin)],
"selected-node-later": [
str(stale_bin),
str(host_bin),
node_directory,
node_directory,
],
"automatic-cli": [str(host_bin), node_directory],
}
for name, path_entries in cases.items():
with self.subTest(name=name):
run_directory = root / name
run_directory.mkdir()
environment = {
"PATH": os.pathsep.join(path_entries),
"CODEX_MCP_NODE_PATH": str(selected_node),
"GIT_EXEC_PATH": str(root / "host-git-helpers"),
"REPLAY_SECRET_CANARY": "synthetic-must-not-reach-node",
}
if name != "automatic-cli":
environment["CODEX_CLI_PATH"] = str(fake_codex)
with (
mock.patch.dict(os.environ, environment, clear=True),
):
result = server._run_worker(
{"model": "gpt-5.6-sol", "prompt": "Check the worker runtime."},
run_directory=run_directory,
working_directory=root,
read_only=True,
log_label="runtime-test",
timeout=10,
)
self.assertEqual(dict(os.environ), environment)
self.assertEqual(result["thread_id"], "runtime-thread")
child_environment = json.loads(result["finalResponse"])
self.assertEqual(
child_environment["PATH"],
os.pathsep.join(
[node_directory, *[p for p in path_entries if p != node_directory]]
),
)
self.assertEqual(
child_environment["GIT_EXEC_PATH"], environment["GIT_EXEC_PATH"]
)
self.assertEqual(child_environment["CLI_EXECUTABLE"], str(fake_codex))
def test_uses_codex_runtime_hints_without_path(self) -> None:
server = load_server()
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
cases = (
(
{"CODEX_BROWSER_USE_NODE_PATH": str(root / "browser-node")},
root / "browser-node",
),
(
{"CODEX_ELECTRON_RESOURCES_PATH": str(root / "resources")},
root / "resources" / "cua_node" / "bin" / "node",
),
(
{"CODEX_CLI_PATH": str(root / "cli" / "codex")},
root / "cli" / "cua_node" / "bin" / "node",
),
)
for environment, node in cases:
with self.subTest(environment=environment):
node.parent.mkdir(parents=True, exist_ok=True)
node.write_text("#!/bin/sh\nprintf 'v22.0.0\\n'\n", encoding="utf-8")
node.chmod(0o700)
with mock.patch.dict(os.environ, {"PATH": "", **environment}, clear=True):
self.assertEqual(server._node_runtime(), str(node))
def test_uses_bundled_runtime_without_path(self) -> None:
server = load_server()
with tempfile.TemporaryDirectory() as temporary:
cache_root = Path(temporary)
node = cache_root / "codex-runtimes/codex-primary-runtime/dependencies/node/bin/node"
node.parent.mkdir(parents=True)
node.write_text("#!/bin/sh\nprintf 'v22.0.0\\n'\n", encoding="utf-8")
node.chmod(0o700)
with mock.patch.dict(
os.environ, {"XDG_CACHE_HOME": str(cache_root), "PATH": ""}, clear=True
):
self.assertEqual(server._node_runtime(), str(node))
def test_uses_homebrew_without_path(self) -> None:
server = load_server()
node = Path("/opt/homebrew/bin/node")
with (
mock.patch.dict(os.environ, {"PATH": ""}, clear=True),
mock.patch.object(
server.Path, "is_file", autospec=True, side_effect=lambda path: path == node
),
mock.patch.object(server.os, "access", return_value=True),
mock.patch.object(
server.subprocess, "run", return_value=mock.Mock(returncode=0, stdout="v22.0.0\n")
),
):
self.assertEqual(server._node_runtime(), str(node))
def test_skips_unsupported_fallback_runtime(self) -> None:
server = load_server()
with tempfile.TemporaryDirectory() as temporary:
cache_root = Path(temporary)
node = cache_root / "codex-runtimes/codex-primary-runtime/dependencies/node/bin/node"
node.parent.mkdir(parents=True)
node.write_text("#!/bin/sh\nprintf 'v16.20.0\\n'\n", encoding="utf-8")
node.chmod(0o700)
with (
mock.patch.dict(
os.environ, {"XDG_CACHE_HOME": str(cache_root), "PATH": ""}, clear=True
),
mock.patch.object(
server.Path, "is_file", autospec=True, side_effect=lambda path: path == node
),
mock.patch.object(server.shutil, "which", return_value="/existing/node"),
):
self.assertEqual(server._node_runtime(), "/existing/node")
SHA-256: c9774e380bbcc20a4ff38187d5bb6f9983f50336e958c019a3e7a82354c95a4a