graphql-engine/server/tests-hspec/Harness/RemoteServer.hs
Antoine Leblanc dc4a286c64 Prepare test suite for remote servers tests
## Description

This PR adds all the scaffolding for tests that require remote servers. It is mostly a refactor of `Feature`; where we listed for each test a list of individual backends, we now provide a list of `Context`s, that allows for tests to specify not only how it should be setup, but also what state needs to be carried around throughout the test. This will be useful when launching custom remote servers.

Additionally, this PR:
- cleans the way we generate logs in the engine as part of the tests
- cleans the cabal file
- introduce a few more helpers for sending commands to the engine (such as `postMetadata_`)
- allows for headers in queries sent to the engine (to support permissions tests)
- adds basic code to start / stop a "remote" server

This PR is a pre-requisite of #3567.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3573
Co-authored-by: jkachmar <8461423+jkachmar@users.noreply.github.com>
GitOrigin-RevId: 05f808c6b85729dbb3ea6648c3e10a3c16b641ef
2022-02-14 17:25:28 +00:00

48 lines
1.7 KiB
Haskell

-- | Functions to setup and run a dedicated graphql server.
module Harness.RemoteServer
( run,
)
where
-------------------------------------------------------------------------------
import Control.Concurrent (forkIO)
import Control.Exception.Safe (bracket)
import Control.Monad.IO.Class (liftIO)
import Data.Aeson qualified as Aeson
import Data.ByteString.Lazy.Char8 (ByteString)
import Harness.Http qualified as Http
import Harness.State (Server (..), serverUrl)
import Network.Socket qualified as Socket
import Network.Wai.Extended qualified as Wai
import Network.Wai.Handler.Warp qualified as Warp
import Web.Spock.Core qualified as Spock
import Prelude
-------------------------------------------------------------------------------
-- | Given a function that deals with an incoming GraphQL request, run a GraphQL
-- server. This function returns the resulting 'Server'.
run ::
-- | Given an incoming 'ByteString', return the resulting 'ByteString.
-- This signature is made to be compatible with Morpheus' @interpeter@.
(ByteString -> IO ByteString) ->
IO Server
run interpreter = do
let urlPrefix = "http://127.0.0.1"
port <- bracket (Warp.openFreePort) (Socket.close . snd) (pure . fst)
threadId <- forkIO $
Spock.runSpockNoBanner port $
Spock.spockT id $ do
Spock.get "/" $ do
Spock.json $ Aeson.String "OK"
Spock.post "/graphql" $ do
req <- Spock.request
body <- liftIO $ Wai.strictRequestBody req
result <- liftIO $ interpreter body
Spock.setHeader "Content-Type" "application/json; charset=utf-8"
Spock.lazyBytes result
let server = Server {port = fromIntegral port, urlPrefix, threadId}
Http.healthCheck $ serverUrl server
pure server