Skip to content

Commit

Permalink
sandbox: Move more resource acquisition into the owner. (digital-as…
Browse files Browse the repository at this point in the history
…set#4501)

* sandbox: Move more resource acquisition into the `owner`.

CHANGELOG_BEGIN
CHANGELOG_END

* sandbox: Reimplement SandboxClientResource as a resources.Resource.

* codegen: Use resources in TestUtil.

* sandbox: Manage PostgreSQL in tests with ResourceOwners.
  • Loading branch information
SamirTalwar authored Feb 14, 2020
1 parent 433f484 commit a589f4a
Show file tree
Hide file tree
Showing 37 changed files with 290 additions and 513 deletions.
1 change: 1 addition & 0 deletions extractor/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ da_scala_test_suite(
"//libs-scala/auth-utils",
"//libs-scala/grpc-utils",
"//libs-scala/postgresql-testing",
"//libs-scala/resources",
"//libs-scala/timer-utils",
"@maven//:ch_qos_logback_logback_classic",
"@maven//:com_chuusai_shapeless_2_12",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ trait ExtractorFixture extends SandboxFixture with PostgresAround with Types {
protected var extractor: Extractor[PostgreSQLTarget] = _

protected def run(): Unit = {
val config: ExtractorConfig = configureExtractor(baseConfig.copy(ledgerPort = getSandboxPort))
val config: ExtractorConfig = configureExtractor(baseConfig.copy(ledgerPort = serverPort))

extractor = new Extractor(config, target)()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
package com.digitalasset.extractor

import java.nio.file.Files
import java.time.{Duration, Instant}
import java.time.temporal.ChronoUnit
import java.time.{Duration, Instant}
import java.util.concurrent.atomic.AtomicReference

import com.digitalasset.daml.lf.data.Ref.Party
Expand Down Expand Up @@ -88,7 +88,7 @@ final class AuthSpec
private def noAuth =
ExtractorConfig(
"127.0.0.1",
ledgerPort = getSandboxPort,
ledgerPort = serverPort,
ledgerInboundMessageSizeMax = 50 * 1024 * 1024,
LedgerOffset(LedgerOffset.Value.Boundary(LedgerOffset.LedgerBoundary.LEDGER_BEGIN)),
SnapshotEndSetting.Head,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class TlsSpec

"Extractor" should "be able to connect with TLS parameters" in {
val config = baseConfig.copy(
ledgerPort = getSandboxPort,
ledgerPort = serverPort,
tlsConfig = TlsConfiguration(true, clientCrt, clientPem, caCrt),
to = SnapshotEndSetting.Head
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class VeryLargeArchiveSpec
override protected def darFile = new File(rlocation("extractor/VeryLargeArchive.dar"))

private def runWithInboundLimit[Z](bytes: Int)(f: => Z): Z = {
val config = baseConfig.copy(ledgerPort = getSandboxPort, ledgerInboundMessageSizeMax = bytes)
val config = baseConfig.copy(ledgerPort = serverPort, ledgerInboundMessageSizeMax = bytes)
val extractor =
new Extractor(config, target)()

Expand Down
2 changes: 1 addition & 1 deletion language-support/java/codegen/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,12 @@ da_scala_test(
"//bazel_tools/runfiles:scala_runfiles",
"//daml-lf/data",
"//language-support/java/bindings:bindings-java",
"//ledger-api/testing-utils",
"//ledger/ledger-api-common",
"//ledger/ledger-api-domain",
"//ledger/participant-state",
"//ledger/sandbox",
"//ledger/sandbox:sandbox-scala-tests-lib",
"//libs-scala/resources",
"@maven//:ch_qos_logback_logback_classic",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:io_grpc_grpc_api",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import java.math.BigDecimal
import java.time.temporal.ChronoField
import java.time.{Instant, LocalDate, ZoneOffset}

import com.digitalasset.daml.lf.data.Numeric
import com.daml.ledger.javaapi.data.{Unit => DamlUnit}
import org.scalatest.{FlatSpec, Matchers}
import com.digitalasset.daml.lf.data.Numeric
import org.scalatest.{AsyncFlatSpec, Matchers}
import wolpertinger.color.Grey
import wolpertinger.{Color, Wolpertinger}

import scala.collection.JavaConverters._

@SuppressWarnings(Array("org.wartremover.warts.Any"))
class CodegenLedgerTest extends FlatSpec with Matchers {
class CodegenLedgerTest extends AsyncFlatSpec with Matchers {

import TestUtil._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

package com.digitalasset

import org.scalatest.{FlatSpec, Matchers}
import org.scalatest.{AsyncFlatSpec, Matchers}
import stakeholders.{ExplicitObservers, ImplicitObservers, MixedObservers, OnlySignatories}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
class StakeholdersTest extends FlatSpec with Matchers {
class StakeholdersTest extends AsyncFlatSpec with Matchers {

import TestUtil._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ import com.digitalasset.ledger.api.v1.TransactionServiceOuterClass.{
}
import com.digitalasset.ledger.api.v1.{CommandServiceGrpc, TransactionServiceGrpc}
import com.digitalasset.platform.common.LedgerIdMode
import com.digitalasset.platform.sandbox.SandboxServer
import com.digitalasset.platform.sandbox.config.SandboxConfig
import com.digitalasset.platform.sandbox.services.{SandboxClientResource, SandboxServerResource}
import com.digitalasset.platform.sandbox.services.SandboxClientResource
import com.digitalasset.platform.services.time.TimeProviderType
import com.google.protobuf.Empty
import io.grpc.Channel
import org.scalatest.Assertion

import scala.collection.JavaConverters._
import scala.concurrent.{ExecutionContext, Future}
import scala.language.implicitConversions

object TestUtil {
Expand All @@ -36,24 +39,23 @@ object TestUtil {
new File(BazelRunfiles.rlocation("language-support/java/codegen/ledger-tests-model.dar"))

val LedgerID = "ledger-test"
def withClient(testCode: Channel => Assertion): Assertion = {

def withClient(testCode: Channel => Assertion)(
implicit executionContext: ExecutionContext
): Future[Assertion] = {
val config = SandboxConfig.default.copy(
port = 0,
damlPackages = List(testDalf),
ledgerIdMode = LedgerIdMode.Static(LedgerId(LedgerID)),
timeProviderType = TimeProviderType.WallClock,
timeModel = TimeModel.reasonableDefault
)
val server = SandboxServerResource(config)
server.setup()
val client = new SandboxClientResource(server.value.port)
client.setup()
try {
testCode(client.value)
} finally {
client.close()
server.close()
}

val channelOwner = for {
server <- SandboxServer.owner(config)
channel <- SandboxClientResource.owner(server.port)
} yield channel
channelOwner.use(channel => Future(testCode(channel)))
}

// unfortunately this is needed to help with passing functions to rxjava methods like Flowable#map
Expand All @@ -65,7 +67,7 @@ object TestUtil {
val Charlie = "Charlie"
val allTemplates = new FiltersByParty(Map[String, Filter](Alice -> NoFilter.instance).asJava)

def sendCmd(channel: Channel, cmds: Command*) = {
def sendCmd(channel: Channel, cmds: Command*): Empty = {
CommandServiceGrpc
.newBlockingStub(channel)
.withDeadlineAfter(40, TimeUnit.SECONDS)
Expand All @@ -85,7 +87,9 @@ object TestUtil {
.build)
}

def readActiveContracts[C <: Contract](fromCreatedEvent: CreatedEvent => C)(channel: Channel) = {
def readActiveContracts[C <: Contract](fromCreatedEvent: CreatedEvent => C)(
channel: Channel
): List[C] = {
val txService = TransactionServiceGrpc.newBlockingStub(channel)
val end = txService.getLedgerEnd(GetLedgerEndRequest.newBuilder().setLedgerId(LedgerID).build)
val txs = txService.getTransactions(
Expand Down
4 changes: 3 additions & 1 deletion language-support/scala/codegen-sample-app/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,14 @@ da_scala_test(
"//language-support/scala/bindings",
"//language-support/scala/bindings-akka",
"//language-support/scala/codegen-testing",
"//ledger-api/rs-grpc-akka",
"//ledger-api/rs-grpc-bridge",
"//ledger-api/testing-utils",
"//ledger/ledger-api-client",
"//ledger/ledger-api-common",
"//ledger/participant-state",
"//ledger/sandbox",
"//ledger/sandbox:sandbox-scala-tests-lib",
"//libs-scala/resources",
"@maven//:org_scalacheck_scalacheck_2_12",
"@maven//:org_scalaz_scalaz_core_2_12",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,12 @@
<level>INFO</level>
<excludeLogger>com.digitalasset.nanobot.log</excludeLogger>
</filter>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<jsonGeneratorDecorator class="com.digitalasset.logging.JsonPrettyPrinter"/>
<timeZone>UTC</timeZone>
<provider class="net.logstash.logback.composite.loggingevent.ArgumentsJsonProvider"/>
<shortenedLoggerNameLength>36</shortenedLoggerNameLength>
<throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
<rootCauseFirst>true</rootCauseFirst>
</throwableConverter>
<fieldNames>
<timestamp>timestamp</timestamp>
<level>level</level>
<levelValue>[ignore]</levelValue>
<logger>logger</logger>
<thread>thread</thread>
<version>[ignore]</version>
</fieldNames>
<includeContext>false</includeContext>
</encoder>
</appender>


<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>target/nanobot-framework-test.log</file>
<!-- logs at specific level specified, except for the excluded logger which inherits the level from root -->
<filter class="com.digitalasset.ledger.client.binding.log.LogbackThresholdFilterWithExclusion">
<level>INFO</level>
<excludeLogger>com.digitalasset.platform.client.remoting.events</excludeLogger>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %X{context}%n</pattern>
<pattern>%level: %msg%n</pattern>
</encoder>
</appender>

<logger name="com.digitalasset.ledger" level="INFO"/>
<logger name="test-akka" level="ERROR"/>

<!-- STDOUT and FILE appender both have different log levels, see above -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@

package com.digitalasset.codegen

import java.io.File
import java.time.Instant
import java.util.UUID

import akka.actor.ActorSystem
import akka.stream.Materializer
import akka.stream.scaladsl.{Sink, Source}
import com.digitalasset.api.util.TimeProvider
import com.digitalasset.api.util.TimestampConversion.fromInstant
import com.digitalasset.codegen.util.TestUtil.{TestContext, requiredResource}
import com.digitalasset.grpc.adapter.AkkaExecutionSequencerPool
import com.digitalasset.ledger.api.domain.LedgerId
import com.digitalasset.ledger.api.refinements.ApiTypes.{CommandId, WorkflowId}
import com.digitalasset.ledger.api.testing.utils.SuiteResourceManagementAroundAll
import com.digitalasset.ledger.api.v1.command_submission_service.SubmitRequest
import com.digitalasset.ledger.api.v1.commands.Commands
import com.digitalasset.ledger.api.v1.event.Event
Expand All @@ -32,8 +31,8 @@ import com.digitalasset.ledger.client.configuration.{
LedgerIdRequirement
}
import com.digitalasset.platform.common.LedgerIdMode
import com.digitalasset.platform.sandbox.SandboxServer
import com.digitalasset.platform.sandbox.config.SandboxConfig
import com.digitalasset.platform.sandbox.services.SandboxFixture
import com.digitalasset.platform.services.time.TimeProviderType
import com.digitalasset.sample.MyMain.{CallablePayout, MkListExample, PayOut}
import com.digitalasset.sample.{EventDecoder, MyMain, MySecondMain}
Expand All @@ -53,37 +52,24 @@ import scala.util.{Failure, Success, Try}
class ScalaCodeGenIT
extends AsyncWordSpec
with Matchers
with BeforeAndAfterAll
with ScalaFutures
with Inside {
with Inside
with SuiteResourceManagementAroundAll
with SandboxFixture {

private val shortTimeout = 5.seconds
private val StartupTimeout = 10.seconds

private implicit val ec: ExecutionContext = ExecutionContext.global

implicit override lazy val patienceConfig: PatienceConfig =
override implicit lazy val patienceConfig: PatienceConfig =
PatienceConfig(timeout = Span(20, Seconds), interval = Span(250, Millis))

private val ledgerId = this.getClass.getSimpleName
override implicit def executionContext: ExecutionContext = ExecutionContext.global

private val archives = List(
override protected def packageFiles: List[File] = List(
requiredResource("language-support/scala/codegen-sample-app/MyMain.dar"),
requiredResource("language-support/scala/codegen-sample-app/MySecondMain.dar"),
)

private val asys = ActorSystem()
private val amat = Materializer(asys)
private val aesf = new AkkaExecutionSequencerPool("clientPool")(asys)

private val serverConfig = SandboxConfig.default.copy(
port = 0,
damlPackages = archives,
timeProviderType = TimeProviderType.WallClock,
ledgerIdMode = LedgerIdMode.Static(LedgerId(ledgerId)),
)

private val sandbox: SandboxServer = new SandboxServer(serverConfig)

private val ledgerId = this.getClass.getSimpleName
private val applicationId = ledgerId + "-client"
private val decoder: DecoderType = EventDecoder.createdEventToContractRef
private val timeProvider = TimeProvider.UTC
Expand All @@ -97,13 +83,10 @@ class ScalaCodeGenIT

private val emptyAgreementText = Some("") // this is by design, starting from release: 0.12.18 it is a requried field

override protected def afterAll(): Unit = {
sandbox.close()
aesf.close()
amat.shutdown()
asys.terminate()
super.afterAll()
}
override protected def config: SandboxConfig = super.config.copy(
ledgerIdMode = LedgerIdMode.Static(LedgerId(ledgerId)),
timeProviderType = TimeProviderType.WallClock,
)

private val clientConfig = LedgerClientConfiguration(
applicationId = applicationId,
Expand All @@ -112,10 +95,12 @@ class ScalaCodeGenIT
sslContext = None
)

private val ledgerF: Future[LedgerClient] =
LedgerClient.singleHost("127.0.0.1", sandbox.port, clientConfig)(ec, aesf)
private var ledger: LedgerClient = _

private val ledger: LedgerClient = Await.result(ledgerF, shortTimeout)
override protected def beforeAll(): Unit = {
super.beforeAll()
ledger = Await.result(LedgerClient(channel, clientConfig), StartupTimeout)
}

"generated package ID among those returned by the packageClient" in {
val expectedPackageId: String = P.TemplateId
Expand Down Expand Up @@ -452,7 +437,7 @@ class ScalaCodeGenIT
ledger.transactionClient
.getTransactions(offset, None, transactionFilter(party))
.take(1)
.runWith(Sink.head)(amat)
.runWith(Sink.head)

private def uniqueId = UUID.randomUUID.toString

Expand Down Expand Up @@ -485,7 +470,7 @@ class ScalaCodeGenIT
.fromIterator(() => input.iterator)
.via(ledger.commandClient.submissionFlow())
.take(take)
.runWith(Sink.seq)(amat)
.runWith(Sink.seq)

private def toFuture[A](o: Option[A]): Future[A] = o match {
case None => Future.failed(new IllegalStateException(s"empty option: $o"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@

package com.digitalasset.ledger.api.testing.utils

import com.digitalasset.dec.DirectExecutionContext
import com.digitalasset.resources

import scala.concurrent.Await
import scala.concurrent.duration.{DurationInt, FiniteDuration}
import scala.concurrent.{Await, ExecutionContext}
import scala.reflect.ClassTag

class OwnedResource[T: ClassTag](
owner: resources.ResourceOwner[T],
acquisitionTimeout: FiniteDuration = 10.seconds,
releaseTimeout: FiniteDuration = 10.seconds,
) extends ManagedResource[T] {
acquisitionTimeout: FiniteDuration = 30.seconds,
releaseTimeout: FiniteDuration = 30.seconds,
)(implicit executionContext: ExecutionContext)
extends ManagedResource[T] {
private var resource: resources.Resource[T] = _

override def construct(): T = {
resource = owner.acquire()(DirectExecutionContext)
resource = owner.acquire()
Await.result(resource.asFuture, acquisitionTimeout)
}

Expand Down
Loading

0 comments on commit a589f4a

Please sign in to comment.