Skip to content

Commit ea2208b

Browse files
committed
Add CDDL checking to Golden and Roundtrip tests (latter is disabled)
1 parent 71a6572 commit ea2208b

File tree

5 files changed

+201
-60
lines changed

5 files changed

+201
-60
lines changed

ouroboros-consensus-diffusion/test/mock-test/Test/ThreadNet/BFT.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ instance Arbitrary TestSetup where
5555
tests :: TestTree
5656
tests =
5757
testGroup "BFT" $
58-
[ roundtrip_all SimpleCodecConfig dictNestedHdr
58+
[ roundtrip_all SimpleCodecConfig dictNestedHdr Nothing
5959
, testProperty "simple convergence" $ \setup ->
6060
prop_simple_bft_convergence setup
6161
]

ouroboros-consensus/ouroboros-consensus.cabal

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ library unstable-consensus-testlib
407407
Test.Util.SOP
408408
Test.Util.SanityCheck
409409
Test.Util.Schedule
410+
Test.Util.Serialisation.CDDL
410411
Test.Util.Serialisation.Examples
411412
Test.Util.Serialisation.Golden
412413
Test.Util.Serialisation.Roundtrip
@@ -458,6 +459,7 @@ library unstable-consensus-testlib
458459
ouroboros-network-api,
459460
ouroboros-network-mock,
460461
pretty-simple,
462+
process,
461463
quickcheck-instances,
462464
quickcheck-state-machine:no-vendored-treediff ^>=0.10,
463465
quiet,
@@ -476,6 +478,7 @@ library unstable-consensus-testlib
476478
tasty-quickcheck >=0.11,
477479
tasty-rerun,
478480
template-haskell,
481+
temporary,
479482
text,
480483
time,
481484
transformers-base,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
3+
module Test.Util.Serialisation.CDDL (cddlTestCase, cddlTest, CDDLsForNodeToNode (..)) where
4+
5+
import qualified Data.ByteString as BS
6+
import qualified Data.Text as T
7+
import System.Exit
8+
import System.IO
9+
import System.IO.Temp
10+
import System.Process
11+
import Test.Tasty
12+
import Test.Tasty.HUnit
13+
14+
-- | A Tasty test case running the @cuddle@
15+
cddlTestCase :: IO BS.ByteString -> FilePath -> T.Text -> TestTree
16+
cddlTestCase cborM cddl rule =
17+
testCase "CDDL compliance" $
18+
cddlTest cborM cddl rule >>= \case
19+
Left err -> assertFailure err
20+
Right _ -> pure ()
21+
22+
-- | Test the CDDL conformance of the given bytestring
23+
cddlTest ::
24+
IO BS.ByteString ->
25+
String ->
26+
T.Text ->
27+
IO (Either String ())
28+
cddlTest cborM cddl rule =
29+
withTempFile "." "testcase.cbor" $ \fp h -> do
30+
bs <- cborM
31+
BS.hPutStr h bs
32+
hClose h
33+
(code, _out, err) <-
34+
readProcessWithExitCode "cuddle" ["validate-cbor", "-c", fp, "-r", T.unpack rule, cddl] mempty
35+
case code of
36+
ExitFailure _ -> do
37+
BS.writeFile "failing.cbor" bs
38+
pure (Left err)
39+
ExitSuccess -> pure (Right ())
40+
41+
-- | A collection of CDDL spec and the relevant rule to use
42+
data CDDLsForNodeToNode = CDDLsForNodeToNode
43+
{ blockCDDL :: (FilePath, T.Text)
44+
, headerCDDL :: (FilePath, T.Text)
45+
}

ouroboros-consensus/src/unstable-consensus-testlib/Test/Util/Serialisation/Golden.hs

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import qualified Data.ByteString.UTF8 as BS.UTF8
4747
import Data.List (nub)
4848
import qualified Data.Map.Strict as Map
4949
import Data.Proxy (Proxy (..))
50+
import qualified Data.Text as T
5051
import Data.TreeDiff
5152
import GHC.Stack (HasCallStack)
5253
import Ouroboros.Consensus.Block (CodecConfig)
@@ -81,6 +82,7 @@ import System.FilePath (takeDirectory, (</>))
8182
import Test.Cardano.Binary.TreeDiff (CBORBytes (..))
8283
import Test.Tasty
8384
import Test.Tasty.Golden.Advanced (goldenTest)
85+
import Test.Util.Serialisation.CDDL
8486
import Test.Util.Serialisation.Examples (Examples (..), Labelled)
8587
import Test.Util.Serialisation.SomeResult (SomeResult (..))
8688

@@ -99,14 +101,27 @@ goldenTestCBOR ::
99101
(a -> Encoding) ->
100102
-- | Path to the file containing the golden output
101103
FilePath ->
104+
-- | Path to the CDDL file that defines this CBOR, and the rule name
105+
Maybe (FilePath, T.Text) ->
102106
TestTree
103-
goldenTestCBOR testName example enc goldenFile =
104-
goldenTest
105-
testName
106-
(Strict.readFile goldenFile)
107-
(either exceptionToByteString id <$> try (evaluate actualValue))
108-
diff
109-
updateGoldenFile
107+
goldenTestCBOR testName example enc goldenFile mCddlPath =
108+
testGroup testName $
109+
[ goldenTest
110+
"Golden == actual"
111+
(Strict.readFile goldenFile)
112+
(either exceptionToByteString id <$> try (evaluate actualValue))
113+
diff
114+
updateGoldenFile
115+
]
116+
++ ( case mCddlPath of
117+
Nothing -> []
118+
Just (cddlPath, rule) ->
119+
[ cddlTestCase
120+
(Strict.readFile goldenFile)
121+
cddlPath
122+
rule
123+
]
124+
)
110125
where
111126
-- Copied from tasty-golden because it isn't exported
112127
updateGoldenFile :: Strict.ByteString -> IO ()
@@ -188,18 +203,19 @@ goldenTests ::
188203
(a -> Encoding) ->
189204
-- | Folder containing the golden files
190205
FilePath ->
206+
Maybe (FilePath, T.Text) ->
191207
TestTree
192-
goldenTests testName examples enc goldenFolder
208+
goldenTests testName examples enc goldenFolder mCDDL
193209
| nub labels /= labels =
194210
error $ "Examples with the same label for " <> testName
195211
| [(Nothing, example)] <- examples =
196212
-- If there's just a single unlabelled example, no need for grouping,
197213
-- which makes the output more verbose.
198-
goldenTestCBOR testName example enc (goldenFolder </> testName)
214+
goldenTestCBOR testName example enc (goldenFolder </> testName) mCDDL
199215
| otherwise =
200216
testGroup
201217
testName
202-
[ goldenTestCBOR testName' example enc (goldenFolder </> testName')
218+
[ goldenTestCBOR testName' example enc (goldenFolder </> testName') mCDDL
203219
| (mbLabel, example) <- examples
204220
, let testName' = case mbLabel of
205221
Nothing -> testName
@@ -215,18 +231,19 @@ goldenTests' ::
215231
Labelled (a, a -> Encoding) ->
216232
-- | Folder containing the golden files
217233
FilePath ->
234+
Maybe (FilePath, T.Text) ->
218235
TestTree
219-
goldenTests' testName examples goldenFolder
236+
goldenTests' testName examples goldenFolder mCDDL
220237
| nub labels /= labels =
221238
error $ "Examples with the same label for " <> testName
222239
| [(Nothing, (example, exampleEncoder))] <- examples =
223240
-- If there's just a single unlabelled example, no need for grouping,
224241
-- which makes the output more verbose.
225-
goldenTestCBOR testName example exampleEncoder (goldenFolder </> testName)
242+
goldenTestCBOR testName example exampleEncoder (goldenFolder </> testName) mCDDL
226243
| otherwise =
227244
testGroup
228245
testName
229-
[ goldenTestCBOR testName' example exampleEncoder (goldenFolder </> testName')
246+
[ goldenTestCBOR testName' example exampleEncoder (goldenFolder </> testName') mCDDL
230247
| (mbLabel, (example, exampleEncoder)) <- examples
231248
, let testName' = case mbLabel of
232249
Nothing -> testName
@@ -276,13 +293,14 @@ goldenTest_all ::
276293
-- | Path relative to the root of the repository that contains the golden
277294
-- files
278295
FilePath ->
296+
Maybe CDDLsForNodeToNode ->
279297
Examples blk ->
280298
TestTree
281-
goldenTest_all codecConfig goldenDir examples =
299+
goldenTest_all codecConfig goldenDir mCDDLs examples =
282300
testGroup
283301
"Golden tests"
284302
[ goldenTest_SerialiseDisk codecConfig goldenDir examples
285-
, goldenTest_SerialiseNodeToNode codecConfig goldenDir examples
303+
, goldenTest_SerialiseNodeToNode codecConfig goldenDir mCDDLs examples
286304
, goldenTest_SerialiseNodeToClient codecConfig goldenDir examples
287305
]
288306

@@ -316,6 +334,7 @@ goldenTest_SerialiseDisk codecConfig goldenDir Examples{..} =
316334
exampleValues
317335
enc
318336
(goldenDir </> "disk")
337+
Nothing
319338

320339
testLedgerTables :: TestTree
321340
testLedgerTables =
@@ -327,6 +346,7 @@ goldenTest_SerialiseDisk codecConfig goldenDir Examples{..} =
327346
exampleLedgerState
328347
)
329348
(goldenDir </> "disk")
349+
Nothing
330350

