Skip to content

tests: add integration tests, perf tests dircet vs gerpo and perf test print results to mr - #51

Merged
Insei merged 7 commits into
mainfrom
integration_tests
Apr 18, 2026
Merged

tests: add integration tests, perf tests dircet vs gerpo and perf test print results to mr#51
Insei merged 7 commits into
mainfrom
integration_tests

Conversation

@Insei

@Insei Insei commented Apr 18, 2026

Copy link
Copy Markdown
Owner

intgration tests was added
fix some issues
add print rerf tests result to first commit message

Insei added 6 commits April 18, 2026 21:16
…r matrix

Introduces tests/integration/ — a new suite that runs against a real
PostgreSQL brought up via docker-compose. Every test is parameterised
over pgx5/pgx4/database-sql through the forEachAdapter helper, so
bodies speak only to Repository[T] and know nothing about the underlying
driver.

- docker-compose.yml spins up postgres:16 on :5433 (keeps 5432 free for
  the existing benchmark).
- schema.sql defines users/posts/comments covering uuid, nullable text,
  int, bool, nullable timestamptz, FK cascade and soft delete.
- setup_test.go/adapters_test.go/repos_test.go/seed_test.go form the
  scaffolding; TestMain skips cleanly if GERPO_INTEGRATION_DB_URL is
  unset so `go test ./...` stays green without Docker.
- Build tag //go:build integration keeps the suite out of the default run.
- .gitlab-ci.yml adds an integration job with a postgres:16 service.

Also fixes a latent bug in sqlstmt/sqlpart/group.go: GroupBy was
concatenating column expressions without a ", " separator, producing
malformed SQL the moment more than one column was grouped. The mock
tests never exercised this path; the integration smoke test caught it
on the first run.
…rt/Update/Delete

12 tests, each parameterised across pgx5/pgx4/database-sql via
forEachAdapter. Exercises happy paths plus ErrNotFound semantics for
GetFirst, Update and Delete. Insert_WithExclude confirms that excluded
fields fall back to the column's DEFAULT on the database side.

Posts repo is used here because it has no persistent query or soft
delete — keeps the CRUD contract clean; users repo will be exercised
separately in the soft-delete suite.
Adds where_test.go, order_pagination_test.go, exclude_only_test.go and
persistent_query_test.go — 29 test functions, each running on all three
adapters. Covers every public query operator (EQ/NEQ/LT/LTE/GT/GTE/IN/NIN,
6 LIKE ops and their _ic variants, EQ(nil)/NEQ(nil), AND/OR/Group),
ORDER BY + multi-field sort, pagination edge cases, Exclude/Only on
SELECT and UPDATE, persistent LeftJoin/InnerJoin with a virtual column
(post_count), persistent Where hiding soft-deleted rows, and persistent
+ per-request Where composition.

The suite uncovered three real bugs, fixed in the same commit:

1. sqlstmt/first.go, sqlstmt/list.go emitted "ORDER BY ... GROUP BY ..."
   which is invalid SQL. Swapped so GROUP BY precedes ORDER BY.

2. sqlstmt/sqlpart/where.go generated "col LIKE CONCAT('%', ?, '%')".
   PostgreSQL cannot infer the parameter type inside CONCAT when another
   parameter of a different type is present, or when the whole thing is
   wrapped in LOWER() for case-insensitive variants. All LIKE operators
   now wrap the placeholder in CAST(? AS text), which is both
   PostgreSQL- and MySQL-compatible. Unit tests in
   sqlstmt/sqlpart/where_test.go updated to the new SQL.

3. query/linq/pagination.go computed offset as (page-1)*size in uint64,
   which underflowed to ~1.8e19 when Size() was set without Page(),
   producing "bigint out of range". Added an early return when page
   is zero.
… error transformer; fix pgx tx state bug

Closes the advanced-feature gap in tests/integration/. 26 functions,
3 adapters each, 78 subtests in total.

- hooks_test.go: before/after insert/update, afterSelect for GetFirst
  and GetList, hook stacking, mutation from BeforeInsert persisting.
- soft_delete_test.go: Delete rewrites to UPDATE deleted_at, soft-deleted
  rows hidden from the repo, repeated Delete returns ErrNotFound, row
  can be restored via direct SQL.
- virtual_test.go: virtual columns are ignored on INSERT and UPDATE,
  and reflect the real underlying state.
- transactions_test.go: Commit, Rollback, isolation from outside
  connections until commit, RollbackUnlessCommitted as both a no-op
  (after Commit) and a real rollback (without it).
- cache_test.go: CtxCache returns the cached value even after an
  external DB change; Insert through the repo invalidates the cache;
  missing middleware degrades gracefully; different contexts keep
  independent caches.
- error_transformer_test.go: ErrNotFound swapped for a domain error
  across GetFirst/Update/Delete; happy path unaffected; non-NotFound
  errors (FK violation) stay untouched.

Also fixes pgx5/tx.go and pgx4/tx.go: txWrap used value receivers, so
Commit()'s state changes never stuck to the original instance, and
RollbackUnlessCommitted() tried to roll back an already-committed tx
("tx is closed"). Methods moved to pointer receivers; Commit() now
sets commited=true and Rollback() clears rollbackUnlessCommittedNeeded,
mirroring databasesql/tx.go which was already correct.
…able

