Skip to content

many: speed up unit/db tests from#1795

Open
lzap wants to merge 7 commits into
osbuild:mainfrom
lzap:faster-tests1
Open

many: speed up unit/db tests from#1795
lzap wants to merge 7 commits into
osbuild:mainfrom
lzap:faster-tests1

Conversation

@lzap

@lzap lzap commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

Several changes that speeds up unit tests significantly. Some patches are easy wins, others are debatable but I really like to have fast tests that just helps me to run them more often when changing things.

Major contributors:

  • Race detector (can be now turned off locally via UNIT_TEST_ARGS ENV variable)
  • Coverage (ditto)
  • Creating new database via psql inside podman (is now native pgx call)
  • Reloading distro registry in the same test package over and over again
  • Waiting for postgres via iterating each second (this is now 250ms, also fixed an infinite loop bug)
  • Optimizations to postgres config (it already runs in tmpfs so minor improvement)

@lzap lzap requested a review from a team as a code owner April 16, 2026 10:39
@lzap lzap requested a review from croissanne April 16, 2026 11:35
Comment thread internal/tutils/psql.go Outdated
Comment thread internal/tutils/psql.go
@lzap

lzap commented Apr 17, 2026

Copy link
Copy Markdown
Collaborator Author

Fixed the leaking connections, this was not caused by this PR it was there before as well. The pool was never closed after tests were finished.

Also noted some warnings in the logs which were caused by the container not using IPv6 which is now the default for localhost on modern systems.

@lzap lzap changed the title many: speed up unit tests from 149s to just 9s many: speed up unit/db tests from 149s to just 3s Apr 17, 2026
@lzap

lzap commented Apr 17, 2026

Copy link
Copy Markdown
Collaborator Author

Also appended two more commits that enables t.Parallel() for all non-db tests (the first one) and then also for the db tests (the second one). The latter needed some concurrency changes in the psql.go but I tested everything 50 times with concurrency of 32.

The total test run on my system is now 3.3s :-)

@lzap lzap force-pushed the faster-tests1 branch 2 times, most recently from c0fc4cb to d17aecd Compare May 4, 2026 15:35
@lzap lzap requested a review from croissanne May 4, 2026 15:35
@lzap lzap force-pushed the faster-tests1 branch from d17aecd to 47f7ca2 Compare May 4, 2026 15:35
@lzap

lzap commented May 4, 2026

Copy link
Copy Markdown
Collaborator Author

@croissanne deps are broken due to OpenAPI, I had to add an extra commit that configures gobump to run unit tests after every single bump. since tests are now fast this is very nice and also it should improve gobump success rate with its PRs: gobump -exec ./tools/prepare-source.sh -exec "make unit-tests"

I just re-executed tests 100x times to ensure this is stable enough, I know timing is not great but in the worst case we can turn off t.Parallel() everywhere if we bump into issues, I have been rebasing this for quite some time.

@croissanne croissanne left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a big PR and I'm not sure if all commits are actually helping with the speedup.

I think it might be nice to collect some stats per 'speedup' commit, in a little table or something, to see what is actually worth having the extra complexity.

The following I think are definitely worth it:

Comment thread internal/distribution/distroregistry_test.go Outdated
Comment thread internal/distribution/distroregistry_test.go Outdated
Comment thread internal/tutils/psql.go
@lzap lzap force-pushed the faster-tests1 branch 2 times, most recently from 4d1348e to 808de5d Compare May 21, 2026 17:13
@lzap

lzap commented May 21, 2026

Copy link
Copy Markdown
Collaborator Author

I rebased, resolved conflicts, reordered commits so tests are all passing, dropped the "localhost" commit that was not contributing any value and then reexecuted tests 3 times. In the PR description, I present cumulative number. As you can see, each commit contributes to better performance except the two that are technical things that are relevant to this:

  • closing connection pool (this was a bug in main, without it, when running tests multiple times it fails)
  • reconfigure gobump to run tests during bumps (this is possible now that tests are fast)

@lzap lzap requested a review from croissanne May 25, 2026 14:08
@lzap lzap force-pushed the faster-tests1 branch from 808de5d to 919d8bb Compare May 25, 2026 14:09
@lzap lzap changed the title many: speed up unit/db tests from 149s to just 3s many: speed up unit/db tests from May 25, 2026
Comment thread .github/workflows/tests.yml
Comment thread internal/common/pagination_test.go Outdated
Comment thread internal/tutils/psql.go
@lzap lzap force-pushed the faster-tests1 branch from 919d8bb to 3fc12c3 Compare June 3, 2026 16:42
@lzap

