mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Extract the participant test context interface [KVL-1320] (#13476)
This commit is contained in:
parent
b9c9acfb9e
commit
f94cec2764
@ -4,7 +4,6 @@
|
||||
package com.daml.ledger.api.testtool.infrastructure
|
||||
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantSession
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Random
|
||||
@ -12,7 +11,6 @@ import scala.util.Random
|
||||
private[infrastructure] final class LedgerSession private (
|
||||
participantSessions: Vector[(String, ParticipantSession)],
|
||||
shuffleParticipants: Boolean,
|
||||
clientTlsConfiguration: Option[TlsConfiguration],
|
||||
)(implicit val executionContext: ExecutionContext) {
|
||||
|
||||
private[infrastructure] def createTestContext(
|
||||
@ -28,7 +26,6 @@ private[infrastructure] final class LedgerSession private (
|
||||
endpointId,
|
||||
applicationId,
|
||||
identifierSuffix,
|
||||
clientTlsConfiguration,
|
||||
session.features,
|
||||
)
|
||||
}
|
||||
@ -42,7 +39,6 @@ object LedgerSession {
|
||||
def apply(
|
||||
participantSessions: Vector[ParticipantSession],
|
||||
shuffleParticipants: Boolean,
|
||||
clientTlsConfiguration: Option[TlsConfiguration],
|
||||
)(implicit executionContext: ExecutionContext): LedgerSession = {
|
||||
val endpointIdProvider =
|
||||
Identification.circularWithIndex(Identification.greekAlphabet)
|
||||
@ -50,7 +46,6 @@ object LedgerSession {
|
||||
new LedgerSession(
|
||||
sessions,
|
||||
shuffleParticipants,
|
||||
clientTlsConfiguration,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ import com.daml.ledger.api.testtool.infrastructure.participant.{
|
||||
ParticipantSession,
|
||||
ParticipantTestContext,
|
||||
}
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
import io.grpc.ClientInterceptor
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@ -50,7 +49,6 @@ final class LedgerTestCasesRunner(
|
||||
uploadDars: Boolean = true,
|
||||
identifierSuffix: String = "test",
|
||||
commandInterceptors: Seq[ClientInterceptor] = Seq.empty,
|
||||
clientTlsConfiguration: Option[TlsConfiguration],
|
||||
) {
|
||||
private[this] val verifyRequirements: Try[Unit] =
|
||||
Try {
|
||||
@ -161,8 +159,7 @@ final class LedgerTestCasesRunner(
|
||||
}
|
||||
|
||||
private def uploadDarsIfRequired(
|
||||
sessions: Vector[ParticipantSession],
|
||||
clientTlsConfiguration: Option[TlsConfiguration],
|
||||
sessions: Vector[ParticipantSession]
|
||||
)(implicit executionContext: ExecutionContext): Future[Unit] =
|
||||
if (uploadDars) {
|
||||
Future
|
||||
@ -171,7 +168,6 @@ final class LedgerTestCasesRunner(
|
||||
context <- session.createInitContext(
|
||||
applicationId = "upload-dars",
|
||||
identifierSuffix = identifierSuffix,
|
||||
clientTlsConfiguration = clientTlsConfiguration,
|
||||
features = session.features,
|
||||
)
|
||||
_ <- Future.sequence(Dars.resources.map(uploadDar(context, _)))
|
||||
@ -240,11 +236,10 @@ final class LedgerTestCasesRunner(
|
||||
val ledgerSession = LedgerSession(
|
||||
sessions,
|
||||
shuffleParticipants,
|
||||
clientTlsConfiguration = clientTlsConfiguration,
|
||||
)
|
||||
val testResults =
|
||||
for {
|
||||
_ <- uploadDarsIfRequired(sessions, clientTlsConfiguration)
|
||||
_ <- uploadDarsIfRequired(sessions)
|
||||
concurrentTestResults <- runTestCases(
|
||||
ledgerSession,
|
||||
concurrentTestCases,
|
||||
|
@ -7,10 +7,8 @@ import java.time.Duration
|
||||
|
||||
import com.daml.api.util.DurationConversion
|
||||
import com.daml.ledger.api.testtool.infrastructure.Assertions.{assertDefined, fail}
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.{
|
||||
CompletionResponse,
|
||||
ParticipantTestContext,
|
||||
}
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantTestContext
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantTestContext.CompletionResponse
|
||||
import com.daml.ledger.api.v1.experimental_features.CommandDeduplicationPeriodSupport.{
|
||||
DurationSupport,
|
||||
OffsetSupport,
|
||||
|
@ -10,7 +10,6 @@ import com.daml.ledger.api.testtool.infrastructure.{
|
||||
LedgerServices,
|
||||
PartyAllocationConfiguration,
|
||||
}
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
import com.daml.ledger.api.v1.ledger_identity_service.GetLedgerIdentityRequest
|
||||
import com.daml.ledger.api.v1.transaction_service.GetLedgerEndRequest
|
||||
import com.daml.ledger.api.v1.version_service.GetLedgerApiVersionRequest
|
||||
@ -41,14 +40,12 @@ private[infrastructure] final class ParticipantSession private (
|
||||
private[testtool] def createInitContext(
|
||||
applicationId: String,
|
||||
identifierSuffix: String,
|
||||
clientTlsConfiguration: Option[TlsConfiguration],
|
||||
features: Features,
|
||||
): Future[ParticipantTestContext] =
|
||||
createTestContext(
|
||||
"init",
|
||||
applicationId,
|
||||
identifierSuffix,
|
||||
clientTlsConfiguration = clientTlsConfiguration,
|
||||
features = features,
|
||||
)
|
||||
|
||||
@ -56,12 +53,11 @@ private[infrastructure] final class ParticipantSession private (
|
||||
endpointId: String,
|
||||
applicationId: String,
|
||||
identifierSuffix: String,
|
||||
clientTlsConfiguration: Option[TlsConfiguration],
|
||||
features: Features,
|
||||
): Future[ParticipantTestContext] =
|
||||
for {
|
||||
end <- services.transaction.getLedgerEnd(new GetLedgerEndRequest(ledgerId)).map(_.getOffset)
|
||||
} yield new ParticipantTestContext(
|
||||
} yield new SingleParticipantTestContext(
|
||||
ledgerId = ledgerId,
|
||||
endpointId = endpointId,
|
||||
applicationId = applicationId,
|
||||
@ -70,7 +66,6 @@ private[infrastructure] final class ParticipantSession private (
|
||||
services = services,
|
||||
partyAllocationConfig = partyAllocationConfig,
|
||||
ledgerEndpoint = ledgerEndpoint,
|
||||
clientTlsConfiguration = clientTlsConfiguration,
|
||||
features = features,
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,382 @@
|
||||
// Copyright (c) 2022 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.api.testtool.infrastructure.participant
|
||||
import java.time.Instant
|
||||
|
||||
import com.daml.ledger.api.refinements.ApiTypes.TemplateId
|
||||
import com.daml.ledger.api.testtool.infrastructure.Endpoint
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantTestContext.CompletionResponse
|
||||
import com.daml.ledger.api.testtool.infrastructure.time.DelayMechanism
|
||||
import com.daml.ledger.api.v1.active_contracts_service.GetActiveContractsRequest
|
||||
import com.daml.ledger.api.v1.admin.config_management_service.{
|
||||
GetTimeModelResponse,
|
||||
SetTimeModelRequest,
|
||||
SetTimeModelResponse,
|
||||
TimeModel,
|
||||
}
|
||||
import com.daml.ledger.api.v1.admin.package_management_service.{
|
||||
PackageDetails,
|
||||
UploadDarFileRequest,
|
||||
}
|
||||
import com.daml.ledger.api.v1.admin.participant_pruning_service.PruneResponse
|
||||
import com.daml.ledger.api.v1.admin.party_management_service.PartyDetails
|
||||
import com.daml.ledger.api.v1.command_completion_service.{
|
||||
Checkpoint,
|
||||
CompletionEndRequest,
|
||||
CompletionEndResponse,
|
||||
CompletionStreamRequest,
|
||||
CompletionStreamResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.command_service.{
|
||||
SubmitAndWaitForTransactionIdResponse,
|
||||
SubmitAndWaitForTransactionResponse,
|
||||
SubmitAndWaitForTransactionTreeResponse,
|
||||
SubmitAndWaitRequest,
|
||||
}
|
||||
import com.daml.ledger.api.v1.command_submission_service.SubmitRequest
|
||||
import com.daml.ledger.api.v1.commands.Command
|
||||
import com.daml.ledger.api.v1.completion.Completion
|
||||
import com.daml.ledger.api.v1.event.CreatedEvent
|
||||
import com.daml.ledger.api.v1.ledger_configuration_service.LedgerConfiguration
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset
|
||||
import com.daml.ledger.api.v1.package_service.{GetPackageResponse, PackageStatus}
|
||||
import com.daml.ledger.api.v1.transaction.{Transaction, TransactionTree}
|
||||
import com.daml.ledger.api.v1.transaction_service.{
|
||||
GetTransactionByEventIdRequest,
|
||||
GetTransactionByIdRequest,
|
||||
GetTransactionsRequest,
|
||||
GetTransactionsResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.value.{Identifier, Value}
|
||||
import com.daml.ledger.client.binding.{Primitive, Template}
|
||||
import com.daml.lf.data.Ref.HexString
|
||||
import com.google.protobuf.ByteString
|
||||
import io.grpc.health.v1.health.HealthCheckResponse
|
||||
import io.grpc.stub.StreamObserver
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
trait ParticipantTestContext extends UserManagementTestContext {
|
||||
|
||||
val begin: LedgerOffset =
|
||||
LedgerOffset(LedgerOffset.Value.Boundary(LedgerOffset.LedgerBoundary.LEDGER_BEGIN))
|
||||
|
||||
/** A reference to the moving ledger end. If you want a fixed reference to the offset at
|
||||
* a given point in time, use [[currentEnd]]
|
||||
*/
|
||||
val end: LedgerOffset =
|
||||
LedgerOffset(LedgerOffset.Value.Boundary(LedgerOffset.LedgerBoundary.LEDGER_END))
|
||||
|
||||
val ledgerId: String
|
||||
val applicationId: String
|
||||
val endpointId: String
|
||||
def ledgerEndpoint: Endpoint
|
||||
def features: Features
|
||||
def referenceOffset: LedgerOffset
|
||||
def nextKeyId: () => String
|
||||
def nextUserId: () => String
|
||||
def delayMechanism: DelayMechanism
|
||||
|
||||
/** Gets the absolute offset of the ledger end at a point in time. Use [[end]] if you need
|
||||
* a reference to the moving end of the ledger.
|
||||
*/
|
||||
def currentEnd(): Future[LedgerOffset]
|
||||
|
||||
/** Works just like [[currentEnd]] but allows to override the ledger identifier.
|
||||
*
|
||||
* Used only for low-level testing. Please use the other method unless you want to test the
|
||||
* behavior of the ledger end endpoint with a wrong ledger identifier.
|
||||
*/
|
||||
def currentEnd(overrideLedgerId: String): Future[LedgerOffset]
|
||||
|
||||
/** Returns an absolute offset that is beyond the current ledger end.
|
||||
*
|
||||
* Note: offsets are opaque byte strings, but they are lexicographically sortable.
|
||||
* Prepending the current absolute ledger end with non-zero bytes creates an offset that
|
||||
* is be beyond the current ledger end for the ledger API server.
|
||||
* The offset might however not be valid for the underlying ledger.
|
||||
* This method can therefore only be used for offsets that are only interpreted by the
|
||||
* ledger API server and not sent to the ledger.
|
||||
*/
|
||||
def offsetBeyondLedgerEnd(): Future[LedgerOffset]
|
||||
def time(): Future[Instant]
|
||||
def setTime(currentTime: Instant, newTime: Instant): Future[Unit]
|
||||
def listKnownPackages(): Future[Seq[PackageDetails]]
|
||||
def uploadDarFile(bytes: ByteString): Future[Unit] =
|
||||
uploadDarFile(new UploadDarFileRequest(bytes))
|
||||
def uploadDarRequest(bytes: ByteString): UploadDarFileRequest
|
||||
def uploadDarFile(request: UploadDarFileRequest): Future[Unit]
|
||||
def participantId(): Future[String]
|
||||
def listPackages(): Future[Seq[String]]
|
||||
def getPackage(packageId: String): Future[GetPackageResponse]
|
||||
def getPackageStatus(packageId: String): Future[PackageStatus]
|
||||
|
||||
/** Managed version of party allocation, should be used anywhere a party has
|
||||
* to be allocated unless the party management service itself is under test
|
||||
*/
|
||||
def allocateParty(): Future[Primitive.Party]
|
||||
|
||||
/** Non managed version of party allocation. Use exclusively when testing the party management service.
|
||||
*/
|
||||
def allocateParty(
|
||||
partyIdHint: Option[String],
|
||||
displayName: Option[String],
|
||||
): Future[Primitive.Party]
|
||||
def allocateParties(n: Int): Future[Vector[Primitive.Party]]
|
||||
def getParties(parties: Seq[Primitive.Party]): Future[Seq[PartyDetails]]
|
||||
def listKnownParties(): Future[Set[Primitive.Party]]
|
||||
|
||||
/** @return a future that completes when all the participants can list all the expected parties
|
||||
*/
|
||||
def waitForParties(
|
||||
otherParticipants: Iterable[ParticipantTestContext],
|
||||
expectedParties: Set[Primitive.Party],
|
||||
): Future[Unit]
|
||||
def activeContracts(
|
||||
request: GetActiveContractsRequest
|
||||
): Future[(Option[LedgerOffset], Vector[CreatedEvent])]
|
||||
def activeContractsRequest(
|
||||
parties: Seq[Primitive.Party],
|
||||
templateIds: Seq[Identifier] = Seq.empty,
|
||||
): GetActiveContractsRequest
|
||||
def activeContracts(parties: Primitive.Party*): Future[Vector[CreatedEvent]]
|
||||
def activeContractsByTemplateId(
|
||||
templateIds: Seq[Identifier],
|
||||
parties: Primitive.Party*
|
||||
): Future[Vector[CreatedEvent]]
|
||||
|
||||
/** Create a [[GetTransactionsRequest]] with a set of [[Party]] objects.
|
||||
* You should use this only when you need to tweak the request of [[flatTransactions]]
|
||||
* or [[transactionTrees]], otherwise use the shortcut override that allows you to
|
||||
* directly pass a set of [[Party]]
|
||||
*/
|
||||
def getTransactionsRequest(
|
||||
parties: Seq[Primitive.Party],
|
||||
templateIds: Seq[TemplateId] = Seq.empty,
|
||||
begin: LedgerOffset = referenceOffset,
|
||||
): GetTransactionsRequest
|
||||
def transactionStream(
|
||||
request: GetTransactionsRequest,
|
||||
responseObserver: StreamObserver[GetTransactionsResponse],
|
||||
): Unit
|
||||
def flatTransactionsByTemplateId(
|
||||
templateId: TemplateId,
|
||||
parties: Primitive.Party*
|
||||
): Future[Vector[Transaction]]
|
||||
|
||||
/** Non-managed version of [[flatTransactions]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(request: GetTransactionsRequest): Future[Vector[Transaction]]
|
||||
|
||||
/** Managed version of [[flatTransactions]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(parties: Primitive.Party*): Future[Vector[Transaction]]
|
||||
|
||||
/** Non-managed version of [[flatTransactions]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(take: Int, request: GetTransactionsRequest): Future[Vector[Transaction]]
|
||||
|
||||
/** Managed version of [[flatTransactions]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(take: Int, parties: Primitive.Party*): Future[Vector[Transaction]]
|
||||
def transactionTreesByTemplateId(
|
||||
templateId: TemplateId,
|
||||
parties: Primitive.Party*
|
||||
): Future[Vector[TransactionTree]]
|
||||
|
||||
/** Non-managed version of [[transactionTrees]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(request: GetTransactionsRequest): Future[Vector[TransactionTree]]
|
||||
|
||||
/** Managed version of [[transactionTrees]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(parties: Primitive.Party*): Future[Vector[TransactionTree]]
|
||||
|
||||
/** Non-managed version of [[transactionTrees]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(
|
||||
take: Int,
|
||||
request: GetTransactionsRequest,
|
||||
): Future[Vector[TransactionTree]]
|
||||
|
||||
/** Managed version of [[transactionTrees]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(take: Int, parties: Primitive.Party*): Future[Vector[TransactionTree]]
|
||||
|
||||
/** Create a [[GetTransactionByIdRequest]] with an identifier and a set of [[Party]] objects.
|
||||
* You should use this only when you need to tweak the request of [[transactionTreeById]] or
|
||||
* [[flatTransactionById]], otherwise use the shortcut override that allows you to directly
|
||||
* pass the identifier and parties.
|
||||
*/
|
||||
def getTransactionByIdRequest(
|
||||
transactionId: String,
|
||||
parties: Seq[Primitive.Party],
|
||||
): GetTransactionByIdRequest
|
||||
|
||||
/** Non-managed version of [[transactionTreeById]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeById(request: GetTransactionByIdRequest): Future[TransactionTree]
|
||||
|
||||
/** Managed version of [[transactionTrees]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeById(transactionId: String, parties: Primitive.Party*): Future[TransactionTree]
|
||||
|
||||
/** Non-managed version of [[flatTransactionById]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionById(request: GetTransactionByIdRequest): Future[Transaction]
|
||||
|
||||
/** Managed version of [[flatTransactionById]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionById(transactionId: String, parties: Primitive.Party*): Future[Transaction]
|
||||
|
||||
/** Create a [[GetTransactionByEventIdRequest]] with an identifier and a set of [[Party]] objects.
|
||||
* You should use this only when you need to tweak the request of [[transactionTreeByEventId]] or
|
||||
* [[flatTransactionByEventId]], otherwise use the shortcut override that allows you to directly
|
||||
* pass the identifier and parties.
|
||||
*/
|
||||
def getTransactionByEventIdRequest(
|
||||
eventId: String,
|
||||
parties: Seq[Primitive.Party],
|
||||
): GetTransactionByEventIdRequest
|
||||
|
||||
/** Non-managed version of [[transactionTreeByEventId]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeByEventId(request: GetTransactionByEventIdRequest): Future[TransactionTree]
|
||||
|
||||
/** Managed version of [[transactionTreeByEventId]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeByEventId(eventId: String, parties: Primitive.Party*): Future[TransactionTree]
|
||||
|
||||
/** Non-managed version of [[flatTransactionByEventId]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionByEventId(request: GetTransactionByEventIdRequest): Future[Transaction]
|
||||
|
||||
/** Managed version of [[flatTransactionByEventId]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionByEventId(eventId: String, parties: Primitive.Party*): Future[Transaction]
|
||||
def create[T](
|
||||
party: Primitive.Party,
|
||||
template: Template[T],
|
||||
): Future[Primitive.ContractId[T]]
|
||||
def create[T](
|
||||
actAs: List[Primitive.Party],
|
||||
readAs: List[Primitive.Party],
|
||||
template: Template[T],
|
||||
): Future[Primitive.ContractId[T]]
|
||||
def createAndGetTransactionId[T](
|
||||
party: Primitive.Party,
|
||||
template: Template[T],
|
||||
): Future[(String, Primitive.ContractId[T])]
|
||||
def exercise[T](
|
||||
party: Primitive.Party,
|
||||
exercise: Primitive.Party => Primitive.Update[T],
|
||||
): Future[TransactionTree]
|
||||
def exercise[T](
|
||||
actAs: List[Primitive.Party],
|
||||
readAs: List[Primitive.Party],
|
||||
exercise: => Primitive.Update[T],
|
||||
): Future[TransactionTree]
|
||||
def exerciseForFlatTransaction[T](
|
||||
party: Primitive.Party,
|
||||
exercise: Primitive.Party => Primitive.Update[T],
|
||||
): Future[Transaction]
|
||||
def exerciseAndGetContract[T](
|
||||
party: Primitive.Party,
|
||||
exercise: Primitive.Party => Primitive.Update[Any],
|
||||
): Future[Primitive.ContractId[T]]
|
||||
def exerciseByKey[T](
|
||||
party: Primitive.Party,
|
||||
template: Primitive.TemplateId[T],
|
||||
key: Value,
|
||||
choice: String,
|
||||
argument: Value,
|
||||
): Future[TransactionTree]
|
||||
def submitRequest(
|
||||
actAs: List[Primitive.Party],
|
||||
readAs: List[Primitive.Party],
|
||||
commands: Command*
|
||||
): SubmitRequest
|
||||
def submitRequest(party: Primitive.Party, commands: Command*): SubmitRequest
|
||||
def submitAndWaitRequest(
|
||||
actAs: List[Primitive.Party],
|
||||
readAs: List[Primitive.Party],
|
||||
commands: Command*
|
||||
): SubmitAndWaitRequest
|
||||
def submitAndWaitRequest(party: Primitive.Party, commands: Command*): SubmitAndWaitRequest
|
||||
def submit(request: SubmitRequest): Future[Unit]
|
||||
def submitAndWait(request: SubmitAndWaitRequest): Future[Unit]
|
||||
def submitAndWaitForTransactionId(
|
||||
request: SubmitAndWaitRequest
|
||||
): Future[SubmitAndWaitForTransactionIdResponse]
|
||||
def submitAndWaitForTransaction(
|
||||
request: SubmitAndWaitRequest
|
||||
): Future[SubmitAndWaitForTransactionResponse]
|
||||
def submitAndWaitForTransactionTree(
|
||||
request: SubmitAndWaitRequest
|
||||
): Future[SubmitAndWaitForTransactionTreeResponse]
|
||||
def completionStreamRequest(from: LedgerOffset = referenceOffset)(
|
||||
parties: Primitive.Party*
|
||||
): CompletionStreamRequest
|
||||
def completionEnd(request: CompletionEndRequest): Future[CompletionEndResponse]
|
||||
def completionStream(
|
||||
request: CompletionStreamRequest,
|
||||
streamObserver: StreamObserver[CompletionStreamResponse],
|
||||
): Unit
|
||||
def firstCompletions(request: CompletionStreamRequest): Future[Vector[Completion]]
|
||||
def firstCompletions(parties: Primitive.Party*): Future[Vector[Completion]]
|
||||
def findCompletionAtOffset(
|
||||
offset: HexString,
|
||||
p: Completion => Boolean,
|
||||
)(parties: Primitive.Party*): Future[Option[CompletionResponse]]
|
||||
def findCompletion(
|
||||
request: CompletionStreamRequest
|
||||
)(p: Completion => Boolean): Future[Option[CompletionResponse]]
|
||||
def findCompletion(parties: Primitive.Party*)(
|
||||
p: Completion => Boolean
|
||||
): Future[Option[CompletionResponse]]
|
||||
def checkpoints(n: Int, request: CompletionStreamRequest): Future[Vector[Checkpoint]]
|
||||
def checkpoints(n: Int, from: LedgerOffset = referenceOffset)(
|
||||
parties: Primitive.Party*
|
||||
): Future[Vector[Checkpoint]]
|
||||
def firstCheckpoint(request: CompletionStreamRequest): Future[Checkpoint]
|
||||
def firstCheckpoint(parties: Primitive.Party*): Future[Checkpoint]
|
||||
def nextCheckpoint(request: CompletionStreamRequest): Future[Checkpoint]
|
||||
def nextCheckpoint(from: LedgerOffset, parties: Primitive.Party*): Future[Checkpoint]
|
||||
def configuration(overrideLedgerId: Option[String] = None): Future[LedgerConfiguration]
|
||||
def checkHealth(): Future[HealthCheckResponse]
|
||||
def watchHealth(): Future[Seq[HealthCheckResponse]]
|
||||
def getTimeModel(): Future[GetTimeModelResponse]
|
||||
def setTimeModel(
|
||||
mrt: Instant,
|
||||
generation: Long,
|
||||
newTimeModel: TimeModel,
|
||||
): Future[SetTimeModelResponse]
|
||||
def setTimeModelRequest(
|
||||
mrt: Instant,
|
||||
generation: Long,
|
||||
newTimeModel: TimeModel,
|
||||
): SetTimeModelRequest
|
||||
|
||||
def setTimeModel(
|
||||
request: SetTimeModelRequest
|
||||
): Future[SetTimeModelResponse]
|
||||
|
||||
private[infrastructure] def preallocateParties(
|
||||
n: Int,
|
||||
participants: Iterable[ParticipantTestContext],
|
||||
): Future[Vector[Primitive.Party]]
|
||||
|
||||
def prune(
|
||||
pruneUpTo: LedgerOffset,
|
||||
attempts: Int = 10,
|
||||
pruneAllDivulgedContracts: Boolean = false,
|
||||
): Future[PruneResponse]
|
||||
|
||||
}
|
||||
|
||||
object ParticipantTestContext {
|
||||
|
||||
case class CompletionResponse(completion: Completion, offset: LedgerOffset, recordTime: Instant)
|
||||
|
||||
}
|
@ -8,6 +8,7 @@ import java.time.{Clock, Instant}
|
||||
import com.daml.ledger.api.refinements.ApiTypes.TemplateId
|
||||
import com.daml.ledger.api.testtool.infrastructure.Eventually.eventually
|
||||
import com.daml.ledger.api.testtool.infrastructure.ProtobufConverters._
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantTestContext.CompletionResponse
|
||||
import com.daml.ledger.api.testtool.infrastructure.time.{
|
||||
DelayMechanism,
|
||||
StaticTimeDelayMechanism,
|
||||
@ -19,7 +20,6 @@ import com.daml.ledger.api.testtool.infrastructure.{
|
||||
LedgerServices,
|
||||
PartyAllocationConfiguration,
|
||||
}
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
import com.daml.ledger.api.v1.active_contracts_service.{
|
||||
GetActiveContractsRequest,
|
||||
GetActiveContractsResponse,
|
||||
@ -97,52 +97,26 @@ import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Failure
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
private[testtool] object ParticipantTestContext {
|
||||
|
||||
private[this] def filter(templateIds: Seq[Identifier]): Filters =
|
||||
new Filters(
|
||||
if (templateIds.isEmpty) None
|
||||
else Some(new InclusiveFilters(templateIds))
|
||||
)
|
||||
|
||||
private def transactionFilter(
|
||||
parties: Seq[String],
|
||||
templateIds: Seq[Identifier],
|
||||
): Some[TransactionFilter] =
|
||||
Some(new TransactionFilter(Map(parties.map(_ -> filter(templateIds)): _*)))
|
||||
|
||||
}
|
||||
|
||||
/** Exposes services running on some participant server in a test case.
|
||||
*
|
||||
* Each time a test case is run it receives a fresh instance of [[ParticipantTestContext]]
|
||||
* Each time a test case is run it receives a fresh instance of [[SingleParticipantTestContext]]
|
||||
* (one for every used participant server).
|
||||
*/
|
||||
final class ParticipantTestContext private[participant] (
|
||||
final class SingleParticipantTestContext private[participant] (
|
||||
val ledgerId: String,
|
||||
val endpointId: String,
|
||||
val applicationId: String,
|
||||
val identifierSuffix: String,
|
||||
referenceOffset: LedgerOffset,
|
||||
identifierSuffix: String,
|
||||
val referenceOffset: LedgerOffset,
|
||||
protected[participant] val services: LedgerServices,
|
||||
partyAllocationConfig: PartyAllocationConfiguration,
|
||||
val ledgerEndpoint: Endpoint,
|
||||
val clientTlsConfiguration: Option[TlsConfiguration],
|
||||
val features: Features,
|
||||
)(protected[participant] implicit val ec: ExecutionContext)
|
||||
extends UserManagementTestContext {
|
||||
extends ParticipantTestContext {
|
||||
private val logger = ContextualizedLogger.get(getClass)
|
||||
|
||||
import ParticipantTestContext._
|
||||
|
||||
val begin: LedgerOffset =
|
||||
LedgerOffset(LedgerOffset.Value.Boundary(LedgerOffset.LedgerBoundary.LEDGER_BEGIN))
|
||||
|
||||
/** A reference to the moving ledger end. If you want a fixed reference to the offset at
|
||||
* a given point in time, use [[currentEnd]]
|
||||
*/
|
||||
val end: LedgerOffset =
|
||||
LedgerOffset(LedgerOffset.Value.Boundary(LedgerOffset.LedgerBoundary.LEDGER_END))
|
||||
import SingleParticipantTestContext._
|
||||
|
||||
private[this] val identifierPrefix =
|
||||
s"$applicationId-$endpointId-$identifierSuffix"
|
||||
@ -159,47 +133,30 @@ final class ParticipantTestContext private[participant] (
|
||||
private[this] val nextCommandId: () => String = nextIdGenerator("command")
|
||||
private[this] val nextSubmissionId: () => String = nextIdGenerator("submission")
|
||||
private[this] val workflowId: String = s"$applicationId-$identifierSuffix"
|
||||
val nextKeyId: () => String = nextIdGenerator("key")
|
||||
val nextUserId: () => String = nextIdGenerator("user", lowerCase = true)
|
||||
override val nextKeyId: () => String = nextIdGenerator("key")
|
||||
override val nextUserId: () => String = nextIdGenerator("user", lowerCase = true)
|
||||
|
||||
lazy val delayMechanism: DelayMechanism = if (features.staticTime) {
|
||||
override lazy val delayMechanism: DelayMechanism = if (features.staticTime) {
|
||||
new StaticTimeDelayMechanism(this)
|
||||
} else
|
||||
new TimeDelayMechanism()
|
||||
|
||||
override def toString: String = s"participant $endpointId"
|
||||
|
||||
/** Gets the absolute offset of the ledger end at a point in time. Use [[end]] if you need
|
||||
* a reference to the moving end of the ledger.
|
||||
*/
|
||||
def currentEnd(): Future[LedgerOffset] =
|
||||
override def currentEnd(): Future[LedgerOffset] =
|
||||
services.transaction
|
||||
.getLedgerEnd(new GetLedgerEndRequest(ledgerId))
|
||||
.map(_.getOffset)
|
||||
|
||||
/** Works just like [[currentEnd]] but allows to override the ledger identifier.
|
||||
*
|
||||
* Used only for low-level testing. Please use the other method unless you want to test the
|
||||
* behavior of the ledger end endpoint with a wrong ledger identifier.
|
||||
*/
|
||||
def currentEnd(overrideLedgerId: String): Future[LedgerOffset] =
|
||||
override def currentEnd(overrideLedgerId: String): Future[LedgerOffset] =
|
||||
services.transaction
|
||||
.getLedgerEnd(new GetLedgerEndRequest(overrideLedgerId))
|
||||
.map(_.getOffset)
|
||||
|
||||
/** Returns an absolute offset that is beyond the current ledger end.
|
||||
*
|
||||
* Note: offsets are opaque byte strings, but they are lexicographically sortable.
|
||||
* Prepending the current absolute ledger end with non-zero bytes creates an offset that
|
||||
* is be beyond the current ledger end for the ledger API server.
|
||||
* The offset might however not be valid for the underlying ledger.
|
||||
* This method can therefore only be used for offsets that are only interpreted by the
|
||||
* ledger API server and not sent to the ledger.
|
||||
*/
|
||||
def offsetBeyondLedgerEnd(): Future[LedgerOffset] =
|
||||
override def offsetBeyondLedgerEnd(): Future[LedgerOffset] =
|
||||
currentEnd().map(end => LedgerOffset(LedgerOffset.Value.Absolute("FFFF" + end.getAbsolute)))
|
||||
|
||||
def time(): Future[Instant] =
|
||||
override def time(): Future[Instant] =
|
||||
new StreamConsumer[GetTimeResponse](services.time.getTime(new GetTimeRequest(ledgerId), _))
|
||||
.first()
|
||||
.map(_.map(r => r.getCurrentTime.asJava).get)
|
||||
@ -207,7 +164,7 @@ final class ParticipantTestContext private[participant] (
|
||||
Clock.systemUTC().instant()
|
||||
}
|
||||
|
||||
def setTime(currentTime: Instant, newTime: Instant): Future[Unit] =
|
||||
override def setTime(currentTime: Instant, newTime: Instant): Future[Unit] =
|
||||
services.time
|
||||
.setTime(
|
||||
SetTimeRequest(
|
||||
@ -218,51 +175,46 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
.map(_ => ())
|
||||
|
||||
def listKnownPackages(): Future[Seq[PackageDetails]] =
|
||||
override def listKnownPackages(): Future[Seq[PackageDetails]] =
|
||||
services.packageManagement
|
||||
.listKnownPackages(new ListKnownPackagesRequest)
|
||||
.map(_.packageDetails)
|
||||
|
||||
def uploadDarFile(bytes: ByteString): Future[Unit] =
|
||||
uploadDarFile(new UploadDarFileRequest(bytes))
|
||||
|
||||
def uploadDarRequest(bytes: ByteString): UploadDarFileRequest =
|
||||
override def uploadDarRequest(bytes: ByteString): UploadDarFileRequest =
|
||||
new UploadDarFileRequest(bytes, nextSubmissionId())
|
||||
|
||||
def uploadDarFile(request: UploadDarFileRequest): Future[Unit] =
|
||||
override def uploadDarFile(request: UploadDarFileRequest): Future[Unit] =
|
||||
services.packageManagement
|
||||
.uploadDarFile(request)
|
||||
.map(_ => ())
|
||||
|
||||
def participantId(): Future[String] =
|
||||
override def participantId(): Future[String] =
|
||||
services.partyManagement
|
||||
.getParticipantId(new GetParticipantIdRequest)
|
||||
.map(_.participantId)
|
||||
|
||||
def listPackages(): Future[Seq[String]] =
|
||||
override def listPackages(): Future[Seq[String]] =
|
||||
services.packages
|
||||
.listPackages(new ListPackagesRequest(ledgerId))
|
||||
.map(_.packageIds)
|
||||
|
||||
def getPackage(packageId: String): Future[GetPackageResponse] =
|
||||
override def getPackage(packageId: String): Future[GetPackageResponse] =
|
||||
services.packages.getPackage(new GetPackageRequest(ledgerId, packageId))
|
||||
|
||||
def getPackageStatus(packageId: String): Future[PackageStatus] =
|
||||
override def getPackageStatus(packageId: String): Future[PackageStatus] =
|
||||
services.packages
|
||||
.getPackageStatus(new GetPackageStatusRequest(ledgerId, packageId))
|
||||
.map(_.packageStatus)
|
||||
|
||||
/** Managed version of party allocation, should be used anywhere a party has
|
||||
* to be allocated unless the party management service itself is under test
|
||||
*/
|
||||
def allocateParty(): Future[Party] =
|
||||
override def allocateParty(): Future[Party] =
|
||||
services.partyManagement
|
||||
.allocateParty(new AllocatePartyRequest(partyIdHint = nextPartyHintId()))
|
||||
.map(r => Party(r.partyDetails.get.party))
|
||||
|
||||
/** Non managed version of party allocation. Use exclusively when testing the party management service.
|
||||
*/
|
||||
def allocateParty(partyIdHint: Option[String], displayName: Option[String]): Future[Party] =
|
||||
override def allocateParty(
|
||||
partyIdHint: Option[String],
|
||||
displayName: Option[String],
|
||||
): Future[Party] =
|
||||
services.partyManagement
|
||||
.allocateParty(
|
||||
new AllocatePartyRequest(
|
||||
@ -272,22 +224,20 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
.map(r => Party(r.partyDetails.get.party))
|
||||
|
||||
def allocateParties(n: Int): Future[Vector[Party]] =
|
||||
override def allocateParties(n: Int): Future[Vector[Party]] =
|
||||
Future.sequence(Vector.fill(n)(allocateParty()))
|
||||
|
||||
def getParties(parties: Seq[Party]): Future[Seq[PartyDetails]] =
|
||||
override def getParties(parties: Seq[Party]): Future[Seq[PartyDetails]] =
|
||||
services.partyManagement
|
||||
.getParties(GetPartiesRequest(parties.map(_.unwrap)))
|
||||
.map(_.partyDetails)
|
||||
|
||||
def listKnownParties(): Future[Set[Party]] =
|
||||
override def listKnownParties(): Future[Set[Party]] =
|
||||
services.partyManagement
|
||||
.listKnownParties(new ListKnownPartiesRequest())
|
||||
.map(_.partyDetails.map(partyDetails => Party(partyDetails.party)).toSet)
|
||||
|
||||
/** @return a future that completes when all the participants can list all the expected parties
|
||||
*/
|
||||
def waitForParties(
|
||||
override def waitForParties(
|
||||
otherParticipants: Iterable[ParticipantTestContext],
|
||||
expectedParties: Set[Party],
|
||||
): Future[Unit] =
|
||||
@ -311,7 +261,7 @@ final class ParticipantTestContext private[participant] (
|
||||
Future.unit
|
||||
}
|
||||
|
||||
def activeContracts(
|
||||
override def activeContracts(
|
||||
request: GetActiveContractsRequest
|
||||
): Future[(Option[LedgerOffset], Vector[CreatedEvent])] =
|
||||
for {
|
||||
@ -322,7 +272,7 @@ final class ParticipantTestContext private[participant] (
|
||||
.map(c => LedgerOffset(LedgerOffset.Value.Absolute(c.offset))) -> contracts
|
||||
.flatMap(_.activeContracts)
|
||||
|
||||
def activeContractsRequest(
|
||||
override def activeContractsRequest(
|
||||
parties: Seq[Party],
|
||||
templateIds: Seq[Identifier] = Seq.empty,
|
||||
): GetActiveContractsRequest =
|
||||
@ -332,21 +282,16 @@ final class ParticipantTestContext private[participant] (
|
||||
verbose = true,
|
||||
)
|
||||
|
||||
def activeContracts(parties: Party*): Future[Vector[CreatedEvent]] =
|
||||
override def activeContracts(parties: Party*): Future[Vector[CreatedEvent]] =
|
||||
activeContractsByTemplateId(Seq.empty, parties: _*)
|
||||
|
||||
def activeContractsByTemplateId(
|
||||
override def activeContractsByTemplateId(
|
||||
templateIds: Seq[Identifier],
|
||||
parties: Party*
|
||||
): Future[Vector[CreatedEvent]] =
|
||||
activeContracts(activeContractsRequest(parties, templateIds)).map(_._2)
|
||||
|
||||
/** Create a [[GetTransactionsRequest]] with a set of [[Party]] objects.
|
||||
* You should use this only when you need to tweak the request of [[flatTransactions]]
|
||||
* or [[transactionTrees]], otherwise use the shortcut override that allows you to
|
||||
* directly pass a set of [[Party]]
|
||||
*/
|
||||
def getTransactionsRequest(
|
||||
override def getTransactionsRequest(
|
||||
parties: Seq[Party],
|
||||
templateIds: Seq[TemplateId] = Seq.empty,
|
||||
begin: LedgerOffset = referenceOffset,
|
||||
@ -372,133 +317,101 @@ final class ParticipantTestContext private[participant] (
|
||||
): Future[Vector[Res]] =
|
||||
new StreamConsumer[Res](service(request, _)).all()
|
||||
|
||||
def transactionStream(
|
||||
override def transactionStream(
|
||||
request: GetTransactionsRequest,
|
||||
responseObserver: StreamObserver[GetTransactionsResponse],
|
||||
): Unit =
|
||||
services.transaction.getTransactions(request, responseObserver)
|
||||
|
||||
def flatTransactionsByTemplateId(
|
||||
override def flatTransactionsByTemplateId(
|
||||
templateId: TemplateId,
|
||||
parties: Party*
|
||||
): Future[Vector[Transaction]] =
|
||||
flatTransactions(getTransactionsRequest(parties, Seq(templateId)))
|
||||
|
||||
/** Non-managed version of [[flatTransactions]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(request: GetTransactionsRequest): Future[Vector[Transaction]] =
|
||||
override def flatTransactions(request: GetTransactionsRequest): Future[Vector[Transaction]] =
|
||||
transactions(request, services.transaction.getTransactions)
|
||||
.map(_.flatMap(_.transactions))
|
||||
|
||||
/** Managed version of [[flatTransactions]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(parties: Party*): Future[Vector[Transaction]] =
|
||||
override def flatTransactions(parties: Party*): Future[Vector[Transaction]] =
|
||||
flatTransactions(getTransactionsRequest(parties))
|
||||
|
||||
/** Non-managed version of [[flatTransactions]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(take: Int, request: GetTransactionsRequest): Future[Vector[Transaction]] =
|
||||
override def flatTransactions(
|
||||
take: Int,
|
||||
request: GetTransactionsRequest,
|
||||
): Future[Vector[Transaction]] =
|
||||
transactions(take, request, services.transaction.getTransactions)
|
||||
.map(_.flatMap(_.transactions))
|
||||
|
||||
/** Managed version of [[flatTransactions]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactions(take: Int, parties: Party*): Future[Vector[Transaction]] =
|
||||
override def flatTransactions(take: Int, parties: Party*): Future[Vector[Transaction]] =
|
||||
flatTransactions(take, getTransactionsRequest(parties))
|
||||
|
||||
def transactionTreesByTemplateId(
|
||||
override def transactionTreesByTemplateId(
|
||||
templateId: TemplateId,
|
||||
parties: Party*
|
||||
): Future[Vector[TransactionTree]] =
|
||||
transactionTrees(getTransactionsRequest(parties, Seq(templateId)))
|
||||
|
||||
/** Non-managed version of [[transactionTrees]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(request: GetTransactionsRequest): Future[Vector[TransactionTree]] =
|
||||
override def transactionTrees(request: GetTransactionsRequest): Future[Vector[TransactionTree]] =
|
||||
transactions(request, services.transaction.getTransactionTrees)
|
||||
.map(_.flatMap(_.transactions))
|
||||
|
||||
/** Managed version of [[transactionTrees]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(parties: Party*): Future[Vector[TransactionTree]] =
|
||||
override def transactionTrees(parties: Party*): Future[Vector[TransactionTree]] =
|
||||
transactionTrees(getTransactionsRequest(parties))
|
||||
|
||||
/** Non-managed version of [[transactionTrees]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(
|
||||
override def transactionTrees(
|
||||
take: Int,
|
||||
request: GetTransactionsRequest,
|
||||
): Future[Vector[TransactionTree]] =
|
||||
transactions(take, request, services.transaction.getTransactionTrees)
|
||||
.map(_.flatMap(_.transactions))
|
||||
|
||||
/** Managed version of [[transactionTrees]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTrees(take: Int, parties: Party*): Future[Vector[TransactionTree]] =
|
||||
override def transactionTrees(take: Int, parties: Party*): Future[Vector[TransactionTree]] =
|
||||
transactionTrees(take, getTransactionsRequest(parties))
|
||||
|
||||
/** Create a [[GetTransactionByIdRequest]] with an identifier and a set of [[Party]] objects.
|
||||
* You should use this only when you need to tweak the request of [[transactionTreeById]] or
|
||||
* [[flatTransactionById]], otherwise use the shortcut override that allows you to directly
|
||||
* pass the identifier and parties.
|
||||
*/
|
||||
def getTransactionByIdRequest(
|
||||
override def getTransactionByIdRequest(
|
||||
transactionId: String,
|
||||
parties: Seq[Party],
|
||||
): GetTransactionByIdRequest =
|
||||
new GetTransactionByIdRequest(ledgerId, transactionId, Tag.unsubst(parties))
|
||||
|
||||
/** Non-managed version of [[transactionTreeById]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeById(request: GetTransactionByIdRequest): Future[TransactionTree] =
|
||||
override def transactionTreeById(request: GetTransactionByIdRequest): Future[TransactionTree] =
|
||||
services.transaction.getTransactionById(request).map(_.getTransaction)
|
||||
|
||||
/** Managed version of [[transactionTrees]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeById(transactionId: String, parties: Party*): Future[TransactionTree] =
|
||||
override def transactionTreeById(
|
||||
transactionId: String,
|
||||
parties: Party*
|
||||
): Future[TransactionTree] =
|
||||
transactionTreeById(getTransactionByIdRequest(transactionId, parties))
|
||||
|
||||
/** Non-managed version of [[flatTransactionById]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionById(request: GetTransactionByIdRequest): Future[Transaction] =
|
||||
override def flatTransactionById(request: GetTransactionByIdRequest): Future[Transaction] =
|
||||
services.transaction.getFlatTransactionById(request).map(_.getTransaction)
|
||||
|
||||
/** Managed version of [[flatTransactionById]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionById(transactionId: String, parties: Party*): Future[Transaction] =
|
||||
override def flatTransactionById(transactionId: String, parties: Party*): Future[Transaction] =
|
||||
flatTransactionById(getTransactionByIdRequest(transactionId, parties))
|
||||
|
||||
/** Create a [[GetTransactionByEventIdRequest]] with an identifier and a set of [[Party]] objects.
|
||||
* You should use this only when you need to tweak the request of [[transactionTreeByEventId]] or
|
||||
* [[flatTransactionByEventId]], otherwise use the shortcut override that allows you to directly
|
||||
* pass the identifier and parties.
|
||||
*/
|
||||
def getTransactionByEventIdRequest(
|
||||
override def getTransactionByEventIdRequest(
|
||||
eventId: String,
|
||||
parties: Seq[Party],
|
||||
): GetTransactionByEventIdRequest =
|
||||
new GetTransactionByEventIdRequest(ledgerId, eventId, Tag.unsubst(parties))
|
||||
|
||||
/** Non-managed version of [[transactionTreeByEventId]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeByEventId(request: GetTransactionByEventIdRequest): Future[TransactionTree] =
|
||||
override def transactionTreeByEventId(
|
||||
request: GetTransactionByEventIdRequest
|
||||
): Future[TransactionTree] =
|
||||
services.transaction.getTransactionByEventId(request).map(_.getTransaction)
|
||||
|
||||
/** Managed version of [[transactionTreeByEventId]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def transactionTreeByEventId(eventId: String, parties: Party*): Future[TransactionTree] =
|
||||
override def transactionTreeByEventId(eventId: String, parties: Party*): Future[TransactionTree] =
|
||||
transactionTreeByEventId(getTransactionByEventIdRequest(eventId, parties))
|
||||
|
||||
/** Non-managed version of [[flatTransactionByEventId]], use this only if you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionByEventId(request: GetTransactionByEventIdRequest): Future[Transaction] =
|
||||
override def flatTransactionByEventId(
|
||||
request: GetTransactionByEventIdRequest
|
||||
): Future[Transaction] =
|
||||
services.transaction
|
||||
.getFlatTransactionByEventId(request)
|
||||
.map(_.getTransaction)
|
||||
|
||||
/** Managed version of [[flatTransactionByEventId]], use this unless you need to tweak the request (i.e. to test low-level details)
|
||||
*/
|
||||
def flatTransactionByEventId(eventId: String, parties: Party*): Future[Transaction] =
|
||||
override def flatTransactionByEventId(eventId: String, parties: Party*): Future[Transaction] =
|
||||
flatTransactionByEventId(getTransactionByEventIdRequest(eventId, parties))
|
||||
|
||||
private def extractContracts[T](transaction: Transaction): Seq[Primitive.ContractId[T]] =
|
||||
@ -506,7 +419,7 @@ final class ParticipantTestContext private[participant] (
|
||||
Primitive.ContractId(e.contractId)
|
||||
}
|
||||
|
||||
def create[T](
|
||||
override def create[T](
|
||||
party: Party,
|
||||
template: Template[T],
|
||||
): Future[Primitive.ContractId[T]] =
|
||||
@ -515,7 +428,7 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
.map(response => extractContracts(response.getTransaction).head)
|
||||
|
||||
def create[T](
|
||||
override def create[T](
|
||||
actAs: List[Party],
|
||||
readAs: List[Party],
|
||||
template: Template[T],
|
||||
@ -524,7 +437,7 @@ final class ParticipantTestContext private[participant] (
|
||||
submitAndWaitRequest(actAs, readAs, template.create.command)
|
||||
).map(response => extractContracts(response.getTransaction).head)
|
||||
|
||||
def createAndGetTransactionId[T](
|
||||
override def createAndGetTransactionId[T](
|
||||
party: Party,
|
||||
template: Template[T],
|
||||
): Future[(String, Primitive.ContractId[T])] =
|
||||
@ -538,7 +451,7 @@ final class ParticipantTestContext private[participant] (
|
||||
}.head
|
||||
)
|
||||
|
||||
def exercise[T](
|
||||
override def exercise[T](
|
||||
party: Party,
|
||||
exercise: Party => Primitive.Update[T],
|
||||
): Future[TransactionTree] =
|
||||
@ -546,7 +459,7 @@ final class ParticipantTestContext private[participant] (
|
||||
submitAndWaitRequest(party, exercise(party).command)
|
||||
).map(_.getTransaction)
|
||||
|
||||
def exercise[T](
|
||||
override def exercise[T](
|
||||
actAs: List[Party],
|
||||
readAs: List[Party],
|
||||
exercise: => Primitive.Update[T],
|
||||
@ -555,7 +468,7 @@ final class ParticipantTestContext private[participant] (
|
||||
submitAndWaitRequest(actAs, readAs, exercise.command)
|
||||
).map(_.getTransaction)
|
||||
|
||||
def exerciseForFlatTransaction[T](
|
||||
override def exerciseForFlatTransaction[T](
|
||||
party: Party,
|
||||
exercise: Party => Primitive.Update[T],
|
||||
): Future[Transaction] =
|
||||
@ -563,7 +476,7 @@ final class ParticipantTestContext private[participant] (
|
||||
submitAndWaitRequest(party, exercise(party).command)
|
||||
).map(_.getTransaction)
|
||||
|
||||
def exerciseAndGetContract[T](
|
||||
override def exerciseAndGetContract[T](
|
||||
party: Party,
|
||||
exercise: Party => Primitive.Update[Any],
|
||||
): Future[Primitive.ContractId[T]] =
|
||||
@ -574,7 +487,7 @@ final class ParticipantTestContext private[participant] (
|
||||
.map(extractContracts)
|
||||
.map(_.head.asInstanceOf[Primitive.ContractId[T]])
|
||||
|
||||
def exerciseByKey[T](
|
||||
override def exerciseByKey[T](
|
||||
party: Party,
|
||||
template: Primitive.TemplateId[T],
|
||||
key: Value,
|
||||
@ -597,7 +510,11 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
).map(_.getTransaction)
|
||||
|
||||
def submitRequest(actAs: List[Party], readAs: List[Party], commands: Command*): SubmitRequest =
|
||||
override def submitRequest(
|
||||
actAs: List[Party],
|
||||
readAs: List[Party],
|
||||
commands: Command*
|
||||
): SubmitRequest =
|
||||
new SubmitRequest(
|
||||
Some(
|
||||
new Commands(
|
||||
@ -613,7 +530,7 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
)
|
||||
|
||||
def submitRequest(party: Party, commands: Command*): SubmitRequest =
|
||||
override def submitRequest(party: Party, commands: Command*): SubmitRequest =
|
||||
new SubmitRequest(
|
||||
Some(
|
||||
new Commands(
|
||||
@ -628,7 +545,7 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
)
|
||||
|
||||
def submitAndWaitRequest(
|
||||
override def submitAndWaitRequest(
|
||||
actAs: List[Party],
|
||||
readAs: List[Party],
|
||||
commands: Command*
|
||||
@ -648,7 +565,7 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
)
|
||||
|
||||
def submitAndWaitRequest(party: Party, commands: Command*): SubmitAndWaitRequest =
|
||||
override def submitAndWaitRequest(party: Party, commands: Command*): SubmitAndWaitRequest =
|
||||
new SubmitAndWaitRequest(
|
||||
Some(
|
||||
new Commands(
|
||||
@ -663,50 +580,52 @@ final class ParticipantTestContext private[participant] (
|
||||
)
|
||||
)
|
||||
|
||||
def submit(request: SubmitRequest): Future[Unit] =
|
||||
override def submit(request: SubmitRequest): Future[Unit] =
|
||||
services.commandSubmission.submit(request).map(_ => ())
|
||||
|
||||
def submitAndWait(request: SubmitAndWaitRequest): Future[Unit] =
|
||||
override def submitAndWait(request: SubmitAndWaitRequest): Future[Unit] =
|
||||
services.command.submitAndWait(request).map(_ => ())
|
||||
|
||||
def submitAndWaitForTransactionId(
|
||||
override def submitAndWaitForTransactionId(
|
||||
request: SubmitAndWaitRequest
|
||||
): Future[SubmitAndWaitForTransactionIdResponse] =
|
||||
services.command.submitAndWaitForTransactionId(request)
|
||||
|
||||
def submitAndWaitForTransaction(
|
||||
override def submitAndWaitForTransaction(
|
||||
request: SubmitAndWaitRequest
|
||||
): Future[SubmitAndWaitForTransactionResponse] =
|
||||
services.command.submitAndWaitForTransaction(request)
|
||||
|
||||
def submitAndWaitForTransactionTree(
|
||||
override def submitAndWaitForTransactionTree(
|
||||
request: SubmitAndWaitRequest
|
||||
): Future[SubmitAndWaitForTransactionTreeResponse] =
|
||||
services.command
|
||||
.submitAndWaitForTransactionTree(request)
|
||||
|
||||
def completionStreamRequest(from: LedgerOffset = referenceOffset)(parties: Party*) =
|
||||
override def completionStreamRequest(from: LedgerOffset = referenceOffset)(
|
||||
parties: Party*
|
||||
): CompletionStreamRequest =
|
||||
new CompletionStreamRequest(ledgerId, applicationId, parties.map(_.unwrap), Some(from))
|
||||
|
||||
def completionEnd(request: CompletionEndRequest): Future[CompletionEndResponse] =
|
||||
override def completionEnd(request: CompletionEndRequest): Future[CompletionEndResponse] =
|
||||
services.commandCompletion.completionEnd(request)
|
||||
|
||||
def completionStream(
|
||||
override def completionStream(
|
||||
request: CompletionStreamRequest,
|
||||
streamObserver: StreamObserver[CompletionStreamResponse],
|
||||
): Unit =
|
||||
services.commandCompletion.completionStream(request, streamObserver)
|
||||
|
||||
def firstCompletions(request: CompletionStreamRequest): Future[Vector[Completion]] =
|
||||
override def firstCompletions(request: CompletionStreamRequest): Future[Vector[Completion]] =
|
||||
new StreamConsumer[CompletionStreamResponse](
|
||||
services.commandCompletion.completionStream(request, _)
|
||||
).find(_.completions.nonEmpty)
|
||||
.map(_.completions.toVector)
|
||||
|
||||
def firstCompletions(parties: Party*): Future[Vector[Completion]] =
|
||||
override def firstCompletions(parties: Party*): Future[Vector[Completion]] =
|
||||
firstCompletions(completionStreamRequest()(parties: _*))
|
||||
|
||||
def findCompletionAtOffset(
|
||||
override def findCompletionAtOffset(
|
||||
offset: Ref.HexString,
|
||||
p: Completion => Boolean,
|
||||
)(parties: Party*): Future[Option[CompletionResponse]] = {
|
||||
@ -720,7 +639,7 @@ final class ParticipantTestContext private[participant] (
|
||||
findCompletion(reportedOffsetCompletionStreamRequest)(p)
|
||||
}
|
||||
|
||||
def findCompletion(
|
||||
override def findCompletion(
|
||||
request: CompletionStreamRequest
|
||||
)(p: Completion => Boolean): Future[Option[CompletionResponse]] =
|
||||
new StreamConsumer[CompletionStreamResponse](
|
||||
@ -733,35 +652,35 @@ final class ParticipantTestContext private[participant] (
|
||||
.map(CompletionResponse(_, checkpoint.getOffset, checkpoint.getRecordTime.asJava))
|
||||
})
|
||||
|
||||
def findCompletion(parties: Party*)(
|
||||
override def findCompletion(parties: Party*)(
|
||||
p: Completion => Boolean
|
||||
): Future[Option[CompletionResponse]] =
|
||||
findCompletion(completionStreamRequest()(parties: _*))(p)
|
||||
|
||||
def checkpoints(n: Int, request: CompletionStreamRequest): Future[Vector[Checkpoint]] =
|
||||
override def checkpoints(n: Int, request: CompletionStreamRequest): Future[Vector[Checkpoint]] =
|
||||
new StreamConsumer[CompletionStreamResponse](
|
||||
services.commandCompletion.completionStream(request, _)
|
||||
).filterTake(_.checkpoint.isDefined)(n)
|
||||
.map(_.map(_.getCheckpoint))
|
||||
|
||||
def checkpoints(n: Int, from: LedgerOffset = referenceOffset)(
|
||||
override def checkpoints(n: Int, from: LedgerOffset)(
|
||||
parties: Party*
|
||||
): Future[Vector[Checkpoint]] =
|
||||
checkpoints(n, completionStreamRequest(from)(parties: _*))
|
||||
|
||||
def firstCheckpoint(request: CompletionStreamRequest): Future[Checkpoint] =
|
||||
override def firstCheckpoint(request: CompletionStreamRequest): Future[Checkpoint] =
|
||||
checkpoints(1, request).map(_.head)
|
||||
|
||||
def firstCheckpoint(parties: Party*): Future[Checkpoint] =
|
||||
override def firstCheckpoint(parties: Party*): Future[Checkpoint] =
|
||||
firstCheckpoint(completionStreamRequest()(parties: _*))
|
||||
|
||||
def nextCheckpoint(request: CompletionStreamRequest): Future[Checkpoint] =
|
||||
override def nextCheckpoint(request: CompletionStreamRequest): Future[Checkpoint] =
|
||||
checkpoints(1, request).map(_.head)
|
||||
|
||||
def nextCheckpoint(from: LedgerOffset, parties: Party*): Future[Checkpoint] =
|
||||
override def nextCheckpoint(from: LedgerOffset, parties: Party*): Future[Checkpoint] =
|
||||
nextCheckpoint(completionStreamRequest(from)(parties: _*))
|
||||
|
||||
def configuration(overrideLedgerId: Option[String] = None): Future[LedgerConfiguration] =
|
||||
override def configuration(overrideLedgerId: Option[String] = None): Future[LedgerConfiguration] =
|
||||
new StreamConsumer[GetLedgerConfigurationResponse](
|
||||
services.configuration
|
||||
.getLedgerConfiguration(
|
||||
@ -771,39 +690,39 @@ final class ParticipantTestContext private[participant] (
|
||||
).first()
|
||||
.map(_.fold(sys.error("No ledger configuration available."))(_.getLedgerConfiguration))
|
||||
|
||||
def checkHealth(): Future[HealthCheckResponse] =
|
||||
override def checkHealth(): Future[HealthCheckResponse] =
|
||||
services.health.check(HealthCheckRequest())
|
||||
|
||||
def watchHealth(): Future[Seq[HealthCheckResponse]] =
|
||||
override def watchHealth(): Future[Seq[HealthCheckResponse]] =
|
||||
new StreamConsumer[HealthCheckResponse](services.health.watch(HealthCheckRequest(), _))
|
||||
.within(1.second)
|
||||
|
||||
def getTimeModel(): Future[GetTimeModelResponse] =
|
||||
override def getTimeModel(): Future[GetTimeModelResponse] =
|
||||
services.configManagement.getTimeModel(GetTimeModelRequest())
|
||||
|
||||
def setTimeModel(
|
||||
override def setTimeModel(
|
||||
mrt: Instant,
|
||||
generation: Long,
|
||||
newTimeModel: TimeModel,
|
||||
): Future[SetTimeModelResponse] =
|
||||
setTimeModel(setTimeModelRequest(mrt, generation, newTimeModel))
|
||||
|
||||
def setTimeModelRequest(
|
||||
override def setTimeModelRequest(
|
||||
mrt: Instant,
|
||||
generation: Long,
|
||||
newTimeModel: TimeModel,
|
||||
): SetTimeModelRequest =
|
||||
SetTimeModelRequest(nextSubmissionId(), Some(mrt.asProtobuf), generation, Some(newTimeModel))
|
||||
|
||||
def setTimeModel(
|
||||
override def setTimeModel(
|
||||
request: SetTimeModelRequest
|
||||
): Future[SetTimeModelResponse] =
|
||||
services.configManagement.setTimeModel(request)
|
||||
|
||||
def prune(
|
||||
pruneUpTo: String,
|
||||
attempts: Int,
|
||||
pruneAllDivulgedContracts: Boolean,
|
||||
override def prune(
|
||||
pruneUpTo: LedgerOffset,
|
||||
attempts: Int = 10,
|
||||
pruneAllDivulgedContracts: Boolean = false,
|
||||
): Future[PruneResponse] =
|
||||
// Distributed ledger participants need to reach global consensus prior to pruning. Hence the "eventually" here:
|
||||
eventually(
|
||||
@ -811,7 +730,7 @@ final class ParticipantTestContext private[participant] (
|
||||
runAssertion = {
|
||||
services.participantPruning
|
||||
.prune(
|
||||
PruneRequest(pruneUpTo, nextSubmissionId(), pruneAllDivulgedContracts)
|
||||
PruneRequest(pruneUpTo.getAbsolute, nextSubmissionId(), pruneAllDivulgedContracts)
|
||||
)
|
||||
.andThen { case Failure(exception) =>
|
||||
logger.warn("Failed to prune", exception)(LoggingContext.ForTesting)
|
||||
@ -819,14 +738,7 @@ final class ParticipantTestContext private[participant] (
|
||||
},
|
||||
)
|
||||
|
||||
def prune(
|
||||
pruneUpTo: LedgerOffset,
|
||||
attempts: Int = 10,
|
||||
pruneAllDivulgedContracts: Boolean = false,
|
||||
): Future[PruneResponse] =
|
||||
prune(pruneUpTo.getAbsolute, attempts, pruneAllDivulgedContracts)
|
||||
|
||||
private[infrastructure] def preallocateParties(
|
||||
private[infrastructure] override def preallocateParties(
|
||||
n: Int,
|
||||
participants: Iterable[ParticipantTestContext],
|
||||
): Future[Vector[Party]] =
|
||||
@ -844,4 +756,18 @@ final class ParticipantTestContext private[participant] (
|
||||
Future.successful(Vector.fill(n)(Party(nextPartyHintId())))
|
||||
}
|
||||
|
||||
case class CompletionResponse(completion: Completion, offset: LedgerOffset, recordTime: Instant)
|
||||
private[testtool] object SingleParticipantTestContext {
|
||||
|
||||
private[this] def filter(templateIds: Seq[Identifier]): Filters =
|
||||
new Filters(
|
||||
if (templateIds.isEmpty) None
|
||||
else Some(new InclusiveFilters(templateIds))
|
||||
)
|
||||
|
||||
private def transactionFilter(
|
||||
parties: Seq[String],
|
||||
templateIds: Seq[Identifier],
|
||||
): Some[TransactionFilter] =
|
||||
Some(new TransactionFilter(Map(parties.map(_ -> filter(templateIds)): _*)))
|
||||
|
||||
}
|
@ -187,7 +187,6 @@ final class TestRunner(availableTests: AvailableTests, config: Config) {
|
||||
concurrentTestRuns = concurrentTestRuns,
|
||||
uploadDars = config.uploadDars,
|
||||
identifierSuffix = identifierSuffix,
|
||||
clientTlsConfiguration = config.tlsConfig,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
package com.daml.ledger.api.testtool.suites
|
||||
|
||||
import com.daml.ledger.api.testtool.infrastructure.LedgerTestSuite
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
|
||||
package object v1_14 {
|
||||
def default(timeoutScaleFactor: Double): Vector[LedgerTestSuite] =
|
||||
@ -12,6 +13,6 @@ package object v1_14 {
|
||||
new ExceptionsIT,
|
||||
)).sortBy(_.name)
|
||||
|
||||
def optional(): Vector[LedgerTestSuite] =
|
||||
v1_8.optional()
|
||||
def optional(tlsConfig: Option[TlsConfiguration]): Vector[LedgerTestSuite] =
|
||||
v1_8.optional(tlsConfig)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
package com.daml.ledger.api.testtool.suites
|
||||
|
||||
import com.daml.ledger.api.testtool.infrastructure.LedgerTestSuite
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
|
||||
package object v1_8 {
|
||||
def default(timeoutScaleFactor: Double): Vector[LedgerTestSuite] =
|
||||
@ -49,9 +50,9 @@ package object v1_8 {
|
||||
new WronglyTypedContractIdIT,
|
||||
)
|
||||
|
||||
def optional(): Vector[LedgerTestSuite] =
|
||||
def optional(tlsConfiguration: Option[TlsConfiguration]): Vector[LedgerTestSuite] =
|
||||
Vector(
|
||||
new TLSOnePointThreeIT,
|
||||
new TLSAtLeastOnePointTwoIT,
|
||||
new TLSOnePointThreeIT(tlsConfiguration),
|
||||
new TLSAtLeastOnePointTwoIT(tlsConfiguration),
|
||||
)
|
||||
}
|
||||
|
@ -18,10 +18,8 @@ import com.daml.ledger.api.testtool.infrastructure.assertions.CommandDeduplicati
|
||||
assertDeduplicationDuration,
|
||||
assertDeduplicationOffset,
|
||||
}
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.{
|
||||
CompletionResponse,
|
||||
ParticipantTestContext,
|
||||
}
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantTestContext
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantTestContext.CompletionResponse
|
||||
import com.daml.ledger.api.testtool.infrastructure.time.DelayMechanism
|
||||
import com.daml.ledger.api.v1.admin.config_management_service.TimeModel
|
||||
import com.daml.ledger.api.v1.command_service.SubmitAndWaitRequest
|
||||
|
@ -34,7 +34,11 @@ class ParticipantPruningIT extends LedgerTestSuite {
|
||||
)(implicit ec => { case Participants(Participant(participant)) =>
|
||||
for {
|
||||
failure <- participant
|
||||
.prune("", attempts = 1, pruneAllDivulgedContracts = true)
|
||||
.prune(
|
||||
LedgerOffset(LedgerOffset.Value.Absolute("")),
|
||||
attempts = 1,
|
||||
pruneAllDivulgedContracts = true,
|
||||
)
|
||||
.mustFail("pruning without specifying an offset")
|
||||
} yield {
|
||||
assertGrpcError(
|
||||
@ -52,7 +56,11 @@ class ParticipantPruningIT extends LedgerTestSuite {
|
||||
)(implicit ec => { case Participants(Participant(participant)) =>
|
||||
for {
|
||||
cannotPruneNonHexOffset <- participant
|
||||
.prune("covfefe", attempts = 1, pruneAllDivulgedContracts = true)
|
||||
.prune(
|
||||
LedgerOffset(LedgerOffset.Value.Absolute("covfefe")),
|
||||
attempts = 1,
|
||||
pruneAllDivulgedContracts = true,
|
||||
)
|
||||
.mustFail("pruning, specifying a non-hexadecimal offset")
|
||||
} yield {
|
||||
assertGrpcError(
|
||||
|
@ -6,7 +6,7 @@ package com.daml.ledger.api.testtool.suites.v1_8
|
||||
import com.daml.ledger.api.testtool.infrastructure.Allocation.{NoParties, allocate}
|
||||
import com.daml.ledger.api.testtool.infrastructure.participant.ParticipantTestContext
|
||||
import com.daml.ledger.api.testtool.infrastructure.{Endpoint, LedgerTestSuite}
|
||||
import com.daml.ledger.api.tls.TlsVersion
|
||||
import com.daml.ledger.api.tls.{TlsConfiguration, TlsVersion}
|
||||
import com.daml.ledger.api.tls.TlsVersion.TlsVersion
|
||||
import com.daml.ledger.api.v1.ledger_identity_service.LedgerIdentityServiceGrpc.LedgerIdentityServiceBlockingStub
|
||||
import com.daml.ledger.api.v1.ledger_identity_service.{
|
||||
@ -26,8 +26,12 @@ import scala.util.{Failure, Success, Try}
|
||||
* - accepts TLSv1.3 connections,
|
||||
* - rejects TLSv1.2 (or lower) connections.
|
||||
*/
|
||||
final class TLSOnePointThreeIT
|
||||
extends TlsIT(shortIdentifierPrefix = "ServerOnTLSv13ConnectionFromClientOn") {
|
||||
final class TLSOnePointThreeIT(
|
||||
clientTlsConfiguration: Option[TlsConfiguration]
|
||||
) extends TlsIT(
|
||||
shortIdentifierPrefix = "ServerOnTLSv13ConnectionFromClientOn",
|
||||
clientTlsConfiguration,
|
||||
) {
|
||||
testTlsConnection(
|
||||
clientTlsVersions = Seq[TlsVersion](TlsVersion.V1_2, TlsVersion.V1_3),
|
||||
assertConnectionOk = true,
|
||||
@ -42,8 +46,12 @@ final class TLSOnePointThreeIT
|
||||
* - accepts either TLSv1.2 or TLSv1.3 connections,
|
||||
* - rejects TLSv1.1 (or lower) connections.
|
||||
*/
|
||||
final class TLSAtLeastOnePointTwoIT
|
||||
extends TlsIT(shortIdentifierPrefix = "ServerOnTLSConnectionFromClientOn") {
|
||||
final class TLSAtLeastOnePointTwoIT(
|
||||
clientTlsConfiguration: Option[TlsConfiguration]
|
||||
) extends TlsIT(
|
||||
shortIdentifierPrefix = "ServerOnTLSConnectionFromClientOn",
|
||||
clientTlsConfiguration,
|
||||
) {
|
||||
testTlsConnection(
|
||||
clientTlsVersions = Seq[TlsVersion](TlsVersion.V1_2, TlsVersion.V1_3),
|
||||
assertConnectionOk = true,
|
||||
@ -58,7 +66,10 @@ final class TLSAtLeastOnePointTwoIT
|
||||
*
|
||||
* It works by creating and exercising a series of client service stubs, each over different TLS version.
|
||||
*/
|
||||
abstract class TlsIT(shortIdentifierPrefix: String) extends LedgerTestSuite {
|
||||
abstract class TlsIT(
|
||||
shortIdentifierPrefix: String,
|
||||
clientTlsConfiguration: Option[TlsConfiguration],
|
||||
) extends LedgerTestSuite {
|
||||
|
||||
def testTlsConnection(clientTlsVersion: TlsVersion, assertConnectionOk: Boolean): Unit = {
|
||||
testTlsConnection(
|
||||
@ -89,10 +100,10 @@ abstract class TlsIT(shortIdentifierPrefix: String) extends LedgerTestSuite {
|
||||
assume(testContexts.nonEmpty, "Missing an expected participant test context!")
|
||||
val firstTextContext = testContexts.head
|
||||
assume(
|
||||
firstTextContext.clientTlsConfiguration.isDefined,
|
||||
clientTlsConfiguration.isDefined,
|
||||
"Missing required TLS configuration!",
|
||||
)
|
||||
val tlsConfiguration = firstTextContext.clientTlsConfiguration.get
|
||||
val tlsConfiguration = clientTlsConfiguration.get
|
||||
assume(
|
||||
tlsConfiguration.enabled,
|
||||
"TLS configuration is disabled but expected to be enabled!",
|
||||
|
@ -4,11 +4,12 @@
|
||||
package com.daml.ledger.api.testtool.suites
|
||||
|
||||
import com.daml.ledger.api.testtool.infrastructure.LedgerTestSuite
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
|
||||
package object v1_dev {
|
||||
def default(timeoutScaleFactor: Double): Vector[LedgerTestSuite] =
|
||||
v1_14.default(timeoutScaleFactor)
|
||||
|
||||
def optional(): Vector[LedgerTestSuite] =
|
||||
v1_14.optional()
|
||||
def optional(tlsConfig: Option[TlsConfiguration]): Vector[LedgerTestSuite] =
|
||||
v1_14.optional(tlsConfig)
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ class NamesSpec extends AnyWordSpec with Matchers {
|
||||
}
|
||||
|
||||
object NamesSpec {
|
||||
private val allTestSuites = v1_dev.default(timeoutScaleFactor = 1) ++ v1_dev.optional()
|
||||
private val allTestSuites =
|
||||
v1_dev.default(timeoutScaleFactor = 1) ++ v1_dev.optional(tlsConfig = None)
|
||||
private val allTestSuiteNames = allTestSuites.map(_.name).sorted
|
||||
|
||||
private val allTests = allTestSuites.flatMap(_.tests)
|
||||
|
@ -4,11 +4,12 @@
|
||||
package com.daml.ledger.api.testtool
|
||||
|
||||
import com.daml.ledger.api.testtool.infrastructure.LedgerTestSuite
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
|
||||
object Tests {
|
||||
def default(timeoutScaleFactor: Double): Vector[LedgerTestSuite] =
|
||||
suites.v1_14.default(timeoutScaleFactor)
|
||||
|
||||
def optional(): Vector[LedgerTestSuite] =
|
||||
suites.v1_14.optional()
|
||||
def optional(tlsConfig: Option[TlsConfiguration]): Vector[LedgerTestSuite] =
|
||||
suites.v1_14.optional(tlsConfig)
|
||||
}
|
||||
|
@ -4,11 +4,12 @@
|
||||
package com.daml.ledger.api.testtool
|
||||
|
||||
import com.daml.ledger.api.testtool.infrastructure.LedgerTestSuite
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
|
||||
object Tests {
|
||||
def default(timeoutScaleFactor: Double): Vector[LedgerTestSuite] =
|
||||
suites.v1_8.default(timeoutScaleFactor)
|
||||
|
||||
def optional(): Vector[LedgerTestSuite] =
|
||||
suites.v1_8.optional()
|
||||
def optional(tlsConfig: Option[TlsConfiguration]): Vector[LedgerTestSuite] =
|
||||
suites.v1_8.optional(tlsConfig)
|
||||
}
|
||||
|
@ -4,11 +4,12 @@
|
||||
package com.daml.ledger.api.testtool
|
||||
|
||||
import com.daml.ledger.api.testtool.infrastructure.LedgerTestSuite
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
|
||||
object Tests {
|
||||
def default(timeoutScaleFactor: Double): Vector[LedgerTestSuite] =
|
||||
suites.v1_dev.default(timeoutScaleFactor)
|
||||
|
||||
def optional(): Vector[LedgerTestSuite] =
|
||||
suites.v1_dev.optional()
|
||||
def optional(tlsConfig: Option[TlsConfiguration]): Vector[LedgerTestSuite] =
|
||||
suites.v1_dev.optional(tlsConfig)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ object Main {
|
||||
Tests.default(timeoutScaleFactor = config.timeoutScaleFactor)
|
||||
|
||||
override def optionalTests: Vector[LedgerTestSuite] =
|
||||
Tests.optional()
|
||||
Tests.optional(config.tlsConfig)
|
||||
}
|
||||
new TestRunner(availableTests, config).runAndExit()
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ object Main {
|
||||
|
||||
val ledgerApiTests = List()
|
||||
.concat(suites.v1_14.default(timeoutScaleFactor = 0L))
|
||||
.concat(suites.v1_14.optional())
|
||||
.concat(suites.v1_14.optional(tlsConfig = None))
|
||||
|
||||
val testSuites: List[Suite] = ScalaTestAdapter.loadTestSuites(runpathList)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user