festung-0.9.1.1: tests/Festung/Vault/VaultHandlerSpec.hs
{-# LANGUAGE NamedFieldPuns #-}
module Festung.Vault.VaultHandlerSpec (spec) where
import Test.Hspec
import Control.Exception (finally)
import System.FilePath ((</>))
import Festung.Vault.VaultHandler
import qualified Festung.Vault.Persistence as P
import qualified Festung.Concurrency.Job as J
import TestUtils
defaultPassword :: P.Password
defaultPassword = [0xDE, 0xAD, 0xBE, 0xEE, 0xEE, 0xEE, 0xEF]
invalidPassword :: P.Password
invalidPassword = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
-- | Create a new VaultHandler in a temporary directory
withHandler :: Int -> (VaultOpener -> Vault -> IO a) -> IO a
withHandler timeout action = withConfig timeout $ \ config@Config{dataDirectory} ->
let vaultPath = dataDirectory </> defaultVaultName
params = P.VaultParameters { P.kdfIter = Nothing }
opener = (vaultPath, defaultPassword, params)
in newHandler config opener >>= action' opener
where action' o (Left err) = fail' $ expectationFailure ("Could not open handler: " ++ show err)
action' o (Right v) = finally (action o v) (stopHandler v)
stopHandler v = return () -- TODO: Really stop the handler
fail' action = action >> fail "Failed"
withHandler_ :: (VaultOpener -> Vault -> IO a) -> IO a
withHandler_ = withHandler defaultTimeout
couldNotReach :: Show a => Either VaultError a -> Expectation
couldNotReach (Right _ ) = expectationFailure "Expected an error"
couldNotReach (Left err) = case err of
CouldNotReach -> return ()
_ -> expectationFailure "Expected CouldNotReach"
spec :: Spec
spec = do
describe "newHandler" $ do
it "Can handle many queries" $ withHandler_ $ \ opener vault -> do
let query' = query opener vault
query' "CREATE TABLE foo(bar int)"
query' "INSERT INTO foo(bar) VALUES (1), (2)"
dat <- noError =<< query' "SELECT bar AS baz FROM foo ORDER BY 1"
P.headers dat `shouldBe` [("baz", Just "int")]
P.rows dat `shouldBe` [[P.IntValue 1], [P.IntValue 2]]
dat <- noError =<< query' "SELECT * FROM foo WHERE bar < 0"
P.rows dat `shouldBe` []
it "queries don't block when stopped" $ withHandler_ $ \ opener vault -> do
J.killJob vault
couldNotReach =<< query opener vault "SELECT 1"
it "It verifies password" $ withHandler_ $ \ opener vault -> do
let (path, password, parameters) = opener
opener' = (path, invalidPassword, parameters)
query' = query opener' vault
ret <- query' "SELECT 1"
case ret of
Left CouldNotOpen -> return ()
Left _ -> expectationFailure "is not CouldNotOpen"
Right _ -> expectationFailure "is not an error"
describe "parametrizedQuery" $
it "Parametrizes the query" $ withHandler_ $ \ opener vault -> do
let query' = query opener vault
parametrizedQuery' = parametrizedQuery opener vault
query' "CREATE TABLE foo(bar int)"
parametrizedQuery' "INSERT INTO foo(bar) VALUES (?), (?)" [P.IntValue 1, P.IntValue 2]
dat <- noError =<< parametrizedQuery' "SELECT bar FROM foo WHERE bar < ?" [P.IntValue 2]
P.headers dat `shouldBe` [("bar", Just "int")]
P.rows dat `shouldBe` [[P.IntValue 1]]