Runs every Direct/Gerpo bench pair via testing.Benchmark() and emits a
padded table to t.Log so the overhead picture lands in one place:

    go test -run=TestCompareDirectVsGerpo -v ./tests/

The report header explains that these ratios are pure-overhead numbers
(mock adapter, zero IO) and should not be read as "gerpo uses 3× CPU in
production" — with a real PostgreSQL the per-op gerpo cost (~1 µs)
gets absorbed by network latency.
Adds a bench-diff GitLab CI job that runs on every merge_request_event:
it benches the MR head (~10 runs of the mock-db Direct/Gerpo suite),
checks out the target branch, benches it the same way, then pipes the
two results through benchstat and posts the summary as a comment on
the MR via the Notes API.

- scripts/bench-diff.sh owns the logic; it's resilient: if BENCH_BOT_TOKEN
  is missing the comment is skipped but the report still lands in the
  job log and artifacts (base.txt/head.txt, kept 1 week); if the base
  revision fails to build the benches, head-only results are reported.
- The job is allow_failure: true so a perf regression can't block a
  merge on its own.
- TestCompareDirectVsGerpo now gates on GERPO_BENCH_REPORT=1 so the
  default `go test ./...` stays under a second instead of spending
  ~20s on the report.
- CLAUDE.md documents the required BENCH_BOT_TOKEN project variable
  (Developer+, api scope).
@codecov-commenter

codecov-commenter commented Apr 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.17%. Comparing base (9b6bf80) to head (abb72cc).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #51      +/-   ##
==========================================
+ Coverage   61.09%   61.17%   +0.07%     
==========================================
  Files          54       54              
  Lines        1951     1955       +4     
==========================================
+ Hits         1192     1196       +4     
  Misses        710      710              
  Partials       49       49              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Add .github/workflows/integration.yml running the //go:build integration
  suite against a postgres:16 service on push and pull_request.
- Add .github/workflows/bench-diff.yml posting a benchstat-based summary
  as a PR comment on every pull_request. Uses the ambient GITHUB_TOKEN
  with permissions: pull-requests: write — no project secret required.
- Rewrite scripts/bench-diff.sh to read GITHUB_BASE_REF / pull request
  number from GITHUB_EVENT_PATH and POST to the GitHub Notes API.
  Fails safe: if the base revision cannot run the benches the comment
  falls back to head-only; if GITHUB_TOKEN is missing the report stays
  in job logs and the base.txt / head.txt artifacts.
- Drop .gitlab-ci.yml — the repository lives on GitHub.
@github-actions

Copy link
Copy Markdown

Benchmark diff: 9b6bf80778efe8 (mockdb, 10 runs)

goos: linux
goarch: amd64
pkg: github.com/insei/gerpo/tests
cpu: AMD EPYC 9V74 80-Core Processor                
                  │  head.txt   │
                  │   sec/op    │
GetFirst_Direct-4   102.6n ± 3%
GetFirst_Gerpo-4    822.3n ± 1%
GetList_Direct-4    563.6n ± 0%
GetList_Gerpo-4     2.022µ ± 0%
Count_Direct-4      60.95n ± 0%
Count_Gerpo-4       502.8n ± 1%
Insert_Direct-4     85.17n ± 0%
Insert_Gerpo-4      435.4n ± 2%
Update_Direct-4     43.84n ± 0%
Update_Gerpo-4      886.8n ± 1%
Delete_Direct-4     41.92n ± 0%
Delete_Gerpo-4      553.5n ± 5%
geomean             260.7n

                  │   head.txt   │
                  │     B/op     │
GetFirst_Direct-4     216.0 ± 0%
GetFirst_Gerpo-4      848.0 ± 0%
GetList_Direct-4    1.586Ki ± 0%
GetList_Gerpo-4     2.289Ki ± 0%
Count_Direct-4        64.00 ± 0%
Count_Gerpo-4         368.0 ± 0%
Insert_Direct-4       112.0 ± 0%
Insert_Gerpo-4        552.0 ± 0%
Update_Direct-4       56.00 ± 0%
Update_Gerpo-4        944.0 ± 0%
Delete_Direct-4       40.00 ± 0%
Delete_Gerpo-4        608.0 ± 0%
geomean               323.3

                  │  head.txt  │
                  │ allocs/op  │
GetFirst_Direct-4   5.000 ± 0%
GetFirst_Gerpo-4    17.00 ± 0%
GetList_Direct-4    21.00 ± 0%
GetList_Gerpo-4     34.00 ± 0%
Count_Direct-4      4.000 ± 0%
Count_Gerpo-4       10.00 ± 0%
Insert_Direct-4     5.000 ± 0%
Insert_Gerpo-4      14.00 ± 0%
Update_Direct-4     3.000 ± 0%
Update_Gerpo-4      23.00 ± 0%
Delete_Direct-4     3.000 ± 0%
Delete_Gerpo-4      17.00 ± 0%
geomean             9.581

@Insei
Insei merged commit 9fb2208 into main Apr 18, 2026
6 checks passed
@Insei
Insei deleted the integration_tests branch April 18, 2026 21:06
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