fix existing flakiness + cut runtime closes #533 #544

Merged
moritz merged 11 commits from issue/mitgliederverwaltung-533 into main 2026-06-16 18:30:14 +02:00
Owner

Description of the implemented changes

The changes were:

  • Bugfixing
  • New Feature
  • Breaking Change
  • Refactoring

Fix the existing test-suite flakiness and reduce its runtime: remove blind Process.sleep waits, share duplicated fee/cycle fixtures, replace internal-state assertions with behavior assertions, fix a seed-dependent property-generator error, and — the root cause of the intermittent failures — eliminate a concurrent-create_member PostgreSQL deadlock by making three foreign keys deferrable.

What has been changed?

  • Share create_fee_type and create_cycle fixtures
  • Drop the dead per-process seeds-run guard
  • Assert rendered behavior instead of socket internals in the index view
  • Wait on observable state instead of blind sleeps
  • Build date-filter property bounds without a reject-filter
  • Make member/user foreign keys deferrable to avoid create_member deadlock
  • Assert member/user foreign keys are deferrable
  • Keep deadlock-prone member tests synchronous
  • Document create_member deadlock fix and async-test-safety

Definition of Done

Code Quality

  • No new technical depths
  • Linting passed
  • Documentation is added were needed

Accessibility

  • New elements are properly defined with html-tags
  • Colour contrast follows WCAG criteria
  • Aria labels are added when needed
  • Everything is accessible by keyboard
  • Tab-Order is comprehensible
  • All interactive elements have a visible focus

Testing

  • Tests for new code are written
  • All tests pass
  • axe-core dev tools show no critical or major issues

Additional Notes

  • Scope was expanded mid-review (backtrack review_loop → requirements): the flakiness root cause turned out to be a product-level concurrent-create_member deadlock, so the test-only constraint was lifted for one bounded change — the deferrable-FK migration. This deadlock is also a latent production risk under concurrent sign-ups.
  • Deadlock fix verified empirically: 0 deadlocks in 15 full-suite runs under maximum CPU contention, versus ~1/12 before; a deterministic test guards the constraint state (an in-process concurrent reproduction is infeasible under the Ecto sandbox).
  • The review loop ran to iteration 4, which was a clean confirming pass (converged, not a cap escalation).
  • The index-view commit (assert rendered behavior …) is a large diff (~314 lines) because it migrates many :sys.get_state assertions to rendered-behavior assertions in one file.
## Description of the implemented changes The changes were: - [x] Bugfixing - [ ] New Feature - [ ] Breaking Change - [ ] Refactoring Fix the existing test-suite flakiness and reduce its runtime: remove blind `Process.sleep` waits, share duplicated fee/cycle fixtures, replace internal-state assertions with behavior assertions, fix a seed-dependent property-generator error, and — the root cause of the intermittent failures — eliminate a concurrent-`create_member` PostgreSQL deadlock by making three foreign keys deferrable. ## What has been changed? - Share create_fee_type and create_cycle fixtures - Drop the dead per-process seeds-run guard - Assert rendered behavior instead of socket internals in the index view - Wait on observable state instead of blind sleeps - Build date-filter property bounds without a reject-filter - Make member/user foreign keys deferrable to avoid create_member deadlock - Assert member/user foreign keys are deferrable - Keep deadlock-prone member tests synchronous - Document create_member deadlock fix and async-test-safety ## Definition of Done ### Code Quality - [ ] No new technical depths - [x] Linting passed - [x] Documentation is added were needed ### Accessibility - [ ] New elements are properly defined with html-tags - [ ] Colour contrast follows WCAG criteria - [ ] Aria labels are added when needed - [ ] Everything is accessible by keyboard - [ ] Tab-Order is comprehensible - [ ] All interactive elements have a visible focus ### Testing - [x] Tests for new code are written - [x] All tests pass - [ ] axe-core dev tools show no critical or major issues ## Additional Notes - Scope was expanded mid-review (backtrack review_loop → requirements): the flakiness root cause turned out to be a product-level concurrent-`create_member` deadlock, so the test-only constraint was lifted for one bounded change — the deferrable-FK migration. This deadlock is also a latent production risk under concurrent sign-ups. - Deadlock fix verified empirically: 0 deadlocks in 15 full-suite runs under maximum CPU contention, versus ~1/12 before; a deterministic test guards the constraint state (an in-process concurrent reproduction is infeasible under the Ecto sandbox). - The review loop ran to iteration 4, which was a clean confirming pass (converged, not a cap escalation). - The index-view commit (`assert rendered behavior …`) is a large diff (~314 lines) because it migrates many `:sys.get_state` assertions to rendered-behavior assertions in one file.
moritz added 11 commits 2026-06-16 18:29:12 +02:00
Replace the create_fee_type/create_cycle helpers duplicated across 18/8
membership-fee test files with a single shared definition in Mv.Fixtures,
reconciling the divergent local signatures (including the reversed
argument order) into one superset so behavior is unchanged.
Replace :sys.get_state assertions on the LiveView socket with assertions on
rendered output, so the tests pin user-visible behavior rather than internal
state; the few sites with no observable equivalent are kept and annotated.
Replace the fixed Process.sleep waits in the import, members-PDF and
field-visibility tests with event-based / bounded-poll waits on the
observable condition, removing a known flakiness vector.
The bound-pair generator filtered out ~1/4 of generated values, so unlucky
seeds hit StreamData's FilterTooNarrowError under full property runs.
Construct an at-least-one-bound-set pair directly instead, preserving the
exact domain with no rejection.
Concurrent create_member transactions took FK FOR KEY SHARE (MultiXact) locks
on shared rows across members/users/membership_fee_types and could form a
cross-transaction cycle, producing intermittent PostgreSQL deadlocks (40P01)
under load. Making the three foreign keys DEFERRABLE INITIALLY DEFERRED moves
the check to commit time and breaks the cycle, without weakening integrity
(NOT NULL and ON DELETE RESTRICT are unaffected).
These member/group/custom-field LiveView tests stay async: false. With the
foreign keys now deferrable the create_member deadlock no longer forces it, so
the rationale is updated: they remain synchronous as a deferred scope decision,
and index_groups_url_params/member_filter_component additionally have separate
async-isolation issues that must be fixed before they can run in parallel.
Merge branch 'main' into issue/mitgliederverwaltung-533
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/production Build is passing
84e1cf1cb8
# Conflicts:
#	test/mv_web/member_live/index_test.exs
moritz merged commit a629bfb617 into main 2026-06-16 18:30:14 +02:00
moritz deleted branch issue/mitgliederverwaltung-533 2026-06-16 18:30:14 +02:00
Sign in to join this conversation.
No description provided.