Skip to content

chore: add postgres template caching for tests #15336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 4, 2024

Conversation

hugodutka
Copy link
Contributor

@hugodutka hugodutka commented Nov 1, 2024

This PR is the first in a series aimed at closing #15109.

Changes

  • Template Database Creation:
    dbtestutil.Open now has the ability to create a template database if none is provided via DB_FROM. The template database’s name is derived from a hash of the migration files, ensuring that it can be reused across tests and is automatically updated whenever migrations change.

  • Optimized Database Handling:
    Previously, dbtestutil.Open would spin up a new container for each test when DB_FROM was unset. Now, it first checks for an active PostgreSQL instance on localhost:5432. If none is found, it creates a single container that remains available for subsequent tests, eliminating repeated container startups.

These changes address the long individual test times (10+ seconds) reported by some users, likely due to the time Docker took to start and complete migrations.

@hugodutka hugodutka changed the title chore: postgres utilities for tests chore: add postgres utilities for tests Nov 1, 2024
@hugodutka hugodutka marked this pull request as ready for review November 1, 2024 13:00
@hugodutka hugodutka requested a review from Emyrk November 1, 2024 13:03
@hugodutka hugodutka changed the title chore: add postgres utilities for tests chore: add postgres template caching for tests Nov 1, 2024
Copy link
Member

@Emyrk Emyrk left a comment

Choose a reason for hiding this comment

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

Overall I like the direction for this.

The container staying up though I am more hesitant of. It just feels strange to leave open a container for running tests. But I also see the value in keeping it open 🤷‍♂️.

I won't block on that. I am ok with keeping it, and letting people complain if it becomes an issue.

Comment on lines +80 to +83
// If there's no database running on the default port, we'll start a
// postgres container. We won't be cleaning it up so it can be reused
// by subsequent tests. It'll keep on running until the user terminates
// it manually.
Copy link
Member

Choose a reason for hiding this comment

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

I know this is a big change. It used to cleanup, and people might be averse to having it stay open?

Is it still slow if we reuse the same docker volume on subsequent docker starts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The container actually uses ramdisk so there's no volume. Cleaning it up would be also hard when you're running more than 1 test. You'd like to share it among the tests in that run, but clean up only once they all finish. And if you're running 2 go test processes at once, you'd need to make sure one doesn't kill the container while the other is running.

Comment on lines 435 to 438
}, func() {
_ = pool.Purge(resource)
_ = os.RemoveAll(tempDir)
}, nil
Copy link
Member

Choose a reason for hiding this comment

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

If another process is reusing the same container, does this purge kill that second container?

Is the resource existence check for when you run go test in 2 different terminals?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If another process is reusing the container there'd be only one container, and the purge would kill it.

Is the resource existence check for when you run go test in 2 different terminals?

Yes.

Copy link
Member

Choose a reason for hiding this comment

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

If test 1 calls purge while test 2 is running. That breaks test 2 right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's correct. It would have to be a named container though, and the name would have to be the same in both runs. The test could work around this by generating a unique name per test run.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: no tests currently use named containers because I introduced them in this PR :)

Comment on lines -120 to +467
err = resource.Expire(120)
err = container.Resource.Expire(120)
if err != nil {
return "", nil, xerrors.Errorf("expire resource: %w", err)
}

pool.MaxWait = 120 * time.Second
container.Pool.MaxWait = 120 * time.Second
Copy link
Member

Choose a reason for hiding this comment

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

Might be useful on the other docker create. If a test is ctl+c the cleanup will not run.

Although I do recall you mentioning the db should stay up after tests are done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I intentionally did not set up expiry times on the other openContainer call.

@hugodutka
Copy link
Contributor Author

@Emyrk I addressed your comments. I don't think leaving a testing container open is an issue - that's how make test-postgres already works. Let's see how people react.

Copy link
Member

@Emyrk Emyrk left a comment

Choose a reason for hiding this comment

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

Approving. If people end up objecting about the docker container remaining, we can tweak.

Approving assuming CI does not break either 😄

@hugodutka hugodutka merged commit 1bfa7d4 into main Nov 4, 2024
27 of 29 checks passed
@hugodutka hugodutka deleted the hugodutka/15109-postgres-utilities branch November 4, 2024 16:23
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