diff --git a/pom.xml b/pom.xml index 5a8b4bc8..bcedfd8c 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ transactionoutbox-guice transactionoutbox-testing transactionoutbox-acceptance + @@ -90,6 +91,12 @@ ${junit.jupiter.version} test + + junit + junit + 4.13 + test + org.mockito mockito-all diff --git a/transactionoutbox-core/src/main/java/com/gruelbox/transactionoutbox/spi/AbstractThreadLocalTransactionManager.java b/transactionoutbox-core/src/main/java/com/gruelbox/transactionoutbox/spi/AbstractThreadLocalTransactionManager.java index 4fb5437f..e6117bbc 100644 --- a/transactionoutbox-core/src/main/java/com/gruelbox/transactionoutbox/spi/AbstractThreadLocalTransactionManager.java +++ b/transactionoutbox-core/src/main/java/com/gruelbox/transactionoutbox/spi/AbstractThreadLocalTransactionManager.java @@ -1,21 +1,28 @@ package com.gruelbox.transactionoutbox.spi; -import com.gruelbox.transactionoutbox.*; -import java.util.Deque; -import java.util.LinkedList; -import java.util.Optional; +import com.gruelbox.transactionoutbox.NoTransactionActiveException; +import com.gruelbox.transactionoutbox.ThreadLocalContextTransactionManager; +import com.gruelbox.transactionoutbox.ThrowingTransactionalSupplier; +import com.gruelbox.transactionoutbox.ThrowingTransactionalWork; +import com.gruelbox.transactionoutbox.TransactionalSupplier; +import com.gruelbox.transactionoutbox.TransactionalWork; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import lombok.extern.slf4j.Slf4j; +import java.util.Deque; +import java.util.Optional; +import java.util.concurrent.ConcurrentLinkedDeque; + @Slf4j @SuperBuilder @NoArgsConstructor(access = AccessLevel.PROTECTED) public abstract class AbstractThreadLocalTransactionManager implements ThreadLocalContextTransactionManager { - private final ThreadLocal> transactions = ThreadLocal.withInitial(LinkedList::new); + private final ThreadLocal> transactions = + ThreadLocal.withInitial(ConcurrentLinkedDeque::new); @Override public final void inTransaction(Runnable runnable) { diff --git a/transactionoutbox-performance/pom.xml b/transactionoutbox-performance/pom.xml new file mode 100644 index 00000000..95763f7a --- /dev/null +++ b/transactionoutbox-performance/pom.xml @@ -0,0 +1,149 @@ + + + + com.gruelbox + transactionoutbox-parent + ${revision} + + 4.0.0 + Transaction Outbox Performance Tests + jar + transactionoutbox-performance + A collection of performance tests to make sure there are no performance regressions and to show ideas for how to performance test your own implementation. + + + com.gruelbox + transactionoutbox-core + ${project.version} + test + + + + + org.projectlombok + lombok + + + + + com.gruelbox + transactionoutbox-testing + ${project.version} + test + + + org.testcontainers + testcontainers + + + org.testcontainers + junit-jupiter + + + org.testcontainers + postgresql + + + org.testcontainers + oracle-xe + + + org.testcontainers + mysql + + + org.postgresql + postgresql + + + com.oracle.database.jdbc + ojdbc11 + + + com.mysql + mysql-connector-j + + + com.h2database + h2 + + + org.testcontainers + mssqlserver + + + com.microsoft.sqlserver + mssql-jdbc + + + org.jsmart + zerocode-tdd-jupiter + 1.3.44 + test + + + com.fasterxml.jackson.core + jackson-annotations + 2.17.2 + test + + + org.junit.jupiter + junit-jupiter-engine + compile + + + org.junit.jupiter + junit-jupiter-api + compile + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.5.1 + + + org.apache.maven.surefire + surefire-junit-platform + 3.2.5 + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.1 + + + org.apache.maven.surefire + surefire-junit-platform + 3.2.5 + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 3.5.1 + + + org.apache.maven.surefire + surefire-junit-platform + 3.2.5 + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 3.1.1 + + + + \ No newline at end of file diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/AbstractPerformanceTest.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/AbstractPerformanceTest.java new file mode 100644 index 00000000..c1426b68 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/AbstractPerformanceTest.java @@ -0,0 +1,34 @@ +package com.gruelbox.transactionoutbox.performance; + +import com.gruelbox.transactionoutbox.DefaultPersistor; +import com.gruelbox.transactionoutbox.Dialect; +import com.gruelbox.transactionoutbox.Persistor; +import com.gruelbox.transactionoutbox.TransactionManager; +import com.gruelbox.transactionoutbox.TransactionOutbox; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; + +@Slf4j +public abstract class AbstractPerformanceTest { + protected abstract Dialect dialect(); + + protected Persistor persistor = DefaultPersistor.builder().dialect(dialect()).build(); + + Persistor persistor() { + return persistor; + } + + protected abstract TransactionManager txManager(); + + @Test + public void testInsertAndSelect() { + // Given + TransactionOutbox outbox = + TransactionOutbox.builder().transactionManager(txManager()).persistor(persistor()).build(); + + // When + txManager() + .inTransaction(tx -> outbox.schedule(Widget.class).widgetize(UUID.randomUUID().toString())); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceH2.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceH2.java new file mode 100644 index 00000000..1bad1172 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceH2.java @@ -0,0 +1,25 @@ +package com.gruelbox.transactionoutbox.performance; + +import com.gruelbox.transactionoutbox.Dialect; +import com.gruelbox.transactionoutbox.TransactionManager; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class TestDefaultPerformanceH2 extends AbstractPerformanceTest { + private final TransactionManager txManager = + TransactionManager.fromConnectionDetails( + "org.h2.Driver", + "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DEFAULT_LOCK_TIMEOUT=2000;LOB_TIMEOUT=2000;MV_STORE=TRUE", + "test", + "test"); + + @Override + protected TransactionManager txManager() { + return txManager; + } + + @Override + protected Dialect dialect() { + return Dialect.H2; + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMSSqlServer2017.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMSSqlServer2017.java new file mode 100644 index 00000000..c63148dd --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMSSqlServer2017.java @@ -0,0 +1,36 @@ +package com.gruelbox.transactionoutbox.performance; + +import com.gruelbox.transactionoutbox.Dialect; +import com.gruelbox.transactionoutbox.TransactionManager; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class TestDefaultPerformanceMSSqlServer2017 extends AbstractPerformanceTest { + + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getMSSQL2017Container(); + + private final TransactionManager txManager = + TransactionManager.fromConnectionDetails( + "com.mysql.cj.jdbc.Driver", + container.getJdbcUrl(), + container.getUsername(), + container.getPassword()); + + @Override + protected TransactionManager txManager() { + return txManager; + } + + @Override + protected Dialect dialect() { + return Dialect.MS_SQL_SERVER; + } + + @BeforeAll + public static void beforeAll() { + container.start(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMySql5.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMySql5.java new file mode 100644 index 00000000..08f57307 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMySql5.java @@ -0,0 +1,42 @@ +package com.gruelbox.transactionoutbox.performance; + +import com.gruelbox.transactionoutbox.Dialect; +import com.gruelbox.transactionoutbox.TransactionManager; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class TestDefaultPerformanceMySql5 extends AbstractPerformanceTest { + + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getMySql5Container(); + + private final TransactionManager txManager = + TransactionManager.fromConnectionDetails( + "com.mysql.cj.jdbc.Driver", + container.getJdbcUrl(), + container.getUsername(), + container.getPassword()); + + @Override + protected TransactionManager txManager() { + return txManager; + } + + @Override + protected Dialect dialect() { + return Dialect.MY_SQL_5; + } + + @BeforeAll + public static void beforeAll() { + container.start(); + } + + @AfterAll + public static void afterAll() { + container.stop(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMySql8.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMySql8.java new file mode 100644 index 00000000..62591331 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceMySql8.java @@ -0,0 +1,36 @@ +package com.gruelbox.transactionoutbox.performance; + +import com.gruelbox.transactionoutbox.Dialect; +import com.gruelbox.transactionoutbox.TransactionManager; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class TestDefaultPerformanceMySql8 extends AbstractPerformanceTest { + + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getMySql8Container(); + + private final TransactionManager txManager = + TransactionManager.fromConnectionDetails( + "com.mysql.cj.jdbc.Driver", + container.getJdbcUrl(), + container.getUsername(), + container.getPassword()); + + @Override + protected TransactionManager txManager() { + return txManager; + } + + @Override + protected Dialect dialect() { + return Dialect.MY_SQL_8; + } + + @BeforeAll + public static void beforeAll() { + container.start(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceOracle18.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceOracle18.java new file mode 100644 index 00000000..22ad7376 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformanceOracle18.java @@ -0,0 +1,36 @@ +package com.gruelbox.transactionoutbox.performance; + +import com.gruelbox.transactionoutbox.Dialect; +import com.gruelbox.transactionoutbox.TransactionManager; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class TestDefaultPerformanceOracle18 extends AbstractPerformanceTest { + + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getOracle18Container(); + + private final TransactionManager txManager = + TransactionManager.fromConnectionDetails( + "com.mysql.cj.jdbc.Driver", + container.getJdbcUrl(), + container.getUsername(), + container.getPassword()); + + @Override + protected TransactionManager txManager() { + return txManager; + } + + @Override + protected Dialect dialect() { + return Dialect.ORACLE; + } + + @BeforeAll + public static void beforeAll() { + container.start(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformancePostgresql16.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformancePostgresql16.java new file mode 100644 index 00000000..15145582 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/TestDefaultPerformancePostgresql16.java @@ -0,0 +1,42 @@ +package com.gruelbox.transactionoutbox.performance; + +import com.gruelbox.transactionoutbox.Dialect; +import com.gruelbox.transactionoutbox.TransactionManager; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class TestDefaultPerformancePostgresql16 extends AbstractPerformanceTest { + + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getPostgres16Container(); + + private final TransactionManager txManager = + TransactionManager.fromConnectionDetails( + "com.mysql.cj.jdbc.Driver", + container.getJdbcUrl(), + container.getUsername(), + container.getPassword()); + + @Override + protected TransactionManager txManager() { + return txManager; + } + + @Override + protected Dialect dialect() { + return Dialect.POSTGRESQL_9; + } + + @BeforeAll + public static void beforeAll() { + container.start(); + } + + @AfterAll + public static void afterAll() { + container.stop(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/Widget.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/Widget.java new file mode 100644 index 00000000..55e51485 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/Widget.java @@ -0,0 +1,9 @@ +package com.gruelbox.transactionoutbox.performance; + +public class Widget { + private String value; + + public void widgetize(String value) { + this.value = value; + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestH2Test.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestH2Test.java new file mode 100644 index 00000000..3eb88619 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestH2Test.java @@ -0,0 +1,21 @@ +package com.gruelbox.transactionoutbox.performance.load; + +import com.gruelbox.transactionoutbox.performance.TestDefaultPerformanceH2; +import org.jsmart.zerocode.core.domain.LoadWith; +import org.jsmart.zerocode.core.domain.TestMapping; +import org.jsmart.zerocode.core.domain.TestMappings; +import org.jsmart.zerocode.jupiter.extension.ParallelLoadExtension; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@LoadWith("load_generation.properties") +@ExtendWith({ParallelLoadExtension.class}) +public class LoadTestH2Test { + @Test + @DisplayName("Testing Parallel Load") + @TestMappings({ + @TestMapping(testClass = TestDefaultPerformanceH2.class, testMethod = "testInsertAndSelect") + }) + public void testLoad() {} +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMSSqlServer2017Test.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMSSqlServer2017Test.java new file mode 100644 index 00000000..f9c687f6 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMSSqlServer2017Test.java @@ -0,0 +1,40 @@ +package com.gruelbox.transactionoutbox.performance.load; + +import com.gruelbox.transactionoutbox.performance.ContainerUtils; +import com.gruelbox.transactionoutbox.performance.TestDefaultPerformanceMSSqlServer2017; +import org.jsmart.zerocode.core.domain.LoadWith; +import org.jsmart.zerocode.core.domain.TestMapping; +import org.jsmart.zerocode.core.domain.TestMappings; +import org.jsmart.zerocode.jupiter.extension.ParallelLoadExtension; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.JdbcDatabaseContainer; + +@LoadWith("load_generation.properties") +@ExtendWith({ParallelLoadExtension.class}) +public class LoadTestMSSqlServer2017Test { + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getMSSQL2017Container(); + + @Test + @DisplayName("Testing Parallel Load") + @TestMappings({ + @TestMapping( + testClass = TestDefaultPerformanceMSSqlServer2017.class, + testMethod = "testInsertAndSelect") + }) + public void testLoad() {} + + @BeforeAll + public static void beforeAll() { + container.start(); + } + + @AfterAll + public static void afterAll() { + container.stop(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMySql5Test.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMySql5Test.java new file mode 100644 index 00000000..94f5127d --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMySql5Test.java @@ -0,0 +1,38 @@ +package com.gruelbox.transactionoutbox.performance.load; + +import com.gruelbox.transactionoutbox.performance.ContainerUtils; +import com.gruelbox.transactionoutbox.performance.TestDefaultPerformanceMySql5; +import org.jsmart.zerocode.core.domain.LoadWith; +import org.jsmart.zerocode.core.domain.TestMapping; +import org.jsmart.zerocode.core.domain.TestMappings; +import org.jsmart.zerocode.jupiter.extension.ParallelLoadExtension; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.JdbcDatabaseContainer; + +@LoadWith("load_generation.properties") +@ExtendWith({ParallelLoadExtension.class}) +public class LoadTestMySql5Test { + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getMySql5Container(); + + @Test + @DisplayName("Testing Parallel Load") + @TestMappings({ + @TestMapping(testClass = TestDefaultPerformanceMySql5.class, testMethod = "testInsertAndSelect") + }) + public void testLoad() {} + + @BeforeAll + public static void beforeAll() { + container.start(); + } + + @AfterAll + public static void afterAll() { + container.stop(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMySql8Test.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMySql8Test.java new file mode 100644 index 00000000..96bb7860 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestMySql8Test.java @@ -0,0 +1,38 @@ +package com.gruelbox.transactionoutbox.performance.load; + +import com.gruelbox.transactionoutbox.performance.ContainerUtils; +import com.gruelbox.transactionoutbox.performance.TestDefaultPerformanceMySql8; +import org.jsmart.zerocode.core.domain.LoadWith; +import org.jsmart.zerocode.core.domain.TestMapping; +import org.jsmart.zerocode.core.domain.TestMappings; +import org.jsmart.zerocode.jupiter.extension.ParallelLoadExtension; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.JdbcDatabaseContainer; + +@LoadWith("load_generation.properties") +@ExtendWith({ParallelLoadExtension.class}) +public class LoadTestMySql8Test { + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getMySql8Container(); + + @Test + @DisplayName("Testing Parallel Load") + @TestMappings({ + @TestMapping(testClass = TestDefaultPerformanceMySql8.class, testMethod = "testInsertAndSelect") + }) + public void testLoad() {} + + @BeforeAll + public static void beforeAll() { + container.start(); + } + + @AfterAll + public static void afterAll() { + container.stop(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestOracle18Test.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestOracle18Test.java new file mode 100644 index 00000000..0c215356 --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestOracle18Test.java @@ -0,0 +1,40 @@ +package com.gruelbox.transactionoutbox.performance.load; + +import com.gruelbox.transactionoutbox.performance.ContainerUtils; +import com.gruelbox.transactionoutbox.performance.TestDefaultPerformanceOracle18; +import org.jsmart.zerocode.core.domain.LoadWith; +import org.jsmart.zerocode.core.domain.TestMapping; +import org.jsmart.zerocode.core.domain.TestMappings; +import org.jsmart.zerocode.jupiter.extension.ParallelLoadExtension; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.JdbcDatabaseContainer; + +@LoadWith("load_generation.properties") +@ExtendWith({ParallelLoadExtension.class}) +public class LoadTestOracle18Test { + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getOracle18Container(); + + @Test + @DisplayName("Testing Parallel Load") + @TestMappings({ + @TestMapping( + testClass = TestDefaultPerformanceOracle18.class, + testMethod = "testInsertAndSelect") + }) + public void testLoad() {} + + @BeforeAll + public static void beforeAll() { + container.start(); + } + + @AfterAll + public static void afterAll() { + container.stop(); + } +} diff --git a/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestPostgresql16Test.java b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestPostgresql16Test.java new file mode 100644 index 00000000..c05ba66e --- /dev/null +++ b/transactionoutbox-performance/src/test/java/com/gruelbox/transactionoutbox/performance/load/LoadTestPostgresql16Test.java @@ -0,0 +1,40 @@ +package com.gruelbox.transactionoutbox.performance.load; + +import com.gruelbox.transactionoutbox.performance.ContainerUtils; +import com.gruelbox.transactionoutbox.performance.TestDefaultPerformancePostgresql16; +import org.jsmart.zerocode.core.domain.LoadWith; +import org.jsmart.zerocode.core.domain.TestMapping; +import org.jsmart.zerocode.core.domain.TestMappings; +import org.jsmart.zerocode.jupiter.extension.ParallelLoadExtension; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.JdbcDatabaseContainer; + +@LoadWith("load_generation.properties") +@ExtendWith({ParallelLoadExtension.class}) +public class LoadTestPostgresql16Test { + @SuppressWarnings({"rawtypes"}) + private static final JdbcDatabaseContainer container = ContainerUtils.getPostgres16Container(); + + @Test + @DisplayName("Testing Parallel Load") + @TestMappings({ + @TestMapping( + testClass = TestDefaultPerformancePostgresql16.class, + testMethod = "testInsertAndSelect") + }) + public void testLoad() {} + + @BeforeAll + public static void beforeAll() { + container.start(); + } + + @AfterAll + public static void afterAll() { + container.stop(); + } +} diff --git a/transactionoutbox-performance/src/test/resources/load_generation.properties b/transactionoutbox-performance/src/test/resources/load_generation.properties new file mode 100644 index 00000000..2c7311d9 --- /dev/null +++ b/transactionoutbox-performance/src/test/resources/load_generation.properties @@ -0,0 +1,4 @@ +number.of.threads=50 +ramp.up.period.in.seconds=50 +loop.count=2 +interactive.html.report.disabled=false \ No newline at end of file diff --git a/transactionoutbox-testing/src/main/java/com/gruelbox/transactionoutbox/testing/TestContainerUtils.java b/transactionoutbox-testing/src/main/java/com/gruelbox/transactionoutbox/testing/TestContainerUtils.java new file mode 100644 index 00000000..15769963 --- /dev/null +++ b/transactionoutbox-testing/src/main/java/com/gruelbox/transactionoutbox/testing/TestContainerUtils.java @@ -0,0 +1,52 @@ +package com.gruelbox.transactionoutbox.testing; + +import java.time.Duration; +import java.util.Map; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.containers.MSSQLServerContainer; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.containers.OracleContainer; +import org.testcontainers.containers.PostgreSQLContainer; + +public class TestContainerUtils { + private TestContainerUtils() {} + + @SuppressWarnings({"rawtypes", "resource"}) + public static JdbcDatabaseContainer getMySql5Container() { + return new MySQLContainer<>("mysql:5") + .withStartupTimeout(Duration.ofMinutes(5)) + .withReuse(true) + .withTmpFs(Map.of("/var/lib/mysql", "rw")); + } + + @SuppressWarnings({"rawtypes", "resource"}) + public static JdbcDatabaseContainer getMySql8Container() { + return new MySQLContainer<>("mysql:8") + .withStartupTimeout(Duration.ofMinutes(5)) + .withReuse(true) + .withTmpFs(Map.of("/var/lib/mysql", "rw")); + } + + @SuppressWarnings({"rawtypes", "resource"}) + public static JdbcDatabaseContainer getPostgres16Container() { + return (JdbcDatabaseContainer) + new PostgreSQLContainer("postgres:16") + .withStartupTimeout(Duration.ofHours(1)) + .withReuse(true); + } + + @SuppressWarnings({"rawtypes", "resource"}) + public static JdbcDatabaseContainer getOracle18Container() { + return new OracleContainer("gvenzl/oracle-xe:18-slim-faststart") + .withStartupTimeout(Duration.ofHours(1)) + .withReuse(true); + } + + @SuppressWarnings({"rawtypes", "resource"}) + public static JdbcDatabaseContainer getMSSQL2017Container() { + return new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2017-latest") + .acceptLicense() + .withStartupTimeout(Duration.ofMinutes(5)) + .withReuse(true); + } +}