Skip to content

Commit

Permalink
[LF] refactor CantonFixture (digital-asset#1673)
Browse files Browse the repository at this point in the history
- force logging when debug is one (overring logbak conf)
- inherit SuiteResourceManagementAroundAll
- minor cleanup
- add default value for CantonFixture parameter
  • Loading branch information
remyhaemmerle-da authored May 5, 2023
1 parent 993ddaa commit 7149ebd
Show file tree
Hide file tree
Showing 25 changed files with 146 additions and 215 deletions.
5 changes: 3 additions & 2 deletions daml-lf/integration-test-lib/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ da_scala_library(
name = "integration-test-lib",
srcs = glob(["src/main/**/*.scala"]),
data = [
":canton-dev_deploy.jar",
":canton-patched_deploy.jar",
":canton_deploy.jar",
"//test-common/test-certificates",
],
Expand Down Expand Up @@ -61,10 +61,11 @@ java_binary(
# We replace engine and archive classes in canton
# This should be used for testing only
java_binary(
name = "canton-dev",
name = "canton-patched",
main_class = "com.digitalasset.canton.CantonCommunityApp",
visibility = ["//visibility:public"],
runtime_deps = [
# The following prevents buildifier from sorting the deps
# Do not sort
"//daml-lf/engine",
"//daml-lf/archive:daml_lf_archive_reader",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package com.daml.lf
package integrationtest

import com.daml.bazeltools.BazelRunfiles.rlocation
import com.daml.grpc.adapter.ExecutionSequencerFactory
import com.daml.ledger.api.refinements.ApiTypes.ApplicationId
import com.daml.ledger.api.tls.TlsConfiguration
Expand All @@ -16,7 +17,7 @@ import io.grpc.ManagedChannel
import scalaz.syntax.tag._

import scala.concurrent.{ExecutionContext, Future}
import java.nio.file.Path
import java.nio.file.{Path, Paths}

object CantonConfig {

Expand All @@ -37,19 +38,42 @@ object CantonConfig {
}

def noTlsConfig = TlsConfiguration(false)

}

final case class CantonConfig(
applicationId: ApplicationId,
darFiles: List[Path] = List.empty,
authSecret: Option[String] = None,
devMode: Boolean = false,
nParticipants: Int = 1,
timeProviderType: TimeProviderType = TimeProviderType.WallClock,
tlsConfig: Option[CantonConfig.Tls] = None,
applicationId: ApplicationId = ApplicationId("integrationtest"),
tlsEnable: Boolean = false,
debug: Boolean = false,
) {

lazy val tlsConfig =
if (tlsEnable)
Some(
CantonConfig.Tls(
Paths.get(rlocation("test-common/test-certificates/server.crt")),
Paths.get(rlocation("test-common/test-certificates/server.pem")),
Paths.get(rlocation("test-common/test-certificates/ca.crt")),
Paths.get(rlocation("test-common/test-certificates/client.crt")),
Paths.get(rlocation("test-common/test-certificates/client.pem")),
)
)
else
None

lazy val participantIds =
Iterator
.range(0, nParticipants)
.map(i => Ref.ParticipantId.assertFromString("participant" + i.toString))
.toVector

lazy val ledgerIds = participantIds.asInstanceOf[Vector[String]]

def getToken(userId: Ref.IdString.UserId): Option[String] =
CantonRunner.getToken(userId, authSecret)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ package integrationtest

import com.daml.bazeltools.BazelRunfiles._
import com.daml.ledger.api.refinements.ApiTypes.ApplicationId
import com.daml.ledger.api.testing.utils.{AkkaBeforeAndAfterAll, OwnedResource, SuiteResource}
import com.daml.ledger.api.testing.utils.{
AkkaBeforeAndAfterAll,
OwnedResource,
SuiteResource,
SuiteResourceManagementAroundAll,
}
import com.daml.ledger.client.LedgerClient
import com.daml.ledger.resources.ResourceContext
import com.daml.lf.data.Ref
Expand Down Expand Up @@ -54,9 +59,30 @@ object CantonFixture {

}

trait CantonFixture extends SuiteResource[Vector[Port]] with AkkaBeforeAndAfterAll {
trait CantonFixture
extends SuiteResource[Vector[Port]]
with AkkaBeforeAndAfterAll
with SuiteResourceManagementAroundAll {
self: Suite =>

protected lazy val authSecret: Option[String] = Option.empty
protected lazy val darFiles: List[Path] = List.empty
protected lazy val devMode: Boolean = false
protected lazy val nParticipants: Int = 1
protected lazy val timeProviderType: TimeProviderType = TimeProviderType.WallClock
protected lazy val tlsEnable: Boolean = false

// This flag setup some behavior to ease debugging tests.
// If `true`
// - temporary file are not deleted (this requires "--test_tmpdir=/tmp/" or similar for bazel builds)
// - some debug info are logged.
protected val cantonFixtureDebugMode = false

final protected val logger = org.slf4j.LoggerFactory.getLogger(getClass)

if (cantonFixtureDebugMode)
logger.asInstanceOf[ch.qos.logback.classic.Logger].setLevel(ch.qos.logback.classic.Level.INFO)

override protected def afterAll(): Unit = {
cantonCleanUp()
super.afterAll()
Expand All @@ -65,53 +91,25 @@ trait CantonFixture extends SuiteResource[Vector[Port]] with AkkaBeforeAndAfterA
final override protected lazy val suiteResource: OwnedResource[ResourceContext, Vector[Port]] = {
implicit val resourceContext: ResourceContext = ResourceContext(system.dispatcher)
new OwnedResource[ResourceContext, Vector[Port]](
CantonRunner.run(config, cantonTmpDir),
CantonRunner.run(config, cantonTmpDir, logger),
acquisitionTimeout = 2.minute,
releaseTimeout = 2.minute,
)
}

protected def authSecret: Option[String]
protected def darFiles: List[Path]
protected def devMode: Boolean
protected def nParticipants: Int
protected def timeProviderType: TimeProviderType
protected def tlsEnable: Boolean
protected def applicationId: ApplicationId

lazy val tlsConfig =
if (tlsEnable)
Some(
CantonConfig.Tls(
Paths.get(rlocation("test-common/test-certificates/server.crt")),
Paths.get(rlocation("test-common/test-certificates/server.pem")),
Paths.get(rlocation("test-common/test-certificates/ca.crt")),
Paths.get(rlocation("test-common/test-certificates/client.crt")),
Paths.get(rlocation("test-common/test-certificates/client.pem")),
)
)
else
None
final protected lazy val applicationId: ApplicationId = ApplicationId(getClass.getName)

lazy val config = CantonConfig(
darFiles: List[Path],
authSecret: Option[String],
devMode: Boolean,
nParticipants: Int,
timeProviderType: TimeProviderType,
tlsConfig = tlsConfig,
applicationId = applicationId: ApplicationId,
applicationId = applicationId,
darFiles = darFiles,
authSecret = authSecret,
devMode = devMode,
nParticipants = nParticipants,
timeProviderType = timeProviderType,
tlsEnable = tlsEnable,
debug = cantonFixtureDebugMode,
)

// This flag setup some behavior to ease debugging tests.
// If `true`
// - temporary file are not deleted (this requires "--test_tmpdir=/tmp/" or similar for bazel builds)
// - some debug info are logged.
protected val cantonFixtureDebugMode = false

private val logger = org.slf4j.LoggerFactory.getLogger(getClass)

protected def info(msg: String): Unit =
if (cantonFixtureDebugMode) logger.info(msg)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,21 @@ import java.nio.file.{Files, Path, Paths}

object CantonRunner {

private val logger = org.slf4j.LoggerFactory.getLogger(getClass)

private[integrationtest] def toJson(s: String): String = JsString(s).toString()
private[integrationtest] def toJson(path: Path): String = toJson(path.toString)

lazy val cantonPath = Paths.get(rlocation("daml-lf/integration-test-lib/canton_deploy.jar"))
lazy val cantonDevPath =
Paths.get(rlocation("daml-lf/integration-test-lib/canton-dev_deploy.jar"))
private lazy val cantonPath =
Paths.get(rlocation("daml-lf/integration-test-lib/canton_deploy.jar"))
private lazy val cantonPatchPath =
Paths.get(rlocation("daml-lf/integration-test-lib/canton-patched_deploy.jar"))

def run(config: CantonConfig, tmpDir: Path)(implicit
def run(config: CantonConfig, tmpDir: Path, logger: org.slf4j.Logger)(implicit
esf: ExecutionSequencerFactory
): ResourceOwner[Vector[Port]] =
new ResourceOwner[Vector[Port]] {
protected val cantonConfigFile = tmpDir.resolve("participant.config")
protected val cantonLogFile = tmpDir.resolve("canton.log")
protected val portFile = tmpDir.resolve("portfile")
val cantonConfigFile = tmpDir.resolve("participant.config")
val cantonLogFile = tmpDir.resolve("canton.log")
val portFile = tmpDir.resolve("portfile")
def info(s: String) = if (config.debug) logger.info(s)

override def acquire()(implicit context: ResourceContext): Resource[Vector[Port]] = {
Expand All @@ -52,18 +51,18 @@ object CantonRunner {
Vector.fill(config.nParticipants)(LockedFreePort.find() -> LockedFreePort.find())
val domainPublicApi = LockedFreePort.find()
val domainAdminApi = LockedFreePort.find()
val jarPath = if (config.devMode) cantonDevPath else cantonPath
val jarPath = if (config.devMode) cantonPatchPath else cantonPath
val exe = if (sys.props("os.name").toLowerCase.contains("windows")) ".exe" else ""
val java = s"${System.getenv("JAVA_HOME")}/bin/java${exe}"
val (timeType, clockType) = config.timeProviderType match {
case TimeProviderType.Static => (Some("monotonic-time"), Some("sim-clock"))
case TimeProviderType.WallClock => (None, None)
}
val authConfig = config.authSecret.fold("")(secret => s"""auth-services = [{
| type = unsafe-jwt-hmac-256
| secret = "${toJson(secret)}"
| }]
|""".stripMargin)
| type = unsafe-jwt-hmac-256
| secret = "${toJson(secret)}"
| }]
|""".stripMargin)
val tls = config.tlsConfig.fold("")(config => s"""tls {
| cert-chain-file = ${toJson(config.serverCrt)}
| private-key-file = ${toJson(config.serverPem)}
Expand All @@ -72,7 +71,8 @@ object CantonRunner {

def participantConfig(i: Int) = {
val (adminPort, ledgerApiPort) = ports(i)
s"""participant${i} {
val participantId = config.participantIds(i)
s"""${participantId} {
| admin-api.port = ${adminPort.port}
| ledger-api{
| port = ${ledgerApiPort.port}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import java.util.UUID
import akka.stream.scaladsl.Sink
import com.daml.SdkVersion
import com.daml.bazeltools.BazelRunfiles
import com.daml.ledger.api.refinements.ApiTypes.{ApplicationId, Party}
import com.daml.ledger.api.testing.utils.SuiteResourceManagementAroundAll
import com.daml.ledger.api.refinements.ApiTypes
import com.daml.ledger.api.tls.TlsConfiguration
import com.daml.ledger.api.v1.command_service.SubmitAndWaitRequest
import com.daml.ledger.api.v1.commands._
Expand All @@ -26,7 +25,6 @@ import com.daml.lf.engine.script.{Participants, Runner}
import com.daml.lf.language.Ast.Package
import com.daml.lf.integrationtest.CantonFixture
import com.daml.platform.services.time.TimeProviderType
import com.typesafe.scalalogging.StrictLogging
import org.scalatest._
import org.scalatest.freespec.AsyncFreeSpec
import org.scalatest.matchers.should.Matchers
Expand All @@ -40,17 +38,10 @@ final class ReproducesTransactions
extends AsyncFreeSpec
with Matchers
with BeforeAndAfterEach
with SuiteResourceManagementAroundAll
with CantonFixture
with StrictLogging {
with CantonFixture {

override protected def authSecret = None
override protected def darFiles = List(darFile)
override protected def devMode = false
override protected def nParticipants = 1
override protected def timeProviderType = TimeProviderType.Static
override protected def tlsEnable = false
override protected def applicationId: ApplicationId = ApplicationId("script-export")
final override protected lazy val darFiles = List(darFile)
final override protected lazy val timeProviderType = TimeProviderType.Static

private val exe = if (sys.props("os.name").toLowerCase.contains("windows")) ".exe" else ""
val scriptPath = BazelRunfiles.rlocation("daml-script/runner/daml-script-binary" + exe)
Expand All @@ -71,7 +62,7 @@ final class ReproducesTransactions
Some(
Commands(
ledgerId = client.ledgerId.unwrap,
applicationId = applicationId.unwrap,
applicationId = config.applicationId.unwrap,
commandId = UUID.randomUUID().toString(),
party = p,
commands = Seq(cmd),
Expand Down Expand Up @@ -125,7 +116,7 @@ final class ReproducesTransactions
tlsConfig = TlsConfiguration(false, None, None, None),
accessToken = None,
partyConfig = PartyConfig(
parties = Party.subst(parties),
parties = ApiTypes.Party.subst(parties),
allParties = false,
),
start = offset,
Expand Down Expand Up @@ -173,7 +164,7 @@ final class ReproducesTransactions
),
timeMode = ScriptTimeMode.Static,
initialClients = Participants(
default_participant = Some(new GrpcLedgerClient(client, ApplicationId("script"))),
default_participant = Some(new GrpcLedgerClient(client, applicationId)),
participants = Map.empty,
party_participants = Map.empty,
),
Expand Down
2 changes: 1 addition & 1 deletion daml-script/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ da_scala_test_suite(
"@maven//:org_scalaz_scalaz_core",
],
tags = [
"canton-dev",
"cpu:4",
"dev-canton-test",
],
deps = [
":test-utils",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package com.daml.lf.engine.script
package test

import com.daml.ledger.api.domain
import com.daml.ledger.api.testing.utils.SuiteResourceManagementAroundAll
import com.daml.lf.data.{ImmArray, Ref}
import com.daml.lf.engine.script.ledgerinteraction.ScriptTimeMode
import com.daml.lf.integrationtest._
Expand All @@ -16,19 +15,12 @@ import org.scalatest.wordspec.AsyncWordSpec
import scala.concurrent.Future
import scala.util.{Failure, Success}

final class AuthIT
extends AsyncWordSpec
with AbstractScriptTest
with Matchers
with SuiteResourceManagementAroundAll {
final class AuthIT extends AsyncWordSpec with AbstractScriptTest with Matchers {
import AbstractScriptTest._

override protected lazy val authSecret = Some("secret")
override protected lazy val darFiles = List(stableDarPath)
override protected lazy val devMode = false
override protected lazy val nParticipants = 1
override protected lazy val timeMode = ScriptTimeMode.WallClock
override protected lazy val tlsEnable = false
final override protected lazy val authSecret = Some("secret")
final override protected lazy val darFiles = List(stableDarPath)
final override protected lazy val timeMode = ScriptTimeMode.WallClock

"Daml Script against authorized ledger" can {
"auth" should {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package com.daml.lf.engine.script

import com.daml.bazeltools.BazelRunfiles
import com.daml.ledger.api.refinements.ApiTypes.ApplicationId
import com.daml.ledger.api.testing.utils.SuiteResourceManagementAroundAll
import com.daml.lf.integrationtest.CantonFixture
import com.daml.platform.services.time.TimeProviderType
import com.daml.scalautil.Statement.discard
Expand All @@ -15,20 +13,10 @@ import org.scalatest.wordspec.AnyWordSpec

import java.nio.file.Files

class DamlScriptTestRunner
extends AnyWordSpec
with CantonFixture
with Matchers
with SuiteResourceManagementAroundAll {
class DamlScriptTestRunner extends AnyWordSpec with CantonFixture with Matchers {
self: Suite =>

override protected def authSecret = None
override protected def darFiles = List.empty
override protected def devMode = false
override protected def nParticipants = 1
override protected def timeProviderType = TimeProviderType.Static
override protected def tlsEnable = false
override protected def applicationId: ApplicationId = ApplicationId("daml-script")
final override protected lazy val timeProviderType = TimeProviderType.Static

private val exe = if (sys.props("os.name").toLowerCase.contains("windows")) ".exe" else ""
val scriptPath = BazelRunfiles.rlocation("daml-script/runner/daml-script-binary" + exe)
Expand Down
Loading

0 comments on commit 7149ebd

Please sign in to comment.