tmp-postgres 1.13.0.0 → 1.13.1.0
raw patch · 6 files changed
+118/−67 lines, 6 files
Files
- CHANGELOG.md +16/−12
- benchmark/Main.hs +7/−7
- src/Database/Postgres/Temp/Internal/Config.hs +16/−0
- src/Database/Postgres/Temp/Internal/Core.hs +4/−7
- test/Spec.hs +74/−40
- tmp-postgres.cabal +1/−1
CHANGELOG.md view
@@ -1,7 +1,7 @@ Changelog for tmp-postgres 1.7.1.0- #35 Add Lenses for configuration+ #35 Add Lenses for configuration. 1.8.0.0 Get rid of `Partial` prefix. Add a `Complete` prefix to the internal configuration types.@@ -10,31 +10,35 @@ Order the Event type creation time. 1.9.0.0- #41 Configurable temporary directory- #59 Change EnvVars to EnvironmentVariables+ #41 Configurable temporary directory.+ #59 Change EnvVars to EnvironmentVariables. 1.9.0.1- Documentation fixes+ Documentation fixes. 1.9.0.2- Documentation fixes+ Documentation fixes. 1.10.0.0- #58 Add connection timeout- Rename partialPlanLoggerL to loggerL- Add temporaryDirectoryL- #31 A silent defaults- #20 Include stderr in errors+ #58 Add connection timeout.+ Rename partialPlanLoggerL to loggerL.+ Add temporaryDirectoryL.+ #31 A silent defaults.+ #20 Include stderr in errors. 1.11.0.0 #90 Extend generated config to provide default Handles and connection timeout. #81 Create public Config module for better documentation organization. 1.12.0.0- #64 Add the 'withNewDB' and 'withNewDBConfig' functions+ #64 Add the 'withNewDB' and 'withNewDBConfig' functions. 1.12.0.1 Documentation fixes 1.13.0.0- #108 'startNewDBConfig' functions added and related+ #108 'startNewDBConfig' functions added and related.++1.13.1.0+ #113 Faster shutdown using SIGQUIT and removed manual session termination.+ #115 Add password support to optionsToDefaultConfig
benchmark/Main.hs view
@@ -43,11 +43,11 @@ [ --bench "with" $ whnfIO $ with $ const $ pure () --, bench "withConfig no --no-sync" $ whnfIO $ -- withConfig defaultConfigDefaultInitDb $ const $ pure ()- --, bench "withConfig silent" $ whnfIO $- -- withConfig silentConfig $ const $ pure ()- bench "with migrate 10x" $ whnfIO $ replicateM 10 $ with $ \db ->- migrateDb db >> testQuery db- , bench "withNewDb migrate 10x" $ whnfIO $ with $ \db -> do- migrateDb db- replicateM 10 $ withNewDb db testQuery+ bench "withConfig silent" $ whnfIO $+ withConfig silentConfig $ const $ pure ()+ -- bench "with migrate 10x" $ whnfIO $ replicateM 10 $ withConfig silent $ \db ->+ -- migrateDb db >> testQuery db+ --, bench "withNewDb migrate 10x" $ whnfIO $ withConfig silent $ \db -> do+ -- migrateDb db+ -- replicateM 10 $ withNewDb db testQuery ]
src/Database/Postgres/Temp/Internal/Config.hs view
@@ -732,6 +732,7 @@ optionsToPlan opts@Client.Options {..} = maybe mempty dbnameToPlan (getLast dbname) <> maybe mempty userToPlan (getLast user)+ <> maybe mempty passwordToPlan (getLast password) <> clientOptionsToPlan opts -- Wrap the 'Client.Options' in an appropiate@@ -765,6 +766,21 @@ { createDbConfig = pure $ mempty { commandLine = mempty { indexBased = Map.singleton 0 dbName+ }+ }+ }++-- Adds the 'PGPASSWORD' to both @initdb@ and @createdb@+passwordToPlan :: String -> Plan+passwordToPlan password = mempty+ { initDbConfig = pure mempty+ { environmentVariables = mempty+ { specific = Map.singleton "PGPASSWORD" password+ }+ }+ , createDbConfig = pure mempty+ { environmentVariables = mempty+ { specific = Map.singleton "PGPASSWORD" password } } }
src/Database/Postgres/Temp/Internal/Core.hs view
@@ -20,7 +20,7 @@ import qualified Database.PostgreSQL.Simple.Options as Client import System.Exit (ExitCode(..)) import System.IO-import System.Posix.Signals (sigINT, signalProcess)+import System.Posix.Signals (sigQUIT, signalProcess) import System.Process import System.Process.Internals import System.Timeout@@ -244,12 +244,9 @@ stopPostgresProcess :: PostgresProcess -> IO ExitCode stopPostgresProcess PostgresProcess{..} = do withProcessHandle postgresProcessHandle $ \case- OpenHandle p -> do- -- try to terminate the connects first. If we can't terminate still- -- keep shutting down- terminateConnections postgresProcessClientOptions-- signalProcess sigINT p+ OpenHandle p ->+ -- Call for "Immediate shutdown"+ signalProcess sigQUIT p OpenExtHandle {} -> pure () -- TODO log windows is not supported ClosedHandle _ -> return ()
test/Spec.hs view
@@ -24,10 +24,11 @@ main :: IO () main = hspec spec --- check coverage--- Test using an existing domain socket+withConfig' :: Config -> (DB -> IO a) -> IO a+withConfig' config = either throwIO pure <=< withConfig config --- Cleanup+with' :: (DB -> IO a) -> IO a+with' = either throwIO pure <=< with fromCreateDb :: Maybe ProcessConfig -> Config fromCreateDb createDb = mempty@@ -41,6 +42,10 @@ withRunner :: (DB -> IO ()) -> Runner -> IO () withRunner g (Runner f) = f g +--+-- TODO this test should only use the public interface+--+ defaultConfigShouldMatchDefaultPlan :: SpecWith Runner defaultConfigShouldMatchDefaultPlan = it "default options should match default plan" $ withRunner $ \DB{..} -> do@@ -62,6 +67,7 @@ } ) + customConfigWork :: (Config -> (DB -> IO ()) -> IO ()) -> Spec customConfigWork action = do let expectedDbName = "thedb"@@ -70,6 +76,10 @@ expectedDuration = "100ms" extraConfig = "log_min_duration_statement='" <> expectedDuration <> "'" +--+-- This is basically the optionsToDefaultConfig but also tests custom postgresql.conf values+--+ it "returns the right client options for the plan" $ withTempDirectory "/tmp" "tmp-postgres-spec" $ \tmpDir -> do let customPlan = mempty { temporaryDirectory = pure tmpDir@@ -211,18 +221,6 @@ { socketClass = IpSocket $ pure "localhost" } - describe "start" $ do- let startAction = bracket (either throwIO pure =<< start) stop (const $ pure ())- throwsIfInitDbIsNotOnThePath startAction- describe "startConfig" $ do- let startAction plan = bracket (either throwIO pure =<< startConfig plan) stop pure- throwsIfInitDbIsNotOnThePath $ startAction silentConfig- invalidConfigFailsQuickly $ void . startAction- customConfigWork $ \config@Config{..} f ->- bracket (either throwIO pure =<< startConfig config) stop f- describe "with" $ do- let startAction = either throwIO pure =<< with (const $ pure ())- throwsIfInitDbIsNotOnThePath startAction describe "withConfig" $ do let startAction plan = either throwIO pure =<< withConfig plan pure@@ -237,25 +235,19 @@ withInitDbEmptyInitially createDbCreatesTheDb dbName - describe "restart" $ do- let startAction f =- bracket (either throwIO pure- =<< restart- =<< either throwIO pure- =<< start) stop f- before (pure $ Runner startAction) $ do- someStandardTests "postgres"- defaultConfigShouldMatchDefaultPlan- describe "withRestart" $ do- let startAction f = bracket (either throwIO pure =<< start) stop $ \db ->+ let startAction f = with' $ \db -> either throwIO pure =<< withRestart db f before (pure $ Runner startAction) $ do someStandardTests "postgres" defaultConfigShouldMatchDefaultPlan +--+-- TODO these can be combined+--+ describe "start/stop" $ do- before (pure $ Runner $ \f -> bracket (either throwIO pure =<< start) stop f) $ do+ before (pure $ Runner with') $ do someStandardTests "postgres" defaultConfigShouldMatchDefaultPlan it "stopPostgres cannot be connected to" $ withRunner $ \db -> do@@ -275,6 +267,9 @@ [PG.Only actualDuration] <- PG.query_ conn "SHOW log_min_duration_statement" actualDuration `shouldBe` expectedDuration +--+-- Keep this test. Invalid createdb options test+-- let invalidCreateDbPlan = silentConfig <> fromCreateDb ( pure $ silentProcessConfig { commandLine = mempty@@ -283,9 +278,13 @@ } } )- before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig invalidCreateDbPlan) stop f) $+ before (pure $ Runner $ either throwIO pure <=< withConfig invalidCreateDbPlan) $ createDbThrowsIfTheDbExists +-- TODO+-- combine this test with another plan+-- tests that the dbName can be specified in the options+-- let noCreateTemplate1 = mempty { plan = mempty { createDbConfig = Nothing@@ -297,16 +296,27 @@ } } noCreateDbPlan = defaultConfig <> noCreateTemplate1- before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig noCreateDbPlan) stop f) $+ before (pure $ Runner $ withConfig' noCreateDbPlan) $ someStandardTests "template1" - before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig defaultIpPlan) stop f) $+--+-- Test the default IpSocket plan. Can be combined.+--+ before (pure $ Runner $ withConfig' defaultIpPlan) $ someStandardTests "postgres" - before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig specificHostIpPlan) stop f) $+-- Specific IpSocket plan+-- Can be combined+--+ before (pure $ Runner $ withConfig' specificHostIpPlan) $ someStandardTests "postgres" - before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig silentConfig) stop f) $+--+-- This test is okay but can be combine with other tests+-- and should use withNewDbConf mempty instead+-- also need to test that I can make a specific database name++ before (pure $ Runner $ withConfig' silentConfig) $ it "withNewDb works" $ withRunner $ \db -> do bracket (PG.connectPostgreSQL $ toConnectionString db ) PG.close $ \conn -> do@@ -320,34 +330,54 @@ one `shouldBe` (1 :: Int) +--+-- This is a optionsToDefaultConfig test+-- It is missing the host options of both+-- a socket and ip address based+-- thePort <- runIO getFreePort let planFromCustomUserDbConnection = optionsToDefaultConfig mempty- { Client.dbname = pure "fancy"- , Client.user = pure "some_user"- , Client.port = pure thePort+ { Client.dbname = pure "fancy"+ , Client.user = pure "some_user"+ , Client.port = pure thePort+ , Client.password = pure "password"+ , Client.host = pure "localhost" } - before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig planFromCustomUserDbConnection) stop f) $+ before (pure $ Runner $ withConfig' planFromCustomUserDbConnection) $ someStandardTests "fancy" +--+-- end optionsToDefaultConfig test+--++--+-- Keep this test -- small connection timeout works+-- let immediantlyTimeout = silentConfig <> mempty { plan = mempty { connectionTimeout = pure 0 } } - before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig immediantlyTimeout) stop f) $+ before (pure $ Runner $ withConfig' immediantlyTimeout) $ it "should timeout" $ \(Runner runner) -> runner (const $ pure ()) `shouldThrow` (== ConnectionTimedOut)+--+-- End this test+-- +--+-- Keep these tests+-- before (createTempDirectory "/tmp" "tmp-postgres-test") $ after rmDirIgnoreErrors $ do it "fails on non-empty data directory" $ \dirPath -> do writeFile (dirPath <> "/PG_VERSION") "1 million" let nonEmptyFolderPlan = silentConfig { dataDirectory = Permanent dirPath }- startAction = bracket (either throwIO pure =<< startConfig nonEmptyFolderPlan) stop $ const $ pure ()+ startAction = withConfig' nonEmptyFolderPlan $ const $ pure () startAction `shouldThrow` (\(InitDbFailed theOut theErr code) -> do code == ExitFailure 1 && length theOut > 0 && length theErr > 0)@@ -360,13 +390,17 @@ { initDbConfig = Nothing } }- bracket (either throwIO pure =<< startConfig nonEmptyFolderPlan) stop $ \db -> do+ withConfig' nonEmptyFolderPlan $ \db -> do one <- fmap (PG.fromOnly . head) $ bracket (PG.connectPostgreSQL $ toConnectionString db ) PG.close $ \conn -> PG.query_ conn "SELECT 1" one `shouldBe` (1 :: Int) +--+-- Backup "test"+--+ let justBackupResources = mempty { plan = mempty { postgresConfigFile =@@ -379,7 +413,7 @@ } } backupResources = silentConfig <> justBackupResources- before (pure $ Runner $ \f -> bracket (either throwIO pure =<< startConfig backupResources) stop f) $+ before (pure $ Runner $ withConfig' backupResources) $ it "can support backup and restore" $ withRunner $ \db@DB {..} -> do let dataDir = toFilePath (resourcesDataDir dbResources) appendFile (dataDir ++ "/pg_hba.conf") $ "local replication all trust"
tmp-postgres.cabal view
@@ -1,5 +1,5 @@ name: tmp-postgres-version: 1.13.0.0+version: 1.13.1.0 synopsis: Start and stop a temporary postgres description: Start and stop a temporary postgres. See README.md homepage: https://github.com/jfischoff/tmp-postgres#readme