Skip to content

server2: make the province mid forecast test independent of the zone list's arrival - #2901

Draft
hwanjjang wants to merge 2 commits into
masterfrom
fix/2614-kma-test-clock
Draft

hwanjjang wants to merge 2 commits into
masterfrom
fix/2614-kma-test-clock

Conversation

@hwanjjang

Copy link
Copy Markdown
Collaborator

Summary

full_response::a_province_under_its_new_name_finds_its_town_and_mid_forecast failed intermittently. It looked time-of-day dependent, but the cause is a race in the test:

  • S3Source::zones() starts the process's forecast-zone fetch without waiting for it (src/domestic/kma/source/mod.rs ~462-514). refresh_zones() then uses the stored list if there is one, otherwise the release's land zones.
  • The test's double answered the zone page with Seoul only. When that list was stored first, towns outside Seoul had no city zone, their mid temperature was not collected, and the test failed with temperature-unavailable.
  • Forcing the wall clock changed nothing: the backend and the zone path use the injected time.

Failure rate, measured by running the test repeatedly with a faked wall clock:

Code Rate
master 1/20 at 08:15, 3/20 at 20:15
#2872 head about 60%

#2872 reads day products at the start of a request, so the zone read starts later.

Change (test only)

  • The double answers the Seoul fixture plus every land zone of Zones::packaged(), as the provider's list does.
  • The test runs each town both with the list stored first and without it.
  • Red: 5/5 failures at forced 08:15 and 20:15 before the fix. After: 20/20 in a row, 5/5 with the CPU saturated, and 60/60 across six forced times.

The same change is in #2872, declared under that PR's task.

Checks

  • fmt and clippy are clean. The full suite has 1,213 passed and 0 failed.
  • The placement gate (KMA-TEST-CLOCK.json) and the artifact policy pass.
  • Other tests that read the real clock are only at risk across a boundary (KST midnight or an hour), not at a time of day: tests/domestic/quota.rs:50, source_s3.rs:1083, air_s3.rs:458 and :628. They are listed, not changed.

🤖 Generated with Claude Code

full_response::a_province_under_its_new_name_finds_its_town_and_mid_forecast
failed intermittently, not at a time of day. The request starts the
process's forecast-zone acquisition without waiting for it and then reads
the stored lists (S3Source::zones/refresh_zones): the release's land zones
when none is stored, the stored list otherwise. The test double answered
the Seoul-only zone_page fixture, so whenever its publication won that
race the towns outside Seoul had no city zone, their mid temperatures were
not collected and the status said temperature-unavailable.

With the wall clock forced to morning and evening starts, master failed
1 to 3 times in 20 at both. #2872 (from b7b81b5, which reads the day
products at the request's start) fails about 60% at any forced time
(12:00 and 20:15 interleaved: 23/40 and 25/40): more request-lane reads
before the zone read, not a clock read.

The test now runs every town with the list stored before the request and
without it, and the double answers the release's land zones besides the
Seoul fixture, as the provider's list holds them. Test-only change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hwanjjang

Copy link
Copy Markdown
Collaborator Author

Cross-provider review (Codex gpt-6.1-sol, high), round 1: PASS at 0c76e77.

Recommended

…TC-force-fallback-order)

full_response::a_province_under_its_new_name_finds_its_town_and_mid_forecast
asked each town with the forecast-zone list stored first and "without
it", but nothing kept the request's own zone acquisition from storing
the list before the answer: counting the lists S3 held when the answer
was made, the "without" case had one in 10 of 10 runs, so it did not pin
the release's land-zone fallback.

In that case the double's zone request now waits at a barrier
(HeldZones) until the answer has been checked, and the test asserts the
lists S3 held at the answer (none, or the one stored first) and that the
held request stores its list once released. 10/10 passes; with the
packaged fallback removed it fails in that case
(temperature-unavailable).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hwanjjang

Copy link
Copy Markdown
Collaborator Author

Cross-provider review (Codex gpt-6.1-sol, high), round 2: PASS at 64541ef. TC-force-fallback-order is resolved: the held zone request now pins the packaged fallback path.

@hwanjjang

Copy link
Copy Markdown
Collaborator Author

Final readiness (pre-merge): merge-ready at 64541ef on master 0ed2eaa. CI passes, and the cross-provider review passed (Codex, two rounds; the selected recommendation is applied). The PR has no auto-merge and no merge queue. Merging is AK's decision. If master moves before this is merged, master must be merged into this branch before any further push (the CI placement base stays at the merge base). #2872 carries the identical test change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant