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.Settings
import Database.PostgreSQL.Replicant.Types.Lsn
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"
context "Settings" $ do
describe "pgConnectionString" $ do
it "should include the password when specified" $ do
let settings
= PgSettings
{ pgUser = "foo"
, pgPassword = Just "bar"
, pgDbName = "test"
, pgHost = "hostname"
, pgPort = "5432"
, pgSlotName = "test-slot"
, pgUpdateDelay = "43"
}
pgConnectionString settings `shouldBe` "user=foo pass=bar dbname=test host=hostname port=5432 replication=database"
it "should omit the password when not specified" $ do
let settings
= PgSettings
{ pgUser = "foo"
, pgPassword = Nothing
, pgDbName = "test"
, pgHost = "hostname"
, pgPort = "5432"
, pgSlotName = "test-slot"
, pgUpdateDelay = "43"
}
pgConnectionString settings `shouldBe` "user=foo dbname=test host=hostname port=5432 replication=database"