{- 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