Skip to content

Commit

Permalink
Ledger API Tests: use real ledger ID everywhere. (digital-asset#1400)
Browse files Browse the repository at this point in the history
This fetches and caches ledger ID inside LedgerContext.SingleChannelContext to
reduce number of calls into the Ledger API under test.
  • Loading branch information
gleber-da authored and gerolf-da committed Jun 3, 2019
1 parent 35acc58 commit a69b4b8
Show file tree
Hide file tree
Showing 36 changed files with 300 additions and 249 deletions.
4 changes: 4 additions & 0 deletions ledger-api/testing-utils/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ da_scala_library(
visibility = [
"//visibility:public",
],
exports = [
"//3rdparty/jvm/org/slf4j:slf4j_api",
],
deps = [
"//3rdparty/jvm/com/typesafe/akka:akka_stream",
"//3rdparty/jvm/io/grpc:grpc_core",
"//3rdparty/jvm/io/grpc:grpc_netty",
"//3rdparty/jvm/org/scalatest",
"//3rdparty/jvm/org/slf4j:slf4j_api",
"//ledger-api/grpc-definitions:ledger-api-scalapb",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@ import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import com.google.common.util.concurrent.ThreadFactoryBuilder
import org.scalatest.{BeforeAndAfterAll, Suite}
import org.slf4j.LoggerFactory

import scala.concurrent.{Await, ExecutionContext}
import scala.concurrent.duration._

trait AkkaBeforeAndAfterAll extends BeforeAndAfterAll {
self: Suite =>
protected def actorSystemName = this.getClass.getSimpleName
private val logger = LoggerFactory.getLogger(getClass)

private val executorContext = ExecutionContext.fromExecutorService(
Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat(s"${actorSystemName}-thread-pool-worker-%d")
.setUncaughtExceptionHandler((thread, _) =>
println(s"got an uncaught exception on thread: ${thread.getName}"))
logger.error(s"got an uncaught exception on thread: ${thread.getName}"))
.build()))

protected implicit val system: ActorSystem =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ import akka.NotUsed
import akka.stream.scaladsl.Source
import com.digitalasset.grpc.adapter.ExecutionSequencerFactory
import com.digitalasset.grpc.adapter.client.akka.ClientAdapter
import com.digitalasset.ledger.api.domain
import com.digitalasset.ledger.api.v1.ledger_configuration_service.{
GetLedgerConfigurationRequest,
LedgerConfiguration
}
import com.digitalasset.ledger.api.v1.ledger_configuration_service.LedgerConfigurationServiceGrpc.LedgerConfigurationService

import scalaz.syntax.tag._

final class LedgerConfigurationClient(
ledgerId: String,
ledgerId: domain.LedgerId,
ledgerConfigurationService: LedgerConfigurationService)(
implicit esf: ExecutionSequencerFactory) {

def getLedgerConfiguration: Source[LedgerConfiguration, NotUsed] =
ClientAdapter
.serverStreaming(
GetLedgerConfigurationRequest(ledgerId),
GetLedgerConfigurationRequest(ledgerId.unwrap),
ledgerConfigurationService.getLedgerConfiguration)
.map(_.ledgerConfiguration.getOrElse(sys.error("No LedgerConfiguration in response.")))

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

package com.digitalasset.platform.tests.integration.ledger.api

import java.util.UUID

import akka.stream.scaladsl.Sink
import com.digitalasset.ledger.api.domain
import com.digitalasset.ledger.api.testing.utils._
Expand All @@ -30,6 +28,8 @@ import org.scalatest.time.SpanSugar._
import org.scalatest.time.{Millis, Span}
import org.scalatest.{Assertion, AsyncWordSpec, Matchers, OptionValues}

import scalaz.syntax.tag._

/**
* There are not many tests here, because restarting the fixtures is very expensive.
* This will likely remain the case in the near future.
Expand All @@ -54,20 +54,14 @@ class ActiveContractsServiceIT
override implicit def patienceConfig: PatienceConfig =
PatienceConfig(scaled(Span(30000, Millis)), scaled(Span(500, Millis)))

private def client(
ctx: LedgerContext,
ledgerId: String = config.assertStaticLedgerId): ActiveContractSetClient =
new ActiveContractSetClient(domain.LedgerId(ledgerId), ctx.acsService)
private def client(ctx: LedgerContext): ActiveContractSetClient =
new ActiveContractSetClient(ctx.ledgerId, ctx.acsService)

private def commandClient(
ctx: LedgerContext,
ledgerId: String = config.assertStaticLedgerId): SynchronousCommandClient =
private def commandClient(ctx: LedgerContext): SynchronousCommandClient =
new SynchronousCommandClient(ctx.commandService)

private def transactionClient(
ctx: LedgerContext,
ledgerId: String = config.assertStaticLedgerId): TransactionClient =
new TransactionClient(domain.LedgerId(ledgerId), ctx.transactionService)
private def transactionClient(ctx: LedgerContext): TransactionClient =
new TransactionClient(ctx.ledgerId, ctx.transactionService)

private def submitRequest(ctx: LedgerContext, request: SubmitAndWaitRequest) =
commandClient(ctx).submitAndWait(request)
Expand Down Expand Up @@ -102,15 +96,17 @@ class ActiveContractsServiceIT
case ce @ CreatedEvent(_, _, Some(`template`), _, _, _) => ce
}.size should equal(occurrence)

def threeCommands(ledgerId: String, commandId: String): SubmitAndWaitRequest =
def threeCommands(ledgerId: domain.LedgerId, commandId: String): SubmitAndWaitRequest =
super.dummyCommands(ledgerId, commandId, "Alice").toWait

private def filter = TransactionFilter(Map(config.parties.head -> Filters()))

"Active Contract Set Service" when {
"asked for active contracts" should {
"fail with the expected status on a ledger Id mismatch" in allFixtures { context =>
client(context, UUID.randomUUID().toString)
new ActiveContractSetClient(
domain.LedgerId(s"not-${context.ledgerId.unwrap}"),
context.acsService)
.getActiveContracts(filter)
.runWith(Sink.head)(materializer)
.failed map { ex =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import com.digitalasset.ledger.api.testing.utils.{
AkkaBeforeAndAfterAll,
SuiteResourceManagementAroundEach
}
import com.digitalasset.ledger.api.{domain, v1}
import com.digitalasset.ledger.api.v1
import com.digitalasset.ledger.api.v1.command_service._
import com.digitalasset.ledger.api.v1.commands._
import com.digitalasset.ledger.api.v1.ledger_offset._
Expand All @@ -33,6 +33,7 @@ import org.scalatest.{AsyncFreeSpec, Matchers, OptionValues}
import org.scalatest.concurrent.{AsyncTimeLimitedTests, ScalaFutures}
import org.scalatest.Inside.inside

import scalaz.syntax.tag._
import scala.language.implicitConversions
import scala.concurrent.Future

Expand All @@ -56,10 +57,10 @@ class DivulgenceIT
new SynchronousCommandClient(ctx.commandService)

private def acsClient(ctx: LedgerContext): ActiveContractSetClient =
new ActiveContractSetClient(domain.LedgerId(ctx.ledgerId), ctx.acsService)
new ActiveContractSetClient(ctx.ledgerId, ctx.acsService)

private def transactionClient(ctx: LedgerContext): TransactionClient =
new TransactionClient(domain.LedgerId(ctx.ledgerId), ctx.transactionService)
new TransactionClient(ctx.ledgerId, ctx.transactionService)

private val ledgerEffectiveTime = Timestamp(0L, 0)
private val maximumRecordTime =
Expand All @@ -72,7 +73,7 @@ class DivulgenceIT
SubmitAndWaitRequest(
commands = Some(
Commands(
ledgerId = ctx.ledgerId,
ledgerId = ctx.ledgerId.unwrap,
workflowId = "divulgence-test-workflow-id",
applicationId = "divulgence-test-application-id",
commandId = commandId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package com.digitalasset.platform.tests.integration.ledger.api

import akka.stream.scaladsl.Sink
import com.digitalasset.ledger.api.domain
import com.digitalasset.ledger.api.testing.utils.{
AkkaBeforeAndAfterAll,
IsStatusException,
Expand All @@ -18,6 +19,7 @@ import org.scalatest.concurrent.AsyncTimeLimitedTests
import org.scalatest.time.Span
import org.scalatest.time.SpanSugar._
import org.scalatest.{AsyncWordSpec, Matchers, OptionValues}
import scalaz.syntax.tag._

@SuppressWarnings(Array("org.wartremover.warts.Any"))
class LedgerConfigurationServiceIT
Expand All @@ -32,10 +34,8 @@ class LedgerConfigurationServiceIT

override def timeLimit: Span = 5.seconds

private def client(
ctx: LedgerContext,
ledgerId: String = config.assertStaticLedgerId): LedgerConfigurationClient =
new LedgerConfigurationClient(ledgerId, ctx.ledgerConfigurationService)
private def client(ctx: LedgerContext): LedgerConfigurationClient =
new LedgerConfigurationClient(ctx.ledgerId, ctx.ledgerConfigurationService)

"Ledger Configuration Service" when {

Expand All @@ -50,7 +50,9 @@ class LedgerConfigurationServiceIT
}

"fail with the expected status on a ledger Id mismatch" in allFixtures { context =>
client(context, "not " + config.assertStaticLedgerId).getLedgerConfiguration
new LedgerConfigurationClient(
domain.LedgerId("not" + context.ledgerId.unwrap),
context.ledgerConfigurationService).getLedgerConfiguration
.runWith(Sink.head)(materializer)
.failed map { ex =>
IsStatusException(Status.NOT_FOUND.getCode)(ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ import com.digitalasset.ledger.api.testing.utils.{
IsStatusException,
SuiteResourceManagementAroundAll
}
import com.digitalasset.ledger.api.v1.package_service.PackageServiceGrpc.PackageService
import com.digitalasset.ledger.api.v1.package_service.PackageStatus
import com.digitalasset.ledger.client.services.pkg.PackageClient
import com.digitalasset.platform.apitesting.MultiLedgerFixture
import com.digitalasset.platform.apitesting.{LedgerContext, MultiLedgerFixture}
import io.grpc.Status
import org.scalatest.concurrent.AsyncTimeLimitedTests
import org.scalatest.time.Span
import org.scalatest.time.SpanSugar._
import org.scalatest.{AsyncWordSpec, Matchers, OptionValues}

import scalaz.syntax.tag._

@SuppressWarnings(Array("org.wartremover.warts.Any"))
class PackageServiceIT
extends AsyncWordSpec
Expand All @@ -33,29 +34,27 @@ class PackageServiceIT

override def timeLimit: Span = 5.seconds

private def client(stub: PackageService): PackageClient = {
client(stub, config.assertStaticLedgerId)
}

private def client(stub: PackageService, ledgerId: String): PackageClient = {
new PackageClient(domain.LedgerId(ledgerId), stub)
private def client(ctx: LedgerContext): PackageClient = {
new PackageClient(ctx.ledgerId, ctx.packageService)
}

private def getARegisteredPackageId(stub: PackageService) =
client(stub).listPackages().map(_.packageIds.headOption.value)
private def getARegisteredPackageId(ctx: LedgerContext) =
client(ctx).listPackages().map(_.packageIds.headOption.value)

"Package Service" when {

"asked for the list of registered packages" should {

"return it" in allFixtures { context =>
client(context.packageService).listPackages() map {
client(context).listPackages() map {
_.packageIds.size shouldEqual 3 // package, stdlib, daml-prim
}
}

"fail with the expected status on a ledger Id mismatch" in allFixtures { context =>
client(context.packageService, "not " + config.assertStaticLedgerId)
new PackageClient(
domain.LedgerId(s"not-${context.ledgerId.unwrap}"),
context.packageService)
.listPackages()
.failed map {
IsStatusException(Status.NOT_FOUND)(_)
Expand All @@ -67,23 +66,25 @@ class PackageServiceIT
"asked to get a package" should {

"return it if it's registered" in allFixtures { context =>
getARegisteredPackageId(context.packageService)
.flatMap(client(context.packageService).getPackage(_)) map {
getARegisteredPackageId(context)
.flatMap(client(context).getPackage(_)) map {
_.archivePayload.size() should be > 0
}

}

"return a NOT_FOUND error if it's not registered" in allFixtures { context =>
client(context.packageService).getPackage(UUID.randomUUID().toString).failed map {
client(context).getPackage(UUID.randomUUID().toString).failed map {
IsStatusException(Status.NOT_FOUND)(_)
}
}

"fail with the expected status on a ledger Id mismatch" in allFixtures { context =>
getARegisteredPackageId(context.packageService)
getARegisteredPackageId(context)
.flatMap(
client(context.packageService, "not " + config.assertStaticLedgerId)
new PackageClient(
domain.LedgerId(s"not-${context.ledgerId.unwrap}"),
context.packageService)
.getPackage(_)
.failed) map {
IsStatusException(Status.NOT_FOUND)(_)
Expand All @@ -94,23 +95,25 @@ class PackageServiceIT
"asked to check a package's status" should {

"return true if it's registered" in allFixtures { context =>
getARegisteredPackageId(context.packageService)
.flatMap(client(context.packageService).getPackageStatus(_)) map {
getARegisteredPackageId(context)
.flatMap(client(context).getPackageStatus(_)) map {
_.packageStatus shouldEqual PackageStatus.REGISTERED
}
}

"return false if it's not registered" in allFixtures { context =>
client(context.packageService).getPackageStatus(UUID.randomUUID().toString) map {
client(context).getPackageStatus(UUID.randomUUID().toString) map {
_.packageStatus shouldEqual PackageStatus.UNKNOWN
}

}

"fail with the expected status on a ledger Id mismatch" in allFixtures { context =>
getARegisteredPackageId(context.packageService)
getARegisteredPackageId(context)
.flatMap(
client(context.packageService, "not " + config.assertStaticLedgerId)
new PackageClient(
domain.LedgerId(s"not-${context.ledgerId.unwrap}"),
context.packageService)
.getPackageStatus(_)
.failed) map {
IsStatusException(Status.NOT_FOUND)(_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import com.digitalasset.ledger.api.testing.utils.{
import com.digitalasset.ledger.api.v1.active_contracts_service.GetActiveContractsResponse
import com.digitalasset.ledger.api.v1.command_service.SubmitAndWaitRequest
import com.digitalasset.ledger.api.v1.event.CreatedEvent
import com.digitalasset.ledger.api.v1.ledger_identity_service.GetLedgerIdentityRequest
import com.digitalasset.ledger.api.v1.testing.reset_service.ResetRequest
import com.digitalasset.platform.apitesting.MultiLedgerFixture
import com.digitalasset.platform.common.LedgerIdMode
import com.digitalasset.platform.sandbox.services.TestCommands
Expand All @@ -34,7 +32,7 @@ class ResetServiceIT
with InfiniteRetries
with Matchers
with AkkaBeforeAndAfterAll
with MultiLedgerFixture
with MultiLedgerFixture // TODO: this suite shoul not be using LedgerContext, as it is smart and hides too much of the reset mechanism
with ScalaFutures
with TestCommands
with SuiteResourceManagementAroundEach {
Expand All @@ -54,18 +52,14 @@ class ResetServiceIT
"ResetService" when {
"state is reset" should {

"return a new ledger ID" in allFixtures { ctx =>
"return a new ledger ID" in allFixtures { ctx1 =>
val lid1 = ctx1.ledgerId
for {
lid1 <- ctx.ledgerIdentityService.getLedgerIdentity(GetLedgerIdentityRequest())
lid1SecondInstance <- ctx.ledgerIdentityService.getLedgerIdentity(
GetLedgerIdentityRequest())
lid2 <- ctx.reset()
lid3 <- ctx.reset()
throwable <- ctx.resetService.reset(ResetRequest(lid1.ledgerId)).failed
ctx2 <- ctx1.reset()
lid2 = ctx2.ledgerId
throwable <- ctx1.reset().failed
} yield {
lid1 shouldEqual lid1SecondInstance
lid1.ledgerId should not equal lid2
lid2 should not equal lid3
lid1 should not equal lid2
IsStatusException(Status.Code.NOT_FOUND)(throwable)
}
}
Expand All @@ -80,8 +74,10 @@ class ResetServiceIT
val events = responses.flatMap(extractEvents)
events.size shouldBe 3
}
_ <- ctx.reset()
newSnapshot <- ctx.acsClient.getActiveContracts(allTemplatesForParty).runWith(Sink.seq)
newContext <- ctx.reset()
newSnapshot <- newContext.acsClient
.getActiveContracts(allTemplatesForParty)
.runWith(Sink.seq)
} yield {
newSnapshot.size shouldBe 1
val newEvents = newSnapshot.flatMap(extractEvents)
Expand Down
Loading

0 comments on commit a69b4b8

Please sign in to comment.