fix(test-e2e-playwright): scale onion timeouts by the tor flavor instead of a flat five

resolveTimeout multiplies every Playwright window by 5 for a .onion
target. That default arrived in 35dee215c8 (2026-07-08), before
5399b48482 (2026-07-24) gave CI the chutney flavor, a private Tor net on
localhost, and PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIER was never set. Waits
that expire by design therefore cost five times their base under chutney
too, which is where most of the Tor surcharge came from.

The Playwright run now passes the multiplier for onion targets only,
looked up from svc-net-tor's services.tor.flavor: 2 for chutney, 5 for
the public network, whose circuits really are slow. An unknown flavor
fails the lookup instead of falling back, and a unit test holds every
flavor directory of svc-net-tor to an entry.

Chutney traces of run 34421944328: 700 successful timed waits across 186
tests used at most 0.42 of their unscaled window, and the longest
client-side expect took 5.1s. Across runs 34421944328 and 34419507038 no
chutney test with its own ceiling (401 of them) used more than 53% of
the new x2 ceiling, even at today's x5-stretched duration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-09-10 15:53:08 +02:00
1 parent dcb9ddb9cf
commit 214e7e29d1
3 files changed
+35

No files matched your search

@@ -234,6 +234,7 @@
+ ['-e', 'PLAYWRIGHT_FULLY_PARALLEL=' ~ TEST_E2E_PLAYWRIGHT_FULLY_PARALLEL]
+ ['-e', 'PLAYWRIGHT_TEST_TIMEOUT=' ~ (TEST_E2E_PLAYWRIGHT_ONION_TEST_TIMEOUT if (TEST_E2E_PLAYWRIGHT_IS_ONION | bool) else test_e2e_playwright_test_timeout)]
+ ['-e', 'PLAYWRIGHT_TIMEOUT_FACTOR=' ~ TIMEOUT_FACTOR]
+ (['-e', 'PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIER=' ~ TEST_E2E_PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIER] if (TEST_E2E_PLAYWRIGHT_IS_ONION | bool) else [])
+ ['-e', 'PLAYWRIGHT_NAVIGATION_TIMEOUT=' ~ (TEST_E2E_PLAYWRIGHT_ONION_NAVIGATION_TIMEOUT if (TEST_E2E_PLAYWRIGHT_IS_ONION | bool) else TEST_E2E_PLAYWRIGHT_NAVIGATION_TIMEOUT)]
+ ['-v', _playwright_stage_dir ~ ':/e2e']
+ ['-v', _playwright_stage_dir ~ '/volume:/volume']
+4
View File
@@ -34,6 +34,10 @@ TEST_E2E_PLAYWRIGHT_ONION_RUN_TIMEOUT: 5400
TEST_E2E_PLAYWRIGHT_RUN_TIMEOUT_EFFECTIVE: "{{ TEST_E2E_PLAYWRIGHT_ONION_RUN_TIMEOUT if (TEST_E2E_PLAYWRIGHT_IS_ONION | bool) else test_e2e_playwright_run_timeout
}}"
TEST_E2E_PLAYWRIGHT_ONION_TEST_TIMEOUT: 900000
TEST_E2E_PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIERS:
chutney: 2
public: 5
TEST_E2E_PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIER: "{{ TEST_E2E_PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIERS[lookup('config', 'svc-net-tor', 'services.tor.flavor')] }}"
TEST_E2E_PLAYWRIGHT_WAIT_ENABLED: true
TEST_E2E_PLAYWRIGHT_WAIT_RETRIES: 30
TEST_E2E_PLAYWRIGHT_WAIT_DELAY: 5
@@ -0,0 +1,30 @@
import unittest
import yaml
from . import PROJECT_ROOT
VARS_PATH = PROJECT_ROOT / "roles" / "test-e2e-playwright" / "vars" / "main.yml"
FLAVOR_DIR = PROJECT_ROOT / "roles" / "svc-net-tor" / "tasks" / "flavor"
class TestOnionTimeoutMultipliers(unittest.TestCase):
def test_every_tor_flavor_has_a_multiplier(self):
multipliers = yaml.safe_load(VARS_PATH.read_text())[
"TEST_E2E_PLAYWRIGHT_ONION_TIMEOUT_MULTIPLIERS"
]
flavors = {path.name for path in FLAVOR_DIR.iterdir() if path.is_dir()}
self.assertTrue(flavors)
self.assertEqual(
sorted(flavors - set(multipliers)),
[],
"the Playwright run looks the multiplier up by the tor flavor and fails without one",
)
for flavor, value in multipliers.items():
self.assertIsInstance(value, int, flavor)
self.assertGreaterEqual(value, 1, flavor)
if __name__ == "__main__":
unittest.main()