From b9472f59410370ba755e474da68dcdeee40712f2 Mon Sep 17 00:00:00 2001 From: Jan Cizmar Date: Thu, 10 Oct 2024 21:50:00 +0200 Subject: [PATCH 1/2] chore: Break the tests --- .../testDataBuilder/TestDataService.kt | 12 +++- .../io/tolgee/BatchJobCleanerListener.kt | 13 ++++ .../main/kotlin/io/tolgee/BatchJobTestUtil.kt | 24 ++++++++ .../kotlin/io/tolgee/CleanDbTestListener.kt | 61 +++++++++++++------ .../testing/AbstractTransactionalTest.kt | 2 + 5 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 backend/testing/src/main/kotlin/io/tolgee/BatchJobCleanerListener.kt create mode 100644 backend/testing/src/main/kotlin/io/tolgee/BatchJobTestUtil.kt diff --git a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt index e28bc46a2f..20f43d0cc4 100644 --- a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt @@ -433,9 +433,11 @@ class TestDataService( private fun saveAllUsers(builder: TestDataBuilder) { val userAccountBuilders = builder.data.userAccounts userAccountService.saveAll( - userAccountBuilders.map { - it.self.password = passwordEncoder.encode(it.rawPassword) - it.self + userAccountBuilders.map { userBuilder -> + userBuilder.self.password = passwordHashCache.computeIfAbsent(userBuilder.rawPassword) { + passwordEncoder.encode(userBuilder.rawPassword) + } + userBuilder.self }, ) saveUserAvatars(userAccountBuilders) @@ -500,4 +502,8 @@ class TestDataService( private fun clearEntityManager() { entityManager.clear() } + + companion object { + private val passwordHashCache = mutableMapOf() + } } diff --git a/backend/testing/src/main/kotlin/io/tolgee/BatchJobCleanerListener.kt b/backend/testing/src/main/kotlin/io/tolgee/BatchJobCleanerListener.kt new file mode 100644 index 0000000000..0522957e08 --- /dev/null +++ b/backend/testing/src/main/kotlin/io/tolgee/BatchJobCleanerListener.kt @@ -0,0 +1,13 @@ +package io.tolgee + +import io.tolgee.BatchJobTestUtil.pauseAndClearBatchJobs +import io.tolgee.BatchJobTestUtil.resumeBatchJobs +import org.springframework.test.context.TestContext +import org.springframework.test.context.TestExecutionListener + +class BatchJobCleanerListener : TestExecutionListener { + override fun beforeTestMethod(testContext: TestContext) { + pauseAndClearBatchJobs(testContext) + resumeBatchJobs(testContext) + } +} diff --git a/backend/testing/src/main/kotlin/io/tolgee/BatchJobTestUtil.kt b/backend/testing/src/main/kotlin/io/tolgee/BatchJobTestUtil.kt new file mode 100644 index 0000000000..3d4264c279 --- /dev/null +++ b/backend/testing/src/main/kotlin/io/tolgee/BatchJobTestUtil.kt @@ -0,0 +1,24 @@ +package io.tolgee + +import io.tolgee.batch.BatchJobChunkExecutionQueue +import io.tolgee.batch.BatchJobConcurrentLauncher +import org.springframework.test.context.TestContext + +object BatchJobTestUtil { + fun resumeBatchJobs(testContext: TestContext) { + getBatchJobConcurrentLauncher(testContext).pause = false + } + + fun pauseAndClearBatchJobs(testContext: TestContext) { + getBatchJobConcurrentLauncher(testContext).pause = true + getBatchJobExecutionQueue(testContext).clear() + } + + private fun getBatchJobExecutionQueue(testContext: TestContext): BatchJobChunkExecutionQueue { + return testContext.applicationContext.getBean(BatchJobChunkExecutionQueue::class.java) + } + + private fun getBatchJobConcurrentLauncher(testContext: TestContext): BatchJobConcurrentLauncher { + return testContext.applicationContext.getBean(BatchJobConcurrentLauncher::class.java) + } +} diff --git a/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt b/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt index a0f4ddad36..88a4f0b189 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt @@ -77,29 +77,50 @@ class CleanDbTestListener : TestExecutionListener { val ignoredTablesString = ignoredTables.joinToString(", ") { "'$it'" } try { val rs: ResultSet = - stmt.executeQuery( - String.format( - "SELECT table_schema, table_name" + - " FROM information_schema.tables" + - " WHERE table_catalog = '%s' and (table_schema in ('public', 'billing', 'ee'))" + - " and table_name not in ($ignoredTablesString)", - databaseName, - ), - ) - val tables: MutableList> = ArrayList() - while (rs.next()) { - tables.add(rs.getString(1) to rs.getString(2)) - } - stmt.execute( - java.lang.String.format( - "TRUNCATE TABLE %s", - tables.joinToString(",") { it.first + "." + it.second }, + stmt.executeQuery( + String.format( + "SELECT table_schema, table_name" + + " FROM information_schema.tables" + + " WHERE table_catalog = '%s' and (table_schema in ('public', 'billing', 'ee'))" + + " and table_name not in ($ignoredTablesString)", + databaseName, ), ) - } catch (e: InterruptedException) { - stmt.cancel() - throw e + val tables: MutableList> = ArrayList() + while (rs.next()) { + tables.add(rs.getString(1) to rs.getString(2)) } + + val disableConstraintsSQL = generateDisableConstraintsSQL(tables) + disableConstraintsSQL.forEach { stmt.addBatch(it) } + stmt.executeBatch() + + stmt.execute( + java.lang.String.format( + "TRUNCATE TABLE %s", + tables.joinToString(",") { it.first + "." + it.second }, + ), + ) + + val enableConstraintsSQL = generateEnableConstraintsSQL(tables) + enableConstraintsSQL.forEach { stmt.addBatch(it) } + stmt.executeBatch() + } catch (e: InterruptedException) { + stmt.cancel() + throw e + } + } + } + + fun generateDisableConstraintsSQL(tables: List>): List { + return tables.map { (schema, table) -> + "ALTER TABLE \"$schema\".\"$table\" DISABLE TRIGGER ALL" + } + } + + fun generateEnableConstraintsSQL(tables: List>): List { + return tables.map { (schema, table) -> + "ALTER TABLE \"$schema\".\"$table\" ENABLE TRIGGER ALL" } } diff --git a/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt b/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt index 4079edb18b..618d55e924 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt @@ -1,5 +1,6 @@ package io.tolgee.testing +import io.tolgee.BatchJobCleanerListener import io.tolgee.CleanDbTestListener import jakarta.persistence.EntityManager import org.springframework.beans.factory.annotation.Autowired @@ -16,6 +17,7 @@ import org.springframework.test.context.transaction.TransactionalTestExecutionLi DependencyInjectionTestExecutionListener::class, CleanDbTestListener::class, DirtiesContextTestExecutionListener::class, + BatchJobCleanerListener::class ], ) @ActiveProfiles(profiles = ["local"]) From c4daa3d167e405f3228cfd1e731b16961d72c0e1 Mon Sep 17 00:00:00 2001 From: Jan Cizmar Date: Thu, 10 Oct 2024 21:52:59 +0200 Subject: [PATCH 2/2] chore: Make tests faster --- .../testDataBuilder/TestDataService.kt | 7 ++- .../kotlin/io/tolgee/CleanDbTestListener.kt | 63 +++++++++---------- .../testing/AbstractTransactionalTest.kt | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt index 20f43d0cc4..5c9399cce7 100644 --- a/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt +++ b/backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt @@ -434,9 +434,10 @@ class TestDataService( val userAccountBuilders = builder.data.userAccounts userAccountService.saveAll( userAccountBuilders.map { userBuilder -> - userBuilder.self.password = passwordHashCache.computeIfAbsent(userBuilder.rawPassword) { - passwordEncoder.encode(userBuilder.rawPassword) - } + userBuilder.self.password = + passwordHashCache.computeIfAbsent(userBuilder.rawPassword) { + passwordEncoder.encode(userBuilder.rawPassword) + } userBuilder.self }, ) diff --git a/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt b/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt index 88a4f0b189..0c69d38c09 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/CleanDbTestListener.kt @@ -58,7 +58,6 @@ class CleanDbTestListener : TestExecutionListener { } } } - i++ } } @@ -77,48 +76,48 @@ class CleanDbTestListener : TestExecutionListener { val ignoredTablesString = ignoredTables.joinToString(", ") { "'$it'" } try { val rs: ResultSet = - stmt.executeQuery( - String.format( - "SELECT table_schema, table_name" + - " FROM information_schema.tables" + - " WHERE table_catalog = '%s' and (table_schema in ('public', 'billing', 'ee'))" + - " and table_name not in ($ignoredTablesString)", - databaseName, + stmt.executeQuery( + String.format( + "SELECT table_schema, table_name" + + " FROM information_schema.tables" + + " WHERE table_catalog = '%s' and (table_schema in ('public', 'billing', 'ee'))" + + " and table_name not in ($ignoredTablesString)", + databaseName, + ), + ) + val tables: MutableList> = ArrayList() + while (rs.next()) { + tables.add(rs.getString(1) to rs.getString(2)) + } + + val disableConstraintsSQL = generateDisableConstraintsSQL(tables) + disableConstraintsSQL.forEach { stmt.addBatch(it) } + stmt.executeBatch() + + stmt.execute( + java.lang.String.format( + "TRUNCATE TABLE %s", + tables.joinToString(",") { it.first + "." + it.second }, ), ) - val tables: MutableList> = ArrayList() - while (rs.next()) { - tables.add(rs.getString(1) to rs.getString(2)) - } - val disableConstraintsSQL = generateDisableConstraintsSQL(tables) - disableConstraintsSQL.forEach { stmt.addBatch(it) } - stmt.executeBatch() - - stmt.execute( - java.lang.String.format( - "TRUNCATE TABLE %s", - tables.joinToString(",") { it.first + "." + it.second }, - ), - ) - - val enableConstraintsSQL = generateEnableConstraintsSQL(tables) - enableConstraintsSQL.forEach { stmt.addBatch(it) } - stmt.executeBatch() - } catch (e: InterruptedException) { - stmt.cancel() - throw e + val enableConstraintsSQL = generateEnableConstraintsSQL(tables) + enableConstraintsSQL.forEach { stmt.addBatch(it) } + stmt.executeBatch() + } catch (e: InterruptedException) { + stmt.cancel() + throw e + } } } - } - fun generateDisableConstraintsSQL(tables: List>): List { + private fun generateDisableConstraintsSQL(tables: List>): List { return tables.map { (schema, table) -> "ALTER TABLE \"$schema\".\"$table\" DISABLE TRIGGER ALL" } } - fun generateEnableConstraintsSQL(tables: List>): List { + private fun generateEnableConstraintsSQL(tables: List>): List { return tables.map { (schema, table) -> "ALTER TABLE \"$schema\".\"$table\" ENABLE TRIGGER ALL" } diff --git a/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt b/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt index 618d55e924..c358039252 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/testing/AbstractTransactionalTest.kt @@ -17,7 +17,7 @@ import org.springframework.test.context.transaction.TransactionalTestExecutionLi DependencyInjectionTestExecutionListener::class, CleanDbTestListener::class, DirtiesContextTestExecutionListener::class, - BatchJobCleanerListener::class + BatchJobCleanerListener::class, ], ) @ActiveProfiles(profiles = ["local"])