Skip to content

test(cron): cover the control-log retention trim end-to-end against real Postgres - #330

Merged
hhvrc merged 3 commits into
developfrom
test/cover-control-log-cleanup-query
Jul 1, 2026
Merged

test(cron): cover the control-log retention trim end-to-end against real Postgres#330
hhvrc merged 3 commits into
developfrom
test/cover-control-log-cleanup-query

Conversation

@hhvrc

@hhvrc hhvrc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What

Mirrors the outbox claim-query extraction (#328) for the other piece of raw SQL in the Cron jobs — the ClearOldShockerControlLogs retention trim.

  • Extract the inline CTE DELETE into Common/OpenShockDb/ShockerControlLogQueries.csDeleteControlLogsBeyondPerUserLimitAsync(this OpenShockContext, int maxPerUser), a single source of truth the job and tests share. Parameterized by the per-user cap so tests can drive it with a small limit.
  • ClearOldShockerControlLogs now calls that extension with HardLimits.MaxShockerControlLogsPerUser. No behavior change (identical SQL).
  • Add Cron.IntegrationTests/Tests/ControlLogRetentionTests.cs (beside the other Cron delivery tests): seeds a user → device → shocker → logs graph and runs the actual statement against a Testcontainers Postgres — exercising the real table/column names, the shocker → device → owner join, the per-user window function, and newest-first ordering. Asserts the newest N survive and the older rows are deleted.

Why

Same rationale as #328: inline raw SQL means a table/column rename only surfaces in the Cron host at runtime. Extracted and covered, a schema drift fails the test instead. The test lives in Cron.IntegrationTests because it exercises a Cron job's query, resolving the pooled OpenShockContext from the Cron host's own DI.

Notes

  • The trim is a global statement, but no other integration test writes shocker control logs, so the seeded user's rows are the only ones in the table — the deleted-count assertion is deterministic and the DELETE can't disturb other tests.

Open in Stage

…eal Postgres

Extract ClearOldShockerControlLogs' inline CTE DELETE into
ShockerControlLogQueries.DeleteControlLogsBeyondPerUserLimitAsync (Common) as a
single source of truth, parameterized by the per-user cap so tests can drive it
with a small limit. The job now calls it with HardLimits.MaxShockerControlLogsPerUser.

Add a Cron integration test (Cron.IntegrationTests, alongside the delivery tests)
that seeds a user -> device -> shocker -> logs graph and runs the actual statement
against a Testcontainers Postgres: it exercises the real table/column names, the
shocker -> device -> owner join, the per-user window function, and newest-first
ordering, asserting the newest N survive and the rest are deleted. A schema rename
now fails the test rather than only the Cron host at runtime. Mirrors the outbox
claim-query extraction (#328). No behavior change to the job.
Copilot AI review requested due to automatic review settings July 1, 2026 11:04
@ghost

ghost commented Jul 1, 2026

Copy link
Copy Markdown

Ready to review this PR? Stage has broken it down into 3 individual chapters for you:

Title
1 Extract control log retention query to reusable extension
2 Refactor Cron job to use extracted query
3 Add integration tests for control log retention
Open in Stage

Chapters generated by Stage for commit fd78421 on Jul 1, 2026 11:15am UTC.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extracts the Cron job’s raw SQL retention-trim for shocker_control_logs into a shared OpenShockContext extension method and adds an integration test that executes the real statement against Postgres to catch schema/query drift in CI instead of at Cron runtime.

Changes:

  • Moved the retention-trim DELETE SQL into ShockerControlLogQueries.DeleteControlLogsBeyondPerUserLimitAsync(...) for reuse by both the Cron job and tests.
  • Updated ClearOldShockerControlLogs to call the shared query helper (no intended behavior change).
  • Added an end-to-end Postgres-backed integration test that seeds control logs and asserts the newest N are retained.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
Cron/Jobs/ClearOldShockerControlLogs.cs Switches Cron job from inline SQL to shared query helper.
Common/OpenShockDb/ShockerControlLogQueries.cs Introduces the shared, parameterized retention-trim SQL extension method.
Cron.IntegrationTests/Tests/ControlLogRetentionTests.cs Adds Postgres integration test executing the shared retention-trim statement end-to-end.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Cron.IntegrationTests/Tests/ControlLogRetentionTests.cs Outdated
Comment on lines +64 to +67
Id = logId,
ShockerId = shockerId,
ControlledByUserId = userId,
Intensity = 50,
hhvrc and others added 2 commits July 1, 2026 13:08
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Per Copilot review: the single-owner setup (where the log's controller equalled the
device owner) couldn't tell PARTITION BY d.owner_id apart from a buggy partition on
controlled_by_user_id or a dropped PARTITION BY.

Strengthen it: seed a second owner under the limit whose (older) logs must all
survive, and attribute the over-limit owner's logs to two distinct controller users
(neither over the limit). Now the assertions fail if the query ranks globally
(would delete 10 and wipe the under-limit owner's logs) or partitions by controller
(would delete 0) - only a correct per-owner trim deletes exactly the owner's oldest 5.

Keeps the await-using async scope from the prior autofix commit.
@hhvrc
hhvrc merged commit 5ff39dd into develop Jul 1, 2026
22 checks passed
@hhvrc
hhvrc deleted the test/cover-control-log-cleanup-query branch July 1, 2026 11:53
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.

2 participants