Skip to content

A timed-out poll abandons the 700-second summary wait in _wait_for_image_numbers #3509

Description

@adamtheturtle

What happens

_wait_for_image_numbers in tests/mock_vws/test_database_summary.py polls GET /summary for up to 700 seconds, because, as its comment says, "the database summary endpoint lags behind the real data". Its retry predicate is:

retry=retry_if_exception_type(exception_types=(AssertionError,)),

tests/mock_vws/test_database_summary.py:42

So the loop retries a stale summary, but any transient failure of a poll — a read timeout, a 429, a 5xx — is not retried and propagates, ending the test with the wait budget mostly unspent.

Where it was seen

TestDatabaseSummary::test_active_images[Real Vuforia] failed twice in a row on #3505 with:

requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='vws.vuforia.com', port=443): Read timed out. (read timeout=30.0)

The second attempt logged 758 polls, every one of them Actual: {'active_images': 0, 'inactive_images': 0, 'failed_images': 1, 'processing_images': 0} — the summary was serving a stale failed_images: 1 while the target the target_id fixture added was in fact successful. The test then died on a timed-out poll at roughly 415 seconds, so the remaining ~285 seconds of the 700-second allowance were never used.

Suggested resolution

Retry the same transient exceptions the rest of the suite already retries. tests/mock_vws/utils/retries.py:13 defines them:

TRANSIENT_VWS_EXCEPTIONS = (TooManyRequestsError, ServerError, RequestsTimeout)

Adding those to the predicate keeps a single flaky poll from throwing away the wait:

retry=retry_if_exception_type(
    exception_types=(AssertionError, *TRANSIENT_VWS_EXCEPTIONS),
),

Two things worth saying plainly. This is not guaranteed to turn the observed failures green — if the summary stays stale past 700 seconds the test fails anyway, and how long Vuforia takes to catch up is not something we control. And pytest-retry does already retry the whole test on these exceptions, but each retry restarts the 700-second clock and adds another target, which is both slower and more API traffic than retrying the one poll that failed.

The same pattern exists in a loop in tests/mock_vws/test_query.py (around line 2050), though with a 3-second window there is much less to lose.

Context

This surfaced because adding a ci_pattern entry shifts every later job's SECRET_INDEX (job-index % 100), so test_active_images moved from database 37 to database 38 — which test_failed_images previously used, and whose summary still reported that test's failed_images: 1. The lag is the underlying problem either way; the reshuffle just made it visible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions