summaryrefslogtreecommitdiff
path: root/formats/json-tests/jvmTest/src/kotlinx/serialization/json/JsonConcurrentStressTest.kt
blob: cdcbab792e822b8384c99c8966bc682b879cc16a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package kotlinx.serialization.json

import kotlinx.coroutines.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.*
import org.junit.Test
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import kotlin.random.*
import kotlin.test.*

// Stresses out that JSON decoded in parallel does not interfere (mostly via caching of various buffers)
class JsonConcurrentStressTest : JsonTestBase() {
    private val charset = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz0123456789"

    @Test
    fun testDecodeInParallelSimpleList() = doTest(100) { mode ->
        val value = (1..10000).map { Random.nextDouble() }
        val string = Json.encodeToString(ListSerializer(Double.serializer()), value, mode)
        assertEquals(value, Json.decodeFromString(ListSerializer(Double.serializer()), string, mode))
    }

    @Serializable
    data class Foo(val s: String, val f: Foo?)

    @Test
    fun testDecodeInParallelListOfPojo() = doTest(1_000) { mode ->
        val value = (1..100).map {
            val randomString = getRandomString()
            val nestedFoo = Foo("null抢\u000E鋽윝䑜厼\uF70A紲ᢨ䣠null⛾䉻嘖緝ᯧnull쎶\u0005null" + randomString, null)
            Foo(getRandomString(), nestedFoo)
        }
        val string = Json.encodeToString(ListSerializer(Foo.serializer()), value, mode)
        assertEquals(value, Json.decodeFromString(ListSerializer(Foo.serializer()), string, mode))
    }

    @Test
    fun testDecodeInParallelPojo() = doTest(100_000) { mode ->
        val randomString = getRandomString()
        val nestedFoo = Foo("null抢\u000E鋽윝䑜厼\uF70A紲ᢨ䣠null⛾䉻嘖緝ᯧnull쎶\u0005null" + randomString, null)
        val randomFoo = Foo(getRandomString(), nestedFoo)
        val string = Json.encodeToString(Foo.serializer(), randomFoo, mode)
        assertEquals(randomFoo, Json.decodeFromString(Foo.serializer(), string, mode))
    }

    @Test
    fun testDecodeInParallelSequencePojo() =  runBlocking<Unit> {
        for (i in 1 until 1_000) {
            launch(Dispatchers.Default) {
                val values = (1..100).map {
                    val randomString = getRandomString()
                    val nestedFoo = Foo("null抢\u000E鋽윝䑜厼\uF70A紲ᢨ䣠null⛾䉻嘖緝ᯧnull쎶\u0005null" + randomString, null)
                    Foo(getRandomString(), nestedFoo)
                }
                val baos = ByteArrayOutputStream()
                for (value in values) {
                    Json.encodeToStream(Foo.serializer(), value, baos)
                }
                val bais = ByteArrayInputStream(baos.toByteArray())
                assertEquals(values, Json.decodeToSequence(bais, Foo.serializer()).toList())
            }
        }
    }

    private fun getRandomString() = (1..Random.nextInt(0, charset.length)).map { charset[it] }.joinToString(separator = "")

    private fun doTest(iterations: Int, block: (JsonTestingMode) -> Unit) {
        runBlocking<Unit> {
            for (i in 1 until iterations) {
                launch(Dispatchers.Default) {
                    parametrizedTest {
                        block(it)
                    }
                }
            }
        }
    }
}