sandwich-contexts 0.3.0.2 → 0.3.0.3
raw patch · 10 files changed
+274/−166 lines, 10 filesdep −connectiondep −timePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: connection, time
API changes (from Hackage documentation)
+ Test.Sandwich.Contexts.Files: findFirstFileInDirs :: (FilePath -> IO Bool) -> [FilePath] -> IO FilePath
+ Test.Sandwich.Contexts.Nix: buildNixPackage :: (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLogger m) => Text -> m FilePath
+ Test.Sandwich.Contexts.Nix: buildNixPackage' :: (HasBaseContextMonad context m, MonadUnliftIO m, MonadLogger m) => NixContext -> Text -> m FilePath
+ Test.Sandwich.Contexts.Nix: nixpkgsMaster :: NixpkgsDerivation
+ Test.Sandwich.Contexts.Nix: nixpkgsRelease2411 :: NixpkgsDerivation
+ Test.Sandwich.Contexts.Nix: nixpkgsRelease2505 :: NixpkgsDerivation
- Test.Sandwich.Contexts.Container: waitForHealth :: forall m. (HasCallStack, MonadLoggerIO m, MonadMask m) => ContainerSystem -> Text -> m ()
+ Test.Sandwich.Contexts.Container: waitForHealth :: (HasCallStack, MonadLoggerIO m, MonadMask m) => ContainerSystem -> Text -> m ()
- Test.Sandwich.Contexts.FakeSmtpServer: FakeSmtpServer :: HostName -> PortNumber -> (forall m. (MonadLoggerIO m, MonadUnliftIO m, MonadThrow m) => m [EmailInfo]) -> FakeSmtpServer
+ Test.Sandwich.Contexts.FakeSmtpServer: FakeSmtpServer :: HostName -> PortNumber -> (forall (m :: Type -> Type). (MonadLoggerIO m, MonadUnliftIO m) => m [EmailInfo]) -> FakeSmtpServer
- Test.Sandwich.Contexts.FakeSmtpServer: [fakeSmtpServerGetEmails] :: FakeSmtpServer -> forall m. (MonadLoggerIO m, MonadUnliftIO m, MonadThrow m) => m [EmailInfo]
+ Test.Sandwich.Contexts.FakeSmtpServer: [fakeSmtpServerGetEmails] :: FakeSmtpServer -> forall (m :: Type -> Type). (MonadLoggerIO m, MonadUnliftIO m) => m [EmailInfo]
- Test.Sandwich.Contexts.FakeSmtpServer: introduceFakeSmtpServer :: (BaseMonad context m, HasFile context "fake-smtp-server") => FakeSmtpServerOptions -> SpecFree (LabelValue "fakeSmtpServer" FakeSmtpServer :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.FakeSmtpServer: introduceFakeSmtpServer :: forall context (m :: Type -> Type). (BaseMonad context m, HasFile context "fake-smtp-server") => FakeSmtpServerOptions -> SpecFree (LabelValue "fakeSmtpServer" FakeSmtpServer :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.FakeSmtpServer: introduceFakeSmtpServerNix :: (BaseMonad context m, HasNixContext context) => FakeSmtpServerOptions -> SpecFree (FakeSmtpServerContext context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.FakeSmtpServer: introduceFakeSmtpServerNix :: forall context (m :: Type -> Type). (BaseMonad context m, HasNixContext context) => FakeSmtpServerOptions -> SpecFree (FakeSmtpServerContext context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.FakeSmtpServer: introduceFakeSmtpServerNix' :: (BaseMonad context m, HasNixContext context) => Text -> FakeSmtpServerOptions -> SpecFree (FakeSmtpServerContext context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.FakeSmtpServer: introduceFakeSmtpServerNix' :: forall context (m :: Type -> Type). (BaseMonad context m, HasNixContext context) => Text -> FakeSmtpServerOptions -> SpecFree (FakeSmtpServerContext context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: EnvironmentFile :: FilePath -> EnvironmentFile a
+ Test.Sandwich.Contexts.Files: EnvironmentFile :: FilePath -> EnvironmentFile (a :: k)
- Test.Sandwich.Contexts.Files: [unEnvironmentFile] :: EnvironmentFile a -> FilePath
+ Test.Sandwich.Contexts.Files: [unEnvironmentFile] :: EnvironmentFile (a :: k) -> FilePath
- Test.Sandwich.Contexts.Files: askFile :: forall a context m. (MonadReader context m, HasFile context a) => m FilePath
+ Test.Sandwich.Contexts.Files: askFile :: forall (a :: Symbol) context m. (MonadReader context m, HasFile context a) => m FilePath
- Test.Sandwich.Contexts.Files: askFile' :: forall a context m. (MonadReader context m, HasFile context a) => Proxy a -> m FilePath
+ Test.Sandwich.Contexts.Files: askFile' :: forall (a :: Symbol) context m. (MonadReader context m, HasFile context a) => Proxy a -> m FilePath
- Test.Sandwich.Contexts.Files: data EnvironmentFile a
+ Test.Sandwich.Contexts.Files: data EnvironmentFile (a :: k)
- Test.Sandwich.Contexts.Files: getBinaryViaNixDerivation :: forall a context m. (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m, MonadMask m, KnownSymbol a) => Text -> m FilePath
+ Test.Sandwich.Contexts.Files: getBinaryViaNixDerivation :: forall (a :: Symbol) context m. (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m, KnownSymbol a) => Text -> m FilePath
- Test.Sandwich.Contexts.Files: getBinaryViaNixDerivation' :: forall a context m. (HasBaseContextMonad context m, MonadUnliftIO m, MonadLoggerIO m, MonadMask m, KnownSymbol a) => NixContext -> Text -> m FilePath
+ Test.Sandwich.Contexts.Files: getBinaryViaNixDerivation' :: forall (a :: Symbol) context m. (HasBaseContextMonad context m, MonadUnliftIO m, MonadLoggerIO m, KnownSymbol a) => NixContext -> Text -> m FilePath
- Test.Sandwich.Contexts.Files: getBinaryViaNixPackage :: forall a context m. (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m, KnownSymbol a) => NixPackageName -> m FilePath
+ Test.Sandwich.Contexts.Files: getBinaryViaNixPackage :: forall (a :: Symbol) context m. (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m, KnownSymbol a) => NixPackageName -> m FilePath
- Test.Sandwich.Contexts.Files: getBinaryViaNixPackage' :: forall a context m. (HasBaseContext context, MonadReader context m, MonadLogger m, MonadUnliftIO m, KnownSymbol a) => NixContext -> NixPackageName -> m FilePath
+ Test.Sandwich.Contexts.Files: getBinaryViaNixPackage' :: forall (a :: Symbol) context m. (HasBaseContext context, MonadReader context m, MonadLogger m, MonadUnliftIO m, KnownSymbol a) => NixContext -> NixPackageName -> m FilePath
- Test.Sandwich.Contexts.Files: getFileViaNixDerivation :: forall context m. (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m, MonadMask m) => Text -> (FilePath -> IO FilePath) -> m FilePath
+ Test.Sandwich.Contexts.Files: getFileViaNixDerivation :: (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m) => Text -> (FilePath -> IO FilePath) -> m FilePath
- Test.Sandwich.Contexts.Files: getFileViaNixPackage :: forall context m. (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m) => NixPackageName -> (FilePath -> IO FilePath) -> m FilePath
+ Test.Sandwich.Contexts.Files: getFileViaNixPackage :: (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLoggerIO m) => NixPackageName -> (FilePath -> IO FilePath) -> m FilePath
- Test.Sandwich.Contexts.Files: introduceBinaryViaEnvironment :: forall a context m. (MonadUnliftIO m, KnownSymbol a) => SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceBinaryViaEnvironment :: forall (a :: Symbol) context (m :: Type -> Type). (MonadUnliftIO m, KnownSymbol a) => SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceBinaryViaEnvironment' :: forall a context m. (MonadUnliftIO m, KnownSymbol a) => NodeOptions -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceBinaryViaEnvironment' :: forall (a :: Symbol) context (m :: Type -> Type). (MonadUnliftIO m, KnownSymbol a) => NodeOptions -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceBinaryViaNixDerivation :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a) => Text -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceBinaryViaNixDerivation :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => Text -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceBinaryViaNixDerivation' :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a) => NodeOptions -> Text -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceBinaryViaNixDerivation' :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NodeOptions -> Text -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceBinaryViaNixPackage :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NixPackageName -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceBinaryViaNixPackage :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NixPackageName -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceBinaryViaNixPackage' :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NodeOptions -> NixPackageName -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceBinaryViaNixPackage' :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NodeOptions -> NixPackageName -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFile :: forall a context m. (MonadUnliftIO m, KnownSymbol a) => FilePath -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFile :: forall (a :: Symbol) context (m :: Type -> Type). (MonadUnliftIO m, KnownSymbol a) => FilePath -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFile' :: forall a context m. (MonadUnliftIO m, KnownSymbol a) => NodeOptions -> FilePath -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFile' :: forall (a :: Symbol) context (m :: Type -> Type). (MonadUnliftIO m, KnownSymbol a) => NodeOptions -> FilePath -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFileViaNixDerivation :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a) => Text -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFileViaNixDerivation :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => Text -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFileViaNixDerivation' :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a) => Text -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFileViaNixDerivation' :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => Text -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFileViaNixDerivation'' :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a) => NodeOptions -> Text -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFileViaNixDerivation'' :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NodeOptions -> Text -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFileViaNixPackage :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NixPackageName -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFileViaNixPackage :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NixPackageName -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFileViaNixPackage' :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NixPackageName -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFileViaNixPackage' :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NixPackageName -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: introduceFileViaNixPackage'' :: forall a context m. (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NodeOptions -> NixPackageName -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Files: introduceFileViaNixPackage'' :: forall (a :: Symbol) context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a) => NodeOptions -> NixPackageName -> (FilePath -> IO FilePath) -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Files: mkFileLabel :: Label (AppendSymbol "file-" a) (EnvironmentFile a)
+ Test.Sandwich.Contexts.Files: mkFileLabel :: forall (a :: Symbol). Label (AppendSymbol "file-" a) (EnvironmentFile a)
- Test.Sandwich.Contexts.Files: type FileValue file = LabelValue (AppendSymbol "file-" file) (EnvironmentFile file)
+ Test.Sandwich.Contexts.Files: type FileValue (file :: Symbol) = LabelValue AppendSymbol "file-" file EnvironmentFile file
- Test.Sandwich.Contexts.Files: type HasFile context a = HasLabel context (AppendSymbol "file-" a) (EnvironmentFile a)
+ Test.Sandwich.Contexts.Files: type HasFile context (a :: Symbol) = HasLabel context AppendSymbol "file-" a EnvironmentFile a
- Test.Sandwich.Contexts.HttpWaits: type WaitConstraints m = (HasCallStack, MonadLogger m, MonadUnliftIO m, MonadThrow m)
+ Test.Sandwich.Contexts.HttpWaits: type WaitConstraints (m :: Type -> Type) = (HasCallStack, MonadLogger m, MonadUnliftIO m)
- Test.Sandwich.Contexts.Nix: buildNixCallPackageDerivation :: (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLogger m, MonadMask m) => Text -> m FilePath
+ Test.Sandwich.Contexts.Nix: buildNixCallPackageDerivation :: (HasBaseContextMonad context m, HasNixContext context, MonadUnliftIO m, MonadLogger m) => Text -> m FilePath
- Test.Sandwich.Contexts.Nix: buildNixCallPackageDerivation' :: (HasBaseContextMonad context m, MonadUnliftIO m, MonadLogger m, MonadMask m) => NixContext -> Text -> m FilePath
+ Test.Sandwich.Contexts.Nix: buildNixCallPackageDerivation' :: (HasBaseContextMonad context m, MonadUnliftIO m, MonadLogger m) => NixContext -> Text -> m FilePath
- Test.Sandwich.Contexts.Nix: introduceNixContext :: (MonadUnliftIO m, MonadThrow m) => NixpkgsDerivation -> SpecFree (LabelValue "nixContext" NixContext :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Nix: introduceNixContext :: forall (m :: Type -> Type) context. (MonadUnliftIO m, MonadThrow m) => NixpkgsDerivation -> SpecFree (LabelValue "nixContext" NixContext :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Nix: introduceNixContext' :: (MonadUnliftIO m, MonadThrow m) => NodeOptions -> NixpkgsDerivation -> SpecFree (LabelValue "nixContext" NixContext :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Nix: introduceNixContext' :: forall (m :: Type -> Type) context. (MonadUnliftIO m, MonadThrow m) => NodeOptions -> NixpkgsDerivation -> SpecFree (LabelValue "nixContext" NixContext :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Nix: introduceNixContext'' :: (MonadUnliftIO m, MonadThrow m, HasFile context "nix") => NodeOptions -> NixpkgsDerivation -> SpecFree (LabelValue "nixContext" NixContext :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Nix: introduceNixContext'' :: forall (m :: Type -> Type) context. (MonadUnliftIO m, MonadThrow m, HasFile context "nix") => NodeOptions -> NixpkgsDerivation -> SpecFree (LabelValue "nixContext" NixContext :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Nix: introduceNixEnvironment :: (HasBaseContext context, HasNixContext context, MonadUnliftIO m) => [Text] -> SpecFree (LabelValue "nixEnvironment" FilePath :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Nix: introduceNixEnvironment :: forall context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m) => [Text] -> SpecFree (LabelValue "nixEnvironment" FilePath :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Nix: introduceNixEnvironment' :: (HasBaseContext context, HasNixContext context, MonadUnliftIO m) => NodeOptions -> [Text] -> SpecFree (LabelValue "nixEnvironment" FilePath :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.Nix: introduceNixEnvironment' :: forall context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m) => NodeOptions -> [Text] -> SpecFree (LabelValue "nixEnvironment" FilePath :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.PostgreSQL: introducePostgresUnixSocketViaNix :: (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m) => PostgresNixOptions -> SpecFree (LabelValue "postgres" PostgresContext :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.PostgreSQL: introducePostgresUnixSocketViaNix :: forall context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m) => PostgresNixOptions -> SpecFree (LabelValue "postgres" PostgresContext :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.PostgreSQL: introducePostgresViaContainer :: (HasBaseContext context, MonadUnliftIO m, MonadMask m) => PostgresContainerOptions -> SpecFree (LabelValue "postgres" PostgresContext :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.PostgreSQL: introducePostgresViaContainer :: forall context (m :: Type -> Type). (HasBaseContext context, MonadUnliftIO m, MonadMask m) => PostgresContainerOptions -> SpecFree (LabelValue "postgres" PostgresContext :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.PostgreSQL: introducePostgresViaNix :: (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m) => PostgresNixOptions -> SpecFree (LabelValue "postgres" PostgresContext :> context) m () -> SpecFree context m ()
+ Test.Sandwich.Contexts.PostgreSQL: introducePostgresViaNix :: forall context (m :: Type -> Type). (HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m) => PostgresNixOptions -> SpecFree (LabelValue "postgres" PostgresContext :> context) m () -> SpecFree context m ()
- Test.Sandwich.Contexts.Util.Ports: findFreePortInRange' :: forall m. (MonadIO m, MonadCatch m) => RetryPolicy -> (PortNumber, PortNumber) -> [PortNumber] -> m (Maybe PortNumber)
+ Test.Sandwich.Contexts.Util.Ports: findFreePortInRange' :: (MonadIO m, MonadCatch m) => RetryPolicy -> (PortNumber, PortNumber) -> [PortNumber] -> m (Maybe PortNumber)
Files
- CHANGELOG.md +15/−2
- lib/Test/Sandwich/Contexts/FakeSmtpServer.hs +3/−4
- lib/Test/Sandwich/Contexts/Files.hs +153/−121
- lib/Test/Sandwich/Contexts/HttpWaits.hs +4/−12
- lib/Test/Sandwich/Contexts/Nix.hs +84/−9
- lib/Test/Sandwich/Contexts/PostgreSQL.hs +2/−2
- lib/Test/Sandwich/Contexts/ReverseProxy/TCP.hs +6/−2
- lib/Test/Sandwich/Contexts/Util/Nix.hs +3/−3
- sandwich-contexts.cabal +4/−10
- test/Spec.hs +0/−1
CHANGELOG.md view
@@ -1,12 +1,25 @@ # Changelog for sandwich-contexts -## Unreleased+## 0.3.0.3 +* Use --no-link in Nix builds to avoid unnecessary result symlinks.+* Make withProxyToUnixSocket more robust with a timeout.+* Add nixpkgsRelease2411, nixpkgsRelease2505, nixpkgsMaster.+* Export findFirstFileInDirs, and make tryFindBinary search under Applications on macOS.+* Add buildNixPackage functions + remove a bunch of Control.Monad.Catch usage.++## 0.3.0.2+ * Add `postgresNixConfExtraLines` to `PostgresNixOptions`, to be able to add extra lines to `postgresql.conf`.+* Add 'fakeSmtpServerHostname' to FakeSmtpServer.+* Add some generic options for launching containers.+* Enable Unix socket based contexts on Windows.+* Add withPostgresViaNix', withPostgresUnixSocketViaNix'.+* Add makeNixContext, makeNixContext'. ## 0.3.0.1 -* Automatically find sufficiently short Unix socket paths when the system temp ones are too long+* Automatically find sufficiently short Unix socket paths when the system temp ones are too long. ## 0.3.0.0
lib/Test/Sandwich/Contexts/FakeSmtpServer.hs view
@@ -34,7 +34,6 @@ ) where import Control.Monad-import Control.Monad.Catch (MonadMask, MonadThrow) import Control.Monad.IO.Unlift import Control.Monad.Logger import Control.Monad.Reader@@ -95,7 +94,7 @@ -- | The port on which the fake SMTP server is running. , fakeSmtpServerSmtpPort :: PortNumber -- | Callback to retrieve the emails the server has received.- , fakeSmtpServerGetEmails :: forall m. (MonadLoggerIO m, MonadUnliftIO m, MonadThrow m) => m [EmailInfo]+ , fakeSmtpServerGetEmails :: forall m. (MonadLoggerIO m, MonadUnliftIO m) => m [EmailInfo] } fakeSmtpServer :: Label "fakeSmtpServer" FakeSmtpServer@@ -103,7 +102,7 @@ -- * Functions -type BaseMonad context m = (HasBaseContext context, MonadMask m, MonadUnliftIO m)+type BaseMonad context m = (HasBaseContext context, MonadUnliftIO m) type FakeSmtpServerContext context = LabelValue "fakeSmtpServer" FakeSmtpServer@@ -215,7 +214,7 @@ Just n -> pure n getEmails :: (- MonadLoggerIO m, MonadUnliftIO m, MonadThrow m+ MonadLoggerIO m, MonadUnliftIO m ) => Manager -> Text -> PortNumber -> m [EmailInfo] getEmails manager authPart httpPort = do req <- liftIO $ parseRequest [i|http://#{authPart}localhost:#{httpPort}/api/emails|]
lib/Test/Sandwich/Contexts/Files.hs view
@@ -66,6 +66,7 @@ -- * Helpers for file-finding callbacks , defaultFindFile , findFirstFile+ , findFirstFileInDirs -- * Low-level , mkFileLabel@@ -77,7 +78,6 @@ , FileValue ) where -import Control.Monad.Catch (MonadMask) import Control.Monad.IO.Unlift import Control.Monad.Logger import Control.Monad.Trans.Except@@ -85,6 +85,7 @@ import GHC.TypeLits import Relude import System.FilePath+import System.Info (os) import Test.Sandwich import Test.Sandwich.Contexts.Files.Types import Test.Sandwich.Contexts.Nix@@ -154,136 +155,148 @@ -- | Introduce a given 'EnvironmentFile' from the 'NixContext' in scope. -- It's recommended to use this with -XTypeApplications. introduceFileViaNixPackage :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a- ) =>- -- | Nix package name which contains the desired file.- -- This package will be evaluated using the configured Nixpkgs version of the 'NixContext'.- NixPackageName- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context+ , MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix package name which contains the desired file.+ -- This package will be evaluated using the configured Nixpkgs version of the 'NixContext'.+ => NixPackageName+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceFileViaNixPackage name = introduceFileViaNixPackage' @a name (defaultFindFile (symbolVal (Proxy @a))) -- | Same as 'introduceFileViaNixPackage', but allows you to customize the search callback. introduceFileViaNixPackage' :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a- ) =>- -- | Nix package name which contains the desired file.- -- This package will be evaluated using the configured Nixpkgs version of the 'NixContext'.- NixPackageName- -- | Callback to find the desired file within the Nix derivation path.- -- It will be passed the derivation path, and should return the file. For example,- -- tryFindFile "\/nix\/store\/...selenium-server-standalone-3.141.59" may return- -- "\/nix\/store\/...selenium-server-standalone-3.141.59\/share\/lib\/selenium-server-standalone-3.141.59\/selenium-server-standalone-3.141.59.jar".- -> (FilePath -> IO FilePath)- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context+ , MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix package name which contains the desired file.+ -- This package will be evaluated using the configured Nixpkgs version of the 'NixContext'.+ => NixPackageName+ -- | Callback to find the desired file within the Nix derivation path.+ -- It will be passed the derivation path, and should return the file. For example,+ -- tryFindFile "\/nix\/store\/...selenium-server-standalone-3.141.59" may return+ -- "\/nix\/store\/...selenium-server-standalone-3.141.59\/share\/lib\/selenium-server-standalone-3.141.59\/selenium-server-standalone-3.141.59.jar".+ -> (FilePath -> IO FilePath)+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceFileViaNixPackage' = introduceFileViaNixPackage'' (defaultNodeOptions { nodeOptionsVisibilityThreshold = defaultFileContextVisibilityThreshold }) -- | Same as 'introduceFileViaNixPackage'', but allows passing custom 'NodeOptions'. introduceFileViaNixPackage'' :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a- ) => NodeOptions- -- | Nix package name which contains the desired file.- -> NixPackageName- -- | Callback to find the desired file within the Nix derivation path.- -- It will be passed the derivation path, and should return the file. For example,- -- tryFindFile "\/nix\/store\/...selenium-server-standalone-3.141.59" may return- -- "\/nix\/store\/...selenium-server-standalone-3.141.59\/share\/lib\/selenium-server-standalone-3.141.59\/selenium-server-standalone-3.141.59.jar".- -> (FilePath -> IO FilePath)- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context+ , MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix package name which contains the desired file.+ => NodeOptions+ -> NixPackageName+ -- | Callback to find the desired file within the Nix derivation path.+ -- It will be passed the derivation path, and should return the file. For example,+ -- tryFindFile "\/nix\/store\/...selenium-server-standalone-3.141.59" may return+ -- "\/nix\/store\/...selenium-server-standalone-3.141.59\/share\/lib\/selenium-server-standalone-3.141.59\/selenium-server-standalone-3.141.59.jar".+ -> (FilePath -> IO FilePath)+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceFileViaNixPackage'' nodeOptions packageName tryFindFile = introduce' nodeOptions [i|#{binaryName} (file via Nix package #{packageName})|] (mkFileLabel @a) alloc (const $ return ()) where binaryName :: String binaryName = symbolVal (Proxy @a) - alloc = buildNixSymlinkJoin [packageName] >>= \p -> EnvironmentFile <$> liftIO (tryFindFile p)+ alloc = buildNixPackage packageName >>= \p -> EnvironmentFile <$> liftIO (tryFindFile p) -- | Lower-level version of 'introduceFileViaNixPackage'. getFileViaNixPackage :: forall context m. ( HasBaseContextMonad context m, HasNixContext context , MonadUnliftIO m, MonadLoggerIO m- ) =>- -- | Nix package name which contains the desired file.- NixPackageName- -- | Callback to find the desired file, as in 'introduceFileViaNixPackage'.- -> (FilePath -> IO FilePath)- -> m FilePath-getFileViaNixPackage packageName tryFindFile = buildNixSymlinkJoin [packageName] >>= liftIO . tryFindFile+ )+ -- | Nix package name which contains the desired file.+ => NixPackageName+ -- | Callback to find the desired file, as in 'introduceFileViaNixPackage'.+ -> (FilePath -> IO FilePath)+ -> m FilePath+getFileViaNixPackage packageName tryFindFile = buildNixPackage packageName >>= liftIO . tryFindFile -- | Introduce a given 'EnvironmentFile' from the 'NixContext' in scope. -- It's recommended to use this with -XTypeApplications.+--+-- This will search for an executable file with the given name in the "bin" directory of the Nix output.+-- On MacOS, it will also recursively search the "Applications" directory. This makes it seamless when you+-- want to work with a derivation like "firefox", which is bundled as an application on macOS. introduceBinaryViaNixPackage :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a- ) =>- -- | Nix package name which contains the desired binary.- -- This package will be evaluated using the configured Nixpkgs version of the 'NixContext'.- -- For example, you can use the "hello" binary from the "hello" package like this:- --- -- introduceBinaryViaNixPackage' @"hello" "hello"- NixPackageName- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context+ , MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix package name which contains the desired binary.+ -- This package will be evaluated using the configured Nixpkgs version of the 'NixContext'.+ -- For example, you can use the "hello" binary from the "hello" package like this:+ --+ -- introduceBinaryViaNixPackage' @"hello" "hello"+ => NixPackageName+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceBinaryViaNixPackage = introduceBinaryViaNixPackage' @a (defaultNodeOptions { nodeOptionsVisibilityThreshold = defaultFileContextVisibilityThreshold }) -- | Same as 'introduceBinaryViaNixPackage', but allows passing custom 'NodeOptions'. introduceBinaryViaNixPackage' :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a- ) => NodeOptions- -- | Nix package name which contains the desired binary.- -> NixPackageName- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context+ , MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix package name which contains the desired binary.+ => NodeOptions+ -> NixPackageName+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceBinaryViaNixPackage' nodeOptions packageName = introduce' nodeOptions [i|#{binaryName} (binary via Nix package #{packageName})|] (mkFileLabel @a) alloc (const $ return ()) where binaryName :: String binaryName = symbolVal (Proxy @a) - alloc = buildNixSymlinkJoin [packageName] >>= tryFindBinary binaryName+ alloc = buildNixPackage packageName >>= tryFindBinary binaryName -- | Lower-level version of 'introduceBinaryViaNixPackage'. getBinaryViaNixPackage :: forall a context m. ( HasBaseContextMonad context m, HasNixContext context , MonadUnliftIO m, MonadLoggerIO m, KnownSymbol a- ) =>- -- | Nix package name which contains the desired binary.- NixPackageName- -> m FilePath+ )+ -- | Nix package name which contains the desired binary.+ => NixPackageName+ -> m FilePath getBinaryViaNixPackage packageName = do- unEnvironmentFile <$> (buildNixSymlinkJoin [packageName] >>= tryFindBinary (symbolVal (Proxy @a)))+ unEnvironmentFile <$> (buildNixPackage packageName >>= tryFindBinary (symbolVal (Proxy @a))) -- | Lower-level version of 'introduceBinaryViaNixPackage'. getBinaryViaNixPackage' :: forall a context m. ( HasBaseContext context, MonadReader context m , MonadLogger m, MonadUnliftIO m, KnownSymbol a- ) =>- -- | 'NixContext' to use.- NixContext- -- | Nix package name which contains the desired binary.- -> NixPackageName- -> m FilePath+ )+ -- | 'NixContext' to use.+ => NixContext+ -- | Nix package name which contains the desired binary.+ -> NixPackageName+ -> m FilePath getBinaryViaNixPackage' nc packageName = do- unEnvironmentFile <$> (buildNixSymlinkJoin' nc [packageName] >>= tryFindBinary (symbolVal (Proxy @a)))+ unEnvironmentFile <$> (buildNixPackage' nc packageName >>= tryFindBinary (symbolVal (Proxy @a))) -- | Introduce a given 'EnvironmentFile' from the 'NixContext' in scope. -- It's recommended to use this with -XTypeApplications. introduceBinaryViaNixDerivation :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a- ) =>- -- | Nix derivation as a string.- Text- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix derivation as a string.+ => Text+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceBinaryViaNixDerivation = introduceBinaryViaNixDerivation' (defaultNodeOptions { nodeOptionsVisibilityThreshold = defaultFileContextVisibilityThreshold }) -- | Same as 'introduceBinaryViaNixDerivation', but allows passing custom 'NodeOptions'. introduceBinaryViaNixDerivation' :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a- ) => NodeOptions- -- | Nix derivation as a string.- -> Text- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix derivation as a string.+ => NodeOptions+ -> Text+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceBinaryViaNixDerivation' nodeOptions derivation = introduce' nodeOptions [i|#{binaryName} (binary via Nix derivation)|] (mkFileLabel @a) alloc (const $ return ()) where binaryName :: String@@ -294,18 +307,18 @@ -- | Lower-level version of 'introduceBinaryViaNixDerivation'. getBinaryViaNixDerivation :: forall a context m. ( HasBaseContextMonad context m, HasNixContext context- , MonadUnliftIO m, MonadLoggerIO m, MonadMask m, KnownSymbol a- ) =>- -- | Nix derivation as a string.- Text- -> m FilePath+ , MonadUnliftIO m, MonadLoggerIO m, KnownSymbol a+ )+ -- | Nix derivation as a string.+ => Text+ -> m FilePath getBinaryViaNixDerivation derivation = unEnvironmentFile <$> (buildNixCallPackageDerivation derivation >>= tryFindBinary (symbolVal (Proxy @a))) -- | Lower-level version of 'getBinaryViaNixDerivation'. getBinaryViaNixDerivation' :: forall a context m. ( HasBaseContextMonad context m- , MonadUnliftIO m, MonadLoggerIO m, MonadMask m, KnownSymbol a+ , MonadUnliftIO m, MonadLoggerIO m, KnownSymbol a ) -- | Nix context. => NixContext@@ -318,36 +331,37 @@ -- | Introduce a given 'EnvironmentFile' from the 'NixContext' in scope. -- It's recommended to use this with -XTypeApplications. introduceFileViaNixDerivation :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a- ) =>- -- | Nix derivation as a string.- Text- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix derivation as a string.+ => Text+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceFileViaNixDerivation derivation = introduceFileViaNixDerivation' @a derivation (defaultFindFile (symbolVal (Proxy @a))) -- | Same as 'introduceFileViaNixDerivation', but allows configuring the file finding callback. introduceFileViaNixDerivation' :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a- ) =>- -- | Nix derivation as a string.- Text- -- | Callback to find the desired file.- -> (FilePath -> IO FilePath)- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix derivation as a string.+ => Text+ -- | Callback to find the desired file.+ -> (FilePath -> IO FilePath)+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceFileViaNixDerivation' = introduceFileViaNixDerivation'' (defaultNodeOptions { nodeOptionsVisibilityThreshold = defaultFileContextVisibilityThreshold }) -- | Same as 'introduceFileViaNixDerivation'', but allows passing custom 'NodeOptions'. introduceFileViaNixDerivation'' :: forall a context m. (- HasBaseContext context, HasNixContext context, MonadUnliftIO m, MonadMask m, KnownSymbol a- ) => NodeOptions- -- | Nix derivation as a string.- -> Text- -- | Callback to find the desired file.- -> (FilePath -> IO FilePath)- -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()- -> SpecFree context m ()+ HasBaseContext context, HasNixContext context, MonadUnliftIO m, KnownSymbol a+ )+ -- | Nix derivation as a string.+ => NodeOptions+ -> Text+ -- | Callback to find the desired file.+ -> (FilePath -> IO FilePath)+ -> SpecFree (LabelValue (AppendSymbol "file-" a) (EnvironmentFile a) :> context) m ()+ -> SpecFree context m () introduceFileViaNixDerivation'' nodeOptions derivation tryFindFile = introduce' nodeOptions [i|#{binaryName} (file via Nix derivation)|] (mkFileLabel @a) alloc (const $ return ()) where binaryName :: String@@ -358,21 +372,33 @@ -- | Lower-level version of 'introduceFileViaNixDerivation'. getFileViaNixDerivation :: forall context m. ( HasBaseContextMonad context m, HasNixContext context- , MonadUnliftIO m, MonadLoggerIO m, MonadMask m- ) =>- -- | Nix derivation as a string.- Text- -- | Callback to find the desired file.- -> (FilePath -> IO FilePath)- -> m FilePath+ , MonadUnliftIO m, MonadLoggerIO m+ )+ -- | Nix derivation as a string.+ => Text+ -- | Callback to find the desired file.+ -> (FilePath -> IO FilePath)+ -> m FilePath getFileViaNixDerivation derivation tryFindFile = buildNixCallPackageDerivation derivation >>= liftIO . tryFindFile +-- | Default binary search function used in 'getBinaryViaNixPackage' etc. tryFindBinary :: (MonadIO m) => String -> FilePath -> m (EnvironmentFile a)-tryFindBinary binaryName env = do- findExecutablesInDirectories [env </> "bin"] binaryName >>= \case- (x:_) -> return $ EnvironmentFile x- _ -> expectationFailure [i|Couldn't find binary '#{binaryName}' in #{env </> "bin"}|]+tryFindBinary binaryName env = case os of+ "darwin" -> do+ dirsToSearch <- filterM doesDirectoryExist [env </> "bin", env </> "Applications"]+ let predicate x = andM [(isExecutable x), (return (takeFileName x == binaryName))]+ -- We use own own implementation here because we want to recursively search under "Applications"+ EnvironmentFile <$> liftIO (findFirstFileInDirs predicate dirsToSearch)+ where+ isExecutable :: FilePath -> IO Bool+ isExecutable path = executable <$> getPermissions path+ _ -> do+ -- This is the implementation from System.Directory, which is *not* recursive and is more performant+ -- than 'findFirstFile' because it doesn't list directories.+ findExecutablesInDirectories [env </> "bin"] binaryName >>= \case+ (x:_) -> return $ EnvironmentFile x+ _ -> expectationFailure [i|Couldn't find binary '#{binaryName}' in #{env </> "bin"}|] -- | Find a file whose name exactly matches a string, using 'findFirstFile'. -- This calls 'takeFileName', so it only matches against the name, not the relative path.@@ -383,9 +409,15 @@ -- Note that the callback receives the full relative path to the file from the root dir. -- Throws using 'expectationFailure' when the file is not found. findFirstFile :: (FilePath -> IO Bool) -> FilePath -> IO FilePath-findFirstFile predicate dir = runExceptT (go dir) >>= \case+findFirstFile predicate dir = findFirstFileInDirs predicate [dir]++-- | Find the first file under the given directory (recursively) which matches the predicate.+-- Note that the callback receives the full relative path to the file from the root dir.+-- Throws using 'expectationFailure' when the file is not found.+findFirstFileInDirs :: (FilePath -> IO Bool) -> [FilePath] -> IO FilePath+findFirstFileInDirs predicate dirs = runExceptT (sequence_ (fmap go dirs)) >>= \case Left x -> return x- Right () -> expectationFailure [i|Couldn't find file in '#{dir}'|]+ Right () -> expectationFailure [i|Couldn't find file matching predicate in '#{dirs}'|] where go :: FilePath -> ExceptT FilePath IO () go currentDir = do
lib/Test/Sandwich/Contexts/HttpWaits.hs view
@@ -21,7 +21,6 @@ import Control.Concurrent import Control.Monad-import Control.Monad.Catch (MonadThrow) import Control.Monad.IO.Unlift import Control.Monad.Logger import Data.Maybe@@ -46,7 +45,7 @@ timePerRequest :: Int timePerRequest = 10_000_000 -type WaitConstraints m = (HasCallStack, MonadLogger m, MonadUnliftIO m, MonadThrow m)+type WaitConstraints m = (HasCallStack, MonadLogger m, MonadUnliftIO m) -- | Whether to verify certificates or not when connecting to an HTTPS endpoint. data VerifyCerts = YesVerify | NoVerify@@ -70,7 +69,9 @@ waitUntilStatusCode :: (WaitConstraints m) => (Int, Int, Int) -> VerifyCerts -> String -> m () waitUntilStatusCode code verifyCerts url = do debug [i|Beginning waitUntilStatusCode request to #{url}|]- req <- parseRequest url+ req <- case parseRequest url of+ Left err -> expectationFailure [i|Couldn't parse URL: #{url}: #{err}|]+ Right x -> pure x man <- liftIO $ newManager (if verifyCerts == YesVerify then tlsManagerSettings else tlsNoVerifySettings) timeout timePerRequest (handleException $ (Right <$>) $ httpLbs req man) >>= \case Just (Right resp)@@ -95,12 +96,3 @@ maybeSuccess <- timeout timeInMicroseconds $ waitUntilStatusCode code verifyCerts url when (isNothing maybeSuccess) $ expectationFailure [i|Failed to connect to URL "#{url}" in waitUntilStatusCodeWithTimeout'...|]---#if !MIN_VERSION_time(1,9,1)-secondsToNominalDiffTime :: Pico -> NominalDiffTime-secondsToNominalDiffTime = realToFrac--nominalDiffTimeToSeconds :: NominalDiffTime -> Pico-nominalDiffTimeToSeconds = realToFrac-#endif
lib/Test/Sandwich/Contexts/Nix.hs view
@@ -37,6 +37,8 @@ -- * Nix environments , introduceNixEnvironment , introduceNixEnvironment'+ , buildNixPackage+ , buildNixPackage' , buildNixSymlinkJoin , buildNixSymlinkJoin' , buildNixExpression@@ -46,6 +48,9 @@ -- * Nixpkgs releases #releases# , nixpkgsReleaseDefault+ , nixpkgsMaster+ , nixpkgsRelease2505+ , nixpkgsRelease2411 , nixpkgsRelease2405 , nixpkgsRelease2311 @@ -62,7 +67,7 @@ , defaultFileContextVisibilityThreshold ) where -import Control.Monad.Catch (MonadMask, MonadThrow)+import Control.Monad.Catch (MonadThrow) import Control.Monad.IO.Unlift import Control.Monad.Logger import Data.Aeson as A@@ -73,7 +78,7 @@ import qualified Data.Vector as V import Relude import System.FilePath-import System.IO.Temp+import System.IO.Temp (createTempDirectory) import Test.Sandwich import Test.Sandwich.Contexts.Files.Types import Test.Sandwich.Contexts.Util.Aeson@@ -83,6 +88,7 @@ import UnliftIO.Environment import UnliftIO.MVar (modifyMVar) import UnliftIO.Process+import UnliftIO.Temporary -- * Types @@ -119,6 +125,42 @@ , nixpkgsDerivationAllowUnfree :: Bool } deriving (Show, Eq) +-- | Nixpkgs master, accessed 6\/6\/2025.+-- You can compute updated values for this release (or others) by running+-- nix-prefetch-github NixOS nixpkgs --rev master+nixpkgsMaster :: NixpkgsDerivation+nixpkgsMaster = NixpkgsDerivationFetchFromGitHub {+ nixpkgsDerivationOwner = "NixOS"+ , nixpkgsDerivationRepo = "nixpkgs"+ , nixpkgsDerivationRev = "067a39e41a125985e061199452c900b0305f4c42"+ , nixpkgsDerivationSha256 = "sha256-N57WqGFUUDJ7QVR4YPRttp4YuTA4oN/KdXHY4OEXGFk="+ , nixpkgsDerivationAllowUnfree = False+ }++-- | Nixpkgs release 25.05, accessed 6\/6\/2025.+-- You can compute updated values for this release (or others) by running+-- nix-prefetch-github NixOS nixpkgs --rev release-25.05+nixpkgsRelease2505 :: NixpkgsDerivation+nixpkgsRelease2505 = NixpkgsDerivationFetchFromGitHub {+ nixpkgsDerivationOwner = "NixOS"+ , nixpkgsDerivationRepo = "nixpkgs"+ , nixpkgsDerivationRev = "8217c6edf391991f07ecacf3d31ba6eb01d733b1"+ , nixpkgsDerivationSha256 = "sha256-aaeXPG9zVvi+aKTp0dMUYOeMuhDXQejRPh2CfK23nf8="+ , nixpkgsDerivationAllowUnfree = False+ }++-- | Nixpkgs release 24.11, accessed 6\/6\/2025.+-- You can compute updated values for this release (or others) by running+-- nix-prefetch-github NixOS nixpkgs --rev release-24.11+nixpkgsRelease2411 :: NixpkgsDerivation+nixpkgsRelease2411 = NixpkgsDerivationFetchFromGitHub {+ nixpkgsDerivationOwner = "NixOS"+ , nixpkgsDerivationRepo = "nixpkgs"+ , nixpkgsDerivationRev = "5908ad2494520214a309e74d5c3f33623a593ecd"+ , nixpkgsDerivationSha256 = "sha256-0q80SLtfhrtZAzLGpwAQjqaTE+HAwmOjoX4Q3M5mB/s="+ , nixpkgsDerivationAllowUnfree = False+ }+ -- | Nixpkgs release 24.05, accessed 11\/9\/2024. -- You can compute updated values for this release (or others) by running -- nix-prefetch-github NixOS nixpkgs --rev release-24.05@@ -238,6 +280,32 @@ -> SpecFree context m () introduceNixEnvironment' nodeOptions packageNames = introduce' nodeOptions "Introduce Nix environment" nixEnvironment (buildNixSymlinkJoin packageNames) (const $ return ()) +-- | Build a single Nix package name from Nixpkgs+buildNixPackage :: (+ HasBaseContextMonad context m, HasNixContext context+ , MonadUnliftIO m, MonadLogger m+ )+ -- | Package name.+ => Text+ -> m FilePath+buildNixPackage packageName = do+ nc <- getContext nixContext+ buildNixPackage' nc packageName++-- | Lower-level version of 'buildNixCallPackageDerivation'+buildNixPackage' :: (+ HasBaseContextMonad context m+ , MonadUnliftIO m, MonadLogger m+ )+ -- | Nix context.+ => NixContext+ -- | Package name.+ -> Text+ -> m FilePath+buildNixPackage' nc packageName = buildNixCallPackageDerivation' nc expr+ where+ expr = [i|{ pkgs }: pkgs."#{packageName}"|]+ -- | Build a Nix environment, as in 'introduceNixEnvironment'. buildNixSymlinkJoin :: ( HasBaseContextMonad context m, HasNixContext context@@ -267,7 +335,7 @@ -- "{ git, gcc, stdenv, ... }: stdenv.mkDerivation {...}" buildNixCallPackageDerivation :: ( HasBaseContextMonad context m, HasNixContext context- , MonadUnliftIO m, MonadLogger m, MonadMask m+ , MonadUnliftIO m, MonadLogger m ) -- | Nix derivation => Text@@ -277,9 +345,9 @@ buildNixCallPackageDerivation' nc derivation -- | Lower-level version of 'buildNixCallPackageDerivation'-buildNixCallPackageDerivation' :: (+buildNixCallPackageDerivation' :: forall context m. ( HasBaseContextMonad context m- , MonadUnliftIO m, MonadLogger m, MonadMask m+ , MonadUnliftIO m, MonadLogger m ) -- | Nix context. => NixContext@@ -303,6 +371,7 @@ return (M.insert derivation asy m, asy) ) where+ withDerivationPath :: Maybe FilePath -> (FilePath -> m a) -> m a withDerivationPath (Just nixExpressionDir) action = action (nixExpressionDir </> "default.nix") withDerivationPath Nothing action = withSystemTempDirectory "nix-expression" $ \dir -> action (dir </> "default.nix") @@ -359,7 +428,7 @@ , "--extra-experimental-features", "nix-command" , "--expr", toString expr , "--json"- ] <> (case maybeOutputPath of Nothing -> []; Just p -> ["-o", p])+ ] <> (case maybeOutputPath of Nothing -> ["--no-link"]; Just p -> ["-o", p]) )) { env = maybeEnv } ) "" @@ -390,8 +459,8 @@ pkgs.symlinkJoin { name = "test-contexts-environment"; paths = with pkgs; [#{T.intercalate " " packageNames}]; } |] -renderCallPackageDerivation :: NixpkgsDerivation -> FilePath -> Text-renderCallPackageDerivation (NixpkgsDerivationFetchFromGitHub {..}) derivationPath = [i|+renderDerivationWithPkgs :: NixpkgsDerivation -> Text -> Text+renderDerivationWithPkgs (NixpkgsDerivationFetchFromGitHub {..}) expr = [i| \# Use the ambient <nixpkgs> channel to bootstrap with { inherit (import (<nixpkgs>) {})@@ -409,5 +478,11 @@ pkgs = import nixpkgs {}; in -pkgs.callPackage #{show derivationPath :: String} {}+#{expr} |]++renderCallPackageDerivation :: NixpkgsDerivation -> FilePath -> Text+renderCallPackageDerivation nixpkgsDerivation derivationPath =+ renderDerivationWithPkgs nixpkgsDerivation expr+ where+ expr = [i|pkgs.callPackage #{show derivationPath :: String} {}|]
lib/Test/Sandwich/Contexts/PostgreSQL.hs view
@@ -205,7 +205,7 @@ -> (FilePath -> m a) -> m a withPostgresUnixSocketViaNix (PostgresNixOptions {..}) action = do- postgresBinDir <- (</> "bin") <$> buildNixSymlinkJoin [postgresNixPostgres]+ postgresBinDir <- (</> "bin") <$> buildNixPackage postgresNixPostgres withPostgresUnixSocket postgresBinDir postgresNixUsername postgresNixPassword postgresNixDatabase postgresNixConfExtraLines action -- | Lower-level variant of 'withPostgresUnixSocket'.@@ -219,7 +219,7 @@ -> (FilePath -> m a) -> m a withPostgresUnixSocketViaNix' nc (PostgresNixOptions {..}) action = do- postgresBinDir <- (</> "bin") <$> buildNixSymlinkJoin' nc [postgresNixPostgres]+ postgresBinDir <- (</> "bin") <$> buildNixPackage' nc postgresNixPostgres withPostgresUnixSocket postgresBinDir postgresNixUsername postgresNixPassword postgresNixDatabase postgresNixConfExtraLines action -- | The lowest-level raw process version.
lib/Test/Sandwich/Contexts/ReverseProxy/TCP.hs view
@@ -17,6 +17,7 @@ import Test.Sandwich (expectationFailure) import UnliftIO.Async import UnliftIO.Exception+import UnliftIO.Timeout withProxyToUnixSocket :: MonadUnliftIO m => FilePath -> (PortNumber -> m a) -> m a@@ -29,8 +30,11 @@ SockAddrInet6 port _ _ _ -> putMVar portVar port x -> expectationFailure [i|withProxyToUnixSocket: expected to bind a TCP socket, but got other addr: #{x}|] )- withAsync (liftIO $ DCN.runTCPServer ss app `onException` (putMVar portVar 0)) $ \_ ->- readMVar portVar >>= f+ withAsync (liftIO $ DCN.runTCPServer ss app `onException` (tryPutMVar portVar (-1))) $ \_ ->+ timeout 60_000_000 (readMVar portVar) >>= \case+ Nothing -> expectationFailure [i|withProxyToUnixSocket: didn't get port within 60s|]+ Just (-1) -> expectationFailure [i|withProxyToUnixSocket: TCP server threw exception|]+ Just port -> f port where app appdata = DCNU.runUnixClient (DCNU.clientSettings socketPath) $ \appdataServer ->
lib/Test/Sandwich/Contexts/Util/Nix.hs view
@@ -3,18 +3,18 @@ withWritableBinaryCache ) where -import Control.Monad.Catch (MonadMask)+import Control.Monad.IO.Unlift import Control.Monad.Logger import Data.String.Interpolate import Relude import System.FilePath-import System.IO.Temp import Test.Sandwich.Logging import UnliftIO.Directory import UnliftIO.Process+import UnliftIO.Temporary -withWritableBinaryCache :: (MonadIO m, MonadMask m, MonadLogger m) => Maybe FilePath -> (Maybe FilePath -> m a) -> m a+withWritableBinaryCache :: (MonadUnliftIO m, MonadLogger m) => Maybe FilePath -> (Maybe FilePath -> m a) -> m a withWritableBinaryCache Nothing action = action Nothing withWritableBinaryCache (Just readOnlyPath) action = withSystemTempDirectory "writable-binary-cache" $ \dir -> do
sandwich-contexts.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.37.0.+-- This file has been generated from package.yaml by hpack version 0.38.0. -- -- see: https://github.com/sol/hpack name: sandwich-contexts-version: 0.3.0.2+version: 0.3.0.3 synopsis: Contexts for the Sandwich test library description: Please see the <https://codedownio.github.io/sandwich documentation>. author: Tom McLaughlin@@ -59,6 +59,8 @@ , conduit , conduit-extra >=1.3.7 , containers+ , crypton-connection+ , data-default , exceptions , filepath , http-client@@ -77,20 +79,12 @@ , string-interpolate , temporary , text- , time , transformers , unix-compat , unliftio , unliftio-core , vector default-language: Haskell2010- if impl(ghc >= 9.6)- build-depends:- crypton-connection- , data-default- if impl(ghc < 9.6)- build-depends:- connection test-suite tests type: exitcode-stdio-1.0
test/Spec.hs view
@@ -18,7 +18,6 @@ -- testsPooled = $(getSpecFromFolder $ defaultGetSpecFromFolderOptions { -- getSpecCombiner = 'describeParallel -- , getSpecIndividualSpecHooks = 'poolify--- , getSpecWarnOnParseError = NoWarnOnParseError -- }) -- main :: IO ()