import Test.Hspec
import Data.Serialize
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Data.Word
import GHC.Int
import Database.PostgreSQL.Replicant.Message
import Database.PostgreSQL.Replicant.Types.Lsn
import qualified Database.PostgreSQL.Replicant.Queue as Q
examplePrimaryKeepAliveMessage :: ByteString
examplePrimaryKeepAliveMessage
= B.concat
[ (B.pack [0x6B])
, (encode @LSN (fromInt64 123))
, (encode @LSN (fromInt64 346))
, (encode @Word8 1)
]
main :: IO ()
main = hspec $ do
context "Message" $ do
describe "PrimaryKeepAlive" $ do
it "should decode a valid primary keep alive message" $ do
(decode $ examplePrimaryKeepAliveMessage)
`shouldBe`
(Right $ PrimaryKeepAlive 123 346 ShouldRespond)
describe "StandbyStatusUpdate" $ do
it "should encode a valid standby status update message" $ do
(encode $ StandbyStatusUpdate
(fromInt64 213)
(fromInt64 232)
(fromInt64 234)
454
DoNotRespond)
`shouldBe`
B.concat
[ B.pack [0x72]
, encode @LSN (fromInt64 213)
, encode @LSN (fromInt64 232)
, encode @LSN (fromInt64 234)
, encode @Int64 454
, encode @Word8 0
]
describe "XLogData" $ do
it "should encode/decode a valid xLogData message" $ do
let msg = XLogData (fromInt64 123) (fromInt64 234) 345 (B8.pack "hello")
(decode . encode $ msg)
`shouldBe`
Right msg
describe "HotStandbyFeedback" $ do
it "should encode/decode a valid HotStandbyFeedback message" $ do
let msg = HotStandbyFeedback 123 234 456
(decode . encode $ msg)
`shouldBe`
Right msg
describe "WalCopyData" $ do
it "should encode/decode an XLogData message" $ do
let msg = XLogDataM (XLogData (fromInt64 123) (fromInt64 234) 345 (B8.pack "hello"))
(decode . encode $ msg)
`shouldBe`
Right msg
it "should encode/decode a PrimaryKeepAlive message" $ do
let msg = KeepAliveM (PrimaryKeepAlive 123 346 ShouldRespond)
(decode . encode $ msg)
`shouldBe`
Right msg
context "Types" $ do
describe "LSN" $ do
context "Serializable" $ do
it "should be serializable" $ do
let lsn = LSN 2 23
(decode . encode $ lsn) `shouldBe` Right lsn
it "should be equivalent to fromByteString/toByteString" $ do
let (Right lsn) = fromByteString "16/3002D50"
(toByteString <$> (decode . encode @LSN $ lsn)) `shouldBe` Right "16/3002d50"
describe "FifoQueue" $ do
it "should dequeue Nothing if the queue is empty" $ do
queue <- Q.empty @Int
res <- Q.dequeue queue
res `shouldBe` Nothing
it "should respect first-in, first-out" $ do
queue <- Q.empty
Q.enqueue queue 1
Q.enqueue queue 2
Q.enqueue queue 3
res <- Q.dequeue queue
res `shouldBe` Just 1
context "null" $ do
it "should return True if the queue is empty" $ do
queue <- Q.empty
res <- Q.null queue
res `shouldBe` True
it "should return False if the queue has at least one element" $ do
queue <- Q.empty
Q.enqueue queue 1
res <- Q.null queue
res `shouldBe` False
context "enqueueRight" $ do
it "should enqueue an item at the head of the queue" $ do
queue <- Q.empty
Q.enqueue queue 1
Q.enqueueRight queue 2
res <- Q.dequeue queue
res `shouldBe` Just 2