Skip to content

chore: improve code coverage toward 90%#222

Merged
tjgreen42 merged 9 commits intomainfrom
improve-code-coverage
Feb 18, 2026
Merged

chore: improve code coverage toward 90%#222
tjgreen42 merged 9 commits intomainfrom
improve-code-coverage

Conversation

@tjgreen42
Copy link
Copy Markdown
Collaborator

@tjgreen42 tjgreen42 commented Feb 11, 2026

Summary

  • Remove ~1000 lines of dead code: exhaustive scoring fallback (score.c,
    scan.c, segment.h), local_memtable module, unused metapage functions,
    enable_bmw GUC
  • Add new tests: coverage.sql (AM handler properties, score/BMW logging,
    page visualization, GUC validation), bulk_load.sql, vacuum_extended.sql,
    plus inheritance and binary I/O test expansions
  • Strip all LCOV_EXCL source annotations, following TimescaleDB's approach
    of not using source-level coverage exclusions
  • Fix shell script cleanup to use pg_ctl stop -m fast before falling back
    to -m immediate, so gcda coverage data flushes from recovery, concurrency,
    segment, cic, and stress tests
  • Add hypertable tests to CI and coverage workflows (exercises CustomScan
    code paths when TimescaleDB is available)
  • Set Codecov project and patch coverage targets to 85%

Testing

  • All 46 regression tests pass (3 new: bulk_load, vacuum_extended, coverage)
  • All shell tests pass (recovery, concurrency, segment, cic, stress)
  • make format-check passes
  • Coverage at 88.2% before annotation stripping; expect increase from
    shell script coverage flush fix

Remove dead code:
- Delete local_memtable.c/.h (428 lines, 0% coverage, never called)
- Remove tp_update_metapage_stats (defined but never called)
- Remove enable_bmw GUC (BMW is always-on; exhaustive fallback kept
  for >8 term queries)

Add tests for under-tested functionality:
- coverage.sql: page visualization, score/BMW stats logging, AM handler
  properties, dump to file
- bulk_load.sql: exercises bulk load spill threshold path
- vacuum_extended.sql: vacuum with segments, empty indexes, bulk deletes
- binary_io.sql: bm25vector binary COPY (recv/send)
- Add explicit_index to REGRESS list (was missing)

Annotate unreachable defensive code with LCOV_EXCL:
- segment.c: overflow guards, magic number checks, page validation
- state.c: recovery failures, stale data, lock upgrade, null guards
- metapage.c: null metapage, magic validation, version check

Also regenerate expected output files to match current NOTICE behavior
(BM25 index build started message was removed in a prior change but
expected files were not updated).
The previous commit incorrectly removed "BM25 index build started"
notices from expected output files because they were generated on a
local build that didn't emit this notice. Regenerated using pg18-release
which correctly produces the notice, matching CI behavior.
Add LCOV_EXCL annotations for code paths that cannot be reached
through normal SQL tests:
- score.c: exhaustive scoring fallback (>8 query terms)
- scan.c: exhaustive segment scoring + defensive block load failures
- state.c: registry double-failure fallbacks
- query.c: PG_CATCH error cleanup

Add new tests:
- Segment BMW seek via ORDER BY LIMIT with spilled data
- tpquery_in parsing with index:query format
- BMW stats logging with segment ORDER BY LIMIT queries
- Inheritance scoring via find_first_child_bm25_index
LCOV_EXCL for genuinely untestable code paths:
- state.c: crash recovery (requires server restart, tested by
  recovery.sh), transaction abort cleanup, DSA allocation failures
- hooks.c: hook chaining (requires other extensions), CustomScan
  handling (requires other extensions)

New tests for real functional gaps:
- Plain text ORDER BY (scan.c sk_subtype == TEXTOID path)
- HAVING clause with BM25 operator (hooks.c havingQual path)
- Build-mode spill with low memtable_spill_threshold
- Double bulk-load spill with pre-existing L0 segment
- Fix inaccurate comments claiming ">8 query terms" triggers
  exhaustive fallback; BMW handles all term counts
- Remove nested LCOV_EXCL_START inside already-excluded crash
  recovery function in state.c (lcov doesn't support nesting)
- Fix test comments: Test 10 tests opclass resolution not
  tp_validate, Test 16 is GROUP BY/HAVING not havingQual
@tjgreen42 tjgreen42 force-pushed the improve-code-coverage branch from 5000168 to 8d2bd4b Compare February 17, 2026 21:11
Install TimescaleDB in both coverage jobs and run hypertable.sh
to exercise the T_CustomScan code paths in hooks.c. This allows
removing the LCOV_EXCL annotations from those cases since they
are now covered by tests.
The exhaustive scoring path in score.c was dead code — BMW always
returns >= 0, so the fallback was never reached. Remove ~700 lines
of unreachable code and associated LCOV_EXCL annotations across
score.c, score.h, scan.c, and segment.h. Clean up unused includes.
Remove all source-level LCOV_EXCL_START/STOP annotations from the
codebase, following TimescaleDB's approach of not using source
annotations for coverage exclusion.

Fix shell script cleanup functions to use `pg_ctl stop -m fast` before
falling back to `-m immediate`. This ensures gcda coverage data is
flushed when processes exit, so code exercised by shell tests
(recovery, concurrency, segment, cic, stress) is properly counted in
coverage reports.
@tjgreen42 tjgreen42 marked this pull request as ready for review February 17, 2026 23:51
Configure project-level and patch-level coverage targets at 85%.
The project check will fail PRs that drop overall coverage below 85%
(with 1% threshold for noise). The patch check requires new/changed
lines to have at least 85% coverage.
@tjgreen42 tjgreen42 merged commit 8c00a5e into main Feb 18, 2026
15 checks passed
@tjgreen42 tjgreen42 deleted the improve-code-coverage branch February 18, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant