Skip to content

claude-code-chat-browser: concurrency test suite for rebuild, pointer swap, and query #136

Description

@clean6378-max-it

Sprint Item

#7 of 8 — Medium severity — after #6 (Wednesday PR 2 of 2)

Block Relations

Blocked by #6 — lock-order doc defines the invariant this suite enforces
Blocks
Repo/day Independent of #1–#5; may spill into Thursday if #6 overruns

Calendar Day

Wednesday, July 22, 2026 (PR 2 of 2 — may spill to Thursday)

Planned Effort

5 story points (Medium) — sprint item #7

Problem

No concurrency test file exists. Nothing runs a query while the background thread rebuilds the index and swaps the pointer — the search subsystem's highest-risk interaction (test-review C6). A race that returns an empty result during a swap would masquerade as a legitimately empty search, silently.

Goal

One PR adding tests/test_search_index_concurrency.py that queries during a looped background rebuild + pointer swap, asserting no crash and no empty-masquerading-as-real result, and that a locked index degrades to a live scan (never silence). The suite goes red if the documented lock order (item #6) regresses.

Sequencing: land after the lock-order doc (item #6, docs/search-index-lock-order). This suite enforces that document's invariant. Ship as a separate PR.

Scope

Part A — the harness

  • New tests/test_search_index_concurrency.py.
  • Point the index dir at tmp_path.
  • Drive build_search_index(..., force=True) on a writer thread and query_index_hits on reader threads, gated by a threading.Barrier to force overlap.
  • Loop the rebuild + pointer swap while readers query.
  • Exercise the api.search live-scan fallback path.

Part B — assertions (oracles, not "does not throw")

  • No crash under concurrent rebuild + query.
  • No empty-masquerading-as-real result: a result produced mid-swap is never an empty list mistaken for a real answer.
  • A locked index returns index_locked=True and degrades to a live scan (never silence).
  • A legitimately empty result is distinguishable from a locked/failed one.
  • The suite goes red if the lock order regresses.

Out of scope

Acceptance Criteria

  • tests/test_search_index_concurrency.py runs queries while a background rebuild swaps the pointer in a loop.
  • Asserts no crash and no empty-masquerading-as-real result.
  • A locked index returns index_locked=True and degrades to live scan.
  • A legitimately empty result is distinguishable from a locked/failed one.
  • Goes red if the lock order regresses.
  • CI green; PR approved by at least 1 reviewer.

Verification

cd C:\Users\Jasen\CppAliance\claude-code-chat-browser
.\.venv\Scripts\Activate.ps1
pytest -q tests/test_search_index_concurrency.py
pytest -q
  • Negative control: perturb the documented lock order → the suite fails.

Metadata

Metadata

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