-
Notifications
You must be signed in to change notification settings - Fork 273
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5414 from unisonweb/cp/serialization-roundtrip-tests
Add ANF and MCode serialization property tests
- Loading branch information
Showing
12 changed files
with
418 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
-- | Hedgehog generators for common unison types. | ||
module Unison.Test.Gen where | ||
|
||
import Data.Text qualified as Text | ||
import Hedgehog hiding (Rec, Test, test) | ||
import Hedgehog.Gen qualified as Gen | ||
import Hedgehog.Range qualified as Range | ||
import Unison.ConstructorReference | ||
import Unison.ConstructorType qualified as CT | ||
import Unison.Hash (Hash) | ||
import Unison.Hash qualified as Hash | ||
import Unison.Prelude | ||
import Unison.Reference qualified as Reference | ||
import Unison.Referent qualified as Referent | ||
import Unison.Util.Text qualified as Unison.Text | ||
|
||
genSmallWord64 :: Gen Word64 | ||
genSmallWord64 = Gen.word64 (Range.linear 0 100) | ||
|
||
genSmallInt :: Gen Int | ||
genSmallInt = Gen.int (Range.linear 0 100) | ||
|
||
genReference :: Gen Reference.Reference | ||
genReference = | ||
Gen.choice | ||
[ Reference.ReferenceBuiltin <$> genSmallText, | ||
Reference.ReferenceDerived <$> genRefId | ||
] | ||
where | ||
genRefId :: Gen (Reference.Id' Hash) | ||
genRefId = Reference.Id <$> genHash <*> genSmallWord64 | ||
|
||
-- This can generate invalid hashes, but that's not really an issue for testing serialization. | ||
genHash :: Gen Hash | ||
genHash = Hash.fromByteString <$> Gen.bytes (Range.singleton 32) | ||
|
||
genReferent :: Gen Referent.Referent | ||
genReferent = | ||
Gen.choice | ||
[ Referent.Ref <$> genReference, | ||
Referent.Con <$> genConstructorReference <*> genConstructorType | ||
] | ||
where | ||
genConstructorType = Gen.choice [pure CT.Data, pure CT.Effect] | ||
genConstructorReference = ConstructorReference <$> genReference <*> genSmallWord64 | ||
|
||
genSmallText :: Gen Text | ||
genSmallText = Gen.text (Range.linear 2 4) Gen.alphaNum | ||
|
||
genUText :: Gen Unison.Text.Text | ||
genUText = Unison.Text.pack . Text.unpack <$> genSmallText |
118 changes: 118 additions & 0 deletions
118
unison-runtime/tests/Unison/Test/Runtime/ANF/Serialization.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
-- | Round trip tests for ANF serialization. | ||
module Unison.Test.Runtime.ANF.Serialization (Unison.Test.Runtime.ANF.Serialization.test) where | ||
|
||
import Data.Bytes.Get (runGetS) | ||
import Data.Bytes.Put (runPutS) | ||
import Data.Primitive.Array (Array) | ||
import Data.Primitive.Array qualified as Array | ||
import Data.Primitive.ByteArray (ByteArray) | ||
import Data.Primitive.ByteArray qualified as ByteArray | ||
import Data.Primitive.Types (Prim) | ||
import Data.Serialize.Get (Get) | ||
import Data.Serialize.Put (Put) | ||
import EasyTest qualified as EasyTest | ||
import Hedgehog hiding (Rec, Test, test) | ||
import Hedgehog.Gen qualified as Gen | ||
import Hedgehog.Range qualified as Range | ||
import Unison.Prelude | ||
import Unison.Runtime.ANF | ||
import Unison.Runtime.ANF.Serialize | ||
import Unison.Test.Gen | ||
import Unison.Util.Bytes qualified as Util.Bytes | ||
|
||
test :: EasyTest.Test () | ||
test = | ||
void . EasyTest.scope "anf.serialization" $ do | ||
success <- | ||
EasyTest.io $ | ||
checkParallel $ | ||
Group | ||
"roundtrip" | ||
[ ("value", valueRoundtrip) | ||
] | ||
EasyTest.expect success | ||
|
||
genUBytes :: Gen Util.Bytes.Bytes | ||
genUBytes = Util.Bytes.fromByteString <$> Gen.bytes (Range.linear 0 4) | ||
|
||
genGroupRef :: Gen GroupRef | ||
genGroupRef = GR <$> genReference <*> genSmallWord64 | ||
|
||
genUBValue :: Gen UBValue | ||
genUBValue = | ||
Gen.choice | ||
[ -- Unboxed values are no longer valid in ANF serialization. | ||
-- Left <$> genSmallWord64, | ||
Right <$> genValue | ||
] | ||
|
||
genValList :: Gen ValList | ||
genValList = Gen.list (Range.linear 0 4) genUBValue | ||
|
||
genCont :: Gen Cont | ||
genCont = do | ||
Gen.choice | ||
[ pure KE, | ||
Mark <$> genSmallWord64 <*> Gen.list (Range.linear 0 4) genReference <*> Gen.map (Range.linear 0 4) ((,) <$> genReference <*> genValue) <*> genCont, | ||
Push <$> genSmallWord64 <*> genSmallWord64 <*> genGroupRef <*> genCont | ||
] | ||
|
||
genArray :: Range Int -> Gen a -> Gen (Array a) | ||
genArray range gen = | ||
Array.arrayFromList <$> Gen.list range gen | ||
|
||
genByteArray :: (Prim p) => Gen p -> Gen ByteArray | ||
genByteArray genP = do | ||
ByteArray.byteArrayFromList <$> Gen.list (Range.linear 0 20) genP | ||
|
||
genBLit :: Gen BLit | ||
genBLit = | ||
Gen.choice | ||
[ Text <$> genUText, | ||
List <$> Gen.seq (Range.linear 0 4) genValue, | ||
TmLink <$> genReferent, | ||
TyLink <$> genReference, | ||
Bytes <$> genUBytes, | ||
Quote <$> genValue, | ||
-- Code is not yet included, generating valid ANF terms is complex. | ||
-- , Code <$> genCode | ||
BArr <$> genByteArray genSmallWord64, | ||
Pos <$> genSmallWord64, | ||
Neg <$> genSmallWord64, | ||
Char <$> Gen.unicode, | ||
Float <$> Gen.double (Range.linearFrac 0 100), | ||
Arr <$> genArray (Range.linear 0 4) genValue | ||
] | ||
|
||
genValue :: Gen Value | ||
genValue = Gen.sized \n -> do | ||
-- Limit amount of recursion to avoid infinitely deep values | ||
let gValList | ||
| n > 1 = Gen.small genValList | ||
| otherwise = pure [] | ||
Gen.choice | ||
[ Partial <$> genGroupRef <*> gValList, | ||
Data <$> genReference <*> genSmallWord64 <*> gValList, | ||
Cont <$> gValList <*> genCont, | ||
BLit <$> genBLit | ||
] | ||
|
||
valueRoundtrip :: Property | ||
valueRoundtrip = | ||
getPutRoundtrip getValue putValue genValue | ||
|
||
getPutRoundtrip :: (Eq a, Show a) => (Version -> Get a) -> (Version -> a -> Put) -> Gen a -> Property | ||
getPutRoundtrip get put builder = | ||
property $ do | ||
v <- forAll builder | ||
version <- forAll versionToTest | ||
let bytes = runPutS (put version v) | ||
runGetS (get version) bytes === Right v | ||
where | ||
versionToTest = do | ||
Gen.choice | ||
[ Transfer <$> Gen.enum 4 valueVersion, | ||
Hash <$> Gen.enum 4 valueVersion | ||
] |
Oops, something went wrong.