TEST-37: test_opt34 stale_live no longer depends on the real clock #231

Merged
admin merged 1 commits from TEST-37 into hotfix-0.20.1 2026-11-05 13:56:39 +01:00
Owner

The first Controller in test_opt34's run_night was built before the datetime patch, so Controller.init judged the stale_live latch (ends 2026-11-04 07:15 CET) against the real clock; it expired on 2026-11-04 and 'latch does charge both' failed on every branch. Now built after the patch with the clock at the scenario start (the restart path already did). Test-only, nothing under app/, no CHANGELOG.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC

The first Controller in test_opt34's run_night was built before the datetime patch, so Controller.__init__ judged the stale_live latch (ends 2026-11-04 07:15 CET) against the real clock; it expired on 2026-11-04 and 'latch does charge both' failed on every branch. Now built after the patch with the clock at the scenario start (the restart path already did). Test-only, nothing under app/, no CHANGELOG. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
admin added 1 commit 2026-11-05 11:02:19 +01:00
TEST-37: test_opt34 builds the first Controller under the scenario clock
checks / unit (pull_request) Successful in 30m38s
infra-pin / fresh (pull_request) Successful in 2s
95bb214155
The stale_live scenario stores a latch ending 2026-11-04 07:15 CET. The first
Controller was built before the datetime patch, so Controller.__init__ judged
that latch against the real clock and it expired on 2026-11-04. Build it after
the patch (clock = scenario start), as the restart path already did. Test-only.

Co-Authored-By: Claude <noreply@anthropic.com>
Author
Owner

TEST-37 review (head 95bb214): approved, merging.

  1. Scope: only goodwe_controller/test_opt34.py (+4 -1). Nothing in app/, no CHANGELOG, no config.yaml.
  2. Cause and fix are right. Controller.__init__ reads datetime.now() once, for the stored latch (app/main.py:1041-1043). The first Controller in run_night was built before the clock patch, so it used the real clock. It is now built inside the patch at the scenario start. The restart path already worked this way. No check, tolerance or scenario date was changed. Proof that it still tests what OPT-34 meant: base 22d09f8 with the clock set to 2026-11-03 11:00 (before the latch ran out) and head today print identical test_opt34 output, apart from the run time.
  3. My own runs in goodwe-addon-checks:1 (--network none, sim mounted, GOODWE_REQUIRE_HWSIM=1, using the dev's clock shim, which I read first):
    • base, today: FAIL, the same check as on the card ("control: the same latch ... does charge both", A 10.0 B 10.0)
    • head, today: all checks pass. With the clock at 2027-06-01 and 2030-01-01 the output is identical.
    • full suite on head, today: 94 files, 0 failed. At 2027-06-01: 94 files, 0 failed.
  4. Scan spot-check: test_opt36, test_maint13, test_safety126 and test_arbitrage use the real clock only relative to now, or as a stopwatch. test_opt36 also builds its Controller before its clock patch, but it never stores a latch, so __init__ has nothing to expire. Only test_opt34 and test_opt36 store or read _charge_latch in __init__'s path. I agree with the dev: there are no other date bombs.
  5. CI run 1528, job 2679, checks / unit (pull_request): success on 95bb214. In the log test_opt34 passes and the result is 94 files, 0 failed.

Note (no action): the clock is set to start when the Controller is built, then moves back to the evening reads. This is harmless, because the latch load is the only use of now() in __init__.

**TEST-37 review (head 95bb214): approved, merging.** 1. Scope: only `goodwe_controller/test_opt34.py` (+4 -1). Nothing in `app/`, no CHANGELOG, no config.yaml. 2. Cause and fix are right. `Controller.__init__` reads `datetime.now()` once, for the stored latch (`app/main.py:1041-1043`). The first Controller in `run_night` was built before the clock patch, so it used the real clock. It is now built inside the patch at the scenario start. The restart path already worked this way. No check, tolerance or scenario date was changed. Proof that it still tests what OPT-34 meant: base 22d09f8 with the clock set to 2026-11-03 11:00 (before the latch ran out) and head today print identical test_opt34 output, apart from the run time. 3. My own runs in `goodwe-addon-checks:1` (`--network none`, sim mounted, `GOODWE_REQUIRE_HWSIM=1`, using the dev's clock shim, which I read first): - base, today: FAIL, the same check as on the card ("control: the same latch ... does charge both", A 10.0 B 10.0) - head, today: all checks pass. With the clock at 2027-06-01 and 2030-01-01 the output is identical. - full suite on head, today: 94 files, 0 failed. At 2027-06-01: 94 files, 0 failed. 4. Scan spot-check: test_opt36, test_maint13, test_safety126 and test_arbitrage use the real clock only relative to now, or as a stopwatch. test_opt36 also builds its Controller before its clock patch, but it never stores a latch, so `__init__` has nothing to expire. Only test_opt34 and test_opt36 store or read `_charge_latch` in `__init__`'s path. I agree with the dev: there are no other date bombs. 5. CI run 1528, job 2679, `checks / unit (pull_request)`: success on 95bb214. In the log test_opt34 passes and the result is 94 files, 0 failed. Note (no action): the clock is set to `start` when the Controller is built, then moves back to the evening reads. This is harmless, because the latch load is the only use of now() in `__init__`.
admin merged commit cfe1f06286 into hotfix-0.20.1 2026-11-05 13:56:39 +01:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/goodwe-addon#231