Skip to content

Retry and pace TestOps uploads - #817

Closed
todti wants to merge 2 commits into
mainfrom
allurectl-signals-errors-pacer
Closed

Retry and pace TestOps uploads#817
todti wants to merge 2 commits into
mainfrom
allurectl-signals-errors-pacer

Conversation

@todti

@todti todti commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • TestOps upload error classificationerrors.ts classifies upload failures into transient (5xx/429/timeout), recoverable ("launch is closed"), or terminal (auth/validation/payload/conflict) kinds. withUploadRetry() retries only the retryable kinds with exponential backoff, and is now wired into all three TestOps upload call sites (test results, global attachments, global errors) — previously a single failed request just logged and gave up with no retry at all.
  • Upload rate pacinguploadPacer.ts adds a leaky-bucket pacer with independent per-window budgets for requests, files, and bytes sent to TestOps. Enabled by default with sane defaults (20 req/s, 1000 files/s, 1 GiB/s), since the server-side limits it approximates are real whether or not anyone explicitly configures for them. Can be disabled via a new uploadRateLimit: false plugin option, or tuned via an explicit uploadRateLimit config.

Also fixes an open.ts command that only handled SIGINT for temp-report cleanup — it now handles SIGTERM too, via a small shared utils/signals.ts helper (notifySignals/waitForAbort) with conventional exit codes (130/143) and a graceful-shutdown deadline.

@todti todti changed the title Port TestOps upload error classification and rate pacing from allurectl Retry and pace TestOps uploads Jul 23, 2026
Classify TestOps upload failures into transient (5xx/429/timeout),
recoverable ("launch is closed"), or terminal (auth/validation/payload/
conflict) kinds, and retry only the retryable ones with exponential
backoff. Wired into all three upload call sites (test results, global
attachments, global errors) — previously a failed request just logged
and gave up with no retry at all.

Add a leaky-bucket pacer with independent per-window budgets for
requests, files, and bytes sent to TestOps, enabled by default with
sane defaults (20 req/s, 1000 files/s, 1 GiB/s) since the server-side
limits it approximates are real regardless of whether anyone configures
for them. Disable via a new uploadRateLimit: false plugin option, or
tune it via an explicit uploadRateLimit config.

Also makes the `open` command's temp-report cleanup handle SIGTERM, not
just SIGINT, via a small shared signals helper (notifySignals/
waitForAbort) with conventional exit codes and a graceful-shutdown
deadline.
@todti
todti force-pushed the allurectl-signals-errors-pacer branch from 55ea290 to a3e71c2 Compare July 23, 2026 16:20
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Allure Report Summary

Name Duration Stats New Flaky Retry Report
Allure 3 Report 40m 41s Passed tests 9785   Skipped tests 15   Unknown tests 27 42 0 33 View
My Dashboard 40m 41s Passed tests 9785   Skipped tests 15   Unknown tests 27 42 0 33 View

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Allure perf metrics

Generated at: 2026-07-23T20:44:03.830Z

Phase Count Total Avg Min Max
restoreState.total 1 1701.2 ms 1701.2 ms 1701.2 ms 1701.2 ms
restoreState.dump 3 1700.8 ms 566.9 ms 517.7 ms 599.2 ms
restoreState.attachments 3 1250.0 ms 416.7 ms 383.9 ms 433.2 ms
restoreState.storeRestore 3 119.6 ms 39.9 ms 36.6 ms 42.7 ms
generate.total 1 5554.1 ms 5554.1 ms 5554.1 ms 5554.1 ms
generate.plugins.done 1 4942.9 ms 4942.9 ms 4942.9 ms 4942.9 ms
publish.upload.total 1 124589.5 ms 124589.5 ms 124589.5 ms 124589.5 ms
summary.generate 2 105.9 ms 52.9 ms 6.3 ms 99.6 ms
generate.plugin.done.agent 1 0.1 ms 0.1 ms 0.1 ms 0.1 ms
generate.plugin.done.awesome 1 4283.6 ms 4283.6 ms 4283.6 ms 4283.6 ms
generate.plugin.done.dashboard 1 655.3 ms 655.3 ms 655.3 ms 655.3 ms
generate.plugin.done.log 1 3.3 ms 3.3 ms 3.3 ms 3.3 ms
publish.upload.plugin.awesome 1 101948.0 ms 101948.0 ms 101948.0 ms 101948.0 ms
publish.upload.plugin.dashboard 1 15148.0 ms 15148.0 ms 15148.0 ms 15148.0 ms

Artifacts: allure-perf-metrics

- classifyError only recognized raw AxiosError, but TestOpsClient never
  sees one: @allurereport/service wraps every HTTP failure into a
  KnownError/UnknownError first, so retry classification silently fell
  through to Unknown and withUploadRetry never retried anything for real.
- uploadTestResults swallowed its own errors internally, making the
  retry wrapper around it a no-op; it now lets failures propagate, with
  logging moved to the plugin-level catch (matching the other upload
  call sites).
- Wire the pacer into every upload call site (global attachments,
  per-result attachments/fixtures, quality gate), including byte cost
  for attachment content, not just requests/files.
- Add reopenClosedLaunch option: reopens a launch TestOps reports as
  closed instead of failing the upload outright.
- Wrap quality gate upload in withUploadRetry, the one upload path that
  was missing it.
@todti todti mentioned this pull request Jul 23, 2026
3 tasks
@todti todti closed this Jul 23, 2026
@todti
todti deleted the allurectl-signals-errors-pacer branch July 23, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant