mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
chore(tests): pass BigQuery service account env var through to HGE
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8532 GitOrigin-RevId: 68e4c846e23369f476fa672b987d6769fad43cbf
This commit is contained in:
parent
5a81eaa9b6
commit
4905dc1675
@ -13,15 +13,16 @@ import Data.Char qualified as Char
|
||||
import Data.IORef
|
||||
import Data.List qualified as List
|
||||
import Database.PostgreSQL.Simple.Options qualified as Options
|
||||
import Harness.Constants qualified as Constants
|
||||
import Harness.Exceptions (HasCallStack, bracket)
|
||||
import Harness.GraphqlEngine (startServerThread)
|
||||
import Harness.Logging
|
||||
import Harness.Services.Composed (mkTestServicesConfig)
|
||||
import Harness.Test.BackendType (BackendType (..))
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment (..), Protocol (..), TestingMode (..), stopServer)
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment (..), PassthroughEnvVars (..), Protocol (..), TestingMode (..), stopServer)
|
||||
import Hasura.Prelude
|
||||
import System.Directory
|
||||
import System.Environment (getEnvironment)
|
||||
import System.Environment (getEnvironment, lookupEnv)
|
||||
import System.FilePath
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import System.Log.FastLogger qualified as FL
|
||||
@ -75,6 +76,7 @@ setupTestEnvironment :: TestingMode -> Logger -> IO GlobalTestEnvironment
|
||||
setupTestEnvironment testingMode logger = do
|
||||
server <- startServerThread
|
||||
servicesConfig <- mkTestServicesConfig
|
||||
passthroughEnvVars <- mkPassthroughEnv
|
||||
pure GlobalTestEnvironment {requestProtocol = HTTP, ..}
|
||||
|
||||
-- | tear down the shared server
|
||||
@ -138,3 +140,14 @@ globalConfigRef = unsafePerformIO $ newIORef Nothing
|
||||
setupGlobalConfig :: TestingMode -> FL.LogType -> IO ()
|
||||
setupGlobalConfig testingMode logType =
|
||||
writeIORef globalConfigRef $ Just (testingMode, logType)
|
||||
|
||||
envToPassthrough :: [String]
|
||||
envToPassthrough = [Constants.bigqueryServiceKeyVar]
|
||||
|
||||
-- | grab items from env to pass through to new HGE instances
|
||||
mkPassthroughEnv :: IO PassthroughEnvVars
|
||||
mkPassthroughEnv =
|
||||
let lookup' env = do
|
||||
value <- fromMaybe "" <$> lookupEnv env
|
||||
pure (env, value)
|
||||
in PassthroughEnvVars <$> traverse lookup' envToPassthrough
|
||||
|
@ -233,7 +233,8 @@ setup tables' (testEnvironment, _) = do
|
||||
}
|
||||
)
|
||||
tables'
|
||||
serviceAccount <- getServiceAccount
|
||||
-- add metadata using env var name so not to log the key
|
||||
let serviceAccountEnvVar = Constants.bigqueryServiceKeyVar
|
||||
projectId <- getProjectId
|
||||
-- create the dataset
|
||||
createDataset schemaName
|
||||
@ -249,7 +250,8 @@ setup tables' (testEnvironment, _) = do
|
||||
kind: *backendType
|
||||
tables: []
|
||||
configuration:
|
||||
service_account: *serviceAccount
|
||||
service_account:
|
||||
from_env: *serviceAccountEnvVar
|
||||
project_id: *projectId
|
||||
datasets: [*schemaName]
|
||||
retry_limit: 5
|
||||
|
@ -38,7 +38,7 @@ where
|
||||
import Data.HashSet qualified as Set
|
||||
import Data.Word (Word16)
|
||||
import Database.PG.Query qualified as PG
|
||||
import Harness.TestEnvironment (UniqueTestId)
|
||||
import Harness.UniqueTestId (UniqueTestId)
|
||||
import Hasura.Backends.Postgres.Connection.MonadTx (ExtensionsSchema (..))
|
||||
import Hasura.GraphQL.Execute.Subscription.Options qualified as ES
|
||||
import Hasura.GraphQL.Schema.Options qualified as Options
|
||||
|
105
server/lib/test-harness/src/Harness/GlobalTestEnvironment.hs
Normal file
105
server/lib/test-harness/src/Harness/GlobalTestEnvironment.hs
Normal file
@ -0,0 +1,105 @@
|
||||
-- | GlobalTestEnvironment shared by tests. We intentionally use an abstract type to
|
||||
-- wrap up the values we need for tests, with accessors. This way, the
|
||||
-- tests are less liable to refactorings when we add or change the
|
||||
-- globalTestEnvironment.
|
||||
module Harness.GlobalTestEnvironment
|
||||
( GlobalTestEnvironment (..),
|
||||
Protocol (..),
|
||||
Server (..),
|
||||
TestingMode (..),
|
||||
PassthroughEnvVars (..),
|
||||
serverUrl,
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Concurrent.Async (Async)
|
||||
import Data.Has
|
||||
import Data.Word
|
||||
import Database.PostgreSQL.Simple.Options (Options)
|
||||
import Harness.Logging.Messages
|
||||
import Harness.PassthroughEnvVars
|
||||
import Harness.Services.Composed qualified as Services
|
||||
import Harness.Test.BackendType
|
||||
import Hasura.Prelude
|
||||
import Network.WebSockets qualified as WS
|
||||
|
||||
-- | static information across an entire test suite run
|
||||
data GlobalTestEnvironment = GlobalTestEnvironment
|
||||
{ -- | shared function to log information from tests
|
||||
logger :: Logger,
|
||||
-- | the mode in which we're running the tests. See 'TestingMode' for
|
||||
-- details'.
|
||||
testingMode :: TestingMode,
|
||||
-- | connection details for the instance of HGE we're connecting to
|
||||
server :: Server,
|
||||
-- | The protocol with which we make server requests.
|
||||
requestProtocol :: Protocol,
|
||||
-- | Any environment variable names we wish to pass through to any new HGE
|
||||
-- instance
|
||||
passthroughEnvVars :: PassthroughEnvVars,
|
||||
servicesConfig :: Services.TestServicesConfig
|
||||
}
|
||||
|
||||
instance Has Logger GlobalTestEnvironment where
|
||||
getter = logger
|
||||
modifier f x = x {logger = f (logger x)}
|
||||
|
||||
instance Has Services.TestServicesConfig GlobalTestEnvironment where
|
||||
getter = servicesConfig
|
||||
modifier f x = x {servicesConfig = f (servicesConfig x)}
|
||||
|
||||
instance Has Services.HgeBinPath GlobalTestEnvironment where
|
||||
getter = getter . getter @Services.TestServicesConfig
|
||||
modifier f = modifier (modifier @_ @Services.TestServicesConfig f)
|
||||
|
||||
instance Has Services.PostgresServerUrl GlobalTestEnvironment where
|
||||
getter = getter . getter @Services.TestServicesConfig
|
||||
modifier f = modifier (modifier @_ @Services.TestServicesConfig f)
|
||||
|
||||
instance Has PassthroughEnvVars GlobalTestEnvironment where
|
||||
getter = passthroughEnvVars
|
||||
modifier f x = x {passthroughEnvVars = f (passthroughEnvVars x)}
|
||||
|
||||
instance Show GlobalTestEnvironment where
|
||||
show GlobalTestEnvironment {server} =
|
||||
"<GlobalTestEnvironment: " ++ urlPrefix server ++ ":" ++ show (port server) ++ " >"
|
||||
|
||||
-- | How should we make requests to `graphql-engine`? Both WebSocket- and HTTP-
|
||||
-- based requests are supported.
|
||||
data Protocol = HTTP | WebSocket WS.Connection
|
||||
|
||||
-- | Credentials for our testing modes. See 'SpecHook.setupTestingMode' for the
|
||||
-- practical consequences of this type.
|
||||
data TestingMode
|
||||
= -- | run all tests, unfiltered
|
||||
TestEverything
|
||||
| -- | run only tests containing this BackendType (or a RemoteSchema, so
|
||||
-- those aren't missed)
|
||||
TestBackend BackendType
|
||||
| -- | run "all the other tests"
|
||||
TestNoBackends
|
||||
| -- | test a Postgres-compatible using a custom connection string
|
||||
TestNewPostgresVariant Options
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
-- | Information about a server that we're working with.
|
||||
data Server = Server
|
||||
{ -- | The port to connect on.
|
||||
port :: Word16,
|
||||
-- | The full URI prefix e.g. http://localhost
|
||||
urlPrefix :: String,
|
||||
-- | The thread that the server is running on, so we can stop it later.
|
||||
thread :: Async ()
|
||||
}
|
||||
|
||||
instance Show Server where
|
||||
show = serverUrl
|
||||
|
||||
-- | Extracts the full URL prefix and port number from a given 'Server'.
|
||||
--
|
||||
-- @
|
||||
-- > serverUrl (Server 8080 "http://localhost" someThreadId)
|
||||
-- "http://localhost:8080"
|
||||
-- @
|
||||
serverUrl :: Server -> String
|
||||
serverUrl Server {urlPrefix, port} = urlPrefix ++ ":" ++ show port
|
12
server/lib/test-harness/src/Harness/PassthroughEnvVars.hs
Normal file
12
server/lib/test-harness/src/Harness/PassthroughEnvVars.hs
Normal file
@ -0,0 +1,12 @@
|
||||
-- | PassthroughEnvVars separated into own file for circular dep reasons
|
||||
module Harness.PassthroughEnvVars
|
||||
( PassthroughEnvVars (..),
|
||||
)
|
||||
where
|
||||
|
||||
import Hasura.Prelude
|
||||
|
||||
-- | When spawning new HGE instances from a binary, we may want to pass through
|
||||
-- some environment variables (for database credentials, for instance).
|
||||
newtype PassthroughEnvVars
|
||||
= PassthroughEnvVars [(String, String)]
|
@ -28,6 +28,7 @@ import Data.Vector (fromList)
|
||||
import Harness.Exceptions
|
||||
import Harness.Http qualified as Http
|
||||
import Harness.Logging
|
||||
import Harness.PassthroughEnvVars
|
||||
import Harness.Services.PostgresDb
|
||||
import Hasura.Prelude
|
||||
import Network.HTTP.Simple qualified as Http
|
||||
@ -65,20 +66,22 @@ emptyHgeConfig = HgeConfig []
|
||||
-- crashes. Ensuring that would require making Hge listen for heartbeats, or
|
||||
-- use a helper process that does.
|
||||
withHge ::
|
||||
( Has HgeBinPath a,
|
||||
Has PostgresServerUrl a,
|
||||
Has Logger a
|
||||
( Has HgeBinPath env,
|
||||
Has PostgresServerUrl env,
|
||||
Has Logger env,
|
||||
Has PassthroughEnvVars env
|
||||
) =>
|
||||
HgeConfig ->
|
||||
SpecWith (HgeServerInstance, a) ->
|
||||
SpecWith a
|
||||
SpecWith (HgeServerInstance, env) ->
|
||||
SpecWith env
|
||||
withHge hgeConfig specs = do
|
||||
flip aroundWith specs \action a -> runManaged do
|
||||
let hgeBin = getter a
|
||||
pgUrl = getter a
|
||||
let logger = getter @Logger a
|
||||
server <- spawnServer logger pgUrl hgeBin hgeConfig
|
||||
liftIO $ action (server, a)
|
||||
flip aroundWith specs \action env -> runManaged do
|
||||
let hgeBin = getter env
|
||||
pgUrl = getter env
|
||||
logger = getter @Logger env
|
||||
passthroughEnvVars = getter env
|
||||
server <- spawnServer logger pgUrl hgeBin hgeConfig passthroughEnvVars
|
||||
liftIO $ action (server, env)
|
||||
|
||||
-- | spin up a Manager HGE instance and check it is healthy
|
||||
spawnServer ::
|
||||
@ -86,10 +89,12 @@ spawnServer ::
|
||||
PostgresServerUrl ->
|
||||
HgeBinPath ->
|
||||
HgeConfig ->
|
||||
PassthroughEnvVars ->
|
||||
Managed HgeServerInstance
|
||||
spawnServer logger pgUrl (HgeBinPath hgeBinPath) (HgeConfig {hgeConfigEnvironmentVars}) = do
|
||||
spawnServer logger pgUrl (HgeBinPath hgeBinPath) (HgeConfig {hgeConfigEnvironmentVars}) (PassthroughEnvVars envVars) = do
|
||||
freshDb <- mkFreshPostgresDb logger pgUrl
|
||||
let metadataDbUrl = mkFreshDbConnectionString pgUrl freshDb
|
||||
let allEnv = hgeConfigEnvironmentVars <> envVars
|
||||
metadataDbUrl = mkFreshDbConnectionString pgUrl freshDb
|
||||
((_, Just hgeStdOut, Just hgeStdErr, _), port) <-
|
||||
managed
|
||||
( bracket
|
||||
@ -112,7 +117,7 @@ spawnServer logger pgUrl (HgeBinPath hgeBinPath) (HgeConfig {hgeConfigEnvironmen
|
||||
{ env =
|
||||
Just $
|
||||
("HASURA_GRAPHQL_GRACEFUL_SHUTDOWN_TIMEOUT", "0")
|
||||
: hgeConfigEnvironmentVars,
|
||||
: allEnv,
|
||||
std_out = CreatePipe,
|
||||
std_err = CreatePipe,
|
||||
create_group = True
|
||||
|
@ -132,6 +132,7 @@ hgeWithEnv env = do
|
||||
(getter globalTestEnvironment)
|
||||
(getter globalTestEnvironment)
|
||||
hgeConfig
|
||||
(getter globalTestEnvironment)
|
||||
liftIO $ useHgeInTestEnvironment globalTestEnvironment hgeServerInstance >>= specs
|
||||
)
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
module Harness.TestEnvironment
|
||||
( TestEnvironment (..),
|
||||
GlobalTestEnvironment (..),
|
||||
PassthroughEnvVars (..),
|
||||
Protocol (..),
|
||||
Server (..),
|
||||
TestingMode (..),
|
||||
@ -26,13 +27,9 @@ module Harness.TestEnvironment
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Concurrent.Async (Async)
|
||||
import Control.Concurrent.Async qualified as Async
|
||||
import Data.Char qualified
|
||||
import Data.Has
|
||||
import Data.UUID (UUID)
|
||||
import Data.Word
|
||||
import Database.PostgreSQL.Simple.Options (Options)
|
||||
import Harness.GlobalTestEnvironment
|
||||
import Harness.Logging.Messages
|
||||
import Harness.Permissions.Types (Permission)
|
||||
import Harness.Services.Composed qualified as Services
|
||||
@ -40,53 +37,12 @@ import Harness.Test.BackendType
|
||||
import Harness.Test.CustomOptions qualified as Custom
|
||||
import Harness.Test.FixtureName
|
||||
import Harness.Test.ScalarType
|
||||
import Harness.UniqueTestId
|
||||
import Harness.Yaml
|
||||
import Hasura.Prelude
|
||||
import Network.WebSockets qualified as WS
|
||||
import System.Process (readProcess)
|
||||
import Text.Pretty.Simple
|
||||
|
||||
newtype UniqueTestId = UniqueTestId {getUniqueTestId :: UUID}
|
||||
|
||||
-- | Sanitise UUID for use in BigQuery dataset name
|
||||
-- must be alphanumeric (plus underscores)
|
||||
instance Show UniqueTestId where
|
||||
show (UniqueTestId uuid) =
|
||||
fmap
|
||||
( \a ->
|
||||
if Data.Char.isAlphaNum a
|
||||
then a
|
||||
else '_'
|
||||
)
|
||||
. show
|
||||
$ uuid
|
||||
|
||||
-- | static information across an entire test suite run
|
||||
data GlobalTestEnvironment = GlobalTestEnvironment
|
||||
{ -- | shared function to log information from tests
|
||||
logger :: Logger,
|
||||
-- | the mode in which we're running the tests. See 'TestingMode' for
|
||||
-- details'.
|
||||
testingMode :: TestingMode,
|
||||
-- | connection details for the instance of HGE we're connecting to
|
||||
server :: Server,
|
||||
-- | The protocol with which we make server requests.
|
||||
requestProtocol :: Protocol,
|
||||
servicesConfig :: Services.TestServicesConfig
|
||||
}
|
||||
|
||||
instance Has Logger GlobalTestEnvironment where
|
||||
getter = logger
|
||||
modifier f x = x {logger = f (logger x)}
|
||||
|
||||
instance Has GlobalTestEnvironment TestEnvironment where
|
||||
getter = globalEnvironment
|
||||
modifier f x = x {globalEnvironment = f (globalEnvironment x)}
|
||||
|
||||
instance Show GlobalTestEnvironment where
|
||||
show GlobalTestEnvironment {server} =
|
||||
"<GlobalTestEnvironment: " ++ urlPrefix server ++ ":" ++ show (port server) ++ " >"
|
||||
|
||||
-- | A testEnvironment that's passed to all tests.
|
||||
data TestEnvironment = TestEnvironment
|
||||
{ -- | shared setup not related to a particular test
|
||||
@ -112,10 +68,6 @@ scalarTypeToText TestEnvironment {fixtureName} = case fixtureName of
|
||||
-- the given permissions will be applied.
|
||||
data TestingRole = Admin | NonAdmin [Permission]
|
||||
|
||||
-- | How should we make requests to `graphql-engine`? Both WebSocket- and HTTP-
|
||||
-- based requests are supported.
|
||||
data Protocol = HTTP | WebSocket WS.Connection
|
||||
|
||||
instance Has Logger TestEnvironment where
|
||||
getter = logger . globalEnvironment
|
||||
modifier f x =
|
||||
@ -129,17 +81,9 @@ instance Has Logger TestEnvironment where
|
||||
}
|
||||
}
|
||||
|
||||
instance Has Services.TestServicesConfig GlobalTestEnvironment where
|
||||
getter = servicesConfig
|
||||
modifier f x = x {servicesConfig = f (servicesConfig x)}
|
||||
|
||||
instance Has Services.HgeBinPath GlobalTestEnvironment where
|
||||
getter = getter . getter @Services.TestServicesConfig
|
||||
modifier f = modifier (modifier @_ @Services.TestServicesConfig f)
|
||||
|
||||
instance Has Services.PostgresServerUrl GlobalTestEnvironment where
|
||||
getter = getter . getter @Services.TestServicesConfig
|
||||
modifier f = modifier (modifier @_ @Services.TestServicesConfig f)
|
||||
instance Has GlobalTestEnvironment TestEnvironment where
|
||||
getter = globalEnvironment
|
||||
modifier f x = x {globalEnvironment = f (globalEnvironment x)}
|
||||
|
||||
instance Has Services.TestServicesConfig TestEnvironment where
|
||||
getter = getter . getter @GlobalTestEnvironment
|
||||
@ -196,46 +140,10 @@ focusFixtureRight testEnv =
|
||||
_ -> error "Could not focus on right-hand FixtureName"
|
||||
}
|
||||
|
||||
-- | Credentials for our testing modes. See 'SpecHook.setupTestingMode' for the
|
||||
-- practical consequences of this type.
|
||||
data TestingMode
|
||||
= -- | run all tests, unfiltered
|
||||
TestEverything
|
||||
| -- | run only tests containing this BackendType (or a RemoteSchema, so
|
||||
-- those aren't missed)
|
||||
TestBackend BackendType
|
||||
| -- | run "all the other tests"
|
||||
TestNoBackends
|
||||
| -- | test a Postgres-compatible using a custom connection string
|
||||
TestNewPostgresVariant Options
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
-- | Information about a server that we're working with.
|
||||
data Server = Server
|
||||
{ -- | The port to connect on.
|
||||
port :: Word16,
|
||||
-- | The full URI prefix e.g. http://localhost
|
||||
urlPrefix :: String,
|
||||
-- | The thread that the server is running on, so we can stop it later.
|
||||
thread :: Async ()
|
||||
}
|
||||
|
||||
instance Show Server where
|
||||
show = serverUrl
|
||||
|
||||
-- | Retrieve the 'Server' associated with some 'TestEnvironment'.
|
||||
getServer :: TestEnvironment -> Server
|
||||
getServer TestEnvironment {globalEnvironment} = server globalEnvironment
|
||||
|
||||
-- | Extracts the full URL prefix and port number from a given 'Server'.
|
||||
--
|
||||
-- @
|
||||
-- > serverUrl (Server 8080 "http://localhost" someThreadId)
|
||||
-- "http://localhost:8080"
|
||||
-- @
|
||||
serverUrl :: Server -> String
|
||||
serverUrl Server {urlPrefix, port} = urlPrefix ++ ":" ++ show port
|
||||
|
||||
-- | Retrieve the 'TestingMode' associated with some 'TestEnvironment'
|
||||
getTestingMode :: TestEnvironment -> TestingMode
|
||||
getTestingMode = testingMode . globalEnvironment
|
||||
|
24
server/lib/test-harness/src/Harness/UniqueTestId.hs
Normal file
24
server/lib/test-harness/src/Harness/UniqueTestId.hs
Normal file
@ -0,0 +1,24 @@
|
||||
-- | Extracted from `TestEnvironment` to stop circular dep hell
|
||||
module Harness.UniqueTestId
|
||||
( UniqueTestId (..),
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Char qualified
|
||||
import Data.UUID (UUID)
|
||||
import Hasura.Prelude
|
||||
|
||||
newtype UniqueTestId = UniqueTestId {getUniqueTestId :: UUID}
|
||||
|
||||
-- | Sanitise UUID for use in BigQuery dataset name
|
||||
-- must be alphanumeric (plus underscores)
|
||||
instance Show UniqueTestId where
|
||||
show (UniqueTestId uuid) =
|
||||
fmap
|
||||
( \a ->
|
||||
if Data.Char.isAlphaNum a
|
||||
then a
|
||||
else '_'
|
||||
)
|
||||
. show
|
||||
$ uuid
|
@ -133,10 +133,12 @@ library
|
||||
Harness.DataConnectorAgent
|
||||
Harness.Env
|
||||
Harness.Exceptions
|
||||
Harness.GlobalTestEnvironment
|
||||
Harness.GraphqlEngine
|
||||
Harness.Http
|
||||
Harness.Logging
|
||||
Harness.Logging.Messages
|
||||
Harness.PassthroughEnvVars
|
||||
Harness.Permissions
|
||||
Harness.PytestPortedCompat
|
||||
Harness.Quoter.Graphql
|
||||
@ -162,6 +164,7 @@ library
|
||||
Harness.Test.SetupAction
|
||||
Harness.Test.TestResource
|
||||
Harness.TestEnvironment
|
||||
Harness.UniqueTestId
|
||||
Harness.WebSockets
|
||||
Harness.Webhook
|
||||
Harness.Yaml
|
||||
|
Loading…
Reference in New Issue
Block a user