Skip to content

Commit 1d16a01

Browse files
authored
add base test class for config db resources (#19640)
1 parent f890045 commit 1d16a01

11 files changed

+426
-494
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2022 Airbyte, Inc., all rights reserved.
3+
*/
4+
5+
package io.airbyte.config.persistence;
6+
7+
import io.airbyte.db.Database;
8+
import io.airbyte.db.factory.DSLContextFactory;
9+
import io.airbyte.db.factory.DataSourceFactory;
10+
import io.airbyte.db.factory.FlywayFactory;
11+
import io.airbyte.db.init.DatabaseInitializationException;
12+
import io.airbyte.db.instance.configs.ConfigsDatabaseMigrator;
13+
import io.airbyte.db.instance.configs.ConfigsDatabaseTestProvider;
14+
import io.airbyte.test.utils.DatabaseConnectionHelper;
15+
import java.io.IOException;
16+
import java.sql.SQLException;
17+
import javax.sql.DataSource;
18+
import org.flywaydb.core.Flyway;
19+
import org.jooq.DSLContext;
20+
import org.jooq.SQLDialect;
21+
import org.junit.jupiter.api.AfterAll;
22+
import org.junit.jupiter.api.BeforeAll;
23+
import org.testcontainers.containers.PostgreSQLContainer;
24+
25+
/**
26+
* This class exists to abstract away the lifecycle of the test container database and the config
27+
* database schema. This is ALL it intends to do. Any additional functionality belongs somewhere
28+
* else. It is useful for test suites that need to interact directly with the database.
29+
*
30+
* This class sets up a test container database and runs the config database migrations against it
31+
* to provide the most up-to-date schema.
32+
*
33+
* What this class is NOT designed to do:
34+
* <ul>
35+
* <li>test migration behavior, only should be used to test query behavior against the current
36+
* schema.</li>
37+
* <li>expose database details -- if you are attempting to expose container, dataSource, dslContext,
38+
* something is wrong.</li>
39+
* <li>add test fixtures or helpers--do NOT put "generic" resource helper methods (e.g.
40+
* createTestSource())</li>
41+
* </ul>
42+
*
43+
* This comment is emphatically worded, because it is tempting to add things to this class. It has
44+
* already happened in 3 previous iterations, and each time it takes multiple engineering days to
45+
* fix it.
46+
*
47+
* Usage:
48+
* <ul>
49+
* <li>Extend: Extend this class. By doing so, it will automatically create the test container db
50+
* and run migrations against it at the start of the test suite (@BeforeAll).</li>
51+
* <li>Use database: As part of the @BeforeAll the database field is set. This is the only field
52+
* that the extending class can access. It's lifecycle is fully managed by this class.</li>
53+
* <li>Reset schema: To reset the database in between tests, call truncateAllTables() as part
54+
* of @BeforeEach. This is the only method that this class exposes externally. It is exposed in such
55+
* a way, because most test suites need to declare their own @BeforeEach, so it is easier for them
56+
* to simply call this method there, then trying to apply a more complex inheritance scheme.</li>
57+
* </ul>
58+
*
59+
* Note: truncateAllTables() works by truncating each table in the db, if you add a new table, you
60+
* will need to add it to that method for it work as expected.
61+
*/
62+
@SuppressWarnings({"PMD.MutableStaticState", "PMD.SignatureDeclareThrowsException"})
63+
class BaseConfigDatabaseTest {
64+
65+
static Database database;
66+
67+
// keep these private, do not expose outside this class!
68+
private static PostgreSQLContainer<?> container;
69+
private static DataSource dataSource;
70+
private static DSLContext dslContext;
71+
72+
/**
73+
* Create db test container, sets up java database resources, and runs migrations. Should not be
74+
* called externally. It is not private because junit cannot access private methods.
75+
*
76+
* @throws DatabaseInitializationException - db fails to initialize
77+
* @throws IOException - failure when interacting with db.
78+
*/
79+
@BeforeAll
80+
static void dbSetup() throws DatabaseInitializationException, IOException {
81+
createDbContainer();
82+
setDb();
83+
migrateDb();
84+
}
85+
86+
/**
87+
* Close all resources (container, data source, dsl context, database). Should not be called
88+
* externally. It is not private because junit cannot access private methods.
89+
*
90+
* @throws Exception - exception while closing resources
91+
*/
92+
@AfterAll
93+
static void dbDown() throws Exception {
94+
dslContext.close();
95+
DataSourceFactory.close(dataSource);
96+
container.close();
97+
}
98+
99+
/**
100+
* Truncates tables to reset them. Designed to be used in between tests.
101+
*
102+
* Note: NEW TABLES -- When a new table is added to the db, it will need to be added here.
103+
*
104+
* @throws SQLException - failure in truncate query.
105+
*/
106+
static void truncateAllTables() throws SQLException {
107+
database.query(ctx -> ctx
108+
.execute(
109+
"""
110+
TRUNCATE TABLE
111+
actor,
112+
actor_catalog,
113+
actor_catalog_fetch_event,
114+
actor_definition,
115+
actor_definition_workspace_grant,
116+
actor_oauth_parameter,
117+
connection,
118+
connection_operation,
119+
operation,
120+
state,
121+
stream_reset,
122+
workspace,
123+
workspace_service_account
124+
"""));
125+
}
126+
127+
private static void createDbContainer() {
128+
container = new PostgreSQLContainer<>("postgres:13-alpine")
129+
.withDatabaseName("airbyte")
130+
.withUsername("docker")
131+
.withPassword("docker");
132+
container.start();
133+
}
134+
135+
private static void setDb() {
136+
dataSource = DatabaseConnectionHelper.createDataSource(container);
137+
dslContext = DSLContextFactory.create(dataSource, SQLDialect.POSTGRES);
138+
database = new Database(dslContext);
139+
}
140+
141+
private static void migrateDb() throws IOException, DatabaseInitializationException {
142+
final Flyway flyway = FlywayFactory.create(
143+
dataSource,
144+
StreamResetPersistenceTest.class.getName(),
145+
ConfigsDatabaseMigrator.DB_IDENTIFIER,
146+
ConfigsDatabaseMigrator.MIGRATION_FILE_LOCATION);
147+
new ConfigsDatabaseTestProvider(dslContext, flyway).create(true);
148+
}
149+
150+
}

airbyte-config/config-persistence/src/test/java/io/airbyte/config/persistence/BaseDatabaseConfigPersistenceTest.java

Lines changed: 0 additions & 231 deletions
This file was deleted.

0 commit comments

Comments
 (0)