Skip to content

Commit

Permalink
Add concurrency test
Browse files Browse the repository at this point in the history
  • Loading branch information
dhoepelman committed May 14, 2024
1 parent 42b7cab commit 2ff23d7
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ kotlin {
apiVersion = kotlinApiTarget
}
}

jvm {
compilations.all {
kotlinOptions.jvmTarget = jvmTarget.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal class NonNullPropertyValidation<T, R>(
) : Validation<T> {
override fun validate(value: T): ValidationResult<T> {
val propertyValue = property(value)
return validation(propertyValue).mapError { ".${property.name}$it" }.map { value }
return validation.validate(propertyValue).mapError { ".${property.name}$it" }.map { value }
}
}

Expand Down Expand Up @@ -75,7 +75,7 @@ internal class ArrayValidation<T>(
) : Validation<Array<T>> {
override fun validate(value: Array<T>): ValidationResult<Array<T>> {
return value.foldIndexed(Valid(value)) { index, result: ValidationResult<Array<T>>, propertyValue ->
val propertyValidation = validation(propertyValue).mapError { "[$index]$it" }.map { value }
val propertyValidation = validation.validate(propertyValue).mapError { "[$index]$it" }.map { value }
result.combineWith(propertyValidation)
}
}
Expand All @@ -86,7 +86,10 @@ internal class MapValidation<K, V>(
) : Validation<Map<K, V>> {
override fun validate(value: Map<K, V>): ValidationResult<Map<K, V>> {
return value.asSequence().fold(Valid(value)) { result: ValidationResult<Map<K, V>>, entry ->
val propertyValidation = validation(entry).mapError { ".${entry.key}${it.removePrefix(".value")}" }.map { value }
val propertyValidation =
validation.validate(entry)
.mapError { ".${entry.key}${it.removePrefix(".value")}" }
.map { value }
result.combineWith(propertyValidation)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class ValidationBuilderTest {
fun validatingNullableValues() {
val nullableValueValidation =
Validation<String?> {
addConstraint("cannot be null") { it != null}
addConstraint("cannot be null") { it != null }
}

"poweruser@test.com".let { assertEquals(Valid(it), nullableValueValidation(it)) }
Expand Down
42 changes: 42 additions & 0 deletions src/jvmTest/kotlin/io/konform/validation/ConcurrencyTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.konform.validation

import kotlin.concurrent.thread
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class ConcurrencyTest {
data class User(val name: String)

val user1 = User("a")
val user2 = User("invalid")

private val sleepTimeMs = 300L

val mustNotBeNamedInvalidValidation =
Validation<User> { (user) ->
addConstraint("Cannot be 'invalid'") {
// Simulate a long expensive blocking operation
Thread.sleep(sleepTimeMs)
user.name != "invalid"
}
}

@Test
fun validationsMustBeThreadSafe() {
var validation1Holder: ValidationResult<User>? = null
// Run the first validation concurrently
thread {
validation1Holder = mustNotBeNamedInvalidValidation.validate(user1)
}
val validation2 = mustNotBeNamedInvalidValidation.validate(user2)
// Give the thread time to finish
Thread.sleep(sleepTimeMs + 100)
val validation1 =
requireNotNull(validation1Holder) {
"Validation 1 should have completed by now"
}
assertContentEquals(validation1.errors, listOf())
assertEquals(1, validation2.errors.size)
}
}

0 comments on commit 2ff23d7

Please sign in to comment.