Skip to content

Commit

Permalink
[fwd port] Check that controller/observer exceptions are not catchabl…
Browse files Browse the repository at this point in the history
…e in dynamic choice exercises (#20124)

* Check that controller/observer exceptions are not catchable in dynamic choice exercises (#19999)

* also test choice controllers and observers

* Check that controller/observer exceptions are not catchable in dynamic choice exercises

* fix compilation
  • Loading branch information
paulbrauner-da authored Oct 18, 2024
1 parent 44089af commit 6c393cb
Showing 1 changed file with 92 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,17 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
p"""metadata ( '-common-defs-' : '1.0.0' )
module Mod {
record @serializable MyUnit = {};
interface (this : Iface) = { viewtype Mod:MyUnit; };
interface (this : Iface) = {
viewtype Mod:MyUnit;

method myChoiceControllers : List Party;
method myChoiceObservers : List Party;

choice @nonConsuming MyChoice (self) (u: Unit): Text
, controllers (call_method @Mod:Iface myChoiceControllers this)
, observers (call_method @Mod:Iface myChoiceObservers this)
to upure @Text "MyChoice was called";
};

record @serializable Key = { label: Text, maintainers: List Party };

Expand Down Expand Up @@ -827,6 +837,8 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
| label = "test-key",
| maintainers = (Cons @Party [Mod:${templateName} {p} this] (Nil @Party))
| }""".stripMargin
def choiceControllers = s"""Cons @Party [Mod:${templateName} {p} this] (Nil @Party)"""
def choiceObservers = """Nil @Party"""

def maintainers =
s"""\\(key: '$commonDefsPkgId':Mod:Key) -> ('$commonDefsPkgId':Mod:Key {maintainers} key)"""
Expand All @@ -844,7 +856,11 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
| , observers (Nil @Party)
| to upure @Text "SomeChoice was called";
|
| implements '$commonDefsPkgId':Mod:Iface { view = '$commonDefsPkgId':Mod:MyUnit {}; };
| implements '$commonDefsPkgId':Mod:Iface {
| view = '$commonDefsPkgId':Mod:MyUnit {};
| method myChoiceControllers = $choiceControllers;
| method myChoiceObservers = $choiceObservers;
| };
|
| key @'$commonDefsPkgId':Mod:Key ($key) ($maintainers);
| };""".stripMargin
Expand Down Expand Up @@ -873,6 +889,14 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
override def maintainers =
s"""throw @('$commonDefsPkgId':Mod:Key -> List Party) @'$commonDefsPkgId':Mod:Ex ('$commonDefsPkgId':Mod:Ex {message = "Maintainers"})"""
}
case object FailingChoiceControllers extends TemplateGenerator("ChoiceControllers") {
override def choiceControllers =
s"""throw @(List Party) @'$commonDefsPkgId':Mod:Ex ('$commonDefsPkgId':Mod:Ex {message = "ChoiceControllers"})"""
}
case object FailingChoiceObservers extends TemplateGenerator("ChoiceObservers") {
override def choiceObservers =
s"""throw @(List Party) @'$commonDefsPkgId':Mod:Ex ('$commonDefsPkgId':Mod:Ex {message = "ChoiceObservers"})"""
}

val templateDefsPkgName = Ref.PackageName.assertFromString("-template-defs-")

Expand All @@ -889,6 +913,8 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
${ValidMetadata("Observers").templateDefinition}
${ValidMetadata("Key").templateDefinition}
${ValidMetadata("Maintainers").templateDefinition}
${ValidMetadata("ChoiceControllers").templateDefinition}
${ValidMetadata("ChoiceObservers").templateDefinition}
}
""" (templateDefsV1ParserParams)

Expand All @@ -907,6 +933,8 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
${FailingObservers.templateDefinition}
${FailingKey.templateDefinition}
${FailingMaintainers.templateDefinition}
${FailingChoiceControllers.templateDefinition}
${FailingChoiceObservers.templateDefinition}
}
""" (templateDefsV2ParserParams)

Expand Down Expand Up @@ -982,6 +1010,19 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
|""".stripMargin
}

def dynamicChoiceTests(templateName: String): String = {
s"""
| // Tries to catch the error thrown by the dynamic exercise of a $templateName choice when fetching it
| // by interface, should fail to do so.
| val exercise${templateName}ByInterfaceAndCatchError: (ContractId '$commonDefsPkgId':Mod:Iface) -> Update Text =
| \\(cid: ContractId '$commonDefsPkgId':Mod:Iface) ->
| try @Text
| exercise_interface @'$commonDefsPkgId':Mod:Iface MyChoice cid ()
| catch
| e -> Some @(Update Text) (upure @Text "unexpected: some exception was caught");
""".stripMargin
}

val metadataTestsPkgId = Ref.PackageId.assertFromString("-metadata-tests-id-")
val metadataTestsParserParams = parserParameters.copy(defaultPackageId = metadataTestsPkgId)
val metadataTestsPkg =
Expand All @@ -992,6 +1033,8 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
${tests(templateDefsV2PkgId, "Observers")}
${tests(templateDefsV2PkgId, "Key")}
${tests(templateDefsV2PkgId, "Maintainers")}
${dynamicChoiceTests("ChoiceControllers")}
${dynamicChoiceTests("ChoiceObservers")}
}
""" (metadataTestsParserParams)

Expand Down Expand Up @@ -1113,5 +1156,52 @@ class ExceptionTest(majorLanguageVersion: LanguageMajorVersion)
}
}
}

for {
test <- List(
FailingChoiceControllers,
FailingChoiceObservers,
)
} {

s"exceptions thrown by ${test.templateName} cannot be caught when exercising a choice by interface" in {
val alice = Ref.Party.assertFromString("Alice")
val cid = Value.ContractId.V1(crypto.Hash.hashPrivateKey("abc"))

inside {
runUpdateApp(
compiledPackages,
packageResolution = Map(
templateDefsPkgName -> templateDefsV2PkgId
),
e"Mod:exercise${test.templateName}ByInterfaceAndCatchError" (metadataTestsParserParams),
Array(SContractId(cid)),
getContract = Map(
cid -> Versioned(
version = TransactionVersion.StableVersions.max,
Value.ContractInstance(
packageName = metadataTestsPkg.pkgName,
template = t"Mod:${test.templateName}" (templateDefsV1ParserParams)
.asInstanceOf[Ast.TTyCon]
.tycon,
arg = Value.ValueRecord(None, ImmArray(None -> Value.ValueParty(alice))),
),
)
),
getKey = PartialFunction.empty,
)
} {
case Left(
SError.SErrorDamlException(
IE.UnhandledException(
_,
Value.ValueRecord(_, ImmArray((_, Value.ValueText(msg)))),
)
)
) =>
msg shouldBe test.templateName
}
}
}
}
}

0 comments on commit 6c393cb

Please sign in to comment.