@@ -6,9 +6,11 @@ import com.digitalasset.canton.integration.EnvironmentSetupPlugin
66import com .digitalasset .canton .logging .SuppressingLogger
77import com .digitalasset .canton .topology .PartyId
88import com .digitalasset .canton .tracing .TraceContext
9+ import com .digitalasset .daml .lf .data .Ref .PackageVersion
910import org .lfdecentralizedtrust .splice .config .SpliceConfig
10- import org .lfdecentralizedtrust .splice .environment .SpliceEnvironment
11+ import org .lfdecentralizedtrust .splice .environment .{ DarResources , SpliceEnvironment }
1112import org .lfdecentralizedtrust .splice .integration .tests .SpliceTests .SpliceTestConsoleEnvironment
13+ import org .lfdecentralizedtrust .splice .sv .config .SvOnboardingConfig
1214import org .lfdecentralizedtrust .splice .util .CommonAppInstanceReferences
1315import org .scalatest .concurrent .Eventually
1416import org .scalatest .matchers .should .Matchers
@@ -25,6 +27,8 @@ import scala.collection.parallel.CollectionConverters.*
2527import scala .util .control .NonFatal
2628import scala .util .{Success , Try }
2729
30+ import org .scalatest .OptionValues
31+
2832/** Runs `token-standard/cli`, to make sure that we have:
2933 * - no transactions that would break it.
3034 * - no transactions that get parsed as raw creates/archives,
@@ -42,77 +46,89 @@ class TokenStandardCliSanityCheckPlugin(
4246 with ScalaFuturesWithPatience
4347 with LoneElement
4448 with Inside
45- with CommonAppInstanceReferences {
49+ with CommonAppInstanceReferences
50+ with OptionValues {
4651
4752 override def beforeEnvironmentDestroyed (
4853 config : SpliceConfig ,
4954 environment : SpliceTestConsoleEnvironment ,
5055 ): Unit = {
5156 try {
5257 TraceContext .withNewTraceContext { implicit tc =>
53- // `SuppressingLogger.suppress` support neither nested nor **concurrent** calls
54- // but we need it for (expected) connection errors
55- loggerFactory.suppressWarningsAndErrors {
56- // Using `par` to save some time per test
57- environment.wallets.par.foreach { wallet =>
58- val ledgerApiUser = wallet.config.ledgerApiUser
59- val validator = environment.validators.local
60- .find(_.config.adminApi.port.unwrap == wallet.config.adminApi.url.effectivePort)
61- .getOrElse(
62- throw new RuntimeException (s " Failed to find validator for wallet of $ledgerApiUser" )
63- )
64- // JSON API port = gRPCport + 1000
65- val participantHttpApiPort =
66- validator.participantClient.config.ledgerApi.port.unwrap + 1000
58+ val sv1 = environment.svs.local.find(_.name == " sv1" ).value
59+ val amuletVersion = inside(sv1.config.onboarding) {
60+ case Some (foundDso : SvOnboardingConfig .FoundDso ) =>
61+ PackageVersion .assertFromString(foundDso.initialPackageConfig.amuletVersion)
62+ }
63+ if (amuletVersion < DarResources .amulet_0_1_9.metadata.version) {
64+ logger.info(s " Amulet version $amuletVersion does not support token standard, skipping " )
65+ } else {
66+ // `SuppressingLogger.suppress` support neither nested nor **concurrent** calls
67+ // but we need it for (expected) connection errors
68+ loggerFactory.suppressWarningsAndErrors {
69+ // Using `par` to save some time per test
70+ environment.wallets.par.foreach { wallet =>
71+ val ledgerApiUser = wallet.config.ledgerApiUser
72+ val validator = environment.validators.local
73+ .find(_.config.adminApi.port.unwrap == wallet.config.adminApi.url.effectivePort)
74+ .getOrElse(
75+ throw new RuntimeException (
76+ s " Failed to find validator for wallet of $ledgerApiUser"
77+ )
78+ )
79+ // JSON API port = gRPCport + 1000
80+ val participantHttpApiPort =
81+ validator.participantClient.config.ledgerApi.port.unwrap + 1000
6782
68- if (
69- validator.config.enableWallet &&
70- Try (wallet.httpLive && validator.participantClient.health.is_running())
71- .getOrElse(false )
72- ) {
73- // Sometimes userStatus will fail with 404
74- Try (wallet.userStatus()) match {
75- case Success (userStatus)
76- if userStatus.userOnboarded && userStatus.userWalletInstalled =>
77- val party = PartyId .tryFromProtoPrimitive(userStatus.party)
78- val authToken = wallet.token.getOrElse(
79- throw new IllegalStateException (
80- s " No auth token found for wallet of ${party.toProtoPrimitive}"
83+ if (
84+ validator.config.enableWallet &&
85+ Try (wallet.httpLive && validator.participantClient.health.is_running())
86+ .getOrElse(false )
87+ ) {
88+ // Sometimes userStatus will fail with 404
89+ Try (wallet.userStatus()) match {
90+ case Success (userStatus)
91+ if userStatus.userOnboarded && userStatus.userWalletInstalled =>
92+ val party = PartyId .tryFromProtoPrimitive(userStatus.party)
93+ val authToken = wallet.token.getOrElse(
94+ throw new IllegalStateException (
95+ s " No auth token found for wallet of ${party.toProtoPrimitive}"
96+ )
8197 )
82- )
83- // check no command blows up
84- runCommand(" list-holdings" , party, authToken, participantHttpApiPort, Seq .empty)
85- val holdingTxsDebugPath =
86- Files .createTempFile(UUID .randomUUID().toString, " .json" )
87- logger.info(
88- s " Debug Output of token-standard command list-holding-txs will be written to $holdingTxsDebugPath"
89- )
90- // check also that list-holding-txs does not contain raw events
91- val holdingTxsExtraArgs =
92- Seq (" -d" , holdingTxsDebugPath.toAbsolutePath.toString) ++ (rawBehavior match {
93- case OutputCreateArchiveBehavior .IgnoreAll => Seq .empty
94- case OutputCreateArchiveBehavior .IgnoreForTemplateIds (templateIds) =>
95- Seq (" --strict" ) ++ templateIds.headOption.toList.flatMap(tId =>
96- Seq (" --strict-ignore" , tId.getEntityName) ++ templateIds.tail
97- .map(_.getEntityName)
98- )
99- })
100- runCommand(
101- " list-holding-txs" ,
102- party,
103- authToken,
104- participantHttpApiPort,
105- holdingTxsExtraArgs,
106- )
107- case result =>
108- logger.info(
109- s " Not checking wallet for user $ledgerApiUser because it's not available: $result"
110- )
98+ // check no command blows up
99+ runCommand(" list-holdings" , party, authToken, participantHttpApiPort, Seq .empty)
100+ val holdingTxsDebugPath =
101+ Files .createTempFile(UUID .randomUUID().toString, " .json" )
102+ logger.info(
103+ s " Debug Output of token-standard command list-holding-txs will be written to $holdingTxsDebugPath"
104+ )
105+ // check also that list-holding-txs does not contain raw events
106+ val holdingTxsExtraArgs =
107+ Seq (" -d" , holdingTxsDebugPath.toAbsolutePath.toString) ++ (rawBehavior match {
108+ case OutputCreateArchiveBehavior .IgnoreAll => Seq .empty
109+ case OutputCreateArchiveBehavior .IgnoreForTemplateIds (templateIds) =>
110+ Seq (" --strict" ) ++ templateIds.headOption.toList.flatMap(tId =>
111+ Seq (" --strict-ignore" , tId.getEntityName) ++ templateIds.tail
112+ .map(_.getEntityName)
113+ )
114+ })
115+ runCommand(
116+ " list-holding-txs" ,
117+ party,
118+ authToken,
119+ participantHttpApiPort,
120+ holdingTxsExtraArgs,
121+ )
122+ case result =>
123+ logger.info(
124+ s " Not checking wallet for user $ledgerApiUser because it's not available: $result"
125+ )
126+ }
127+ } else {
128+ logger.info(
129+ s " Token-standard CLI not running for $ledgerApiUser because either wallet or participant are not alive. "
130+ )
111131 }
112- } else {
113- logger.info(
114- s " Token-standard CLI not running for $ledgerApiUser because either wallet or participant are not alive. "
115- )
116132 }
117133 }
118134 }
0 commit comments