diff --git a/mysql-persistence/build.gradle b/mysql-persistence/build.gradle index 6339edf527..11cd9eb073 100644 --- a/mysql-persistence/build.gradle +++ b/mysql-persistence/build.gradle @@ -29,7 +29,7 @@ dependencies { implementation "org.flywaydb:flyway-core" testImplementation "org.testcontainers:mysql:${revTestContainer}" - testImplementation "org.testinfected.hamcrest-matchers:all-matchers:${revHamcrestAllMatchers}" + testImplementation project(':conductor-core').sourceSets.test.output testImplementation project(':conductor-common').sourceSets.test.output } diff --git a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java index a9d36f6dcc..7e21993a11 100644 --- a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java +++ b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java @@ -13,9 +13,6 @@ package com.netflix.conductor.mysql.config; import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.conductor.dao.ExecutionDAO; -import com.netflix.conductor.dao.MetadataDAO; -import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.mysql.dao.MySQLExecutionDAO; import com.netflix.conductor.mysql.dao.MySQLMetadataDAO; import com.netflix.conductor.mysql.dao.MySQLQueueDAO; @@ -39,19 +36,19 @@ public class MySQLConfiguration { @Bean @DependsOn({"flyway", "flywayInitializer"}) - public MetadataDAO mySqlMetadataDAO(ObjectMapper objectMapper, DataSource dataSource, MySQLProperties properties) { + public MySQLMetadataDAO mySqlMetadataDAO(ObjectMapper objectMapper, DataSource dataSource, MySQLProperties properties) { return new MySQLMetadataDAO(objectMapper, dataSource, properties); } @Bean @DependsOn({"flyway", "flywayInitializer"}) - public ExecutionDAO mySqlExecutionDAO(ObjectMapper objectMapper, DataSource dataSource) { + public MySQLExecutionDAO mySqlExecutionDAO(ObjectMapper objectMapper, DataSource dataSource) { return new MySQLExecutionDAO(objectMapper, dataSource); } @Bean @DependsOn({"flyway", "flywayInitializer"}) - public QueueDAO mySqlQueueDAO(ObjectMapper objectMapper, DataSource dataSource) { + public MySQLQueueDAO mySqlQueueDAO(ObjectMapper objectMapper, DataSource dataSource) { return new MySQLQueueDAO(objectMapper, dataSource); } } diff --git a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java index fe21d5107c..b0b9ed1e51 100644 --- a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java +++ b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java @@ -12,56 +12,43 @@ */ package com.netflix.conductor.mysql.dao; -import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.ExecutionDAOTest; -import com.netflix.conductor.mysql.util.MySQLDAOTestUtil; -import org.junit.After; +import com.netflix.conductor.mysql.config.MySQLConfiguration; +import org.flywaydb.core.Flyway; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.testcontainers.containers.MySQLContainer; -import org.testcontainers.utility.DockerImageName; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -@ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) +@ContextConfiguration(classes = {TestObjectMapperConfiguration.class, MySQLConfiguration.class, FlywayAutoConfiguration.class}) @RunWith(SpringRunner.class) +@SpringBootTest public class MySQLExecutionDAOTest extends ExecutionDAOTest { - private MySQLDAOTestUtil testUtil; + @Autowired private MySQLExecutionDAO executionDAO; @Autowired - private ObjectMapper objectMapper; - - @Rule - public TestName name = new TestName(); - - public MySQLContainer mySQLContainer; + Flyway flyway; + // clean the database between tests. @Before - public void setup() { - mySQLContainer = new MySQLContainer<>(DockerImageName.parse("mysql")).withDatabaseName(name.getMethodName()); - mySQLContainer.start(); - testUtil = new MySQLDAOTestUtil(mySQLContainer, objectMapper); - executionDAO = new MySQLExecutionDAO(testUtil.getObjectMapper(), testUtil.getDataSource()); - } - - @After - public void teardown() { - testUtil.getDataSource().close(); + public void before() { + flyway.clean(); + flyway.migrate(); } @Test diff --git a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAOTest.java b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAOTest.java index b024d5e952..80bd4100e5 100644 --- a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAOTest.java +++ b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAOTest.java @@ -12,26 +12,22 @@ */ package com.netflix.conductor.mysql.dao; -import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.events.EventHandler; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; import com.netflix.conductor.core.exception.ApplicationException; -import com.netflix.conductor.mysql.util.MySQLDAOTestUtil; +import com.netflix.conductor.mysql.config.MySQLConfiguration; import org.apache.commons.lang3.builder.EqualsBuilder; -import org.junit.After; +import org.flywaydb.core.Flyway; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.testcontainers.containers.MySQLContainer; -import org.testcontainers.utility.DockerImageName; import java.util.Arrays; import java.util.List; @@ -42,66 +38,52 @@ import static com.netflix.conductor.core.exception.ApplicationException.Code.CONFLICT; import static com.netflix.conductor.core.exception.ApplicationException.Code.NOT_FOUND; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -@ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) +@ContextConfiguration(classes = {TestObjectMapperConfiguration.class, MySQLConfiguration.class, FlywayAutoConfiguration.class}) @RunWith(SpringRunner.class) +@SpringBootTest public class MySQLMetadataDAOTest { - private MySQLDAOTestUtil testUtil; + @Autowired private MySQLMetadataDAO metadataDAO; @Autowired - private ObjectMapper objectMapper; - - @Rule - public TestName name = new TestName(); - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - public MySQLContainer mySQLContainer; + Flyway flyway; + // clean the database between tests. @Before - public void setup() { - mySQLContainer = new MySQLContainer<>(DockerImageName.parse("mysql")).withDatabaseName(name.getMethodName()); - mySQLContainer.start(); - testUtil = new MySQLDAOTestUtil(mySQLContainer, objectMapper); - metadataDAO = new MySQLMetadataDAO(testUtil.getObjectMapper(), testUtil.getDataSource(), - testUtil.getTestProperties()); - } - - @After - public void teardown() { - testUtil.getDataSource().close(); + public void before() { + flyway.clean(); + flyway.migrate(); } @Test public void testDuplicateWorkflowDef() { - thrown.expect(ApplicationException.class); - thrown.expectMessage("Workflow with testDuplicate.1 already exists!"); - thrown.expect(hasProperty("code", is(CONFLICT))); WorkflowDef def = new WorkflowDef(); def.setName("testDuplicate"); def.setVersion(1); metadataDAO.createWorkflowDef(def); - metadataDAO.createWorkflowDef(def); + + ApplicationException applicationException = assertThrows(ApplicationException.class, + () -> metadataDAO.createWorkflowDef(def)); + assertEquals("Workflow with testDuplicate.1 already exists!", applicationException.getMessage()); + assertEquals(CONFLICT, applicationException.getCode()); + } @Test public void testRemoveNotExistingWorkflowDef() { - thrown.expect(ApplicationException.class); - thrown.expectMessage("No such workflow definition: test version: 1"); - thrown.expect(hasProperty("code", is(NOT_FOUND))); - - metadataDAO.removeWorkflowDef("test", 1); + ApplicationException applicationException = assertThrows(ApplicationException.class, + () -> metadataDAO.removeWorkflowDef("test", 1)); + assertEquals("No such workflow definition: test version: 1", applicationException.getMessage()); + assertEquals(NOT_FOUND, applicationException.getCode()); } @Test @@ -190,7 +172,7 @@ public void testWorkflowDefOperations() { } @Test - public void testTaskDefOperations() throws Exception { + public void testTaskDefOperations() { TaskDef def = new TaskDef("taskA"); def.setDescription("description"); def.setCreatedBy("unit_test"); @@ -244,11 +226,10 @@ public void testTaskDefOperations() throws Exception { @Test public void testRemoveNotExistingTaskDef() { - thrown.expect(ApplicationException.class); - thrown.expectMessage("No such task definition"); - thrown.expect(hasProperty("code", is(NOT_FOUND))); - - metadataDAO.removeTaskDef("test" + UUID.randomUUID().toString()); + ApplicationException applicationException = assertThrows(ApplicationException.class, + () -> metadataDAO.removeTaskDef("test" + UUID.randomUUID().toString())); + assertEquals("No such task definition", applicationException.getMessage()); + assertEquals(NOT_FOUND, applicationException.getCode()); } @Test diff --git a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLQueueDAOTest.java b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLQueueDAOTest.java index 4704ac6c6b..9d06d68c26 100644 --- a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLQueueDAOTest.java +++ b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLQueueDAOTest.java @@ -16,23 +16,22 @@ import com.google.common.collect.ImmutableList; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.core.events.queue.Message; -import com.netflix.conductor.mysql.util.MySQLDAOTestUtil; +import com.netflix.conductor.mysql.config.MySQLConfiguration; import com.netflix.conductor.mysql.util.Query; -import org.junit.After; +import org.flywaydb.core.Flyway; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.testcontainers.containers.MySQLContainer; -import org.testcontainers.utility.DockerImageName; +import javax.sql.DataSource; import java.sql.Connection; import java.util.ArrayList; import java.util.Arrays; @@ -46,37 +45,31 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -@ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) +@ContextConfiguration(classes = {TestObjectMapperConfiguration.class, MySQLConfiguration.class, FlywayAutoConfiguration.class}) @RunWith(SpringRunner.class) +@SpringBootTest public class MySQLQueueDAOTest { private static final Logger LOGGER = LoggerFactory.getLogger(MySQLQueueDAOTest.class); - private MySQLDAOTestUtil testUtil; + @Autowired private MySQLQueueDAO queueDAO; @Autowired private ObjectMapper objectMapper; - @Rule - public TestName name = new TestName(); - - @Rule - public ExpectedException expected = ExpectedException.none(); + @Qualifier("dataSource") + @Autowired + private DataSource dataSource; - public MySQLContainer mySQLContainer; + @Autowired + Flyway flyway; + // clean the database between tests. @Before - public void setup() { - mySQLContainer = new MySQLContainer<>(DockerImageName.parse("mysql")).withDatabaseName(name.getMethodName()); - mySQLContainer.start(); - testUtil = new MySQLDAOTestUtil(mySQLContainer, objectMapper); - queueDAO = new MySQLQueueDAO(testUtil.getObjectMapper(), testUtil.getDataSource()); - } - - @After - public void teardown() { - testUtil.getDataSource().close(); + public void before() { + flyway.clean(); + flyway.migrate(); } @Test @@ -218,9 +211,9 @@ public void pollMessagesTest() { // Assert that our un-popped messages match our expected size final long expectedSize = totalSize - firstPollSize - secondPollSize; - try (Connection c = testUtil.getDataSource().getConnection()) { + try (Connection c = dataSource.getConnection()) { String UNPOPPED = "SELECT COUNT(*) FROM queue_message WHERE queue_name = ? AND popped = false"; - try (Query q = new Query(testUtil.getObjectMapper(), c, UNPOPPED)) { + try (Query q = new Query(objectMapper, c, UNPOPPED)) { long count = q.addParameter(queueName).executeCount(); assertEquals("Remaining queue size mismatch", expectedSize, count); } @@ -300,9 +293,9 @@ public void pollDeferredMessagesTest() throws InterruptedException { // Assert that our un-popped messages match our expected size final long expectedSize = totalSize - firstPollSize - secondPollSize; - try (Connection c = testUtil.getDataSource().getConnection()) { + try (Connection c = dataSource.getConnection()) { String UNPOPPED = "SELECT COUNT(*) FROM queue_message WHERE queue_name = ? AND popped = false"; - try (Query q = new Query(testUtil.getObjectMapper(), c, UNPOPPED)) { + try (Query q = new Query(objectMapper, c, UNPOPPED)) { long count = q.addParameter(queueName).executeCount(); assertEquals("Remaining queue size mismatch", expectedSize, count); } diff --git a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/util/MySQLDAOTestUtil.java b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/util/MySQLDAOTestUtil.java deleted file mode 100644 index c573412ce5..0000000000 --- a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/util/MySQLDAOTestUtil.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2020 Netflix, Inc. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.mysql.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.conductor.mysql.config.MySQLProperties; -import com.zaxxer.hikari.HikariDataSource; -import org.flywaydb.core.Flyway; -import org.flywaydb.core.api.configuration.FluentConfiguration; -import org.testcontainers.containers.MySQLContainer; - -import javax.sql.DataSource; -import java.time.Duration; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class MySQLDAOTestUtil { - - private final HikariDataSource dataSource; - private final MySQLProperties properties = mock(MySQLProperties.class); - private final ObjectMapper objectMapper; - - public MySQLDAOTestUtil(MySQLContainer mySQLContainer, ObjectMapper objectMapper) { - - this.objectMapper = objectMapper; - - this.dataSource = new HikariDataSource(); - dataSource.setJdbcUrl(mySQLContainer.getJdbcUrl()); - dataSource.setUsername(mySQLContainer.getUsername()); - dataSource.setPassword(mySQLContainer.getPassword()); - dataSource.setAutoCommit(false); - - when(properties.getTaskDefCacheRefreshInterval()).thenReturn(Duration.ofSeconds(60)); - - // Prevent DB from getting exhausted during rapid testing - dataSource.setMaximumPoolSize(8); - - flywayMigrate(dataSource); - } - - private void flywayMigrate(DataSource dataSource) { - FluentConfiguration fluentConfiguration = Flyway.configure() - .table("schema_version") - .dataSource(dataSource) - .placeholderReplacement(false); - - Flyway flyway = fluentConfiguration.load(); - flyway.migrate(); - } - - public HikariDataSource getDataSource() { - return dataSource; - } - - public MySQLProperties getTestProperties() { - return properties; - } - - public ObjectMapper getObjectMapper() { - return objectMapper; - } - -} diff --git a/mysql-persistence/src/test/resources/application.properties b/mysql-persistence/src/test/resources/application.properties new file mode 100644 index 0000000000..1abda5a9cc --- /dev/null +++ b/mysql-persistence/src/test/resources/application.properties @@ -0,0 +1,6 @@ +conductor.db.type=mysql +spring.datasource.url=jdbc:tc:mysql:///conductor +spring.datasource.username=root +spring.datasource.password=root +spring.datasource.hikari.maximum-pool-size=8 +spring.datasource.hikari.auto-commit=false diff --git a/postgres-persistence/build.gradle b/postgres-persistence/build.gradle index 99dad0fd3d..d07299bf9d 100644 --- a/postgres-persistence/build.gradle +++ b/postgres-persistence/build.gradle @@ -28,7 +28,6 @@ dependencies { implementation "org.flywaydb:flyway-core" testImplementation "org.testcontainers:postgresql:${revTestContainer}" - testImplementation "org.testinfected.hamcrest-matchers:all-matchers:${revHamcrestAllMatchers}" testImplementation project(':conductor-core').sourceSets.test.output testImplementation project(':conductor-common').sourceSets.test.output diff --git a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java index 615aceca01..d6cef49c0e 100644 --- a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java +++ b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java @@ -13,9 +13,6 @@ package com.netflix.conductor.postgres.config; import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.conductor.dao.ExecutionDAO; -import com.netflix.conductor.dao.MetadataDAO; -import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.postgres.dao.PostgresExecutionDAO; import com.netflix.conductor.postgres.dao.PostgresMetadataDAO; import com.netflix.conductor.postgres.dao.PostgresQueueDAO; @@ -46,20 +43,20 @@ public FlywayConfigurationCustomizer flywayConfigurationCustomizer() { @Bean @DependsOn({"flyway", "flywayInitializer"}) - public MetadataDAO postgresMetadataDAO(ObjectMapper objectMapper, DataSource dataSource, + public PostgresMetadataDAO postgresMetadataDAO(ObjectMapper objectMapper, DataSource dataSource, PostgresProperties properties) { return new PostgresMetadataDAO(objectMapper, dataSource, properties); } @Bean @DependsOn({"flyway", "flywayInitializer"}) - public ExecutionDAO postgresExecutionDAO(ObjectMapper objectMapper, DataSource dataSource) { + public PostgresExecutionDAO postgresExecutionDAO(ObjectMapper objectMapper, DataSource dataSource) { return new PostgresExecutionDAO(objectMapper, dataSource); } @Bean @DependsOn({"flyway", "flywayInitializer"}) - public QueueDAO postgresQueueDAO(ObjectMapper objectMapper, DataSource dataSource) { + public PostgresQueueDAO postgresQueueDAO(ObjectMapper objectMapper, DataSource dataSource) { return new PostgresQueueDAO(objectMapper, dataSource); } } diff --git a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java index 70b5ecbf96..5bb14cc51d 100644 --- a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java +++ b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java @@ -12,60 +12,44 @@ */ package com.netflix.conductor.postgres.dao; -import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.ExecutionDAOTest; -import com.netflix.conductor.postgres.util.PostgresDAOTestUtil; -import org.junit.After; +import com.netflix.conductor.postgres.config.PostgresConfiguration; +import org.flywaydb.core.Flyway; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.utility.DockerImageName; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -@ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) +@ContextConfiguration( + classes = {TestObjectMapperConfiguration.class, PostgresConfiguration.class, FlywayAutoConfiguration.class}) @RunWith(SpringRunner.class) +@SpringBootTest public class PostgresExecutionDAOTest extends ExecutionDAOTest { - private PostgresDAOTestUtil testPostgres; + @Autowired private PostgresExecutionDAO executionDAO; @Autowired - private ObjectMapper objectMapper; - - @Rule - public TestName name = new TestName(); - - public PostgreSQLContainer postgreSQLContainer; + Flyway flyway; + // clean the database between tests. @Before - public void setup() { - postgreSQLContainer = - new PostgreSQLContainer<>(DockerImageName.parse("postgres")).withDatabaseName(name.getMethodName().toLowerCase()); - postgreSQLContainer.start(); - testPostgres = new PostgresDAOTestUtil(postgreSQLContainer, objectMapper); - executionDAO = new PostgresExecutionDAO( - testPostgres.getObjectMapper(), - testPostgres.getDataSource() - ); - } - - @After - public void teardown() { - testPostgres.getDataSource().close(); + public void before() { + flyway.clean(); + flyway.migrate(); } @Test diff --git a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java index 03b60fb7c2..e27c485b2e 100644 --- a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java +++ b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java @@ -12,26 +12,24 @@ */ package com.netflix.conductor.postgres.dao; -import com.fasterxml.jackson.databind.ObjectMapper; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.events.EventHandler; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; import com.netflix.conductor.core.exception.ApplicationException; -import com.netflix.conductor.postgres.util.PostgresDAOTestUtil; +import com.netflix.conductor.postgres.config.PostgresConfiguration; import org.apache.commons.lang3.builder.EqualsBuilder; -import org.junit.After; +import org.flywaydb.core.Flyway; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.utility.DockerImageName; import java.util.Arrays; import java.util.List; @@ -42,67 +40,56 @@ import static com.netflix.conductor.core.exception.ApplicationException.Code.CONFLICT; import static com.netflix.conductor.core.exception.ApplicationException.Code.NOT_FOUND; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -@ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) +@ContextConfiguration( + classes = {TestObjectMapperConfiguration.class, PostgresConfiguration.class, FlywayAutoConfiguration.class}) @RunWith(SpringRunner.class) +@SpringBootTest public class PostgresMetadataDAOTest { - private PostgresDAOTestUtil testUtil; - private PostgresMetadataDAO metadataDAO; - @Autowired - private ObjectMapper objectMapper; + private PostgresMetadataDAO metadataDAO; @Rule public TestName name = new TestName(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - public PostgreSQLContainer postgreSQLContainer; + @Autowired + Flyway flyway; + // clean the database between tests. @Before - public void setup() { - postgreSQLContainer = - new PostgreSQLContainer<>(DockerImageName.parse("postgres")).withDatabaseName(name.getMethodName().toLowerCase()); - postgreSQLContainer.start(); - testUtil = new PostgresDAOTestUtil(postgreSQLContainer, objectMapper); - metadataDAO = new PostgresMetadataDAO(testUtil.getObjectMapper(), testUtil.getDataSource(), - testUtil.getTestProperties()); - } - - @After - public void teardown() { - testUtil.getDataSource().close(); + public void before() { + flyway.clean(); + flyway.migrate(); } @Test public void testDuplicateWorkflowDef() { - expectedException.expect(ApplicationException.class); - expectedException.expectMessage("Workflow with testDuplicate.1 already exists!"); - expectedException.expect(hasProperty("code", is(CONFLICT))); - WorkflowDef def = new WorkflowDef(); def.setName("testDuplicate"); def.setVersion(1); metadataDAO.createWorkflowDef(def); - metadataDAO.createWorkflowDef(def); + + ApplicationException applicationException = assertThrows(ApplicationException.class, + () -> metadataDAO.createWorkflowDef(def)); + assertEquals("Workflow with testDuplicate.1 already exists!", applicationException.getMessage()); + assertEquals(CONFLICT, applicationException.getCode()); + } @Test public void testRemoveNotExistingWorkflowDef() { - expectedException.expect(ApplicationException.class); - expectedException.expectMessage("No such workflow definition: test version: 1"); - expectedException.expect(hasProperty("code", is(NOT_FOUND))); - - metadataDAO.removeWorkflowDef("test", 1); + ApplicationException applicationException = assertThrows(ApplicationException.class, + () -> metadataDAO.removeWorkflowDef("test", 1)); + assertEquals("No such workflow definition: test version: 1", applicationException.getMessage()); + assertEquals(NOT_FOUND, applicationException.getCode()); } @Test @@ -245,11 +232,10 @@ public void testTaskDefOperations() { @Test public void testRemoveNotExistingTaskDef() { - expectedException.expect(ApplicationException.class); - expectedException.expectMessage("No such task definition"); - expectedException.expect(hasProperty("code", is(NOT_FOUND))); - - metadataDAO.removeTaskDef("test" + UUID.randomUUID().toString()); + ApplicationException applicationException = assertThrows(ApplicationException.class, + () -> metadataDAO.removeTaskDef("test" + UUID.randomUUID().toString())); + assertEquals("No such task definition", applicationException.getMessage()); + assertEquals(NOT_FOUND, applicationException.getCode()); } @Test diff --git a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java index d56653972a..9e164868cc 100644 --- a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java +++ b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java @@ -16,23 +16,24 @@ import com.google.common.collect.ImmutableList; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.core.events.queue.Message; -import com.netflix.conductor.postgres.util.PostgresDAOTestUtil; +import com.netflix.conductor.postgres.config.PostgresConfiguration; import com.netflix.conductor.postgres.util.Query; -import org.junit.After; +import org.flywaydb.core.Flyway; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.utility.DockerImageName; +import javax.sql.DataSource; import java.sql.Connection; import java.util.ArrayList; import java.util.Arrays; @@ -46,38 +47,36 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -@ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) +@ContextConfiguration( + classes = {TestObjectMapperConfiguration.class, PostgresConfiguration.class, FlywayAutoConfiguration.class}) @RunWith(SpringRunner.class) +@SpringBootTest public class PostgresQueueDAOTest { private static final Logger LOGGER = LoggerFactory.getLogger(PostgresQueueDAOTest.class); - private PostgresDAOTestUtil testUtil; + @Autowired private PostgresQueueDAO queueDAO; + @Qualifier("dataSource") + @Autowired + private DataSource dataSource; + @Autowired private ObjectMapper objectMapper; @Rule public TestName name = new TestName(); - @Rule - public ExpectedException expected = ExpectedException.none(); - public PostgreSQLContainer postgreSQLContainer; + @Autowired + Flyway flyway; + // clean the database between tests. @Before - public void setup() { - postgreSQLContainer = - new PostgreSQLContainer<>(DockerImageName.parse("postgres")).withDatabaseName(name.getMethodName().toLowerCase()); - postgreSQLContainer.start(); - testUtil = new PostgresDAOTestUtil(postgreSQLContainer, objectMapper); - queueDAO = new PostgresQueueDAO(testUtil.getObjectMapper(), testUtil.getDataSource()); - } - - @After - public void teardown() { - testUtil.getDataSource().close(); + public void before() { + flyway.clean(); + flyway.migrate(); } @Test @@ -196,9 +195,9 @@ public void pollMessagesTest() { // Assert that our un-popped messages match our expected size final long expectedSize = totalSize - firstPollSize - secondPollSize; - try (Connection c = testUtil.getDataSource().getConnection()) { + try (Connection c = dataSource.getConnection()) { String UNPOPPED = "SELECT COUNT(*) FROM queue_message WHERE queue_name = ? AND popped = false"; - try (Query q = new Query(testUtil.getObjectMapper(), c, UNPOPPED)) { + try (Query q = new Query(objectMapper, c, UNPOPPED)) { long count = q.addParameter(queueName).executeCount(); assertEquals("Remaining queue size mismatch", expectedSize, count); } @@ -305,9 +304,9 @@ public void pollDeferredMessagesTest() throws InterruptedException { // Assert that our un-popped messages match our expected size final long expectedSize = totalSize - firstPollSize - secondPollSize; - try (Connection c = testUtil.getDataSource().getConnection()) { + try (Connection c = dataSource.getConnection()) { String UNPOPPED = "SELECT COUNT(*) FROM queue_message WHERE queue_name = ? AND popped = false"; - try (Query q = new Query(testUtil.getObjectMapper(), c, UNPOPPED)) { + try (Query q = new Query(objectMapper, c, UNPOPPED)) { long count = q.addParameter(queueName).executeCount(); assertEquals("Remaining queue size mismatch", expectedSize, count); } diff --git a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/util/PostgresDAOTestUtil.java b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/util/PostgresDAOTestUtil.java deleted file mode 100644 index e491ead409..0000000000 --- a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/util/PostgresDAOTestUtil.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2020 Netflix, Inc. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.postgres.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.conductor.postgres.config.PostgresProperties; -import com.zaxxer.hikari.HikariDataSource; -import org.flywaydb.core.Flyway; -import org.flywaydb.core.api.configuration.FluentConfiguration; -import org.testcontainers.containers.PostgreSQLContainer; - -import javax.sql.DataSource; -import java.nio.file.Paths; -import java.time.Duration; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class PostgresDAOTestUtil { - - private final HikariDataSource dataSource; - private final PostgresProperties properties = mock(PostgresProperties.class); - private final ObjectMapper objectMapper; - - public PostgresDAOTestUtil(PostgreSQLContainer postgreSQLContainer, ObjectMapper objectMapper) { - - this.objectMapper = objectMapper; - - this.dataSource = new HikariDataSource(); - dataSource.setJdbcUrl(postgreSQLContainer.getJdbcUrl()); - dataSource.setUsername(postgreSQLContainer.getUsername()); - dataSource.setPassword(postgreSQLContainer.getPassword()); - dataSource.setAutoCommit(false); - // Prevent DB from getting exhausted during rapid testing - dataSource.setMaximumPoolSize(8); - - when(properties.getTaskDefCacheRefreshInterval()).thenReturn(Duration.ofSeconds(60)); - - flywayMigrate(dataSource); - } - - private void flywayMigrate(DataSource dataSource) { - FluentConfiguration fluentConfiguration = Flyway.configure() - .table("schema_version") - .locations(Paths.get("db", "migration_postgres").toString()) - .dataSource(dataSource) - .placeholderReplacement(false); - - Flyway flyway = fluentConfiguration.load(); - flyway.migrate(); - } - - public HikariDataSource getDataSource() { - return dataSource; - } - - public PostgresProperties getTestProperties() { - return properties; - } - - public ObjectMapper getObjectMapper() { - return objectMapper; - } - - -} diff --git a/postgres-persistence/src/test/resources/application.properties b/postgres-persistence/src/test/resources/application.properties new file mode 100644 index 0000000000..c7a5732047 --- /dev/null +++ b/postgres-persistence/src/test/resources/application.properties @@ -0,0 +1,7 @@ +conductor.db.type=postgres +spring.datasource.url=jdbc:tc:postgresql:///conductor +spring.datasource.username=postgres +spring.datasource.password=postgres +spring.datasource.hikari.maximum-pool-size=8 +spring.datasource.hikari.auto-commit=false +spring.flyway.locations=classpath:db/migration_postgres