From 9505dd7095d3a4e0f7ed438c70598dbca6476667 Mon Sep 17 00:00:00 2001 From: scarreras Date: Mon, 2 Nov 2026 03:53:37 -0300 Subject: [PATCH] test(sdkharness): run the upload.stall recovery check with a stall longer than the upload timeout The check stalls the upload for 130 s, above b2sdk's 128 s upload timeout (the simulator now accepts a stall up to 300000 ms), instead of skipping with no-client-option. CI and GITHUB_REPOSITORY are removed from the CLI's environment so its CI-only short-timeout hook never applies. Co-Authored-By: Claude Sonnet 5.5 --- .sdkharness/tests/resilience-upload.py | 19 +++++++++++-------- ...+sdkharness-upload-stall.infrastructure.md | 1 + 2 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 changelog.d/+sdkharness-upload-stall.infrastructure.md diff --git a/.sdkharness/tests/resilience-upload.py b/.sdkharness/tests/resilience-upload.py index f395c7d9..31f84409 100755 --- a/.sdkharness/tests/resilience-upload.py +++ b/.sdkharness/tests/resilience-upload.py @@ -19,6 +19,7 @@ from collections.abc import Mapping LEVEL = 'resilience' +STALL_MS = 130000 # above b2sdk's 128 s upload timeout; the simulator accepts up to 300000 SCENARIOS = { 'upload.retry_503': ('b2_upload_file', 503, 'service_unavailable'), 'upload.retry_500': ('b2_upload_file', 500, 'internal_error'), @@ -192,7 +193,13 @@ class Cli: def __init__(self, scratch: str) -> None: self.scratch = scratch - self.env = {k: v for k, v in os.environ.items() if not k.startswith('B2_')} + # CI and GITHUB_REPOSITORY are dropped so the CLI's CI-only short-timeout hook + # (b2/_internal/_cli/b2api.py) never applies: a customer's CLI has the default timeouts. + self.env = { + k: v + for k, v in os.environ.items() + if not k.startswith('B2_') and k not in ('CI', 'GITHUB_REPOSITORY') + } self.env.update( B2_APPLICATION_KEY_ID='test-key-id', B2_APPLICATION_KEY='test-key', @@ -375,12 +382,6 @@ def run_retry() -> None: def run_wire_fault() -> None: kind = WIRE_SCENARIOS[SCENARIO] - if kind == 'stall': - raise Skip( - 'no-client-option', - 'the CLI exposes no supported per-request timeout shorter than the controlled stall', - ) - cli, bucket = setup() payload = (b'sdkharness resilience wire fault ' * 64)[:1024] arm() @@ -575,7 +576,9 @@ def main() -> int: kind = WIRE_SCENARIOS[SCENARIO] FAULT = {'on': 'b2_upload_file', 'kind': kind, 'count': 1} if kind == 'stall': - FAULT['ms'] = 60000 + # The CLI has no timeout option, so the stall must outlast b2sdk's own upload + # timeout (b2http.TIMEOUT_FOR_UPLOAD, 128 s) for the client to give up on it. + FAULT['ms'] = STALL_MS ARM_PATH = '/wire-faults' run_wire_fault() elif SCENARIO in API_SCENARIOS: diff --git a/changelog.d/+sdkharness-upload-stall.infrastructure.md b/changelog.d/+sdkharness-upload-stall.infrastructure.md new file mode 100644 index 00000000..f59cbe76 --- /dev/null +++ b/changelog.d/+sdkharness-upload-stall.infrastructure.md @@ -0,0 +1 @@ +Make the `.sdkharness` `upload.stall` recovery check run: it stalls the upload for 130 s, longer than the 128 s upload timeout of b2sdk, instead of reporting that no client option can shorten it.