Skip to content

Commit 8f652e9

Browse files
Added tests
[ci] Signed-off-by: Pasindu Tennage <[email protected]>
1 parent 5bc870d commit 8f652e9

File tree

4 files changed

+105
-25
lines changed

4 files changed

+105
-25
lines changed

apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V050__create_scan_config.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ CREATE TABLE validator_internal_config
22
(
33
config_key text not null,
44
config_value jsonb not null,
5-
CONSTRAINT uc_validator_config PRIMARY KEY (config_key)
5+
CONSTRAINT uc_validator_internal_config PRIMARY KEY (config_key)
66
);

apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/ValidatorInternalStore.scala

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,44 @@ package org.lfdecentralizedtrust.splice.validator.store
55

66
import com.digitalasset.canton.tracing.TraceContext
77
import io.circe.Json
8-
9-
import scala.concurrent.Future
8+
import io.circe.syntax.*
9+
import io.circe.{Encoder, Decoder}
10+
import scala.concurrent.{Future, ExecutionContext}
1011

1112
trait ValidatorInternalStore {
1213

1314
def setConfig(key: String, value: Json)(implicit tc: TraceContext): Future[Unit]
1415

1516
def getConfig(key: String)(implicit tc: TraceContext): Future[Json]
1617

18+
private val scanInternalConfigKey = "validator_scan_internal_config_key"
19+
20+
implicit val scanUrlEncoder: Encoder[ScanUrlInternalConfig] =
21+
Encoder.forProduct2("svName", "url")(s => (s.svName, s.url))
22+
implicit val scanUrlDecoder: Decoder[ScanUrlInternalConfig] =
23+
Decoder.forProduct2("svName", "url")(ScanUrlInternalConfig.apply)
24+
25+
def setScanUrlInternalConfig(
26+
value: Seq[ScanUrlInternalConfig]
27+
)(implicit tc: TraceContext): Future[Unit] = {
28+
setConfig(scanInternalConfigKey, value.asJson)
29+
}
30+
31+
def getScanUrlInternalConfig(
32+
)(implicit tc: TraceContext, ec: ExecutionContext): Future[Seq[ScanUrlInternalConfig]] = {
33+
getConfig(scanInternalConfigKey).map { json =>
34+
if (json.isNull || json.asObject.exists(_.isEmpty)) {
35+
Seq.empty[ScanUrlInternalConfig]
36+
} else {
37+
json.as[Seq[ScanUrlInternalConfig]].toOption.getOrElse {
38+
Seq.empty[ScanUrlInternalConfig]
39+
}
40+
}
41+
}
42+
}
1743
}
44+
45+
final case class ScanUrlInternalConfig(
46+
svName: String,
47+
url: String,
48+
)

apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorInternalStore.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class DbValidatorInternalStore(
3434
ON CONFLICT (config_key) DO UPDATE
3535
SET config_value = excluded.config_value""".asUpdate
3636

37-
storage.update(action, "set-validator-config").map(_ => ())
37+
storage.update(action, "set-validator-internal-config").map(_ => ())
3838
}
3939

4040
override def getConfig(key: String)(implicit tc: TraceContext): Future[Json] = {
@@ -43,7 +43,7 @@ class DbValidatorInternalStore(
4343
WHERE config_key = $key
4444
""".as[Json].headOption
4545

46-
val jsonOptionF = storage.querySingle(queryAction, "get-validator-config")
46+
val jsonOptionF = storage.querySingle(queryAction, "get-validator-internal-config")
4747

4848
jsonOptionF.value.map {
4949
_.getOrElse(Json.obj())

apps/validator/src/test/scala/org/lfdecentralizedtrust/splice/store/ValidatorInternalStoreTest.scala

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import com.digitalasset.canton.tracing.TraceContext
1111
import com.digitalasset.canton.{HasActorSystem, HasExecutionContext}
1212
import io.circe.Json
1313
import org.lfdecentralizedtrust.splice.store.db.SplicePostgresTest
14-
import org.lfdecentralizedtrust.splice.validator.store.ValidatorInternalStore
14+
import org.lfdecentralizedtrust.splice.validator.store.{
15+
ScanUrlInternalConfig,
16+
ValidatorInternalStore,
17+
}
1518
import org.lfdecentralizedtrust.splice.validator.store.db.DbValidatorInternalStore
1619
import org.scalatest.matchers.should.Matchers
1720
import org.scalatest.wordspec.AsyncWordSpec
@@ -29,51 +32,97 @@ abstract class ValidatorInternalStoreTest
2932
implicit val tc: TraceContext = TraceContext.empty
3033

3134
val configKey = "test-config-key"
32-
val initialValues = Json.fromString("payload1")
35+
val initialValue = Json.fromString("payload1")
3336
val otherKey = "other-config"
34-
val otherValues = Json.fromString("payload2")
37+
val otherValue = Json.fromString("payload2")
3538

36-
"set and get a configuration successfully" in {
39+
"set and get a json payload successfully" in {
3740
for {
3841
store <- mkStore()
39-
_ <- store.setConfig(configKey, initialValues)
40-
retrievedValues <- store.getConfig(configKey)
42+
_ <- store.setConfig(configKey, initialValue)
43+
retrievedValue <- store.getConfig(configKey)
4144
} yield {
42-
retrievedValues shouldEqual initialValues
45+
retrievedValue shouldEqual initialValue
4346
}
4447
}
4548

4649
"return an empty JSON for a non-existent key" in {
4750
for {
4851
store <- mkStore()
49-
retrievedValues <- store.getConfig("non-existent-key")
52+
retrievedValue <- store.getConfig("non-existent-key")
5053
} yield {
51-
retrievedValues shouldEqual Json.obj()
54+
retrievedValue shouldEqual Json.obj()
5255
}
5356
}
5457

55-
"update an existing configuration on conflict" in {
58+
"update an existing payload" in {
5659
for {
5760
store <- mkStore()
58-
_ <- store.setConfig(configKey, initialValues)
59-
_ <- store.setConfig(configKey, otherValues)
60-
retrievedValues <- store.getConfig(configKey)
61+
_ <- store.setConfig(configKey, initialValue)
62+
_ <- store.setConfig(configKey, otherValue)
63+
retrievedValue <- store.getConfig(configKey)
6164
} yield {
62-
retrievedValues shouldEqual otherValues
65+
retrievedValue shouldEqual otherValue
6366
}
6467
}
6568

6669
"handle multiple different keys independently" in {
6770
for {
6871
store <- mkStore()
69-
_ <- store.setConfig(configKey, initialValues)
70-
_ <- store.setConfig(otherKey, otherValues)
72+
_ <- store.setConfig(configKey, initialValue)
73+
_ <- store.setConfig(otherKey, otherValue)
7174

72-
mainKeyValues <- store.getConfig(configKey)
73-
otherKeyValues <- store.getConfig(otherKey)
75+
mainKeyValue <- store.getConfig(configKey)
76+
otherKeyValue <- store.getConfig(otherKey)
7477
} yield {
75-
mainKeyValues shouldEqual initialValues
76-
otherKeyValues shouldEqual otherValues
78+
mainKeyValue shouldEqual initialValue
79+
otherKeyValue shouldEqual otherValue
80+
}
81+
}
82+
83+
val scanConfig1: Seq[ScanUrlInternalConfig] = Seq(
84+
ScanUrlInternalConfig("sv1", "url1"),
85+
ScanUrlInternalConfig("sv2", "url2"),
86+
ScanUrlInternalConfig("sv3", "url3"),
87+
ScanUrlInternalConfig("sv4", "url4"),
88+
)
89+
90+
val scanConfig2: Seq[ScanUrlInternalConfig] = Seq(
91+
ScanUrlInternalConfig("sv1", "url5"),
92+
ScanUrlInternalConfig("sv2", "url6"),
93+
ScanUrlInternalConfig("sv3", "url7"),
94+
ScanUrlInternalConfig("sv4", "url8"),
95+
)
96+
97+
"saves a scan config" in {
98+
for {
99+
store <- mkStore()
100+
_ <- store.setScanUrlInternalConfig(scanConfig1)
101+
returnConfig <- store.getScanUrlInternalConfig()
102+
} yield {
103+
returnConfig shouldEqual scanConfig1
104+
105+
}
106+
}
107+
"updates a scan config" in {
108+
for {
109+
store <- mkStore()
110+
_ <- store.setScanUrlInternalConfig(scanConfig1)
111+
_ <- store.setScanUrlInternalConfig(scanConfig2)
112+
returnConfig <- store.getScanUrlInternalConfig()
113+
} yield {
114+
returnConfig shouldEqual scanConfig2
115+
116+
}
117+
}
118+
119+
"retrieves an empty scan config" in {
120+
for {
121+
store <- mkStore()
122+
returnConfig <- store.getScanUrlInternalConfig()
123+
} yield {
124+
returnConfig shouldEqual Seq.empty[ScanUrlInternalConfig]
125+
77126
}
78127
}
79128

0 commit comments

Comments
 (0)