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