lzap commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator Author

Thank you, fixed both problems. Also fixed the embarrassing Schutzbot git authorship (I accidentally set that while I was testing gobump a week before).

@avitova

avitova commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

There is more of the tc := tc or tt := tt. I personally do not mind, so I think I am good here. You need only one approval, so I will let Sanne judge if she's okay with it now.

@lzap

lzap commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator Author

Dropped it, I missed it, thanks. Rebased. Here is the summary of all these improvements:

Commit Time (s) Comment
db: close connection pool in tests 491.33 A bugfix that only manifests when parallel execution is enabled later on
cicd: allow overriding unit flags locally 503.36 Improvement: Allows for running tests without coverage report locally.
tutils: improve postgres container startup 64.52 Improvement: This is the biggest leap in this patch series.
tutils: run tern directly instead of through podman 60.96 Improvement: Looks like a small improvement, but this is actually a lot when tests are executed in parallel later.
cicd: run tests and prepare-source for each gobump 59.16 Since tests are now fast, let's make use of it in gobump.
distribution: share distro registry between tests 29.17 Improvement: Excessive loading of distros.
Use parallel tests for some unit tests 12.36 Improvement: Codebase is now thread-safe, so we can do this.

@croissanne

@lzap lzap force-pushed the faster-tests1 branch from 3fc12c3 to b87497b Compare June 4, 2026 08:01
@lzap lzap requested a review from avitova June 4, 2026 08:01
ochosi
ochosi previously approved these changes Jun 9, 2026

@ochosi ochosi 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.

This looks good to me! ⚡ I have a slight concern about the test behaving differently and returning different results locally and in CI, but I get that the coverage may not something you always want to execute.

@lzap

lzap commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

Added a warning message: WARNING: To run tests in CICD configuration, run: make unit-tests-coverage

lzap added 7 commits June 15, 2026 10:13
Connection pool was never closed in tests, causing database connections
to leak. This became apparent when running tests multiple times in
sequence, as connections would accumulate until exhausting available
resources.

Reproducer:
    go test ./... -count 5

Properly closing the connection pool after each test ensures clean
teardown and prevents connection leaks during repeated test runs.
Only enable verbose output and race detector when running in CI
environment. This significantly speeds up local development iteration.

In CI (GitHub Actions where CI=true):
  make unit-tests → go test -v -race ./...

Locally (CI not set):
  make unit-tests → go test ./...

Coverage targets still work in both modes, with CI getting additional
-v -race flags for comprehensive checking.
Unit tests are quite slow. Most of the time is spent either creating and
migrating databases and parsing distro JSONs.

This patch slightly improves postgres performance by tuning some
settings. Then the database creation, which is called 40 times in unit
tests, is improved by using native pgx connection instead of podman exec.

The previous patch allows overriding unit test arguments:

    make unit-tests UNIT_TEST_ARGS=

Combined with the changes from this patch, unit tests are now run in 19s
instead of 149s on my system.
By running tern (database migration tool) directly instead of through
podman exec, we eliminate process spawning overhead. This allows the
migration step to complete faster, shaving off approximately one second
from the total test execution time.
Now that tests are faster, we can run them for each gobump.
Instead of loading and parsing distribution JSON files separately for
each test, share a single distro registry instance across all tests.
Distribution metadata parsing is expensive, and reusing the parsed
registry eliminates this redundant work, speeding up tests by an
additional 10 seconds.
Some unit tests can be safely executed in parallel. This was tested 50
times with high concurrency. Running tests in parallel exposed several
race conditions that were previously hidden.

This commit fixes those races by:

- Adding proper synchronization where shared state is accessed
- Ensuring test cleanup happens after parallel subtests complete
- Fixing defer ordering issues with parallel execution

Not all tests can be run in parallel, specifically subtests when the
parent uses defer shutdownFn(): in Go, t.Run returns as soon as a
subtest calls t.Parallel(), so the parent returns, defer runs (server
stops), then the parallel subtests run → connection refused.
@lzap lzap requested a review from ochosi June 15, 2026 08:13
@lzap

lzap commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator Author

@croissanne did I drop all of the unnecessary commits?

@lzap lzap mentioned this pull request Jun 22, 2026
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.

4 participants