packages feed

postgresql-replicant-0.2.0.0: test/Spec.hs

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"