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:
Martin Huschenbett 2019-05-22 12:19:52 +02:00 committed by mergify[bot]
parent 89b9ed1e89
commit d87ba19ea2
2 changed files with 72 additions and 10 deletions

View File

@ -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) =>

View File

@ -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))"
}