331351
encodeExt = encodeDiskExtLedgerState codecConfig
332352

@@ -341,9 +361,10 @@ goldenTest_SerialiseNodeToNode ::
341361
) =>
342362
CodecConfig blk ->
343363
FilePath ->
364+
Maybe CDDLsForNodeToNode ->
344365
Examples blk ->
345366
TestTree
346-
goldenTest_SerialiseNodeToNode codecConfig goldenDir Examples{..} =
367+
goldenTest_SerialiseNodeToNode codecConfig goldenDir mCDDLs Examples{..} =
347368
testGroup
348369
"SerialiseNodeToNode"
349370
[ testVersion version
@@ -354,15 +375,15 @@ goldenTest_SerialiseNodeToNode codecConfig goldenDir Examples{..} =
354375
testVersion version =
355376
testGroup
356377
(toGoldenDirectory version)
357-
[ test "Block" exampleBlock
358-
, test "Header" exampleHeader
359-
, test "SerialisedBlock" exampleSerialisedBlock
360-
, test "SerialisedHeader" exampleSerialisedHeader
361-
, test "GenTx" exampleGenTx
362-
, test "GenTxId" exampleGenTxId
378+
[ test "Block" exampleBlock $ fmap blockCDDL mCDDLs
379+
, test "Header" exampleHeader $ fmap headerCDDL mCDDLs
380+
, test "SerialisedBlock" exampleSerialisedBlock Nothing
381+
, test "SerialisedHeader" exampleSerialisedHeader Nothing
382+
, test "GenTx" exampleGenTx Nothing
383+
, test "GenTxId" exampleGenTxId Nothing
363384
]
364385
where
365-
test :: SerialiseNodeToNode blk a => TestName -> Labelled a -> TestTree
386+
test :: SerialiseNodeToNode blk a => TestName -> Labelled a -> Maybe (FilePath, T.Text) -> TestTree
366387
test testName exampleValues =
367388
goldenTests
368389
testName
@@ -421,6 +442,7 @@ goldenTest_SerialiseNodeToClient codecConfig goldenDir Examples{..} =
421442
exampleValues
422443
enc
423444
(goldenDir </> toGoldenDirectory versions)
445+
Nothing
424446

425447
testQuery name values =
426448
test name (filter (\(_, SomeBlockQuery q) -> blockQueryIsSupportedOnVersion q blockVersion) values)

0 commit comments

Comments
 (0)