mirror of
https://github.com/digital-asset/daml.git
synced 2024-11-05 03:56:26 +03:00
adding missing tests around Sandbox's CLI module (#668)
* introducing CliSpec * updating sandbox sdk docs * fixing the missing code block * adding missing copyright headers * making allow-dev hidden * HardCoded -> Predefined * updated changelog
This commit is contained in:
parent
80e2107130
commit
cc32ee5025
@ -30,6 +30,8 @@ HEAD — ongoing
|
||||
implement "callable updates" (aka functions of type ``Update a`` that can be
|
||||
called from the Ledger API via a contract).
|
||||
- Publish the participant-state APIs and reference implementations.
|
||||
- Add `-s` option to Sandbox CLI to have a shortened version for `--static-time` as well
|
||||
- Change `--allow-dev` to be a hidden CLI option in Sandbox
|
||||
|
||||
0.12.7 — 2019-04-17
|
||||
-------------------
|
||||
|
@ -29,18 +29,20 @@ Here, ``da run sandbox --`` tells the SDK Assistant to run ``sandbox`` from the
|
||||
Command-line reference
|
||||
**********************
|
||||
|
||||
Sandbox requires the names of the input ``.dar`` or ``.dalf`` files as arguments to start.
|
||||
The available command line options are listed here::
|
||||
|
||||
-p, --port <value> Sandbox service port. Defaults to 6865.
|
||||
-a, --address <value> Sandbox service host. Defaults to binding on all addresses.
|
||||
--dalf This argument is present for backwards compatibility. DALF and DAR archives are now identified by their extensions.
|
||||
--static-time Use static time, configured with TimeService through gRPC.
|
||||
-w, --wall-clock-time Use wall clock time (UTC). When not provided, static time is used.
|
||||
--no-parity Disables Ledger Server parity mode. Features which are not supported by the Platform become available.
|
||||
--scenario <value> If set, the sandbox will execute the given scenario on startup and store all the contracts created by it. Two formats are supported: Module.Name:Entity.Name (preferred) and Module.Name.Entity.Name (deprecated, will print a warning when used).
|
||||
--daml-lf-archive-recursion-limit <value>
|
||||
Set the recursion limit when decoding DAML-LF archives (.dalf files). Default is 1000
|
||||
<archive>... Daml archives to load. Either in .dar or .dalf format. Only DAML-LF v1 Archives are currently supported.
|
||||
--help Print the usage text
|
||||
::
|
||||
|
||||
Usage: sandbox [options] <archive>...
|
||||
|
||||
-p, --port <value> Sandbox service port. Defaults to 6865.
|
||||
-a, --address <value> Sandbox service host. Defaults to binding on all addresses.
|
||||
--dalf This argument is present for backwards compatibility. DALF and DAR archives are now identified by their extensions.
|
||||
-s, --static-time Use static time, configured with TimeService through gRPC.
|
||||
-w, --wall-clock-time Use wall clock time (UTC). When not provided, static time is used.
|
||||
--no-parity Legacy flag with no effect.
|
||||
--scenario <value> If set, the sandbox will execute the given scenario on startup and store all the contracts created by it. Two formats are supported: Module.Name:Entity.Name (preferred) and Module.Name.Entity.Name (deprecated, will print a warning when used).
|
||||
<archive>... Daml archives to load. Either in .dar or .dalf format. Only DAML-LF v1 Archives are currently supported.
|
||||
--pem <value> TLS: The pem file to be used as the private key.
|
||||
--crt <value> TLS: The crt file to be used as the cert chain. Required if any other TLS parameters are set.
|
||||
--cacrt <value> TLS: The crt file to be used as the the trusted root CA.
|
||||
--ledgerid <value> Sandbox ledger ID. If missing, a random unique ledger ID will be used. Only useful with persistent stores.
|
||||
--help Print the usage text
|
||||
|
@ -51,7 +51,7 @@ class CodegenLedgerTest extends FlatSpec with Matchers {
|
||||
val cfg = SandboxConfig.default.copy(
|
||||
port = 0,
|
||||
damlPackageContainer = DamlPackageContainer(List(testDalf)),
|
||||
ledgerIdMode = LedgerIdMode.HardCoded(LedgerID),
|
||||
ledgerIdMode = LedgerIdMode.Predefined(LedgerID),
|
||||
timeProviderType = TimeProviderType.WallClock,
|
||||
timeModel = TimeModel.reasonableDefault
|
||||
)
|
||||
|
@ -101,7 +101,7 @@ class ScalaCodeGenIT
|
||||
port = port,
|
||||
damlPackageContainer = DamlPackageContainer(archives),
|
||||
timeProviderType = TimeProviderType.WallClock,
|
||||
ledgerIdMode = LedgerIdMode.HardCoded(ledgerId),
|
||||
ledgerIdMode = LedgerIdMode.Predefined(ledgerId),
|
||||
)
|
||||
|
||||
private val sandbox: SandboxServer = SandboxApplication(serverConfig)
|
||||
|
@ -51,7 +51,7 @@ object ExampleMain extends App {
|
||||
port = port,
|
||||
damlPackageContainer = DamlPackageContainer(List(dar)),
|
||||
timeProviderType = TimeProviderType.WallClock,
|
||||
ledgerIdMode = LedgerIdMode.HardCoded(ledgerId),
|
||||
ledgerIdMode = LedgerIdMode.Predefined(ledgerId),
|
||||
)
|
||||
|
||||
private val server: SandboxServer = SandboxApplication(serverConfig)
|
||||
|
@ -102,7 +102,7 @@ object PlatformApplications {
|
||||
|
||||
SandboxApplication(
|
||||
SandboxConfig(
|
||||
addressOption = None,
|
||||
address = None,
|
||||
port = selectedPort,
|
||||
damlPackageContainer = DamlPackageContainer(config.darFiles.map(_.toFile)),
|
||||
timeProviderType = config.timeProviderType,
|
||||
@ -111,7 +111,7 @@ object PlatformApplications {
|
||||
scenario = None,
|
||||
tlsConfig = None,
|
||||
ledgerIdMode =
|
||||
config.ledgerId.fold[LedgerIdMode](LedgerIdMode.Random)(LedgerIdMode.HardCoded),
|
||||
config.ledgerId.fold[LedgerIdMode](LedgerIdMode.Random)(LedgerIdMode.Predefined),
|
||||
jdbcUrl = jdbcUrl
|
||||
)
|
||||
)
|
||||
|
@ -139,7 +139,7 @@ object Application {
|
||||
|
||||
new Server(
|
||||
"LedgerApiServer",
|
||||
config.addressOption,
|
||||
config.address,
|
||||
config.port,
|
||||
config,
|
||||
serverSslContext(config.tlsConfig, ClientAuth.REQUIRE),
|
||||
|
@ -57,7 +57,7 @@ object LedgerApiServer {
|
||||
services(config, ledgerBackend, engine, timeProvider, optTimeServiceBackend)(mat, esf)
|
||||
},
|
||||
optResetService,
|
||||
config.addressOption,
|
||||
config.address,
|
||||
serverPort,
|
||||
serverSslContext(config.tlsConfig, ClientAuth.REQUIRE)
|
||||
).start()
|
||||
|
@ -165,7 +165,7 @@ object SandboxApplication {
|
||||
|
||||
new SandboxServer(
|
||||
"sandbox",
|
||||
config.addressOption,
|
||||
config.address,
|
||||
config.port,
|
||||
config,
|
||||
serverSslContext(config.tlsConfig, ClientAuth.REQUIRE),
|
||||
|
@ -8,7 +8,7 @@ import java.time.Duration
|
||||
|
||||
import com.digitalasset.ledger.client.configuration.TlsConfiguration
|
||||
import com.digitalasset.platform.sandbox.BuildInfo
|
||||
import com.digitalasset.platform.sandbox.config.LedgerIdMode.HardCoded
|
||||
import com.digitalasset.platform.sandbox.config.LedgerIdMode.Predefined
|
||||
import com.digitalasset.platform.sandbox.config.SandboxConfig
|
||||
import com.digitalasset.platform.services.time.TimeProviderType
|
||||
import scopt.Read
|
||||
@ -25,12 +25,7 @@ object Cli {
|
||||
override val reads: String => Duration = Duration.parse
|
||||
}
|
||||
|
||||
private val crtConfig = (path: String, config: SandboxConfig) =>
|
||||
config.copy(
|
||||
tlsConfig =
|
||||
config.tlsConfig.fold(Some(TlsConfiguration(true, Some(new File(path)), None, None)))(c =>
|
||||
Some(c.copy(keyCertChainFile = Some(new File(path))))))
|
||||
|
||||
// format: off
|
||||
private val cmdArgParser = new scopt.OptionParser[SandboxConfig]("sandbox") {
|
||||
head(s"Sandbox version ${BuildInfo.Version}")
|
||||
|
||||
@ -39,7 +34,7 @@ object Cli {
|
||||
.text(s"Sandbox service port. Defaults to ${SandboxConfig.DefaultPort}.")
|
||||
|
||||
opt[String]('a', "address")
|
||||
.action((x, c) => c.copy(addressOption = Some(x)))
|
||||
.action((x, c) => c.copy(address = Some(x)))
|
||||
.text("Sandbox service host. Defaults to binding on all addresses.")
|
||||
|
||||
// TODO remove in next major release.
|
||||
@ -48,7 +43,7 @@ object Cli {
|
||||
.text(
|
||||
"This argument is present for backwards compatibility. DALF and DAR archives are now identified by their extensions.")
|
||||
|
||||
opt[Unit]("static-time")
|
||||
opt[Unit]('s', "static-time")
|
||||
.action { (_, c) =>
|
||||
assertTimeModeIsDefault(c)
|
||||
c.copy(timeProviderType = TimeProviderType.Static)
|
||||
@ -91,7 +86,11 @@ object Cli {
|
||||
opt[String]("crt")
|
||||
.optional()
|
||||
.text("TLS: The crt file to be used as the cert chain. Required if any other TLS parameters are set.")
|
||||
.action(crtConfig)
|
||||
.action((path: String, config: SandboxConfig) =>
|
||||
config.copy(
|
||||
tlsConfig =
|
||||
config.tlsConfig.fold(Some(TlsConfiguration(true, Some(new File(path)), None, None)))(c =>
|
||||
Some(c.copy(keyCertChainFile = Some(new File(path)))))))
|
||||
|
||||
opt[String]("cacrt")
|
||||
.optional()
|
||||
@ -108,6 +107,7 @@ object Cli {
|
||||
.action((url, config) => config.copy(jdbcUrl = Some(url)))
|
||||
|
||||
opt[Unit]("allow-dev")
|
||||
.hidden()
|
||||
.action { (_, c) =>
|
||||
c.copy(damlPackageContainer = c.damlPackageContainer.allowDev)
|
||||
}
|
||||
@ -116,12 +116,12 @@ object Cli {
|
||||
//TODO (robert): Think about all implications of allowing users to set the ledger ID.
|
||||
opt[String]("ledgerid")
|
||||
.optional()
|
||||
.action((id, c) => c.copy(ledgerIdMode = HardCoded(id)))
|
||||
.action((id, c) => c.copy(ledgerIdMode = Predefined(id)))
|
||||
.text("Sandbox ledger ID. If missing, a random unique ledger ID will be used. Only useful with persistent stores.")
|
||||
|
||||
help("help").text("Print the usage text")
|
||||
}
|
||||
|
||||
// format: on
|
||||
private def assertTimeModeIsDefault(c: SandboxConfig): Unit = {
|
||||
if (c.timeProviderType != TimeProviderType.default)
|
||||
throw new IllegalArgumentException(
|
||||
|
@ -61,9 +61,9 @@ case class DamlPackageContainer(files: List[File] = Nil, devAllowed: Boolean = f
|
||||
|
||||
lazy val packageIds: Iterable[String] = archives.map(_.getHash)
|
||||
|
||||
def withFile(file: File): DamlPackageContainer = DamlPackageContainer(file :: files)
|
||||
def withFile(file: File): DamlPackageContainer = copy(files = file :: files)
|
||||
|
||||
def getPackage(id: PackageId): Option[Ast.Package] = packages.get(id)
|
||||
|
||||
def allowDev: DamlPackageContainer = DamlPackageContainer(files, true)
|
||||
def allowDev: DamlPackageContainer = copy(devAllowed = true)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ sealed trait LedgerIdMode extends Product with Serializable {
|
||||
|
||||
object LedgerIdMode {
|
||||
|
||||
final case class HardCoded(_ledgerId: String) extends LedgerIdMode {
|
||||
final case class Predefined(_ledgerId: String) extends LedgerIdMode {
|
||||
def ledgerId(): String = _ledgerId
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ final case class TlsServerConfiguration(
|
||||
* Defines the basic configuration for running sandbox
|
||||
*/
|
||||
final case class SandboxConfig(
|
||||
addressOption: Option[String],
|
||||
address: Option[String],
|
||||
port: Int,
|
||||
damlPackageContainer: DamlPackageContainer,
|
||||
timeProviderType: TimeProviderType,
|
||||
|
@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.digitalasset.platform.sandbox.cli
|
||||
|
||||
import java.io.File
|
||||
|
||||
import com.digitalasset.ledger.client.configuration.TlsConfiguration
|
||||
import com.digitalasset.platform.sandbox.config.LedgerIdMode.Predefined
|
||||
import com.digitalasset.platform.sandbox.config.SandboxConfig
|
||||
import com.digitalasset.platform.services.time.TimeProviderType
|
||||
import org.scalatest.{Matchers, WordSpec}
|
||||
|
||||
class CliSpec extends WordSpec with Matchers {
|
||||
|
||||
private val archiveName = "whatever.dar"
|
||||
private val defaultConfig = SandboxConfig.default
|
||||
|
||||
private def checkOption(
|
||||
options: Array[String],
|
||||
expectedChange: SandboxConfig => SandboxConfig) = {
|
||||
val expectedConfig = expectedChange(
|
||||
defaultConfig.copy(
|
||||
damlPackageContainer = defaultConfig.damlPackageContainer.withFile(new File(archiveName))))
|
||||
|
||||
val config =
|
||||
Cli.parse(options ++: Array(archiveName))
|
||||
|
||||
config shouldEqual Some(expectedConfig)
|
||||
|
||||
}
|
||||
|
||||
"Cli" should {
|
||||
|
||||
"return None when required arguments are missing" in {
|
||||
val config = Cli.parse(Array.empty)
|
||||
config shouldEqual None
|
||||
}
|
||||
|
||||
"return a Config with sensible defaults when mandatory arguments are given" in {
|
||||
val expectedConfig = defaultConfig.copy(
|
||||
damlPackageContainer = defaultConfig.damlPackageContainer.withFile(new File(archiveName)))
|
||||
|
||||
val config = Cli.parse(Array(archiveName))
|
||||
|
||||
config shouldEqual Some(expectedConfig)
|
||||
}
|
||||
|
||||
"parse the port when given" in {
|
||||
val port = "1234"
|
||||
checkOption(Array(s"-p", port), _.copy(port = port.toInt))
|
||||
checkOption(Array(s"--port", port), _.copy(port = port.toInt))
|
||||
}
|
||||
|
||||
"parse the address when given" in {
|
||||
val address = "myhost"
|
||||
checkOption(Array(s"-a", address), _.copy(address = Some(address)))
|
||||
checkOption(Array(s"--address", address), _.copy(address = Some(address)))
|
||||
}
|
||||
|
||||
"apply static time when given" in {
|
||||
checkOption(Array(s"-s"), _.copy(timeProviderType = TimeProviderType.Static))
|
||||
checkOption(Array(s"--static-time"), _.copy(timeProviderType = TimeProviderType.Static))
|
||||
}
|
||||
|
||||
"apply wall-clock time when given" in {
|
||||
checkOption(
|
||||
Array(s"--wall-clock-time"),
|
||||
_.copy(timeProviderType = TimeProviderType.WallClock))
|
||||
checkOption(Array(s"-w"), _.copy(timeProviderType = TimeProviderType.WallClock))
|
||||
}
|
||||
|
||||
"parse the scenario when given" in {
|
||||
val scenario = "myscenario"
|
||||
checkOption(Array(s"--scenario", scenario), _.copy(scenario = Some(scenario)))
|
||||
}
|
||||
|
||||
"parse the crt file when given" in {
|
||||
val crt = "mycrt"
|
||||
checkOption(
|
||||
Array(s"--crt", crt),
|
||||
_.copy(tlsConfig = Some(TlsConfiguration(true, Some(new File(crt)), None, None))))
|
||||
}
|
||||
|
||||
"parse the cacrt file when given" in {
|
||||
val cacrt = "mycacrt"
|
||||
checkOption(
|
||||
Array(s"--cacrt", cacrt),
|
||||
_.copy(tlsConfig = Some(TlsConfiguration(true, None, None, Some(new File(cacrt))))))
|
||||
}
|
||||
|
||||
"parse the pem file when given" in {
|
||||
val pem = "mypem"
|
||||
checkOption(
|
||||
Array(s"--pem", pem),
|
||||
_.copy(tlsConfig = Some(TlsConfiguration(true, None, Some(new File(pem)), None))))
|
||||
}
|
||||
|
||||
"enable allow-dev when given" in {
|
||||
checkOption(
|
||||
Array(s"--allow-dev"),
|
||||
c => c.copy(damlPackageContainer = c.damlPackageContainer.allowDev))
|
||||
}
|
||||
|
||||
"parse the ledger id when given" in {
|
||||
val ledgerId = "myledger"
|
||||
checkOption(Array(s"--ledgerid", ledgerId), _.copy(ledgerIdMode = Predefined(ledgerId)))
|
||||
}
|
||||
|
||||
"parse the jdbc url when given" in {
|
||||
val jdbcUrl = "jdbc:postgresql://localhost:5432/test?user=test"
|
||||
checkOption(Array(s"--jdbcurl", jdbcUrl), _.copy(jdbcUrl = Some(jdbcUrl)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -54,7 +54,7 @@ trait SandboxFixture extends SuiteResource[Channel] {
|
||||
timeProviderType = TimeProviderType.Static,
|
||||
timeModel = TimeModel.reasonableDefault,
|
||||
scenario = scenario,
|
||||
ledgerIdMode = LedgerIdMode.HardCoded("sandbox server")
|
||||
ledgerIdMode = LedgerIdMode.Predefined("sandbox server")
|
||||
)
|
||||
|
||||
protected def packageFiles: List[File] = List(darFile)
|
||||
|
Loading…
Reference in New Issue
Block a user