Skip to content

Commit 9a859cb

Browse files
author
Piotr Fałdrowicz
committed
tests
1 parent 6af265e commit 9a859cb

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

engine/flink/components/base-tests/src/test/scala/pl/touk/nussknacker/engine/flink/util/transformer/aggregate/JavaCollectionsSerializationTest.scala

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,56 @@ import pl.touk.nussknacker.engine.flink.test.FlinkSpec
1414
import pl.touk.nussknacker.engine.flink.test.ScalatestMiniClusterJobStatusCheckingOps.miniClusterWithServicesToOps
1515
import pl.touk.nussknacker.engine.flink.util.source.CollectionSource
1616
import pl.touk.nussknacker.engine.flink.util.transformer.FlinkBaseComponentProvider
17+
import pl.touk.nussknacker.engine.graph.expression.Expression
1718
import pl.touk.nussknacker.engine.process.helpers.ConfigCreatorWithCollectingListener
1819
import pl.touk.nussknacker.engine.process.runner.FlinkScenarioUnitTestJob
1920
import pl.touk.nussknacker.engine.spel.SpelExtension._
2021
import pl.touk.nussknacker.engine.testing.LocalModelData
2122
import pl.touk.nussknacker.engine.testmode.{ResultsCollectingListener, ResultsCollectingListenerHolder}
2223

24+
import java.util
2325
import scala.collection.mutable
2426
import scala.jdk.CollectionConverters._
27+
import scala.util.Random
2528

2629
class JavaCollectionsSerializationTest extends AnyFunSuite with FlinkSpec with Matchers with Inside {
2730

2831
private val processId = "aggregateFilterProcess"
2932

30-
private val process: CanonicalProcess =
31-
ScenarioBuilder
33+
private def process(expressionOption: Option[Expression] = None): CanonicalProcess = {
34+
val scenario = ScenarioBuilder
3235
.streaming(processId)
3336
.parallelism(1)
3437
.source("start", "start")
38+
39+
expressionOption
40+
.map(expression => scenario.buildSimpleVariable("mapVariable", "mapVariable", expression))
41+
.getOrElse(scenario)
3542
.customNodeNoOutput(
3643
"delay",
3744
"delay",
3845
"key" -> "#input.id".spel,
3946
"delay" -> "T(java.time.Duration).parse('PT30M')".spel
4047
)
4148
.emptySink("end", "dead-end")
49+
}
50+
51+
private val record = Record(
52+
id = "2",
53+
map = mutable.Map(1 -> "a").asJava,
54+
list = mutable.ListBuffer("abc").asJava,
55+
set = mutable.Set("def").asJava
56+
)
4257

4358
// In Scala 2.13 all java collections class wrappers were rewritten from case class to regular class. Now kryo does not
4459
// serialize them properly, so JavaWrapperScala2_13Registrar class was added to fix this issue. This test verifies
4560
// if we can serialize and deserialize records properly.
4661
test("should serialize record with java map, list and set") {
47-
val record = Record(
48-
id = "2",
49-
map = mutable.Map(1 -> "a").asJava,
50-
list = mutable.ListBuffer("abc").asJava,
51-
set = mutable.Set("def").asJava
52-
)
5362

5463
ResultsCollectingListenerHolder.withListener { collectingListener =>
5564
val model = modelData(collectingListener, List(record))
5665

57-
runScenario(model, process)
66+
runScenario(model, process())
5867

5968
val result = collectingListener.results
6069
.nodeResults("end")
@@ -64,6 +73,40 @@ class JavaCollectionsSerializationTest extends AnyFunSuite with FlinkSpec with M
6473
}
6574
}
6675

76+
test("should serialize java map without changing fields order") {
77+
78+
ResultsCollectingListenerHolder.withListener { collectingListener =>
79+
val model = modelData(collectingListener, List(record))
80+
81+
val sampleMap =
82+
('a' to 'z')
83+
.map(x => x -> Random.nextInt())
84+
.sortBy(_._2)
85+
86+
runScenario(
87+
model,
88+
process(
89+
Some(
90+
sampleMap
91+
.map { case (c, i) => s""""$c" : $i""" }
92+
.mkString("{", ",", "}")
93+
.spel
94+
)
95+
)
96+
)
97+
98+
val linkedHashMap = new util.LinkedHashMap[String, AnyRef]()
99+
sampleMap.foreach { case (char, int) => linkedHashMap.put(s"$char", Integer.valueOf(int)) }
100+
101+
val result = collectingListener.results
102+
.nodeResults("end")
103+
.map(_.variableTyped[Map[_, _]]("mapVariable"))
104+
105+
result shouldBe List(Some(linkedHashMap))
106+
107+
}
108+
}
109+
67110
def modelData(collectingListener: ResultsCollectingListener[Any], list: List[Record] = List()): LocalModelData = {
68111
val sourceComponent = SourceFactory.noParamUnboundedStreamFactory[Record](
69112
CollectionSource[Record](list, None, Typed.fromDetailedType[List[Record]])

utils/utils/src/test/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoderSpec.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import java.time._
1010
import java.util
1111
import java.util.UUID
1212
import scala.collection.immutable.{ListMap, ListSet}
13+
import scala.util.Random
1314

1415
class ToJsonEncoderSpec extends AnyFunSpec with Matchers {
1516

@@ -72,6 +73,19 @@ class ToJsonEncoderSpec extends AnyFunSpec with Matchers {
7273
encoder.encode(map) shouldEqual obj("key1" -> fromLong(1), "key2" -> fromString("value"))
7374
}
7475

76+
it("should encode maps as a json without changing fields order") {
77+
val sampleMap =
78+
('a' to 'z')
79+
.map(x => x -> Random.nextInt())
80+
.sortBy(_._2)
81+
val linkedHashMap = new util.LinkedHashMap[String, AnyRef]()
82+
sampleMap.foreach { case (char, int) => linkedHashMap.put(s"$char", Integer.valueOf(int)) }
83+
84+
val encoded = encoder.encode(linkedHashMap)
85+
val expected = obj(sampleMap.map { case (c, i) => s"$c" -> fromInt(i) }: _*)
86+
encoded.asObject.map(_.keys.toList) shouldEqual expected.asObject.map(_.keys.toList)
87+
}
88+
7589
it("should encode arrays as a json") {
7690
encoder.encode(Array(1, 2, 3)) shouldEqual arr(fromLong(1), fromLong(2), fromLong(3))
7791
encoder.encode(Seq(Array(1, 2, 3))) shouldEqual arr(arr(fromLong(1), fromLong(2), fromLong(3)))

0 commit comments

Comments
 (0)