{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE RankNTypes #-}
module Test.Consensus.Util.Versioned (tests) where
import Codec.CBOR.Read (deserialiseFromBytes)
import Codec.CBOR.Write (toLazyByteString)
import Codec.Serialise (DeserialiseFailure (..), Serialise (..))
import GHC.Generics (Generic)
import Ouroboros.Consensus.Util.Versioned
import Test.Tasty
import Test.Tasty.HUnit
tests :: TestTree
tests :: TestTree
tests = String -> [TestTree] -> TestTree
testGroup String
"Versioned"
[ String -> Assertion -> TestTree
testCase String
"version0" Assertion
test_version0
, String -> Assertion -> TestTree
testCase String
"version1" Assertion
test_version1
, String -> Assertion -> TestTree
testCase String
"version2" Assertion
test_version2
, String -> Assertion -> TestTree
testCase String
"unknown" Assertion
test_unknown
]
data Version0 = Version0
{ Version0 -> Int
field1 :: Int
}
deriving (Version0 -> Version0 -> Bool
(Version0 -> Version0 -> Bool)
-> (Version0 -> Version0 -> Bool) -> Eq Version0
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Version0 -> Version0 -> Bool
== :: Version0 -> Version0 -> Bool
$c/= :: Version0 -> Version0 -> Bool
/= :: Version0 -> Version0 -> Bool
Eq, Int -> Version0 -> ShowS
[Version0] -> ShowS
Version0 -> String
(Int -> Version0 -> ShowS)
-> (Version0 -> String) -> ([Version0] -> ShowS) -> Show Version0
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Version0 -> ShowS
showsPrec :: Int -> Version0 -> ShowS
$cshow :: Version0 -> String
show :: Version0 -> String
$cshowList :: [Version0] -> ShowS
showList :: [Version0] -> ShowS
Show, (forall x. Version0 -> Rep Version0 x)
-> (forall x. Rep Version0 x -> Version0) -> Generic Version0
forall x. Rep Version0 x -> Version0
forall x. Version0 -> Rep Version0 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Version0 -> Rep Version0 x
from :: forall x. Version0 -> Rep Version0 x
$cto :: forall x. Rep Version0 x -> Version0
to :: forall x. Rep Version0 x -> Version0
Generic, [Version0] -> Encoding
Version0 -> Encoding
(Version0 -> Encoding)
-> (forall s. Decoder s Version0)
-> ([Version0] -> Encoding)
-> (forall s. Decoder s [Version0])
-> Serialise Version0
forall s. Decoder s [Version0]
forall s. Decoder s Version0
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
$cencode :: Version0 -> Encoding
encode :: Version0 -> Encoding
$cdecode :: forall s. Decoder s Version0
decode :: forall s. Decoder s Version0
$cencodeList :: [Version0] -> Encoding
encodeList :: [Version0] -> Encoding
$cdecodeList :: forall s. Decoder s [Version0]
decodeList :: forall s. Decoder s [Version0]
Serialise)
data Version1 = Version1
{ Version1 -> Int
field1 :: Int
, Version1 -> Int
field2 :: Int
}
deriving (Version1 -> Version1 -> Bool
(Version1 -> Version1 -> Bool)
-> (Version1 -> Version1 -> Bool) -> Eq Version1
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Version1 -> Version1 -> Bool
== :: Version1 -> Version1 -> Bool
$c/= :: Version1 -> Version1 -> Bool
/= :: Version1 -> Version1 -> Bool
Eq, Int -> Version1 -> ShowS
[Version1] -> ShowS
Version1 -> String
(Int -> Version1 -> ShowS)
-> (Version1 -> String) -> ([Version1] -> ShowS) -> Show Version1
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Version1 -> ShowS
showsPrec :: Int -> Version1 -> ShowS
$cshow :: Version1 -> String
show :: Version1 -> String
$cshowList :: [Version1] -> ShowS
showList :: [Version1] -> ShowS
Show, (forall x. Version1 -> Rep Version1 x)
-> (forall x. Rep Version1 x -> Version1) -> Generic Version1
forall x. Rep Version1 x -> Version1
forall x. Version1 -> Rep Version1 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Version1 -> Rep Version1 x
from :: forall x. Version1 -> Rep Version1 x
$cto :: forall x. Rep Version1 x -> Version1
to :: forall x. Rep Version1 x -> Version1
Generic, [Version1] -> Encoding
Version1 -> Encoding
(Version1 -> Encoding)
-> (forall s. Decoder s Version1)
-> ([Version1] -> Encoding)
-> (forall s. Decoder s [Version1])
-> Serialise Version1
forall s. Decoder s [Version1]
forall s. Decoder s Version1
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
$cencode :: Version1 -> Encoding
encode :: Version1 -> Encoding
$cdecode :: forall s. Decoder s Version1
decode :: forall s. Decoder s Version1
$cencodeList :: [Version1] -> Encoding
encodeList :: [Version1] -> Encoding
$cdecodeList :: forall s. Decoder s [Version1]
decodeList :: forall s. Decoder s [Version1]
Serialise)
data Version2 = Version2
{ Version2 -> Int
field1 :: Int
, Version2 -> Int
field2 :: Int
, Version2 -> Int
field3 :: Int
}
deriving (Version2 -> Version2 -> Bool
(Version2 -> Version2 -> Bool)
-> (Version2 -> Version2 -> Bool) -> Eq Version2
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Version2 -> Version2 -> Bool
== :: Version2 -> Version2 -> Bool
$c/= :: Version2 -> Version2 -> Bool
/= :: Version2 -> Version2 -> Bool
Eq, Int -> Version2 -> ShowS
[Version2] -> ShowS
Version2 -> String
(Int -> Version2 -> ShowS)
-> (Version2 -> String) -> ([Version2] -> ShowS) -> Show Version2
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Version2 -> ShowS
showsPrec :: Int -> Version2 -> ShowS
$cshow :: Version2 -> String
show :: Version2 -> String
$cshowList :: [Version2] -> ShowS
showList :: [Version2] -> ShowS
Show, (forall x. Version2 -> Rep Version2 x)
-> (forall x. Rep Version2 x -> Version2) -> Generic Version2
forall x. Rep Version2 x -> Version2
forall x. Version2 -> Rep Version2 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Version2 -> Rep Version2 x
from :: forall x. Version2 -> Rep Version2 x
$cto :: forall x. Rep Version2 x -> Version2
to :: forall x. Rep Version2 x -> Version2
Generic, [Version2] -> Encoding
Version2 -> Encoding
(Version2 -> Encoding)
-> (forall s. Decoder s Version2)
-> ([Version2] -> Encoding)
-> (forall s. Decoder s [Version2])
-> Serialise Version2
forall s. Decoder s [Version2]
forall s. Decoder s Version2
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
$cencode :: Version2 -> Encoding
encode :: Version2 -> Encoding
$cdecode :: forall s. Decoder s Version2
decode :: forall s. Decoder s Version2
$cencodeList :: [Version2] -> Encoding
encodeList :: [Version2] -> Encoding
$cdecodeList :: forall s. Decoder s [Version2]
decodeList :: forall s. Decoder s [Version2]
Serialise)
version0 :: Version0
version0 :: Version0
version0 = Int -> Version0
Version0 Int
1
version1 :: Version1
version1 :: Version1
version1 = Int -> Int -> Version1
Version1 Int
1 Int
100
version2 :: Version2
version2 :: Version2
version2 = Int -> Int -> Int -> Version2
Version2 Int
1 Int
100 Int
101
decodeLatestVersion ::
[(VersionNumber, VersionDecoder Version2)]
decodeLatestVersion :: [(VersionNumber, VersionDecoder Version2)]
decodeLatestVersion =
[ (VersionNumber
0, String -> VersionDecoder Version2
forall a. String -> VersionDecoder a
Incompatible String
"missing field 1")
, (VersionNumber
1, VersionDecoder Version1
-> (Version1 -> Either String Version2) -> VersionDecoder Version2
forall from a.
VersionDecoder from
-> (from -> Either String a) -> VersionDecoder a
Migrate ((forall s. Decoder s Version1) -> VersionDecoder Version1
forall a. (forall s. Decoder s a) -> VersionDecoder a
Decode Decoder s Version1
forall s. Decoder s Version1
forall a s. Serialise a => Decoder s a
decode) ((Version1 -> Either String Version2) -> VersionDecoder Version2)
-> (Version1 -> Either String Version2) -> VersionDecoder Version2
forall a b. (a -> b) -> a -> b
$ \(Version1 Int
a Int
b) ->
Version2 -> Either String Version2
forall a. a -> Either String a
forall (m :: * -> *) a. Monad m => a -> m a
return (Version2 -> Either String Version2)
-> Version2 -> Either String Version2
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> Version2
Version2 Int
a Int
b (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
b))
, (VersionNumber
2, (forall s. Decoder s Version2) -> VersionDecoder Version2
forall a. (forall s. Decoder s a) -> VersionDecoder a
Decode Decoder s Version2
forall s. Decoder s Version2
forall a s. Serialise a => Decoder s a
decode)
]
test_decodeVersioned
:: Serialise a
=> [(VersionNumber, VersionDecoder b)]
-> VersionNumber
-> a
-> Either String (Versioned b)
test_decodeVersioned :: forall a b.
Serialise a =>
[(VersionNumber, VersionDecoder b)]
-> VersionNumber -> a -> Either String (Versioned b)
test_decodeVersioned [(VersionNumber, VersionDecoder b)]
decs VersionNumber
vn a
a =
case (forall s. Decoder s (Versioned b))
-> ByteString
-> Either DeserialiseFailure (ByteString, Versioned b)
forall a.
(forall s. Decoder s a)
-> ByteString -> Either DeserialiseFailure (ByteString, a)
deserialiseFromBytes
([(VersionNumber, VersionDecoder b)]
-> forall s. Decoder s (Versioned b)
forall a.
[(VersionNumber, VersionDecoder a)]
-> forall s. Decoder s (Versioned a)
decodeVersioned [(VersionNumber, VersionDecoder b)]
decs)
(Encoding -> ByteString
toLazyByteString (VersionNumber -> Encoding -> Encoding
encodeVersion VersionNumber
vn (a -> Encoding
forall a. Serialise a => a -> Encoding
encode a
a))) of
Left (DeserialiseFailure ByteOffset
_offset String
msg) -> String -> Either String (Versioned b)
forall a b. a -> Either a b
Left String
msg
Right (ByteString
_unconsumed, Versioned b
b) -> Versioned b -> Either String (Versioned b)
forall a b. b -> Either a b
Right Versioned b
b
test_version0 :: Assertion
test_version0 :: Assertion
test_version0 =
[(VersionNumber, VersionDecoder Version2)]
-> VersionNumber -> Version0 -> Either String (Versioned Version2)
forall a b.
Serialise a =>
[(VersionNumber, VersionDecoder b)]
-> VersionNumber -> a -> Either String (Versioned b)
test_decodeVersioned [(VersionNumber, VersionDecoder Version2)]
decodeLatestVersion VersionNumber
0 Version0
version0
Either String (Versioned Version2)
-> Either String (Versioned Version2) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= String -> Either String (Versioned Version2)
forall a b. a -> Either a b
Left String
"IncompatibleVersion 0 \"missing field 1\""
test_version1 :: Assertion
test_version1 :: Assertion
test_version1 =
[(VersionNumber, VersionDecoder Version2)]
-> VersionNumber -> Version1 -> Either String (Versioned Version2)
forall a b.
Serialise a =>
[(VersionNumber, VersionDecoder b)]
-> VersionNumber -> a -> Either String (Versioned b)
test_decodeVersioned [(VersionNumber, VersionDecoder Version2)]
decodeLatestVersion VersionNumber
1 Version1
version1
Either String (Versioned Version2)
-> Either String (Versioned Version2) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Versioned Version2 -> Either String (Versioned Version2)
forall a b. b -> Either a b
Right (VersionNumber -> Version2 -> Versioned Version2
forall a. VersionNumber -> a -> Versioned a
Versioned VersionNumber
1 Version2
version2)
test_version2 :: Assertion
test_version2 :: Assertion
test_version2 =
[(VersionNumber, VersionDecoder Version2)]
-> VersionNumber -> Version2 -> Either String (Versioned Version2)
forall a b.
Serialise a =>
[(VersionNumber, VersionDecoder b)]
-> VersionNumber -> a -> Either String (Versioned b)
test_decodeVersioned [(VersionNumber, VersionDecoder Version2)]
decodeLatestVersion VersionNumber
2 Version2
version2
Either String (Versioned Version2)
-> Either String (Versioned Version2) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Versioned Version2 -> Either String (Versioned Version2)
forall a b. b -> Either a b
Right (VersionNumber -> Version2 -> Versioned Version2
forall a. VersionNumber -> a -> Versioned a
Versioned VersionNumber
2 Version2
version2)
test_unknown :: Assertion
test_unknown :: Assertion
test_unknown =
[(VersionNumber, VersionDecoder Version2)]
-> VersionNumber -> Bool -> Either String (Versioned Version2)
forall a b.
Serialise a =>
[(VersionNumber, VersionDecoder b)]
-> VersionNumber -> a -> Either String (Versioned b)
test_decodeVersioned [(VersionNumber, VersionDecoder Version2)]
decodeLatestVersion VersionNumber
12 Bool
True
Either String (Versioned Version2)
-> Either String (Versioned Version2) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= String -> Either String (Versioned Version2)
forall a b. a -> Either a b
Left String
"UnknownVersion 12"