Skip to content

use postgres / jooq (without code generation) / test containers #57

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 18 commits into from
Aug 14, 2020

Conversation

jrhizor
Copy link
Contributor

@jrhizor jrhizor commented Aug 14, 2020

  • switches from SQLite to Postgres
  • allows dependency injection of db connection pool instead of using a singleton connection pool
  • provides a way to use the same version of postgres for testing

You should look at ServerUuid for an example of how to use JOOQ for querying. I didn't do codegen so it isn't using the ORM functionality, but Result<Record> provides a much nicer interface than something like ResultSet.

@jrhizor jrhizor requested a review from cgardens August 14, 2020 16:28
@@ -2,3 +2,4 @@
.idea
build
.DS_Store
dataline-db/pg_data/*
Copy link
Contributor

Choose a reason for hiding this comment

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

what generates that directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's what I'm using as the default mount for the dev docker db. I'm just setting it to an explicit location so it's easy to delete if we want to iterate on db schemas or start from scratch.

.env Outdated
@@ -1,2 +1,7 @@
VERSION=0.1.0
ENV=docker
POSTGRES_VERSION=13-alpine
Copy link
Contributor

Choose a reason for hiding this comment

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

we should hardcode this one in compose. We should keep the env for the env varialbes that are read by the code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be read by test containers to pull the correct version of the image, so it's consistent with docker compose. I'll add that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually it's hard to set variables used for test in intellij, github, and gradle versions of tests. Maybe that should just be hardcoded in both places.

return connectionPool;
public static BasicDataSource getConnectionPoolFromEnv() {
return getConnectionPool(
System.getenv("POSTGRES_USER"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we create a class in commons that serves as a repository for these env variable and provides accessors?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll do this separately since I already have some ENV helpers in the scheduling PR.

CREATE TABLE DATALINE_METADATA (id varchar(255), value varchar(255), PRIMARY KEY (id));
INSERT INTO DATALINE_METADATA VALUES ('server-uuid', ((lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-4' || substr(lower(hex(randomblob(2))),2) || '-' || substr('89ab',abs(random()) % 4 + 1, 1) || substr(lower(hex(randomblob(2))),2) || '-' || lower(hex(randomblob(6))))));
CREATE TABLE JOBS (id INTEGER PRIMARY KEY AUTOINCREMENT, scope varchar(255), created_at INTEGER, started_at INTEGER, updated_at INTEGER, status INTEGER, config BLOB, output, BLOB, stdout_path varchar(255), stderr_path varchar(255));
-- extensions
Copy link
Contributor

Choose a reason for hiding this comment

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

Clean :D

private static final JdbcDatabaseContainer POSTGRES_CONTAINER;
private static final BasicDataSource CONNECTION_POOL;

static {
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: can you use @BeforeAll instead?


static {
// todo: load image from env and don't hardcode absolute path
POSTGRES_CONTAINER = new PostgreSQLContainer("postgres:13-alpine").withInitScript("schema.sql");
Copy link
Contributor

Choose a reason for hiding this comment

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

really nice!

Are there good practices to ensure that tests run in isolation? It seems that since you instantiate the db once, that content in tables will be shared accross the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What we did in the past was create a single db container and then run tests one at a time, clearing the db in between runs. I'll make a better db test class after merging this PR.

- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_CONNECT_STR=${POSTGRES_CONNECT_STR}
- WAIT_HOSTS=db:5432
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume the depends_on isn't enough? Maybe we can make it work with some sort of a tcp healthcheck defined in the db.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is basically just a tcp healtcheck. Searching around, it seems like doing something like using one of the wait/wait-for/wait-for-it scripts is the "accepted" method of doing the check. You can do things like setting the value of WAIT_HOSTS to db:5432,db2:5433 if you have multiple TCP dependencies, for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And to answer the other question, yes, depends_on isn't enough. It only waits for the container to start, but the PG server doesn't run until the init script finishes.

@jrhizor jrhizor marked this pull request as ready for review August 14, 2020 17:42
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.

3 participants