mirror of
https://github.com/digital-asset/daml.git
synced 2024-11-10 10:46:11 +03:00
Add more tests for (un)serializable contract ids (#1296)
* Add more tests for (un)serializable contract ids I want to lift this restriction in a subsequent PR for the next version of DAML-LF. Let's first make sure we have a correct implementation for the current version though. * fix test * in serializability tests, check the modules are properly typed
This commit is contained in:
parent
89b9ed1e89
commit
d87ba19ea2
@ -6,7 +6,7 @@ package com.digitalasset.daml.lf.validation
|
||||
import com.digitalasset.daml.lf.data.ImmArray
|
||||
import com.digitalasset.daml.lf.data.Ref.{Identifier, PackageId, QualifiedName}
|
||||
import com.digitalasset.daml.lf.lfpackage.Ast._
|
||||
import com.digitalasset.daml.lf.lfpackage.Util.{TContractId, TList, TOptional, TMap}
|
||||
import com.digitalasset.daml.lf.lfpackage.Util.{TContractId, TList, TMap, TOptional}
|
||||
|
||||
private[validation] object Serializability {
|
||||
|
||||
@ -33,8 +33,12 @@ private[validation] object Serializability {
|
||||
|
||||
def checkType(typ0: Type): Unit = typ0 match {
|
||||
case TContractId(TTyCon(tCon)) =>
|
||||
lookupTemplate(ctx, tCon)
|
||||
()
|
||||
lookupDataType(ctx, tCon) match {
|
||||
case DDataType(_, _, DataRecord(_, Some(_))) =>
|
||||
()
|
||||
case _ =>
|
||||
unserializable(URContractId)
|
||||
}
|
||||
case TVar(name) =>
|
||||
if (!vars(name)) unserializable(URFreeVar(name))
|
||||
case TTyCon(tycon) =>
|
||||
|
@ -10,6 +10,8 @@ import com.digitalasset.daml.lf.testing.parser._
|
||||
import org.scalatest.prop.TableDrivenPropertyChecks
|
||||
import org.scalatest.{Matchers, WordSpec}
|
||||
|
||||
import scala.util.Try
|
||||
|
||||
class SerializabilitySpec extends WordSpec with TableDrivenPropertyChecks with Matchers {
|
||||
|
||||
"Serializability checking" should {
|
||||
@ -152,7 +154,7 @@ class SerializabilitySpec extends WordSpec with TableDrivenPropertyChecks with M
|
||||
observers Nil @Party,
|
||||
agreement "Agreement",
|
||||
choices {
|
||||
choice Ch (i : Mod:SerializableType) : Mod:SerializableType by 'Alice' to upure @Unit ()
|
||||
choice Ch (i : Mod:SerializableType) : Mod:SerializableType by $partiesAlice to upure @Mod:SerializableType (Mod:SerializableType {})
|
||||
}
|
||||
} ;
|
||||
}
|
||||
@ -167,8 +169,8 @@ class SerializabilitySpec extends WordSpec with TableDrivenPropertyChecks with M
|
||||
agreement "Agreement",
|
||||
choices {
|
||||
choice Ch (i : Mod:SerializableType) :
|
||||
Mod:SerializableType by 'Alice'
|
||||
to upure @Unit ()
|
||||
Mod:SerializableType by $partiesAlice
|
||||
to upure @Mod:SerializableType (Mod:SerializableType {})
|
||||
}
|
||||
} ;
|
||||
}
|
||||
@ -184,7 +186,7 @@ class SerializabilitySpec extends WordSpec with TableDrivenPropertyChecks with M
|
||||
agreement "Agreement",
|
||||
choices {
|
||||
choice Ch (i : Mod:UnserializableType) : // disallowed unserializable type
|
||||
Mod:SerializableType by 'Alice' to
|
||||
Unit by $partiesAlice to
|
||||
upure @Unit ()
|
||||
}
|
||||
} ;
|
||||
@ -200,8 +202,8 @@ class SerializabilitySpec extends WordSpec with TableDrivenPropertyChecks with M
|
||||
agreement "Agreement",
|
||||
choices {
|
||||
choice Ch (i : Mod:SerializableType) :
|
||||
Mod:UnserializableType by 'Alice' to // disallowed unserializable type
|
||||
upure @Unit ()
|
||||
Mod:UnserializableType by $partiesAlice to // disallowed unserializable type
|
||||
upure @Mod:UnserializableType (Mod:UnserializableType {})
|
||||
}
|
||||
} ;
|
||||
}
|
||||
@ -220,6 +222,59 @@ class SerializabilitySpec extends WordSpec with TableDrivenPropertyChecks with M
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
"reject unserializable contract id" in {
|
||||
|
||||
val pkg =
|
||||
p"""
|
||||
// well-formed module
|
||||
module NegativeTestCase1 {
|
||||
record @serializable SerializableRecord = {};
|
||||
|
||||
template (this : SerializableRecord) = {
|
||||
precondition True,
|
||||
signatories Nil @Party,
|
||||
observers Nil @Party,
|
||||
agreement "Agreement",
|
||||
choices {
|
||||
}
|
||||
} ;
|
||||
|
||||
record @serializable SerializableContractId = { cid : ContractId NegativeTestCase1:SerializableRecord };
|
||||
}
|
||||
|
||||
module NegativeTestCase2 {
|
||||
record @serializable SerializableContractId = { cid : ContractId NegativeTestCase1:SerializableRecord };
|
||||
}
|
||||
|
||||
module PositiveTestCase1 {
|
||||
record @serializable SerializableRecord = {};
|
||||
|
||||
record @serializable UnserializableContractId = { cid : ContractId PositiveTestCase1:SerializableRecord };
|
||||
}
|
||||
|
||||
module PositiveTestCase2 {
|
||||
record @serializable UnserializableContractId = { cid : ContractId Int64 };
|
||||
}
|
||||
|
||||
module PositiveTestCase3 {
|
||||
record @serializable UnserializableContractId (a : *) = { cid : ContractId a };
|
||||
}
|
||||
"""
|
||||
|
||||
val positiveTestCases = Table(
|
||||
"module",
|
||||
"PositiveTestCase1",
|
||||
"PositiveTestCase2",
|
||||
"PositiveTestCase3",
|
||||
)
|
||||
|
||||
check(pkg, "NegativeTestCase1")
|
||||
check(pkg, "NegativeTestCase2")
|
||||
forEvery(positiveTestCases) { modName =>
|
||||
an[EExpectedSerializableType] shouldBe thrownBy(check(pkg, modName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val defaultPkg =
|
||||
@ -249,11 +304,14 @@ class SerializabilitySpec extends WordSpec with TableDrivenPropertyChecks with M
|
||||
private def world(pkg: Package) =
|
||||
new World(Map(defaultPkgId -> pkg))
|
||||
|
||||
private def check(pkg: Package, modName: String) = {
|
||||
private def check(pkg: Package, modName: String): Unit = {
|
||||
val w = world(pkg)
|
||||
val longModName = DottedName.assertFromString(modName)
|
||||
val mod = w.lookupModule(NoContext, defaultPkgId, longModName)
|
||||
require(Try(Typing.checkModule(w, defaultPkgId, mod)).isSuccess)
|
||||
Serializability.checkModule(w, defaultPkgId, mod)
|
||||
}
|
||||
|
||||
private val partiesAlice = "(Cons @Party ['Alice'] (Nil @Party))"
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user