Skip to content

Commit

Permalink
Split "convert rejection to proto models and back to expected grpc code"
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiotudone-da committed Oct 14, 2021
1 parent ebb21e6 commit 4b4861e
Showing 1 changed file with 56 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package com.daml.ledger.participant.state.kvutils

import com.daml.error.ValueSwitch

import java.time.{Duration, Instant}
import com.daml.ledger.api.DeduplicationPeriod
import com.daml.ledger.configuration.LedgerTimeModel
import com.daml.ledger.participant.state.kvutils.Conversions._
Expand Down Expand Up @@ -48,6 +46,7 @@ import org.scalatest.matchers.should.Matchers
import org.scalatest.prop.TableDrivenPropertyChecks.{Table, forAll}
import org.scalatest.wordspec.AnyWordSpec

import java.time.{Duration, Instant}
import scala.annotation.nowarn
import scala.collection.immutable.{ListMap, ListSet}
import scala.collection.mutable
Expand Down Expand Up @@ -121,110 +120,93 @@ class ConversionsSpec extends AnyWordSpec with Matchers with OptionValues {
val submitterInfo = DamlSubmitterInfo.newBuilder().build()
val now = Instant.now

"convert rejection to proto models and back to expected grpc code" in {
"convert rejection to proto models and back to expected grpc v1 code" in {
forAll(
Table[ValueSwitch[Status], Rejection, Code, Map[String, String]](
("Error Version", "Rejection", "Expected Code", "Expected Additional Details"),
Table[Rejection, Code, Map[String, String]](
("Rejection", "Expected Code", "Expected Additional Details"),
(
v1ErrorSwitch,
Rejection.ValidationFailure(Error.Package(Error.Package.Internal("ERROR", "ERROR"))),
Code.INVALID_ARGUMENT,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.InternallyInconsistentTransaction.InconsistentKeys,
Code.INVALID_ARGUMENT,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.InternallyInconsistentTransaction.DuplicateKeys,
Code.INVALID_ARGUMENT,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.ExternallyInconsistentTransaction.InconsistentContracts,
Code.ABORTED,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.ExternallyInconsistentTransaction.InconsistentKeys,
Code.ABORTED,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.ExternallyInconsistentTransaction.DuplicateKeys,
Code.ABORTED,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.MissingInputState(DamlStateKey.getDefaultInstance),
Code.ABORTED,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.InvalidParticipantState(Err.InternalError("error")),
Code.INVALID_ARGUMENT,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.InvalidParticipantState(
Err.ArchiveDecodingFailed(Ref.PackageId.assertFromString("id"), "reason")
),
Code.INVALID_ARGUMENT,
Map("package_id" -> "id"),
),
(
v1ErrorSwitch,
Rejection.InvalidParticipantState(Err.MissingDivulgedContractInstance("id")),
Code.INVALID_ARGUMENT,
Map("contract_id" -> "id"),
),
(
v1ErrorSwitch,
Rejection.RecordTimeOutOfRange(now, now),
Code.ABORTED,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.LedgerTimeOutOfRange(LedgerTimeModel.OutOfRange(now, now, now)),
Code.ABORTED,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.CausalMonotonicityViolated,
Code.ABORTED,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.SubmittingPartyNotKnownOnLedger(Ref.Party.assertFromString("party")),
Code.INVALID_ARGUMENT,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.PartiesNotKnownOnLedger(Seq.empty),
Code.INVALID_ARGUMENT,
Map.empty,
),
(
v1ErrorSwitch,
Rejection.MissingInputState(partyStateKey("party")),
Code.ABORTED,
Map("key" -> "party: \"party\"\n"),
),
(
v1ErrorSwitch,
Rejection.RecordTimeOutOfRange(Instant.EPOCH, Instant.EPOCH),
Code.ABORTED,
Map(
Expand All @@ -233,117 +215,118 @@ class ConversionsSpec extends AnyWordSpec with Matchers with OptionValues {
),
),
(
v1ErrorSwitch,
Rejection.SubmittingPartyNotKnownOnLedger(party0),
Code.INVALID_ARGUMENT,
Map("submitter_party" -> party0),
),
(
v1ErrorSwitch,
Rejection.PartiesNotKnownOnLedger(Iterable(party0, party1)),
Code.INVALID_ARGUMENT,
Map("parties" -> s"""[\"$party0\",\"$party1\"]"""),
),
)
) { (rejection, expectedCode, expectedAdditionalDetails) =>
checkErrors(
v1ErrorSwitch,
submitterInfo,
rejection,
expectedCode,
expectedAdditionalDetails,
)
}
}

"convert rejection to proto models and back to expected grpc v2 code" in {
forAll(
Table[Rejection, Code, Map[String, String]](
(
"Rejection",
"Expected Code",
"Expected Additional Details",
),
(
v2ErrorSwitch,
Rejection.ValidationFailure(Error.Package(Error.Package.Internal("ERROR", "ERROR"))),
Code.INTERNAL,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.InternallyInconsistentTransaction.InconsistentKeys,
Code.INTERNAL,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.InternallyInconsistentTransaction.DuplicateKeys,
Code.INTERNAL,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.ExternallyInconsistentTransaction.InconsistentContracts,
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.ExternallyInconsistentTransaction.InconsistentKeys,
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.ExternallyInconsistentTransaction.DuplicateKeys,
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.MissingInputState(DamlStateKey.getDefaultInstance),
Code.INTERNAL,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.InvalidParticipantState(Err.InternalError("error")),
Code.INTERNAL,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.InvalidParticipantState(
Err.ArchiveDecodingFailed(Ref.PackageId.assertFromString("id"), "reason")
),
Code.INTERNAL,
Map("package_id" -> "id"),
),
(
v2ErrorSwitch,
Rejection.InvalidParticipantState(Err.MissingDivulgedContractInstance("id")),
Code.INTERNAL,
Map("contract_id" -> "id"),
),
(
v2ErrorSwitch,
Rejection.RecordTimeOutOfRange(now, now),
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.LedgerTimeOutOfRange(LedgerTimeModel.OutOfRange(now, now, now)),
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.CausalMonotonicityViolated,
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.SubmittingPartyNotKnownOnLedger(Ref.Party.assertFromString("party")),
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.PartiesNotKnownOnLedger(Seq.empty),
Code.FAILED_PRECONDITION,
Map.empty,
),
(
v2ErrorSwitch,
Rejection.MissingInputState(partyStateKey("party")),
Code.INTERNAL,
Map("key" -> "party: \"party\"\n"),
),
(
v2ErrorSwitch,
Rejection.RecordTimeOutOfRange(Instant.EPOCH, Instant.EPOCH),
Code.FAILED_PRECONDITION,
Map(
Expand All @@ -352,32 +335,24 @@ class ConversionsSpec extends AnyWordSpec with Matchers with OptionValues {
),
),
(
v2ErrorSwitch,
Rejection.SubmittingPartyNotKnownOnLedger(party0),
Code.FAILED_PRECONDITION,
Map("submitter_party" -> party0),
),
(
v2ErrorSwitch,
Rejection.PartiesNotKnownOnLedger(Iterable(party0, party1)),
Code.FAILED_PRECONDITION,
Map("parties" -> s"""[\"$party0\",\"$party1\"]"""),
),
)
) { (errorVersionSwitch, rejection, expectedCode, expectedAdditionalDetails) =>
val encodedEntry = Conversions
.encodeTransactionRejectionEntry(
submitterInfo,
rejection,
)
.build()
val finalReason = Conversions
.decodeTransactionRejectionEntry(encodedEntry, errorVersionSwitch)
.value
finalReason.code shouldBe expectedCode.value()
finalReason.definiteAnswer shouldBe false
val actualDetails = finalReasonToDetails(finalReason)
actualDetails should contain allElementsOf (expectedAdditionalDetails)
) { (rejection, expectedCode, expectedAdditionalDetails) =>
checkErrors(
v2ErrorSwitch,
submitterInfo,
rejection,
expectedCode,
expectedAdditionalDetails,
)
}
}

Expand Down Expand Up @@ -555,6 +530,28 @@ class ConversionsSpec extends AnyWordSpec with Matchers with OptionValues {
}
}

private def checkErrors(
errorVersionSwitch: ValueSwitch[Status],
submitterInfo: DamlSubmitterInfo,
rejection: Rejection,
expectedCode: Code,
expectedAdditionalDetails: Map[String, String],
) = {
val encodedEntry = Conversions
.encodeTransactionRejectionEntry(
submitterInfo,
rejection,
)
.build()
val finalReason = Conversions
.decodeTransactionRejectionEntry(encodedEntry, errorVersionSwitch)
.value
finalReason.code shouldBe expectedCode.value()
finalReason.definiteAnswer shouldBe false
val actualDetails = finalReasonToDetails(finalReason)
actualDetails should contain allElementsOf (expectedAdditionalDetails)
}

private def newDisclosureEntry(node: NodeId, parties: List[String]) =
DisclosureEntry.newBuilder
.setNodeId(node.index.toString)
Expand Down Expand Up @@ -625,12 +622,8 @@ class ConversionsSpec extends AnyWordSpec with Matchers with OptionValues {
)
.build

private lazy val v1ErrorSwitch = new ValueSwitch[Status](enableSelfServiceErrorCodes = false) {
override def toString: String = "1"
}
private lazy val v2ErrorSwitch = new ValueSwitch[Status](enableSelfServiceErrorCodes = true) {
override def toString: String = "2"
}
private lazy val v1ErrorSwitch = new ValueSwitch[Status](enableSelfServiceErrorCodes = false)
private lazy val v2ErrorSwitch = new ValueSwitch[Status](enableSelfServiceErrorCodes = true)

private[this] val txVersion = TransactionVersion.StableVersions.max

Expand Down

0 comments on commit 4b4861e

Please sign in to comment.