Skip to content

Commit

Permalink
Add DAO tests for MySQL databases (#354)
Browse files Browse the repository at this point in the history
* Add testcontainers and MySQL driver dependencies
* Add JDBI3 and JDBC DAO tests  for MySQL
* Add new utilities to TestHelpers
* Add custom MySQL migration file

Closes #352
  • Loading branch information
sleberknight authored Feb 14, 2024
1 parent b44f47d commit c91b802
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 0 deletions.
20 changes: 20 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

<!-- Versions for test dependencies -->
<kiwi-test.version>3.2.1</kiwi-test.version>
<mysql-connector-j.version>8.3.0</mysql-connector-j.version>

<!-- Sonar properties -->
<sonar.projectKey>kiwiproject_dropwizard-application-errors</sonar.projectKey>
Expand Down Expand Up @@ -167,6 +168,25 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql-connector-j.version}</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.kiwiproject.dropwizard.error.dao.jdbi3;

import static org.kiwiproject.dropwizard.error.util.TestHelpers.migrateDatabase;
import static org.kiwiproject.dropwizard.error.util.TestHelpers.newLatestMySQLContainer;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.kiwiproject.test.junit.jupiter.Jdbi3DaoExtension;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.sql.SQLException;

@DisplayName("Jdbi3ApplicationErrorDao (MySQL)")
@Testcontainers
class MySqlJdbi3ApplicationErrorDaoTest extends AbstractJdbi3ApplicationErrorDaoTest {

@Container
private static final MySQLContainer<?> MYSQL = newLatestMySQLContainer();

@RegisterExtension
final Jdbi3DaoExtension<Jdbi3ApplicationErrorDao> jdbi3DaoExtension =
Jdbi3DaoExtension.<Jdbi3ApplicationErrorDao>builder()
.daoType(Jdbi3ApplicationErrorDao.class)
.url(MYSQL.getJdbcUrl())
.username(MYSQL.getUsername())
.password(MYSQL.getPassword())
.build();

@Override
Jdbi3DaoExtension<Jdbi3ApplicationErrorDao> getTestExtension() {
return jdbi3DaoExtension;
}

@BeforeAll
static void beforeAll() throws SQLException {
migrateDatabase(MYSQL, "dropwizard-app-errors-migrations-mysql.xml");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.kiwiproject.dropwizard.error.dao.jdk;

import static org.kiwiproject.dropwizard.error.util.TestHelpers.migrateDatabase;
import static org.kiwiproject.dropwizard.error.util.TestHelpers.newLatestMySQLContainer;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.kiwiproject.test.jdbc.SimpleSingleConnectionDataSource;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
@DisplayName("MySqlJdbcApplicationErrorDao (MySQL)")
class MySqlJdbcApplicationErrorDaoTest extends AbstractJdbcApplicationErrorDaoTest {

private static SimpleSingleConnectionDataSource DATA_SOURCE;

@Container
private static final MySQLContainer<?> MYSQL = newLatestMySQLContainer();

@BeforeAll
static void beforeAll() {
migrateDatabase(MYSQL, "dropwizard-app-errors-migrations-mysql.xml");

DATA_SOURCE = new SimpleSingleConnectionDataSource(
MYSQL.getJdbcUrl(), MYSQL.getUsername(), MYSQL.getPassword());
}

@Override
protected SimpleSingleConnectionDataSource getDataSource() {
return DATA_SOURCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
import static com.google.common.base.Preconditions.checkState;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.kiwiproject.dropwizard.error.dao.ApplicationErrorJdbc;
import org.kiwiproject.dropwizard.error.dao.ApplicationErrorJdbc.ApplicationErrorJdbcException;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.utility.DockerImageName;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

@UtilityClass
@Slf4j
public class TestHelpers {

@SuppressWarnings({ "SqlDialectInspection", "SqlNoDataSourceInspection" })
Expand All @@ -29,4 +37,29 @@ private static void checkIsH2Connection(Connection conn) throws SQLException {
checkState("H2".equalsIgnoreCase(databaseProductName),
"Connection is not to an H2 database. Database product name: %s", databaseProductName);
}

public static MySQLContainer<?> newLatestMySQLContainer() {
return new MySQLContainer<>(DockerImageName.parse("mysql:latest"));
}

/**
* Use the given JDBC testcontainer to run Liquibase migrations.
*
* @param container a JDBC testcontainer
* @param migrationsFilename the Liquibase migrations file
* @throws ApplicationErrorJdbcException if the migration fails
*/
public static void migrateDatabase(JdbcDatabaseContainer<?> container, String migrationsFilename) {
var dockerImageName = container.getDockerImageName();
var jdbcUrl = container.getJdbcUrl();
LOG.info("Migrating {} container database with JDBC URL {} using file {}", dockerImageName, jdbcUrl, migrationsFilename);

try (var conn = DriverManager.getConnection(jdbcUrl, container.getUsername(), container.getPassword())) {
ApplicationErrorJdbc.migrateDatabase(conn, migrationsFilename);
} catch (SQLException e) {
throw new ApplicationErrorJdbcException(e);
}

LOG.info("Completed migrating {} container database using file {}", dockerImageName, migrationsFilename);
}
}
51 changes: 51 additions & 0 deletions src/test/resources/dropwizard-app-errors-migrations-mysql.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Migrations file for integration tests using MySQL as the database.
-->

<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

<changeSet id="0001-add-application-errors-table" author="dropwizard-application-errors">
<createTable tableName="application_errors" remarks="Stores application errors">
<column name="id" type="bigint" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<!--
The fractional seconds part "(6)"" MUST be specified here for both type and default value.
See https://dev.mysql.com/doc/refman/8.3/en/date-and-time-type-syntax.html
-->
<column name="created_at" type="timestamp(6)" defaultValueComputed="current_timestamp(6)">
<constraints nullable="false"/>
</column>
<column name="updated_at" type="timestamp(6)" defaultValueComputed="current_timestamp(6)">
<constraints nullable="false"/>
</column>
<column name="num_times_occurred" type="integer" defaultValueNumeric="1">
<constraints nullable="false"/>
</column>
<column name="description" type="text">
<constraints nullable="false"/>
</column>
<column name="exception_type" type="text"/>
<column name="exception_message" type="text"/>
<column name="exception_cause_type" type="text"/>
<column name="exception_cause_message" type="text"/>
<column name="stack_trace" type="text"/>
<!--
MySQL doesn't have booleans, so this actually becomes a tinyint(1).
See https://www.mysqltutorial.org/mysql-basics/mysql-boolean/ and also
https://dev.mysql.com/doc/refman/8.3/en/boolean-literals.html
-->
<column name="resolved" type="boolean" defaultValueBoolean="false">
<constraints nullable="false"/>
</column>
<column name="host_name" type="text"/>
<column name="ip_address" type="text"/>
<column name="port" type="integer"/>
</createTable>
</changeSet>

</databaseChangeLog>

0 comments on commit c91b802

Please sign in to comment.