Files
computer-playbook/tests/unit/python/roles/test-e2e-playwright/test_timeouts_helper.py
T
kevinveenbirkenbachandClaude Opus 5 f068efc728 fix(domains): carry the rename into the escaped form the search missed
INFINITO_DOMAIN_RE is INFINITO_DOMAIN with the dot escaped for regex use, and
the comment directly above it says to keep the two in sync. The rename moved
INFINITO_DOMAIN to infinito.test and left the escaped twin on infinito.example,
because the backslash hid it from a literal search for the old domain.

Its only consumer is compose/coredns/Corefile.tmpl, which matches on it four
times. CoreDNS was therefore rewriting for infinito.example while every deploy
answered under infinito.test, so none of the four rules could match a name the
stack actually resolves.

The two test files are ruff format reflow: the shorter domain lets the calls
fit on one line again. autoformat wrote them; they are here because the rename
shipped without it, not because anything about them changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 15:53:20 +02:00

122 lines
3.6 KiB
Python

"""Unit tests for roles/test-e2e-playwright/files/timeouts.js.
The helper is dependency-free plain CommonJS. We copy it into a temp dir
and call it from a short Node script with controlled env, then assert the
computed timeout / onion detection.
"""
import os
import shutil
import subprocess
import tempfile
import textwrap
import unittest
from pathlib import Path
from . import PROJECT_ROOT
HELPER_PATH = str(
PROJECT_ROOT / "roles" / "test-e2e-playwright" / "files" / "timeouts.js"
)
def _have_node():
return shutil.which("node") is not None
@unittest.skipUnless(_have_node(), "node is not available in PATH")
class TestTimeoutsHelper(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp(prefix="timeouts-helper-")
shutil.copy(HELPER_PATH, str(Path(self.tmpdir) / "timeouts.js"))
def tearDown(self):
shutil.rmtree(self.tmpdir, ignore_errors=True)
def _run(self, expr, env):
script = textwrap.dedent(
f"""
const t = require("./timeouts");
process.stdout.write("RESULT:" + JSON.stringify({expr}) + "\\n");
"""
)
script_path = str(Path(self.tmpdir) / "run.js")
with Path(script_path).open("w") as f:
f.write(script)
proc = subprocess.run(
["node", "run.js"],
capture_output=True,
text=True,
env={**os.environ, **env},
cwd=self.tmpdir,
timeout=10,
check=False,
)
self.assertEqual(
proc.returncode, 0, msg=f"stderr={proc.stderr}\nstdout={proc.stdout}"
)
return proc.stdout
def test_clearnet_default_factor_is_identity(self):
out = self._run(
"t.resolveTimeout(60000)",
{"CANONICAL_DOMAIN": '"x.infinito.test"'},
)
self.assertIn("RESULT:60000", out)
def test_onion_applies_default_multiplier(self):
out = self._run(
"t.resolveTimeout(60000)",
{"CANONICAL_DOMAIN": '"x.abc123.onion"'},
)
self.assertIn("RESULT:300000", out)
def test_global_factor_scales_clearnet(self):
out = self._run(
"t.resolveTimeout(60000)",
{
"CANONICAL_DOMAIN": "x.infinito.test",
"PLAYWRIGHT_TIMEOUT_FACTOR": "2",
},
)
self.assertIn("RESULT:120000", out)
def test_factor_and_onion_multiplier_compose(self):
out = self._run(
"t.resolveTimeout(60000)",
{
"CANONICAL_DOMAIN": '"x.abc123.onion"',
"PLAYWRIGHT_TIMEOUT_FACTOR": "2",
"PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIER": "3",
},
)
self.assertIn("RESULT:360000", out)
def test_invalid_factor_falls_back_to_one(self):
out = self._run(
"t.resolveTimeout(60000)",
{
"CANONICAL_DOMAIN": "x.infinito.test",
"PLAYWRIGHT_TIMEOUT_FACTOR": "0",
},
)
self.assertIn("RESULT:60000", out)
def test_is_onion_target_detects_quoted_and_bare(self):
self.assertIn(
"RESULT:true",
self._run("t.isOnionTarget()", {"CANONICAL_DOMAIN": '"x.abc.onion"'}),
)
self.assertIn(
"RESULT:true",
self._run("t.isOnionTarget()", {"CANONICAL_DOMAIN": "x.abc.onion"}),
)
self.assertIn(
"RESULT:false",
self._run("t.isOnionTarget()", {"CANONICAL_DOMAIN": '"x.infinito.test"'}),
)
if __name__ == "__main__":
unittest.main()