glean-0.1.0.0: glean/test/lib/Glean/Database/Catalog/Test.hs
{-
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.
-}
{-# LANGUAGE TypeApplications #-}
module Glean.Database.Catalog.Test
( MockStore(..)
, memStore
, withMemCatalog
, checkConsistency
) where
import Control.Exception hiding (assert)
import Control.Monad
import Data.Default
import Data.HashMap.Strict (HashMap)
import Data.List ((\\))
import Data.Proxy
import qualified Data.Text as Text
import Test.HUnit
import Util.STM
import Glean.Database.Catalog (Catalog)
import qualified Glean.Database.Catalog as Catalog
import qualified Glean.Database.Catalog.Local.Memory as Catalog
import Glean.Database.Catalog.Filter
import qualified Glean.Database.Catalog.Store as Store
import Glean.Database.Meta (Meta)
import Glean.Test.HUnit
import Glean.Test.Mock
import Glean.Types (Repo(..), UnknownDatabase(..))
data MockStore = MockStore
{ storeList :: Mock (IO (HashMap Repo Meta))
, storeCreate :: Mock (Repo -> Meta -> IO Bool)
, storeDelete :: Mock (Repo -> IO Bool)
, storePut :: Mock (Repo -> Meta -> IO Bool)
, storeGet :: Mock (Repo -> IO (Maybe Meta))
}
instance Store.Store MockStore where
list = call . storeList
create = call . storeCreate
delete = call . storeDelete
put = call . storePut
get = call . storeGet
memStore :: IO MockStore
memStore = do
cat <- Catalog.memoryCatalog
storeList <- implement "Store.list" $ Store.list cat
storeCreate <- implement "Store.create" $ Store.create cat
storeDelete <- implement "Store.delete" $ Store.delete cat
storePut <- implement "Store.put" $ Store.put cat
storeGet <- implement "Store.get" $ Store.get cat
return MockStore{..}
withMemCatalog :: (MockStore -> Catalog -> IO a) -> IO a
withMemCatalog f = do
store <- memStore
bracket (Catalog.open store) Catalog.close $ f store
checkConsistency :: Catalog -> IO ()
checkConsistency cat = do
xs <- map itemRepo <$> atomically (Catalog.list cat [Local] everythingF)
mapM_ live xs
mapM_ not_live
$ take 4
$ map (Repo "test" . Text.pack . show) [1::Int ..] \\ xs
where
live repo = do
assert $ Catalog.exists cat [Local] repo
assert $ void $ Catalog.readMeta cat repo
assert $ Catalog.writeMeta cat repo def
assert $ void $ Catalog.modifyMeta cat repo return
not_live repo = do
assert $ not <$> Catalog.exists cat [Local] repo
assertThrowsType "" (Proxy @UnknownDatabase)
$ atomically $ Catalog.readMeta cat repo
assertThrowsType "" (Proxy @UnknownDatabase)
$ atomically $ Catalog.writeMeta cat repo def
assertThrowsType "" (Proxy @UnknownDatabase)
$ atomically $ Catalog.modifyMeta cat repo return