Skip to content

Commit

Permalink
Migrate Daml3ScriptTrySubmit test to also run on 1.15
Browse files Browse the repository at this point in the history
  • Loading branch information
samuel-williams-da committed Nov 4, 2024
1 parent 1ddabb5 commit 2300e87
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 0 deletions.
12 changes: 12 additions & 0 deletions sdk/daml-script/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ da_scala_library(
],
)

daml_compile(
name = "try-submit-test-1.15",
srcs = [":daml/Daml3ScriptTrySubmit15.daml"],
dependencies = [
"//daml-script/daml3:daml3-script-1.15.dar",
],
project_name = "try-submit-test",
target = "1.15",
version = "1.0.0",
)

daml_compile(
name = "upgrade-test-lib",
srcs = [":daml/UpgradeTestLib.daml"],
Expand Down Expand Up @@ -260,6 +271,7 @@ da_scala_test_suite(
data = [
":script-test.dar",
":script-test-no-ledger.dar",
":try-submit-test-1.15.dar",
"//daml-script/runner:daml-script-binary",
"//daml-script/test:retrointerface.dar",
"//daml-script/test:template.dar",
Expand Down
203 changes: 203 additions & 0 deletions sdk/daml-script/test/daml/Daml3ScriptTrySubmit15.daml
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
-- Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0

{-# LANGUAGE ApplicativeDo #-}

module Daml3ScriptTrySubmit15 where

import Daml.Script
import Daml.Script.Internal
import DA.Assert
import DA.Exception
import DA.Text

template T1 with
t1_p : Party
where
signatory t1_p

key t1_p : Party
maintainer key

template T2 with
t2_p : Party
moreThan3 : Int
where
signatory t2_p
ensure moreThan3 > 3

template T3 with
t3_p : Party
ms : [Party]
where
signatory t3_p

key (t3_p, ms) : (Party, [Party])
maintainer key._2

template FetchByKeyT3 with
fetcher : Party
fetchKey : (Party, [Party])
where
signatory fetcher

choice DoFetch : (ContractId T3, T3)
controller fetcher
do fetchByKey @T3 fetchKey

template T4 with
t4_p : Party
keyParties : [Party]
where
signatory t4_p

key (t4_p, keyParties) : (Party, [Party])
maintainer key._1

-- ContractNotFound: Cannot test contract not found with IDELedger, no way to get an invalid contract ID

contractKeyNotFound : Script ()
contractKeyNotFound = script do
alice <- allocateParty "alice"
res <- alice `trySubmit` exerciseByKeyCmd @T1 alice Archive
case res of
Left (ContractKeyNotFound (fromAnyContractKey @T1 -> Some shouldBeAlice)) -> shouldBeAlice === alice
Left e -> error $ "contractKeyNotFound incorrect error: " <> show e
Right _ -> error "contractKeyNotFound incorrectly succeeded"

authorizationError : Script ()
authorizationError = script do
alice <- allocateParty "alice"
bob <- allocateParty "bob"
res <- alice `trySubmit` createCmd T1 with t1_p = bob
case res of
Left (AuthorizationError err) ->
assert $ ("requires authorizers " <> partyToText bob <> ", but only " <> partyToText alice <> " were given") `isInfixOf` err
Left e -> error $ "authorizationError incorrect error: " <> show e
Right _ -> error "authorizationError incorrectly succeeded"

contractNotActive : Script ()
contractNotActive = script do
alice <- allocateParty "alice"
cid <- alice `submit` createCmd T1 with t1_p = alice
res <- alice `trySubmit` do
exerciseCmd cid Archive
exerciseCmd cid Archive
pure ()
case res of
Left e@(ContractNotFound _ mbAdditionalInfo) ->

case mbAdditionalInfo of
None -> error "contractNotActive no additional info"
Some additionalInfo ->
case isNotActive additionalInfo of
None -> error "contractNotActive additional info is not NotActive variant"
Some anyCid ->
case fromAnyContractId @T1 anyCid of
None -> error $ "contractNotActive cannot find contract with id: " <> show e
Some shouldBeCid -> shouldBeCid === cid
Left e -> error $ "contractNotActive incorrect error: " <> show e
Right _ -> error "contractNotActive incorrectly succeeded"

-- TODO[SW] Behaviour between Canton and IDE Ledger here is different - canton will give a NotFound, whereas IDE gives a NotActive.
-- Changes to IDE needed to match canton behavior, alongside restructing of NotFound to provide more IDE context.
-- As such, we don't run this test yet

-- contractNotActiveSeparate : Script ()
-- contractNotActiveSeparate = script do
-- alice <- allocateParty "alice"
-- cid <- alice `submit` createCmd T1 with t1_p = alice
-- alice `submit` exerciseCmd cid Archive
-- res <- alice `trySubmit` exerciseCmd cid Archive
-- case res of
-- Left (ContractNotActive (fromAnyContractId @T1 -> Some shouldBeCid)) -> shouldBeCid === cid
-- Left e -> error $ "contractNotActive incorrect error: " <> show e
-- Right _ -> error "contractNotActive incorrectly succeeded"

-- DisclosedContractKeyHashingError: Cannot test DisclosedContractKeyHashingError yet, scripts does not support this functionality

duplicateContractKey : Script ()
duplicateContractKey = script do
alice <- allocateParty "alice"
alice `submit` createCmd T1 with t1_p = alice
res <- alice `trySubmit` createCmd T1 with t1_p = alice
case res of
Left (DuplicateContractKey (Some (fromAnyContractKey @T1 -> Some shouldBeAlice))) -> shouldBeAlice === alice
-- Key is often not provided when using canton
Left (DuplicateContractKey None) -> pure ()
Left e -> error $ "duplicateContractKey incorrect error: " <> show e
Right _ -> error "duplicateContractKey incorrectly succeeded"

-- InconsistentContractKey: I don't know how to trigger an InconsistentContractKey error

unhandledException : Script ()
unhandledException = script do
alice <- allocateParty "alice"
res <- alice `trySubmit` createCmd T2 with t2_p = alice, moreThan3 = 2
case res of
Left (UnhandledException (Some (fromAnyException @PreconditionFailed -> Some pfError))) -> assert $ "Template precondition violated" `isInfixOf` pfError.message
Left e -> error $ "unhandledException incorrect error: " <> show e
Right _ -> error "unhandledException incorrectly succeeded"

-- UserError: Only throwable pre LF 1.14, which daml3-script doesn't support. Consider dropping the error
-- but keep in mind that daml3-script may be usable against a ledger running older contracts, so it might be possible
-- TODO: verify this

-- TemplatePreconditionViolated: Same as above

createEmptyContractKeyMaintainers : Script ()
createEmptyContractKeyMaintainers = script do
alice <- allocateParty "alice"
let t3 = T3 with t3_p = alice, ms = []
res <- alice `trySubmit` createCmd t3
case res of
Left (CreateEmptyContractKeyMaintainers (fromAnyTemplate @T3 -> Some shouldBeT3)) -> shouldBeT3 === t3
Left e -> error $ "createEmptyContractKeyMaintainers incorrect error: " <> show e
Right _ -> error "createEmptyContractKeyMaintainers incorrectly succeeded"

fetchEmptyContractKeyMaintainers : Script ()
fetchEmptyContractKeyMaintainers = script do
alice <- allocateParty "alice"
let t3Key = (alice, [])
res <- alice `trySubmit` createAndExerciseCmd (FetchByKeyT3 with fetcher = alice, fetchKey = t3Key) DoFetch
case res of
Left (FetchEmptyContractKeyMaintainers (fromAnyContractKey @T3 -> Some shouldBeT3Key)) -> shouldBeT3Key === t3Key
Left e -> error $ "fetchEmptyContractKeyMaintainers incorrect error: " <> show e
Right _ -> error "fetchEmptyContractKeyMaintainers incorrectly succeeded"

wronglyTypedContract : Script ()
wronglyTypedContract = script do
alice <- allocateParty "alice"
t1Cid <- alice `submit` createCmd T1 with t1_p = alice
let t2Cid = coerceContractId @T1 @T2 t1Cid
res <- alice `trySubmit` exerciseCmd t2Cid Archive
case res of
Left (WronglyTypedContract (fromAnyContractId @T1 -> Some shouldBeT1Cid) expectedTypeRep actualTypeRep) -> do
shouldBeT1Cid === t1Cid
expectedTypeRep === templateTypeRep @T2
actualTypeRep === templateTypeRep @T1
Left e -> error $ "wronglyTypedContract incorrect error: " <> show e
Right _ -> error "wronglyTypedContract incorrectly succeeded"

-- ContractDoesNotImplementInterface: Can't do this from daml-script with IDELedger
-- ContractDoesNotImplementRequiringInterface: Can't do this from daml-script with IDELedger
-- NonComparableValues: Can't do this from daml-script with IDELedger
-- ContractIdInContractKey: Can't do this from daml-script with IDELedger
-- ContractIdComparability: Can't do this from daml-script with IDELedger

-- UnknownError: Shouldn't be testable, we should know all the possible errors.
-- Can reproduce right now with a timeout, or package vetting test.

-- Using contractKeyNotFound with an enormous key
truncatedError : Script ()
truncatedError = script do
alice <- allocateParty "alice"
let t4Key = (alice, replicate 10000 alice)
res <- alice `trySubmit` exerciseByKeyCmd @T4 t4Key Archive
case res of
-- We specifically throw a fixed string to be caught by the real Ledger tests
Left (TruncatedError "ContractKeyNotFound" _) -> error "EXPECTED_TRUNCATED_ERROR"
-- We silently accept this case for the IDE Ledger
Left (ContractKeyNotFound (fromAnyContractKey @T4 -> Some shouldBeT4Key)) | shouldBeT4Key == t4Key -> pure ()
Left e -> error $ "contractKeyNotFound incorrect error: " <> show e
Right _ -> error "contractKeyNotFound incorrectly succeeded"
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.lf.engine.script

import com.daml.bazeltools.BazelRunfiles
import org.scalatest.Suite

import java.nio.file.Paths

class Daml3ScriptTestRunner extends DamlScriptTestRunner {
self: Suite =>

val trySubmitTestDarPath =
Paths.get(BazelRunfiles.rlocation("daml-script/test/try-submit-test-1.15.dar"))

override lazy val darFiles = List(trySubmitTestDarPath)

val expectedContractNotActiveResponse =
"""FAILURE (com.daml.lf.engine.free.InterpretationError: Error: Unhandled Daml exception: DA.Exception.GeneralError:GeneralError@XXXXXXXX{ message = "contractNotActive no additional info" })"""

"daml-script command line" should {
"pick up all scripts and returns somewhat sensible outputs for daml3-script features" in
assertDamlScriptRunnerResult(
trySubmitTestDarPath,
f"""Daml3ScriptTrySubmit15:authorizationError SUCCESS
|Daml3ScriptTrySubmit15:contractKeyNotFound SUCCESS
|Daml3ScriptTrySubmit15:contractNotActive ${expectedContractNotActiveResponse}
|Daml3ScriptTrySubmit15:createEmptyContractKeyMaintainers SUCCESS
|Daml3ScriptTrySubmit15:duplicateContractKey SUCCESS
|Daml3ScriptTrySubmit15:fetchEmptyContractKeyMaintainers SUCCESS
|Daml3ScriptTrySubmit15:truncatedError FAILURE (com.daml.lf.engine.free.InterpretationError: Error: Unhandled Daml exception: DA.Exception.GeneralError:GeneralError@XXXXXXXX{ message = "EXPECTED_TRUNCATED_ERROR" })
|Daml3ScriptTrySubmit15:unhandledException SUCCESS
|Daml3ScriptTrySubmit15:wronglyTypedContract SUCCESS
|""".stripMargin,
)

}
}

0 comments on commit 2300e87

Please sign in to comment.