Skip to content

Commit

Permalink
Add tests for transaction handling in batch operations
Browse files Browse the repository at this point in the history
  • Loading branch information
hermannm committed Sep 16, 2024
1 parent 92c3a8a commit c7295f2
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,32 @@ package no.liflig.documentstore.repository

import java.text.DecimalFormat
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import no.liflig.documentstore.testutils.exampleRepo
import no.liflig.documentstore.testutils.exampleRepoPostMigration
import no.liflig.documentstore.testutils.exampleRepoPreMigration
import no.liflig.documentstore.testutils.examples.ExampleEntity
import no.liflig.documentstore.testutils.jdbi
import org.junit.jupiter.api.MethodOrderer
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestMethodOrder

// Use @Order here, so transaction test below does not interfere with main migration test
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
class MigrationTest {
@Order(1)
@Test
fun `test migration`() {
// For deterministic sorting
val numberFormat = DecimalFormat("00000")

val entitiesToCreate =
val existingEntities =
(0 until 10_000)
.asSequence()
.map { number -> ExampleEntity(text = "migration-test-${numberFormat.format(number)}") }
.asIterable()
exampleRepoPreMigration.batchCreate(entitiesToCreate)
exampleRepoPreMigration.batchCreate(existingEntities)

exampleRepoPostMigration.migrate(
transformEntity = { (entity, _) -> entity.copy(newFieldAfterMigration = entity.text) },
Expand All @@ -37,4 +46,28 @@ class MigrationTest {

assertEquals(10_000, count)
}

@Order(2)
@Test
fun `migration rolls back on failed transaction`() {
val entitiesToCreate = (0 until 10).map { ExampleEntity(text = "Original") }
exampleRepoPreMigration.batchCreate(entitiesToCreate)

val createdEntities = exampleRepo.listByIds(entitiesToCreate.map { it.id })

assertFailsWith<Exception> {
transactional(jdbi) {
exampleRepoPostMigration.migrate(
transformEntity = { (entity, _) -> entity.copy(text = "Migrated") },
)
throw Exception("Rolling back transaction")
}
}

val fetchedEntities = exampleRepo.listByIds(createdEntities.map { it.item.id })
assertEquals(createdEntities.size, fetchedEntities.size)
for (entity in fetchedEntities) {
assertEquals("Original", entity.item.text)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlin.concurrent.thread
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotEquals
import no.liflig.documentstore.entity.mapEntities
import no.liflig.documentstore.testutils.exampleRepo
import no.liflig.documentstore.testutils.examples.ExampleEntity
import no.liflig.documentstore.testutils.jdbi
Expand Down Expand Up @@ -99,4 +100,59 @@ class TransactionTest {

assertEquals("Two", result)
}

@Test
fun `batchCreate rolls back on failed transaction`() {
val entitiesToCreate = (1..10).map { ExampleEntity(text = "batchCreate transaction test") }

assertFailsWith<Exception> {
transactional(jdbi) {
exampleRepo.batchCreate(entitiesToCreate)
throw Exception("Rolling back transaction")
}
}

val createdEntities = exampleRepo.listByIds(entitiesToCreate.map { it.id })
assertEquals(0, createdEntities.size)
}

@Test
fun `batchUpdate rolls back on failed transaction`() {
val entitiesToCreate = (1..10).map { ExampleEntity(text = "Original") }
exampleRepo.batchCreate(entitiesToCreate)

val createdEntities = exampleRepo.listByIds(entitiesToCreate.map { it.id })
val updatedEntities = createdEntities.mapEntities { it.copy(text = "Updated") }

assertFailsWith<Exception> {
transactional(jdbi) {
exampleRepo.batchUpdate(updatedEntities)
throw Exception("Rolling back transaction")
}
}

val fetchedEntities = exampleRepo.listByIds(createdEntities.map { it.item.id })
assertEquals(createdEntities.size, fetchedEntities.size)
for (entity in fetchedEntities) {
assertEquals("Original", entity.item.text)
}
}

@Test
fun `batchDelete rolls back on failed transaction`() {
val entitiesToCreate = (1..10).map { ExampleEntity(text = "Original") }
exampleRepo.batchCreate(entitiesToCreate)

val createdEntities = exampleRepo.listByIds(entitiesToCreate.map { it.id })

assertFailsWith<Exception> {
transactional(jdbi) {
exampleRepo.batchDelete(createdEntities)
throw Exception("Rolling back transaction")
}
}

val fetchedEntities = exampleRepo.listByIds(createdEntities.map { it.item.id })
assertEquals(createdEntities.size, fetchedEntities.size)
}
}

0 comments on commit c7295f2

Please sign in to comment.