"""The execution track: synapse/code_run.py. Python is the only toolchain guaranteed present (it is the interpreter running these tests), so it carries the behavioural coverage — limits, streams, exit codes, isolation. The compiled languages are covered for the parts that hold without their toolchain installed (screening, argv shape, the missing-toolchain message) and skipped where they need it, so this file passes on a machine with no clang and no rustc as well as on one with both. """ import shutil import sys import pytest from synapse import code_run def _requires(lang): entry = code_run.RUN_LANGS[lang] return pytest.mark.skipif( not entry["tool"](), reason=f"no {lang} toolchain on this machine" ) # --------------------------------------------------------------------------- # Registry # --------------------------------------------------------------------------- def test_every_lang_has_a_complete_driver(): for name, entry in code_run.RUN_LANGS.items(): assert entry["summary"], name assert callable(entry["tool"]), name assert callable(entry["source_name"]), name assert callable(entry["run"]), name assert callable(entry["critique"]), name assert entry["install"], name def test_aliases_resolve_to_real_langs(): for alias, target in code_run.ALIASES.items(): assert target in code_run.RUN_LANGS, alias assert code_run.resolve_lang("C++") == "cpp" assert code_run.resolve_lang(" Py ") == "python" assert code_run.resolve_lang("javascript") == "javascript" # unknown passes through def test_erlang_source_name_follows_the_dialect(): """escript reads the same bytes two ways depending on the extension. Writing a bare main/1 script to main.erl makes it a module with no exports, which fails at load with an error that says nothing about the real problem.""" assert code_run._erlang_source_name("main(_) -> ok.") == "main.escript" assert code_run._erlang_source_name("-module(main).\nmain(_) -> ok.") == "main.erl" def test_erlang_escript_gets_a_shebang_when_missing(): """OTP 28+ rejects shebang-less .escript with 'Premature end of file'.""" bare = "main(_) -> ok.\n" out = code_run._erlang_write_source(bare) assert out.startswith("#!/usr/bin/env escript\n") assert out.endswith(bare) already = "#!/usr/bin/env escript\nmain(_) -> ok.\n" assert code_run._erlang_write_source(already) == already module = "-module(main).\n-export([main/1]).\nmain(_) -> ok.\n" assert code_run._erlang_write_source(module) == module # --------------------------------------------------------------------------- # Screening # --------------------------------------------------------------------------- def test_clean_snippets_pass_screening(): assert code_run.critique("python", "print(sum(range(100)))") == [] assert code_run.critique("c", '#include \nint main(void){puts("x");}') == [] assert code_run.critique("rust", 'fn main(){ println!("x"); }') == [] assert code_run.critique("erlang", 'main(_) -> io:format("x~n").') == [] @pytest.mark.parametrize("lang,source,needle", [ ("python", "import socket\nprint(socket)", "network"), ("python", "import requests\nprint(requests)", "network"), ("python", "import subprocess\nsubprocess.run(['ls'])", "processes"), ("c", "#include \nint main(void){return 0;}", "network"), ("c", '#include \nint main(void){system("ls");}', "processes"), ("rust", "fn main(){ std::process::Command::new(\"ls\"); }", "processes"), ("erlang", 'main(_) -> os:cmd("ls").', "processes"), ]) def test_screening_catches_the_obvious_reaches(lang, source, needle): issues = code_run.critique(lang, source) assert issues, f"{lang} snippet passed screening" assert any(needle in i for i in issues), issues def test_screening_catches_absolute_paths_and_urls(): assert any("absolute" in i for i in code_run.critique( "python", 'data = open("/etc/passwd").read()\nprint(data)')) # Escaped and raw Windows paths both count. assert any("absolute" in i for i in code_run.critique( "python", 'data = open("C:\\\\Users\\\\me").read()')) assert any("absolute" in i for i in code_run.critique( "python", r'data = open(r"C:\Users\me").read()')) assert any("http" in i for i in code_run.critique( "python", 'print("see https://example.com/data.csv")')) def test_url_in_a_comment_is_not_a_network_reach(): """A citation in a comment is not fetch(); bouncing it costs a useless retry.""" c = ( "/* spec: https://en.cppreference.com/w/c/string */\n" "#include \n" "int main(void){ puts(\"ok\"); return 0; }\n" ) assert code_run.critique("c", c) == [] def test_erlang_nproc_ceiling_is_relative_to_the_user(monkeypatch): """RLIMIT_NPROC is UID-scoped; an absolute 512 is not 512 of headroom.""" monkeypatch.setattr(code_run, "_user_process_count", lambda: 400) assert code_run._max_procs_for("erlang") == 400 + code_run._ERLANG_PROC_HEADROOM assert code_run._max_procs_for("python") == code_run._MAX_PROCS monkeypatch.setattr(code_run, "_user_process_count", lambda: None) assert code_run._max_procs_for("erlang") is None def test_missing_entry_point_is_named_up_front(): """Without this the user sees a linker error about _main, or an escript load failure — neither of which says 'you forgot the entry point'.""" assert any("main()" in i for i in code_run.critique("c", "int add(int a){return a+1;}")) assert any("main()" in i for i in code_run.critique("rust", "fn add(a: i32) -> i32 { a }")) assert any("main/1" in i for i in code_run.critique("erlang", "add(A) -> A + 1.")) def test_empty_source_says_so_and_stops(): issues = code_run.critique("python", " ") assert issues == ["source is empty or too short to run."] def test_unknown_lang_is_refused_by_both_entry_points(): assert code_run.critique("brainfuck", "+++.")[0].startswith("cannot run") assert code_run.run("brainfuck", "+++.")["ok"] is False def test_oversized_source_is_refused_without_running(): issues = code_run.critique("python", "x = 1\n" * 40_000) assert issues and "characters" in issues[0] # --------------------------------------------------------------------------- # Execution (python: always available) # --------------------------------------------------------------------------- def test_stdout_and_exit_code_come_back(): out = code_run.run("python", "print('hello', 6 * 7)") assert out["ok"] is True assert out["stdout"].strip() == "hello 42" assert out["exit_code"] == 0 def test_streams_are_kept_separate(): out = code_run.run("python", "import sys\nprint('o')\nprint('e', file=sys.stderr)") assert out["stdout"].strip() == "o" assert out["stderr"].strip() == "e" def test_nonzero_exit_is_still_a_successful_run(): out = code_run.run("python", "raise SystemExit(3)") assert out["ok"] is True assert out["exit_code"] == 3 def test_a_traceback_is_returned_not_raised(): out = code_run.run("python", "print(1/0)") assert out["ok"] is True assert out["exit_code"] != 0 assert "ZeroDivisionError" in out["stderr"] def test_stdin_is_piped_in(): out = code_run.run("python", "import sys\nprint(sys.stdin.read().upper())", stdin="abc") assert out["stdout"].strip() == "ABC" def test_a_program_reading_stdin_with_none_given_does_not_hang(): """stdin is always closed rather than inherited: a snippet calling input() with nothing piped in would otherwise block on the server's own stdin until the wall clock killed it, five seconds of 'thinking' for nothing.""" out = code_run.run("python", "print(input('prompt: '))") assert out["ok"] is True assert "EOFError" in out["stderr"] def test_an_infinite_loop_is_killed_and_explained(): out = code_run.run("python", "while True:\n pass") assert out["ok"] is False assert out["stage"] == "run" assert "did not finish" in out["error"] def test_output_is_truncated_not_streamed_whole(): out = code_run.run("python", f"print('x' * {code_run.MAX_OUTPUT * 3})") assert len(out["stdout"]) < code_run.MAX_OUTPUT + 200 assert "truncated" in out["stdout"] def test_the_working_directory_is_ephemeral(): """Two runs must not see each other's files. The temp dir is the only thing standing between a snippet and the user's cwd, so its lifetime is worth a test rather than an assumption.""" first = code_run.run("python", "open('note.txt', 'w').write('hi')\nprint('wrote')") assert first["ok"] is True, first second = code_run.run("python", "import os\nprint(os.path.exists('note.txt'))") assert second["stdout"].strip() == "False" def test_the_child_does_not_inherit_the_servers_environment(): """A snippet has no business reading the process environment it happens to be spawned from — that is where an API key would be.""" import os os.environ["NEXUS_RUN_LEAK_PROBE"] = "secret" try: out = code_run.run( "python", "import os\nprint(os.environ.get('NEXUS_RUN_LEAK_PROBE'))" ) finally: os.environ.pop("NEXUS_RUN_LEAK_PROBE", None) assert out["stdout"].strip() == "None" def test_home_points_at_the_scratch_dir(): """HOME is rewritten so a snippet writing a dotfile writes it somewhere that gets deleted, rather than into the user's real home.""" out = code_run.run("python", "import os\nprint(os.path.expanduser('~'))") assert "nexus-run-" in out["stdout"] # --------------------------------------------------------------------------- # Toolchains # --------------------------------------------------------------------------- def test_a_missing_toolchain_explains_itself(monkeypatch): """The model has to be able to tell 'you cannot run this here' from 'your code is wrong' — otherwise it rewrites a correct program repeatedly.""" monkeypatch.setitem( code_run.RUN_LANGS["rust"], "tool", lambda: None ) out = code_run.run("rust", 'fn main(){ println!("x"); }') assert out["ok"] is False assert out["stage"] == "toolchain" assert "rustup.rs" in out["error"] assert "Show the code instead" in out["error"] @_requires("c") def test_c_compiles_and_runs(): out = code_run.run("c", '#include \nint main(void){printf("%d\\n", 6*7);return 0;}') assert out["ok"] is True, out assert out["stdout"].strip() == "42" @_requires("c") def test_a_compile_error_comes_back_as_a_compile_error(): """Stage matters: the compiler's diagnostics are the useful payload, and labelling this a run failure would hide that nothing ever executed.""" out = code_run.run("c", "int main(void){ return oops; }") assert out["ok"] is False assert out["stage"] == "compile" assert "oops" in out["stderr"] @_requires("cpp") def test_cpp_compiles_and_runs(): out = code_run.run("cpp", '#include \nint main(){std::cout << 6*7 << "\\n";}') assert out["ok"] is True, out assert out["stdout"].strip() == "42" @_requires("rust") def test_rust_compiles_and_runs(): out = code_run.run("rust", 'fn main(){ println!("{}", (1..=10).sum::()); }') assert out["ok"] is True, out assert out["stdout"].strip() == "55" @_requires("erlang") def test_erlang_runs_a_bare_escript(): out = code_run.run("erlang", 'main(_) -> io:format("~p~n", [lists:sum(lists:seq(1,10))]).') assert out["ok"] is True, out assert out["stdout"].strip() == "55" @_requires("erlang") def test_erlang_runs_a_module_form_script(): out = code_run.run( "erlang", "-module(main).\n-export([main/1]).\nmain(_) -> io:format(\"~p~n\", [7*6]).", ) assert out["ok"] is True, out assert out["stdout"].strip() == "42" @pytest.mark.skipif(sys.platform != "linux", reason="unshare is Linux-only") def test_network_isolation_probe_is_honest(): """Either we got a namespace or we did not — but the probe must never claim one it did not verify, because the tool description promises 'no network' on the strength of it.""" prefix = code_run._net_isolation() assert prefix in ([], ["unshare", "-rn"]) if prefix: assert shutil.which("unshare")