mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-08-16 22:21:06 +03:00
Use Dataset Clones for all SQLite tests
[GDC-718]: https://hasurahq.atlassian.net/browse/GDC-718?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7743 GitOrigin-RevId: 6c3577c1d4ffd2212a72b6e1a24e0e384f2db046
This commit is contained in:
parent
1fe7fe43b8
commit
b012f2ebc7
@ -25,12 +25,13 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "65007:8100"
|
- "65007:8100"
|
||||||
volumes:
|
volumes:
|
||||||
- "./sqlite/test/db.chinook.sqlite:/db.chinook.sqlite"
|
- "./sqlite/dataset_templates:/app/sqlite/dataset_templates"
|
||||||
- "./sqlite/test/db.sqlite:/db.sqlite"
|
|
||||||
environment:
|
environment:
|
||||||
METRICS: y
|
METRICS: y
|
||||||
PRETTY_PRINT_LOGS: y
|
PRETTY_PRINT_LOGS: y
|
||||||
LOG_LEVEL: debug
|
LOG_LEVEL: debug
|
||||||
|
DATASETS: y
|
||||||
|
DATASET_DELETE: y
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
- CMD
|
- CMD
|
||||||
|
@ -69,7 +69,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- reference-agent
|
- reference-agent
|
||||||
image: "hasura/dc-agent-tests:${HASURA_VERSION}"
|
image: "hasura/dc-agent-tests:${HASURA_VERSION}"
|
||||||
command: ["tests-dc-api", 'test', '-u', 'http://reference-agent:8100', '-s', '{}']
|
command: ["tests-dc-api", 'test', '--agent-base-url', 'http://reference-agent:8100']
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
|
|
||||||
swagger-ui:
|
swagger-ui:
|
||||||
|
2
dc-agents/sqlite/.gitignore
vendored
2
dc-agents/sqlite/.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
./*.sqlite
|
./*.sqlite
|
||||||
./dataset_clones/
|
dataset_clones/
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -66,7 +66,7 @@ function mkTemplatePath(name: string): string {
|
|||||||
if(name != safeName) {
|
if(name != safeName) {
|
||||||
throw(Error(`Template name ${name} is not valid.`));
|
throw(Error(`Template name ${name} is not valid.`));
|
||||||
}
|
}
|
||||||
return path.join(DATASET_TEMPLATES, safeName);
|
return path.join(DATASET_TEMPLATES, safeName + ".sqlite");
|
||||||
}
|
}
|
||||||
|
|
||||||
function mkClonePath(name: string): string {
|
function mkClonePath(name: string): string {
|
||||||
@ -75,5 +75,5 @@ function mkClonePath(name: string): string {
|
|||||||
if(name != safeName) {
|
if(name != safeName) {
|
||||||
throw(Error(`Template name ${name} is not valid.`));
|
throw(Error(`Template name ${name} is not valid.`));
|
||||||
}
|
}
|
||||||
return path.join(DATASET_CLONES, safeName);
|
return path.join(DATASET_CLONES, safeName + ".sqlite");
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ addSource =
|
|||||||
name: myfoobar
|
name: myfoobar
|
||||||
replace_configuration: false
|
replace_configuration: false
|
||||||
configuration:
|
configuration:
|
||||||
db: /db.chinook.sqlite
|
value: {}
|
||||||
|]
|
|]
|
||||||
|
|
||||||
listSourceKinds :: Value
|
listSourceKinds :: Value
|
||||||
|
@ -13,13 +13,11 @@ import Data.Aeson qualified as Aeson
|
|||||||
import Data.Aeson.Lens (key, _Array)
|
import Data.Aeson.Lens (key, _Array)
|
||||||
import Data.List.NonEmpty qualified as NE
|
import Data.List.NonEmpty qualified as NE
|
||||||
import Data.Vector qualified as Vector
|
import Data.Vector qualified as Vector
|
||||||
import Harness.Backend.DataConnector.Chinook qualified as Chinook
|
|
||||||
import Harness.Backend.DataConnector.Chinook.Reference qualified as Reference
|
import Harness.Backend.DataConnector.Chinook.Reference qualified as Reference
|
||||||
import Harness.Backend.DataConnector.Chinook.Sqlite qualified as Sqlite
|
import Harness.Backend.DataConnector.Chinook.Sqlite qualified as Sqlite
|
||||||
import Harness.GraphqlEngine qualified as GraphqlEngine
|
import Harness.GraphqlEngine qualified as GraphqlEngine
|
||||||
import Harness.Quoter.Graphql (graphql)
|
import Harness.Quoter.Graphql (graphql)
|
||||||
import Harness.Quoter.Yaml (yaml)
|
import Harness.Quoter.Yaml (yaml)
|
||||||
import Harness.Test.BackendType (BackendTypeConfig)
|
|
||||||
import Harness.Test.Fixture qualified as Fixture
|
import Harness.Test.Fixture qualified as Fixture
|
||||||
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
||||||
import Harness.TestEnvironment qualified as TE
|
import Harness.TestEnvironment qualified as TE
|
||||||
@ -33,67 +31,14 @@ spec :: SpecWith GlobalTestEnvironment
|
|||||||
spec =
|
spec =
|
||||||
Fixture.runWithLocalTestEnvironment
|
Fixture.runWithLocalTestEnvironment
|
||||||
( NE.fromList
|
( NE.fromList
|
||||||
[ (Fixture.fixture $ Fixture.Backend Reference.backendTypeMetadata)
|
[ Reference.chinookFixture,
|
||||||
{ Fixture.setupTeardown = \(testEnvironment, _) ->
|
Sqlite.chinookFixture
|
||||||
[ Chinook.setupAction (sourceMetadata Reference.backendTypeMetadata Reference.sourceConfiguration) Reference.agentConfig testEnvironment
|
|
||||||
]
|
|
||||||
},
|
|
||||||
(Fixture.fixture $ Fixture.Backend Sqlite.backendTypeMetadata)
|
|
||||||
{ Fixture.setupTeardown = \(testEnvironment, _) ->
|
|
||||||
[ Chinook.setupAction (sourceMetadata Sqlite.backendTypeMetadata Sqlite.sourceConfiguration) Sqlite.agentConfig testEnvironment
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
tests
|
tests
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
sourceMetadata :: BackendTypeConfig -> Aeson.Value -> Aeson.Value
|
|
||||||
sourceMetadata backendTypeMetadata config =
|
|
||||||
let source = Fixture.backendSourceName backendTypeMetadata
|
|
||||||
backendTypeString = Fixture.backendTypeString backendTypeMetadata
|
|
||||||
in [yaml|
|
|
||||||
name : *source
|
|
||||||
kind: *backendTypeString
|
|
||||||
tables:
|
|
||||||
- table: [Album]
|
|
||||||
object_relationships:
|
|
||||||
- name: Artist
|
|
||||||
using:
|
|
||||||
manual_configuration:
|
|
||||||
remote_table: [Artist]
|
|
||||||
column_mapping:
|
|
||||||
ArtistId: ArtistId
|
|
||||||
- table: [Artist]
|
|
||||||
array_relationships:
|
|
||||||
- name: Albums
|
|
||||||
using:
|
|
||||||
manual_configuration:
|
|
||||||
remote_table: [Album]
|
|
||||||
column_mapping:
|
|
||||||
ArtistId: ArtistId
|
|
||||||
- table: [Invoice]
|
|
||||||
array_relationships:
|
|
||||||
- name: InvoiceLines
|
|
||||||
using:
|
|
||||||
manual_configuration:
|
|
||||||
remote_table: [InvoiceLine]
|
|
||||||
column_mapping:
|
|
||||||
InvoiceId: InvoiceId
|
|
||||||
- table: [InvoiceLine]
|
|
||||||
object_relationships:
|
|
||||||
- name: Invoice
|
|
||||||
using:
|
|
||||||
manual_configuration:
|
|
||||||
remote_table: [Invoice]
|
|
||||||
column_mapping:
|
|
||||||
InvoiceId: InvoiceId
|
|
||||||
configuration: *config
|
|
||||||
|]
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
tests :: Fixture.Options -> SpecWith (TestEnvironment, a)
|
tests :: Fixture.Options -> SpecWith (TestEnvironment, a)
|
||||||
tests opts = describe "Aggregate Query Tests" $ do
|
tests opts = describe "Aggregate Query Tests" $ do
|
||||||
nodeTests opts
|
nodeTests opts
|
||||||
|
@ -22,7 +22,7 @@ import Data.Aeson.KeyMap qualified as KM
|
|||||||
import Data.Aeson.Lens
|
import Data.Aeson.Lens
|
||||||
import Data.List.NonEmpty qualified as NE
|
import Data.List.NonEmpty qualified as NE
|
||||||
import Data.Vector qualified as Vector
|
import Data.Vector qualified as Vector
|
||||||
import Harness.Backend.DataConnector.Chinook (ChinookTestEnv)
|
import Harness.Backend.DataConnector.Chinook (ChinookTestEnv, NameFormatting (..))
|
||||||
import Harness.Backend.DataConnector.Chinook qualified as Chinook
|
import Harness.Backend.DataConnector.Chinook qualified as Chinook
|
||||||
import Harness.Backend.DataConnector.Chinook.Reference qualified as Reference
|
import Harness.Backend.DataConnector.Chinook.Reference qualified as Reference
|
||||||
import Harness.Backend.DataConnector.Chinook.Sqlite qualified as Sqlite
|
import Harness.Backend.DataConnector.Chinook.Sqlite qualified as Sqlite
|
||||||
@ -47,15 +47,15 @@ spec = do
|
|||||||
Fixture.runWithLocalTestEnvironmentSingleSetup
|
Fixture.runWithLocalTestEnvironmentSingleSetup
|
||||||
( NE.fromList
|
( NE.fromList
|
||||||
[ Fixture
|
[ Fixture
|
||||||
{ name = Fixture.Backend Reference.backendTypeMetadata,
|
{ name = Fixture.Backend Reference.backendTypeConfig,
|
||||||
mkLocalTestEnvironment = \_ -> pure $ Chinook.ChinookTestEnv Reference.sourceConfiguration id id id,
|
mkLocalTestEnvironment = Reference.mkChinookStaticTestEnvironment,
|
||||||
setupTeardown = \(testEnv, _localEnv) ->
|
setupTeardown = \(testEnv, _localEnv) ->
|
||||||
[emptySetupAction testEnv],
|
[emptySetupAction testEnv],
|
||||||
customOptions = Nothing
|
customOptions = Nothing
|
||||||
},
|
},
|
||||||
Fixture
|
Fixture
|
||||||
{ name = Fixture.Backend Sqlite.backendTypeMetadata,
|
{ name = Fixture.Backend Sqlite.backendTypeConfig,
|
||||||
mkLocalTestEnvironment = \_ -> pure $ Chinook.ChinookTestEnv Sqlite.sourceConfiguration id id Sqlite.formatForeignKeyName,
|
mkLocalTestEnvironment = Sqlite.mkChinookCloneTestEnvironment,
|
||||||
setupTeardown = \(testEnv, _localEnv) ->
|
setupTeardown = \(testEnv, _localEnv) ->
|
||||||
[emptySetupAction testEnv],
|
[emptySetupAction testEnv],
|
||||||
customOptions = Nothing
|
customOptions = Nothing
|
||||||
@ -66,20 +66,8 @@ spec = do
|
|||||||
|
|
||||||
Fixture.runWithLocalTestEnvironmentSingleSetup
|
Fixture.runWithLocalTestEnvironmentSingleSetup
|
||||||
( NE.fromList
|
( NE.fromList
|
||||||
[ Fixture
|
[ Reference.chinookFixture,
|
||||||
{ name = Fixture.Backend Reference.backendTypeMetadata,
|
Sqlite.chinookFixture
|
||||||
mkLocalTestEnvironment = \_ -> pure $ Chinook.ChinookTestEnv Reference.sourceConfiguration id id id,
|
|
||||||
setupTeardown = \(testEnv, _localEnv) ->
|
|
||||||
[Chinook.setupAction Chinook.referenceSourceConfig Reference.agentConfig testEnv],
|
|
||||||
customOptions = Nothing
|
|
||||||
},
|
|
||||||
Fixture
|
|
||||||
{ name = Fixture.Backend Sqlite.backendTypeMetadata,
|
|
||||||
mkLocalTestEnvironment = \_ -> pure $ Chinook.ChinookTestEnv Sqlite.sourceConfiguration id id Sqlite.formatForeignKeyName,
|
|
||||||
setupTeardown = \(testEnv, _localEnv) ->
|
|
||||||
[Chinook.setupAction Chinook.sqliteSourceConfig Sqlite.agentConfig testEnv],
|
|
||||||
customOptions = Nothing
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
schemaInspectionTests
|
schemaInspectionTests
|
||||||
@ -89,7 +77,7 @@ spec = do
|
|||||||
schemaInspectionTests :: Fixture.Options -> SpecWith (TestEnvironment, ChinookTestEnv)
|
schemaInspectionTests :: Fixture.Options -> SpecWith (TestEnvironment, ChinookTestEnv)
|
||||||
schemaInspectionTests opts = describe "Schema and Source Inspection" $ do
|
schemaInspectionTests opts = describe "Schema and Source Inspection" $ do
|
||||||
describe "get_source_tables" $ do
|
describe "get_source_tables" $ do
|
||||||
it "success" $ \(testEnvironment, Chinook.ChinookTestEnv {..}) -> do
|
it "success" $ \(testEnvironment, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}}) -> do
|
||||||
let sortYamlArray :: J.Value -> IO J.Value
|
let sortYamlArray :: J.Value -> IO J.Value
|
||||||
sortYamlArray (J.Array a) = pure $ J.Array (Vector.fromList (sort (Vector.toList a)))
|
sortYamlArray (J.Array a) = pure $ J.Array (Vector.fromList (sort (Vector.toList a)))
|
||||||
sortYamlArray _ = fail "Should return Array"
|
sortYamlArray _ = fail "Should return Array"
|
||||||
@ -97,17 +85,17 @@ schemaInspectionTests opts = describe "Schema and Source Inspection" $ do
|
|||||||
case BackendType.backendSourceName <$> getBackendTypeConfig testEnvironment of
|
case BackendType.backendSourceName <$> getBackendTypeConfig testEnvironment of
|
||||||
Nothing -> pendingWith "Backend not found for testEnvironment"
|
Nothing -> pendingWith "Backend not found for testEnvironment"
|
||||||
Just sourceString -> do
|
Just sourceString -> do
|
||||||
let album = formatTableName ["Album"]
|
let album = _nfFormatTableName ["Album"]
|
||||||
artist = formatTableName ["Artist"]
|
artist = _nfFormatTableName ["Artist"]
|
||||||
customer = formatTableName ["Customer"]
|
customer = _nfFormatTableName ["Customer"]
|
||||||
employee = formatTableName ["Employee"]
|
employee = _nfFormatTableName ["Employee"]
|
||||||
genre = formatTableName ["Genre"]
|
genre = _nfFormatTableName ["Genre"]
|
||||||
invoice = formatTableName ["Invoice"]
|
invoice = _nfFormatTableName ["Invoice"]
|
||||||
invoiceLine = formatTableName ["InvoiceLine"]
|
invoiceLine = _nfFormatTableName ["InvoiceLine"]
|
||||||
mediaType = formatTableName ["MediaType"]
|
mediaType = _nfFormatTableName ["MediaType"]
|
||||||
playlist = formatTableName ["Playlist"]
|
playlist = _nfFormatTableName ["Playlist"]
|
||||||
playlistTrack = formatTableName ["PlaylistTrack"]
|
playlistTrack = _nfFormatTableName ["PlaylistTrack"]
|
||||||
track = formatTableName ["Track"]
|
track = _nfFormatTableName ["Track"]
|
||||||
shouldReturnYamlF
|
shouldReturnYamlF
|
||||||
sortYamlArray
|
sortYamlArray
|
||||||
opts
|
opts
|
||||||
@ -134,7 +122,7 @@ schemaInspectionTests opts = describe "Schema and Source Inspection" $ do
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
describe "get_table_info" $ do
|
describe "get_table_info" $ do
|
||||||
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {..}) -> do
|
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}}) -> do
|
||||||
let removeDescriptions (J.Object o) = J.Object (KM.delete "description" (removeDescriptions <$> o))
|
let removeDescriptions (J.Object o) = J.Object (KM.delete "description" (removeDescriptions <$> o))
|
||||||
removeDescriptions (J.Array a) = J.Array (removeDescriptions <$> a)
|
removeDescriptions (J.Array a) = J.Array (removeDescriptions <$> a)
|
||||||
removeDescriptions x = x
|
removeDescriptions x = x
|
||||||
@ -153,12 +141,12 @@ schemaInspectionTests opts = describe "Schema and Source Inspection" $ do
|
|||||||
case BackendType.backendSourceName <$> getBackendTypeConfig testEnvironment of
|
case BackendType.backendSourceName <$> getBackendTypeConfig testEnvironment of
|
||||||
Nothing -> pendingWith "Backend not found for testEnvironment"
|
Nothing -> pendingWith "Backend not found for testEnvironment"
|
||||||
Just sourceString -> do
|
Just sourceString -> do
|
||||||
let album = formatTableName ["Album"]
|
let album = _nfFormatTableName ["Album"]
|
||||||
artist = formatTableName ["Artist"]
|
artist = _nfFormatTableName ["Artist"]
|
||||||
albumId = formatColumnName "AlbumId"
|
albumId = _nfFormatColumnName "AlbumId"
|
||||||
artistId = formatColumnName "ArtistId"
|
artistId = _nfFormatColumnName "ArtistId"
|
||||||
title = formatColumnName "Title"
|
title = _nfFormatColumnName "Title"
|
||||||
artistForeignKeys = formatForeignKeyName "Artist"
|
artistForeignKeys = _nfFormatForeignKeyName "Artist"
|
||||||
shouldReturnYamlF
|
shouldReturnYamlF
|
||||||
(pure . removeDescriptions)
|
(pure . removeDescriptions)
|
||||||
opts
|
opts
|
||||||
@ -341,12 +329,12 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
describe "<kind>_track_table" $ do
|
describe "<kind>_track_table" $ do
|
||||||
it "success" $ \(testEnvironment, Chinook.ChinookTestEnv {..}) -> do
|
it "success" $ \(testEnvironment, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}}) -> do
|
||||||
case (backendTypeString &&& backendSourceName) <$> TestEnvironment.getBackendTypeConfig testEnvironment of
|
case (backendTypeString &&& backendSourceName) <$> TestEnvironment.getBackendTypeConfig testEnvironment of
|
||||||
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
||||||
Just (backendType, sourceName) -> do
|
Just (backendType, sourceName) -> do
|
||||||
let actionType = backendType <> "_track_table"
|
let actionType = backendType <> "_track_table"
|
||||||
album = formatTableName ["Album"]
|
album = _nfFormatTableName ["Album"]
|
||||||
shouldReturnYaml
|
shouldReturnYaml
|
||||||
opts
|
opts
|
||||||
( GraphqlEngine.postMetadata
|
( GraphqlEngine.postMetadata
|
||||||
@ -363,15 +351,15 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
describe "<kind>_create_object_relationship" $ do
|
describe "<kind>_create_object_relationship" $ do
|
||||||
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {..}) -> do
|
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}}) -> do
|
||||||
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
||||||
case (backendTypeString &&& backendSourceName) <$> getBackendTypeConfig testEnvironment of
|
case (backendTypeString &&& backendSourceName) <$> getBackendTypeConfig testEnvironment of
|
||||||
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
||||||
Just (backendType, sourceName) -> do
|
Just (backendType, sourceName) -> do
|
||||||
let actionType = backendType <> "_track_table"
|
let actionType = backendType <> "_track_table"
|
||||||
artistTable = formatTableName ["Artist"]
|
artistTable = _nfFormatTableName ["Artist"]
|
||||||
albumTable = formatTableName ["Album"]
|
albumTable = _nfFormatTableName ["Album"]
|
||||||
artistId = formatColumnName "ArtistId"
|
artistId = _nfFormatColumnName "ArtistId"
|
||||||
GraphqlEngine.postMetadata_
|
GraphqlEngine.postMetadata_
|
||||||
testEnvironment
|
testEnvironment
|
||||||
[yaml|
|
[yaml|
|
||||||
@ -406,7 +394,7 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
describe "<kind>_create_array_relationship" $ do
|
describe "<kind>_create_array_relationship" $ do
|
||||||
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {..}) -> do
|
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}}) -> do
|
||||||
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
||||||
when
|
when
|
||||||
(foreignKeySupport == Just False)
|
(foreignKeySupport == Just False)
|
||||||
@ -415,9 +403,9 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
||||||
Just (backendType, sourceName) -> do
|
Just (backendType, sourceName) -> do
|
||||||
let actionType = backendType <> "_create_array_relationship"
|
let actionType = backendType <> "_create_array_relationship"
|
||||||
albumTable = formatTableName ["Album"]
|
albumTable = _nfFormatTableName ["Album"]
|
||||||
artistTable = formatTableName ["Artist"]
|
artistTable = _nfFormatTableName ["Artist"]
|
||||||
artistId = formatColumnName "ArtistId"
|
artistId = _nfFormatColumnName "ArtistId"
|
||||||
shouldReturnYaml
|
shouldReturnYaml
|
||||||
opts
|
opts
|
||||||
( GraphqlEngine.postMetadata
|
( GraphqlEngine.postMetadata
|
||||||
@ -440,14 +428,14 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
describe "export_metadata" $ do
|
describe "export_metadata" $ do
|
||||||
it "produces the expected metadata structure" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {..}) -> do
|
it "produces the expected metadata structure" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}, ..}) -> do
|
||||||
case ((fold . backendServerUrl) &&& backendTypeString &&& backendSourceName) <$> TestEnvironment.getBackendTypeConfig testEnvironment of
|
case ((fold . backendServerUrl) &&& backendTypeString &&& backendSourceName) <$> TestEnvironment.getBackendTypeConfig testEnvironment of
|
||||||
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
||||||
Just (agentUrl, (backendType, sourceName)) -> do
|
Just (agentUrl, (backendType, sourceName)) -> do
|
||||||
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
||||||
albumTable = formatTableName ["Album"]
|
albumTable = _nfFormatTableName ["Album"]
|
||||||
artistTable = formatTableName ["Artist"]
|
artistTable = _nfFormatTableName ["Artist"]
|
||||||
artistId = formatColumnName "ArtistId"
|
artistId = _nfFormatColumnName "ArtistId"
|
||||||
shouldReturnYaml
|
shouldReturnYaml
|
||||||
opts
|
opts
|
||||||
( GraphqlEngine.postMetadata
|
( GraphqlEngine.postMetadata
|
||||||
@ -500,7 +488,7 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
describe "<kind>_drop_relationship" $ do
|
describe "<kind>_drop_relationship" $ do
|
||||||
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {..}) -> do
|
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}}) -> do
|
||||||
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
||||||
when
|
when
|
||||||
(foreignKeySupport == Just False)
|
(foreignKeySupport == Just False)
|
||||||
@ -509,7 +497,7 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
||||||
Just (backendType, sourceName) -> do
|
Just (backendType, sourceName) -> do
|
||||||
let actionType = backendType <> "_drop_relationship"
|
let actionType = backendType <> "_drop_relationship"
|
||||||
artistTable = formatTableName ["Artist"]
|
artistTable = _nfFormatTableName ["Artist"]
|
||||||
shouldReturnYaml
|
shouldReturnYaml
|
||||||
opts
|
opts
|
||||||
( GraphqlEngine.postMetadata
|
( GraphqlEngine.postMetadata
|
||||||
@ -527,7 +515,7 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
describe "<kind>_untrack_table" $ do
|
describe "<kind>_untrack_table" $ do
|
||||||
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {..}) -> do
|
it "success" $ \(testEnvironment@TestEnvironment {}, Chinook.ChinookTestEnv {nameFormatting = NameFormatting {..}}) -> do
|
||||||
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
let foreignKeySupport = (getBackendTypeConfig testEnvironment >>= BackendType.parseCapabilities) <&> API._dscSupportsForeignKeys . API._cDataSchema
|
||||||
when
|
when
|
||||||
(foreignKeySupport == Just False)
|
(foreignKeySupport == Just False)
|
||||||
@ -536,7 +524,7 @@ schemaCrudTests opts = describe "A series of actions to setup and teardown a sou
|
|||||||
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
Nothing -> pendingWith "Backend Type not found in testEnvironment"
|
||||||
Just (backendType, sourceName) -> do
|
Just (backendType, sourceName) -> do
|
||||||
let actionType = backendType <> "_untrack_table"
|
let actionType = backendType <> "_untrack_table"
|
||||||
artistTable = formatTableName ["Artist"]
|
artistTable = _nfFormatTableName ["Artist"]
|
||||||
shouldReturnYaml
|
shouldReturnYaml
|
||||||
opts
|
opts
|
||||||
( GraphqlEngine.postMetadata
|
( GraphqlEngine.postMetadata
|
||||||
|
@ -25,7 +25,6 @@ where
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
import Data.List.NonEmpty qualified as NE
|
import Data.List.NonEmpty qualified as NE
|
||||||
import Harness.Backend.DataConnector.Chinook qualified as Chinook
|
|
||||||
import Harness.Backend.DataConnector.Chinook.Reference qualified as Reference
|
import Harness.Backend.DataConnector.Chinook.Reference qualified as Reference
|
||||||
import Harness.Backend.DataConnector.Chinook.Sqlite qualified as Sqlite
|
import Harness.Backend.DataConnector.Chinook.Sqlite qualified as Sqlite
|
||||||
import Harness.GraphqlEngine qualified as GraphqlEngine
|
import Harness.GraphqlEngine qualified as GraphqlEngine
|
||||||
@ -46,14 +45,8 @@ spec :: SpecWith GlobalTestEnvironment
|
|||||||
spec =
|
spec =
|
||||||
Fixture.runWithLocalTestEnvironment
|
Fixture.runWithLocalTestEnvironment
|
||||||
( NE.fromList
|
( NE.fromList
|
||||||
[ (Fixture.fixture $ Fixture.Backend Reference.backendTypeMetadata)
|
[ Reference.chinookFixture,
|
||||||
{ Fixture.setupTeardown = \(testEnv, _) ->
|
Sqlite.chinookFixture
|
||||||
[Chinook.setupAction Chinook.referenceSourceConfig Reference.agentConfig testEnv]
|
|
||||||
},
|
|
||||||
(Fixture.fixture $ Fixture.Backend Sqlite.backendTypeMetadata)
|
|
||||||
{ Fixture.setupTeardown = \(testEnv, _) ->
|
|
||||||
[Chinook.setupAction Chinook.sqliteSourceConfig Sqlite.agentConfig testEnv]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
tests
|
tests
|
||||||
@ -169,7 +162,7 @@ paginationTests :: Fixture.Options -> SpecWith (TestEnvironment, a)
|
|||||||
paginationTests opts =
|
paginationTests opts =
|
||||||
describe "Pagination" $ do
|
describe "Pagination" $ do
|
||||||
it "works with pagination" $ \(testEnvironment, _) -> do
|
it "works with pagination" $ \(testEnvironment, _) -> do
|
||||||
-- NOTE: We order by in this pagination test to ensure that the rows are ordered correctly (which they are not in db.chinook.sqlite)
|
-- NOTE: We order by in this pagination test to ensure that the rows are ordered correctly (which they are not in Sqlite Chinook)
|
||||||
shouldReturnYaml
|
shouldReturnYaml
|
||||||
opts
|
opts
|
||||||
( GraphqlEngine.postGraphql
|
( GraphqlEngine.postGraphql
|
||||||
|
@ -24,14 +24,8 @@ spec :: SpecWith GlobalTestEnvironment
|
|||||||
spec =
|
spec =
|
||||||
Fixture.runWithLocalTestEnvironment
|
Fixture.runWithLocalTestEnvironment
|
||||||
( NE.fromList
|
( NE.fromList
|
||||||
[ (Fixture.fixture $ Fixture.Backend Reference.backendTypeMetadata)
|
[ Reference.chinookFixture,
|
||||||
{ Fixture.setupTeardown = \(testEnv, _) ->
|
Sqlite.chinookFixture
|
||||||
[Chinook.setupAction Chinook.referenceSourceConfig Reference.agentConfig testEnv]
|
|
||||||
},
|
|
||||||
(Fixture.fixture $ Fixture.Backend Sqlite.backendTypeMetadata)
|
|
||||||
{ Fixture.setupTeardown = \(testEnv, _) ->
|
|
||||||
[Chinook.setupAction Chinook.sqliteSourceConfig Sqlite.agentConfig testEnv]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
tests
|
tests
|
||||||
|
@ -10,6 +10,7 @@ module Command
|
|||||||
SandwichArguments (..),
|
SandwichArguments (..),
|
||||||
TestConfig (..),
|
TestConfig (..),
|
||||||
AgentOptions (..),
|
AgentOptions (..),
|
||||||
|
AgentConfig (..),
|
||||||
NameCasing (..),
|
NameCasing (..),
|
||||||
ExportDataConfig (..),
|
ExportDataConfig (..),
|
||||||
ExportFormat (..),
|
ExportFormat (..),
|
||||||
@ -55,9 +56,13 @@ data SensitiveOutputHandling
|
|||||||
|
|
||||||
data AgentOptions = AgentOptions
|
data AgentOptions = AgentOptions
|
||||||
{ _aoAgentBaseUrl :: BaseUrl,
|
{ _aoAgentBaseUrl :: BaseUrl,
|
||||||
_aoAgentConfig :: Maybe API.Config
|
_aoAgentConfig :: AgentConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data AgentConfig
|
||||||
|
= ManualConfig API.Config
|
||||||
|
| DatasetConfig (Maybe API.Config)
|
||||||
|
|
||||||
data NameCasing
|
data NameCasing
|
||||||
= PascalCase
|
= PascalCase
|
||||||
| Lowercase
|
| Lowercase
|
||||||
@ -181,15 +186,23 @@ agentOptionsParser =
|
|||||||
<> metavar "URL"
|
<> metavar "URL"
|
||||||
<> help "The base URL of the Data Connector agent to be tested"
|
<> help "The base URL of the Data Connector agent to be tested"
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> ( ManualConfig
|
||||||
( option
|
<$> option
|
||||||
configValue
|
configValue
|
||||||
( long "agent-config"
|
( long "agent-config"
|
||||||
<> short 's'
|
<> metavar "JSON"
|
||||||
<> metavar "JSON"
|
<> help "The configuration JSON to be sent to the agent via the X-Hasura-DataConnector-Config header. If omitted, datasets will be used to load test data and provide this configuration dynamically"
|
||||||
<> help "The configuration JSON to be sent to the agent via the X-Hasura-DataConnector-Config header. If omitted, datasets will be used to load test data and provide this configuration dynamically"
|
)
|
||||||
)
|
<|> DatasetConfig
|
||||||
)
|
<$> optional
|
||||||
|
( option
|
||||||
|
configValue
|
||||||
|
( long "merge-agent-config"
|
||||||
|
<> metavar "JSON"
|
||||||
|
<> help "Datasets will be used to load test data and provide configuration JSON to be sent to the agent via the X-Hasura-DataConnector-Config header. This config will be merged with the dataset-provided config before being sent to the agent."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
exportDataConfigParser :: Parser ExportDataConfig
|
exportDataConfigParser :: Parser ExportDataConfig
|
||||||
exportDataConfigParser =
|
exportDataConfigParser =
|
||||||
|
@ -2,7 +2,7 @@ module Main (main) where
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
import Command (AgentOptions (..), Command (..), SandwichArguments (..), TestOptions (..), parseCommandLine)
|
import Command (AgentConfig (..), AgentOptions (..), Command (..), SandwichArguments (..), TestOptions (..), parseCommandLine)
|
||||||
import Control.Exception (bracket)
|
import Control.Exception (bracket)
|
||||||
import Data.Aeson.Text (encodeToLazyText)
|
import Data.Aeson.Text (encodeToLazyText)
|
||||||
import Data.Foldable (for_)
|
import Data.Foldable (for_)
|
||||||
@ -12,7 +12,7 @@ import Hasura.Backends.DataConnector.API (openApiSchema)
|
|||||||
import Hasura.Backends.DataConnector.API qualified as API
|
import Hasura.Backends.DataConnector.API qualified as API
|
||||||
import Servant.Client ((//))
|
import Servant.Client ((//))
|
||||||
import System.Environment (withArgs)
|
import System.Environment (withArgs)
|
||||||
import Test.AgentAPI (guardCapabilitiesResponse, guardSchemaResponse)
|
import Test.AgentAPI (guardCapabilitiesResponse, guardSchemaResponse, mergeAgentConfig)
|
||||||
import Test.AgentClient (AgentIOClient (..), introduceAgentClient, mkAgentClientConfig, mkAgentIOClient)
|
import Test.AgentClient (AgentIOClient (..), introduceAgentClient, mkAgentClientConfig, mkAgentIOClient)
|
||||||
import Test.AgentDatasets (DatasetCloneInfo (..), chinookTemplate, createClone, deleteClone, usesDataset)
|
import Test.AgentDatasets (DatasetCloneInfo (..), chinookTemplate, createClone, deleteClone, usesDataset)
|
||||||
import Test.AgentTestContext (AgentTestContext (..), introduceAgentTestContext)
|
import Test.AgentTestContext (AgentTestContext (..), introduceAgentTestContext)
|
||||||
@ -46,18 +46,18 @@ tests testData capabilitiesResponse@API.CapabilitiesResponse {..} = do
|
|||||||
for_ (API._cMetrics _crCapabilities) \m -> Test.Specs.MetricsSpec.spec m
|
for_ (API._cMetrics _crCapabilities) \m -> Test.Specs.MetricsSpec.spec m
|
||||||
for_ (API._cExplain _crCapabilities) \_ -> Test.Specs.ExplainSpec.spec testData _crCapabilities
|
for_ (API._cExplain _crCapabilities) \_ -> Test.Specs.ExplainSpec.spec testData _crCapabilities
|
||||||
|
|
||||||
getChinookSchema :: API.Capabilities -> Maybe API.Config -> AgentIOClient -> IO API.SchemaResponse
|
getChinookSchema :: API.Capabilities -> AgentConfig -> AgentIOClient -> IO API.SchemaResponse
|
||||||
getChinookSchema API.Capabilities {..} manuallyProvidedConfig (AgentIOClient agentClient) = do
|
getChinookSchema API.Capabilities {..} manuallyProvidedConfig (AgentIOClient agentClient) = do
|
||||||
case manuallyProvidedConfig of
|
case manuallyProvidedConfig of
|
||||||
Just config -> (agentClient // API._schema) testSourceName config >>= guardSchemaResponse
|
ManualConfig config -> (agentClient // API._schema) testSourceName config >>= guardSchemaResponse
|
||||||
Nothing ->
|
DatasetConfig mergeConfig ->
|
||||||
if isJust _cDatasets
|
if isJust _cDatasets
|
||||||
then
|
then
|
||||||
bracket
|
bracket
|
||||||
(createClone agentClient chinookTemplate)
|
(createClone agentClient chinookTemplate)
|
||||||
(deleteClone agentClient)
|
(deleteClone agentClient)
|
||||||
( \DatasetCloneInfo {..} ->
|
( \DatasetCloneInfo {..} ->
|
||||||
(agentClient // API._schema) testSourceName _dciAgentConfig >>= guardSchemaResponse
|
(agentClient // API._schema) testSourceName (mergeAgentConfig _dciAgentConfig mergeConfig) >>= guardSchemaResponse
|
||||||
)
|
)
|
||||||
else fail $ "The agent does not support datasets, therefore an agent configuration must be provided on the command line (--agent-config)"
|
else fail $ "The agent does not support datasets, therefore an agent configuration must be provided on the command line (--agent-config)"
|
||||||
|
|
||||||
|
@ -9,20 +9,22 @@ The executable also has the ability to export the OpenAPI spec of the Data Conne
|
|||||||
### Running Tests
|
### Running Tests
|
||||||
First, start your Data Connector agent and ensure it is populated with the [Chinook data set](https://github.com/lerocha/chinook-database/). For example, you could start the Reference Agent by following the instructions in [its README](../../dc-agents/reference/README.md).
|
First, start your Data Connector agent and ensure it is populated with the [Chinook data set](https://github.com/lerocha/chinook-database/). For example, you could start the Reference Agent by following the instructions in [its README](../../dc-agents/reference/README.md).
|
||||||
|
|
||||||
To run the tests against the agent (for example), you must specify the agent's URL on the command line (`-u`), as well as the agent's configuration JSON (`-s`, sent in the `X-Hasura-DataConnector-Config` header):
|
To run the tests against the agent (for example), you must specify the agent's URL on the command line (`--agent-base-url`), as well as the agent's configuration JSON (`--agent-config`, sent in the `X-Hasura-DataConnector-Config` header):
|
||||||
|
|
||||||
```
|
```
|
||||||
cabal run test:tests-dc-api -- test -u "http://localhost:8100" -s '{}'
|
cabal run test:tests-dc-api -- test --agent-base-url "http://localhost:8100" --agent-config '{}'
|
||||||
```
|
```
|
||||||
|
|
||||||
The test suite will discover what capabilities the agent has by querying it. It will then tailor the tests that it will run to match only those capabilities that the agent has said it supports.
|
The test suite will discover what capabilities the agent has by querying it. It will then tailor the tests that it will run to match only those capabilities that the agent has said it supports.
|
||||||
|
|
||||||
|
If your agent supports the datasets capability, you can omit the `--agent-config` argument and the test suite will clone the Chinook dataset template on the agent to run its test against. If you need to specify some additional configuration to be added to the cloned dataset's configuration, you can specify it using `--merge-agent-config`.
|
||||||
|
|
||||||
The test suite is implemented using the [Sandwich](https://codedownio.github.io/sandwich/) test framework. The standard Sandwich command line arguments can be passed by suffixing your command line with `sandwich` and then all following args will be passed to Sandwich.
|
The test suite is implemented using the [Sandwich](https://codedownio.github.io/sandwich/) test framework. The standard Sandwich command line arguments can be passed by suffixing your command line with `sandwich` and then all following args will be passed to Sandwich.
|
||||||
|
|
||||||
For example, to run the Terminal UI mode of Sandwich, you could run:
|
For example, to run the Terminal UI mode of Sandwich, you could run:
|
||||||
|
|
||||||
```
|
```
|
||||||
cabal run test:tests-dc-api -- test -u "http://localhost:8100" -s '{}' sandwich --tui
|
cabal run test:tests-dc-api -- test --agent-base-url "http://localhost:8100" --agent-config '{}' sandwich --tui
|
||||||
```
|
```
|
||||||
|
|
||||||
By default Sandwich will write test results into a `test_runs` folder. Every test has a folder that will contain debug information, for example:
|
By default Sandwich will write test results into a `test_runs` folder. Every test has a folder that will contain debug information, for example:
|
||||||
|
@ -21,12 +21,15 @@ module Test.AgentAPI
|
|||||||
explain,
|
explain,
|
||||||
getMetrics,
|
getMetrics,
|
||||||
getSourceNameAndConfig,
|
getSourceNameAndConfig,
|
||||||
|
mergeAgentConfig,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
import Command (AgentConfig (..))
|
||||||
import Control.Monad.Catch (MonadThrow)
|
import Control.Monad.Catch (MonadThrow)
|
||||||
import Control.Monad.IO.Class (MonadIO)
|
import Control.Monad.IO.Class (MonadIO)
|
||||||
import Control.Monad.Reader (MonadReader)
|
import Control.Monad.Reader (MonadReader)
|
||||||
|
import Data.Aeson.KeyMap qualified as KeyMap
|
||||||
import Data.Maybe (isJust)
|
import Data.Maybe (isJust)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Hasura.Backends.DataConnector.API qualified as API
|
import Hasura.Backends.DataConnector.API qualified as API
|
||||||
@ -108,13 +111,20 @@ supportsDatasets = isJust . API._cDatasets . API._crCapabilities
|
|||||||
getSourceNameAndConfig :: (HasAgentTestContext context, HasDatasetContext context, MonadReader context m, MonadThrow m) => m (API.SourceName, API.Config)
|
getSourceNameAndConfig :: (HasAgentTestContext context, HasDatasetContext context, MonadReader context m, MonadThrow m) => m (API.SourceName, API.Config)
|
||||||
getSourceNameAndConfig = do
|
getSourceNameAndConfig = do
|
||||||
AgentTestContext {..} <- getAgentTestContext
|
AgentTestContext {..} <- getAgentTestContext
|
||||||
case _atcManualConfig of
|
case _atcAgentConfig of
|
||||||
Just config -> pure (_atcSourceName, config)
|
ManualConfig config -> pure (_atcSourceName, config)
|
||||||
Nothing ->
|
DatasetConfig mergeConfig ->
|
||||||
if supportsDatasets _atcCapabilitiesResponse
|
if supportsDatasets _atcCapabilitiesResponse
|
||||||
then do
|
then do
|
||||||
cloneInfo <- _dcClone <$> getDatasetContext
|
cloneInfo <- _dcClone <$> getDatasetContext
|
||||||
case cloneInfo of
|
case cloneInfo of
|
||||||
Just DatasetCloneInfo {..} -> pure (_atcSourceName, _dciAgentConfig)
|
Just DatasetCloneInfo {..} ->
|
||||||
|
let mergedConfig = mergeAgentConfig _dciAgentConfig mergeConfig
|
||||||
|
in pure (_atcSourceName, mergedConfig)
|
||||||
Nothing -> expectationFailure "Expected a dataset clone to have been created, because the agent supports datasets, but one wasn't"
|
Nothing -> expectationFailure "Expected a dataset clone to have been created, because the agent supports datasets, but one wasn't"
|
||||||
else expectationFailure "An agent configuration is required to be provided if the agent does not support datasets"
|
else expectationFailure "An agent configuration is required to be provided if the agent does not support datasets"
|
||||||
|
|
||||||
|
mergeAgentConfig :: API.Config -> Maybe API.Config -> API.Config
|
||||||
|
mergeAgentConfig (API.Config configA) mergeConfig =
|
||||||
|
let configB = maybe mempty API.unConfig mergeConfig
|
||||||
|
in API.Config $ KeyMap.union configA configB
|
||||||
|
@ -8,6 +8,7 @@ module Test.AgentTestContext
|
|||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
import Command (AgentConfig)
|
||||||
import Control.Monad.Reader.Class (MonadReader)
|
import Control.Monad.Reader.Class (MonadReader)
|
||||||
import GHC.Stack (HasCallStack)
|
import GHC.Stack (HasCallStack)
|
||||||
import Hasura.Backends.DataConnector.API qualified as API
|
import Hasura.Backends.DataConnector.API qualified as API
|
||||||
@ -20,7 +21,7 @@ data AgentTestContext = AgentTestContext
|
|||||||
_atcCapabilitiesResponse :: API.CapabilitiesResponse,
|
_atcCapabilitiesResponse :: API.CapabilitiesResponse,
|
||||||
-- | This is the configuration passed by the user on the command line which will
|
-- | This is the configuration passed by the user on the command line which will
|
||||||
-- be used in preference to any dataset clone's config if it is specified
|
-- be used in preference to any dataset clone's config if it is specified
|
||||||
_atcManualConfig :: Maybe API.Config
|
_atcAgentConfig :: AgentConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
introduceAgentTestContext :: forall context m. (Monad m) => AgentTestContext -> SpecFree (LabelValue "agent-test-context" AgentTestContext :> context) m () -> SpecFree context m ()
|
introduceAgentTestContext :: forall context m. (Monad m) => AgentTestContext -> SpecFree (LabelValue "agent-test-context" AgentTestContext :> context) m () -> SpecFree context m ()
|
||||||
|
@ -3,24 +3,27 @@
|
|||||||
-- | Chinook Based Agent Fixtures used in DataConnector specific
|
-- | Chinook Based Agent Fixtures used in DataConnector specific
|
||||||
-- Specs.
|
-- Specs.
|
||||||
module Harness.Backend.DataConnector.Chinook
|
module Harness.Backend.DataConnector.Chinook
|
||||||
( setupAction,
|
( ChinookTestEnv (..),
|
||||||
referenceSourceConfig,
|
NameFormatting (..),
|
||||||
sqliteSourceConfig,
|
mkChinookCloneTestEnvironment,
|
||||||
|
mkChinookStaticTestEnvironment,
|
||||||
|
setupChinookSourceAction,
|
||||||
|
setupCustomSourceAction,
|
||||||
testRoleName,
|
testRoleName,
|
||||||
ChinookTestEnv (..),
|
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import Control.Monad.Managed (Managed)
|
||||||
import Data.Aeson qualified as Aeson
|
import Data.Aeson qualified as Aeson
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Harness.Backend.DataConnector.Chinook.Reference qualified as Reference
|
import Harness.DataConnectorAgent (createManagedClone)
|
||||||
import Harness.Backend.DataConnector.Chinook.Sqlite qualified as Sqlite
|
|
||||||
import Harness.GraphqlEngine qualified as GraphqlEngine
|
import Harness.GraphqlEngine qualified as GraphqlEngine
|
||||||
import Harness.Quoter.Yaml (yaml)
|
import Harness.Quoter.Yaml (yaml)
|
||||||
import Harness.Test.Fixture qualified as Fixture
|
import Harness.Test.Fixture qualified as Fixture
|
||||||
import Harness.TestEnvironment (TestEnvironment)
|
import Harness.TestEnvironment (TestEnvironment, getBackendTypeConfig)
|
||||||
|
import Hasura.Backends.DataConnector.API qualified as API
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@ -28,26 +31,78 @@ import Hasura.Prelude
|
|||||||
data ChinookTestEnv = ChinookTestEnv
|
data ChinookTestEnv = ChinookTestEnv
|
||||||
{ -- | Default configuration JSON for the backend source.
|
{ -- | Default configuration JSON for the backend source.
|
||||||
backendSourceConfig :: Aeson.Value,
|
backendSourceConfig :: Aeson.Value,
|
||||||
-- | Can be used to apply custom formatting to table names. Eg.,
|
-- | Default configuration for the backend config that sets the agent configuration
|
||||||
-- adjusting the casing.
|
backendAgentConfig :: Aeson.Value,
|
||||||
formatTableName :: [Text] -> [Text],
|
-- | Name formatting functions to correct for backend-specific naming rules
|
||||||
-- | Can be used to apply custom formatting to column names. Eg.,
|
nameFormatting :: NameFormatting
|
||||||
-- adjusting the casing.
|
|
||||||
formatColumnName :: Text -> Text,
|
|
||||||
formatForeignKeyName :: Text -> Text
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupAction :: Aeson.Value -> Aeson.Value -> TestEnvironment -> Fixture.SetupAction
|
data NameFormatting = NameFormatting
|
||||||
setupAction sourceMetadata backendConfig' testEnv =
|
{ -- | Can be used to apply custom formatting to table names. Eg.,
|
||||||
|
-- adjusting the casing.
|
||||||
|
_nfFormatTableName :: [Text] -> [Text],
|
||||||
|
-- | Can be used to apply custom formatting to column names. Eg.,
|
||||||
|
-- adjusting the casing.
|
||||||
|
_nfFormatColumnName :: Text -> Text,
|
||||||
|
_nfFormatForeignKeyName :: Text -> Text
|
||||||
|
}
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- | Create a test environment that uses agent dataset cloning to clone a copy of the Chinook
|
||||||
|
-- DB for the test and use that as the source config configured in HGE.
|
||||||
|
-- This should be used with agents that support datasets.
|
||||||
|
mkChinookCloneTestEnvironment :: NameFormatting -> TestEnvironment -> Managed ChinookTestEnv
|
||||||
|
mkChinookCloneTestEnvironment nameFormatting testEnv = do
|
||||||
|
backendTypeConfig <- getBackendTypeConfig testEnv `onNothing` fail "Unable to find backend type config in this test environment"
|
||||||
|
agentUrl <- Fixture.backendServerUrl backendTypeConfig `onNothing` fail ("Backend " <> show (Fixture.backendType backendTypeConfig) <> " does not have a server url")
|
||||||
|
cloneConfig <- API._dccrConfig <$> createManagedClone agentUrl testEnv (API.DatasetTemplateName "Chinook")
|
||||||
|
let agentBackendConfig = mkAgentBackendConfig backendTypeConfig
|
||||||
|
let cloneConfigValue = Aeson.Object $ API.unConfig cloneConfig
|
||||||
|
let sourceConfig =
|
||||||
|
[yaml|
|
||||||
|
value: *cloneConfigValue
|
||||||
|
template:
|
||||||
|
timeout:
|
||||||
|
|]
|
||||||
|
pure $ ChinookTestEnv sourceConfig agentBackendConfig nameFormatting
|
||||||
|
|
||||||
|
-- | Create a test environment that uses the source config specified to connect to a specific DB on the agent
|
||||||
|
-- that contains the Chinook dataset.
|
||||||
|
-- This should be used with agents that do not support datasets.
|
||||||
|
mkChinookStaticTestEnvironment :: NameFormatting -> Aeson.Value -> TestEnvironment -> Managed ChinookTestEnv
|
||||||
|
mkChinookStaticTestEnvironment nameFormatting sourceConfig testEnv = do
|
||||||
|
backendTypeConfig <- getBackendTypeConfig testEnv `onNothing` fail "Unable to find backend type config in this test environment"
|
||||||
|
let agentBackendConfig = mkAgentBackendConfig backendTypeConfig
|
||||||
|
pure $ ChinookTestEnv sourceConfig agentBackendConfig nameFormatting
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- | Sets up a source in HGE using the source returned by 'mkSourceMetadata'
|
||||||
|
setupCustomSourceAction ::
|
||||||
|
-- | Function that makes a source metadata, taking the 'BackendTypeConfig' and source's configuration as its input parameters
|
||||||
|
(Fixture.BackendTypeConfig -> Aeson.Value -> Aeson.Value) ->
|
||||||
|
(TestEnvironment, ChinookTestEnv) ->
|
||||||
Fixture.SetupAction
|
Fixture.SetupAction
|
||||||
(setup sourceMetadata backendConfig' testEnv)
|
setupCustomSourceAction mkSourceMetadata testEnvs@(testEnv, _chinookTestEnv) =
|
||||||
|
Fixture.SetupAction
|
||||||
|
(setupCustomSource mkSourceMetadata testEnvs)
|
||||||
(const $ teardown testEnv)
|
(const $ teardown testEnv)
|
||||||
|
|
||||||
-- | Setup the schema given source metadata and backend config.
|
-- | Sets up a source in HGE that contains tracked Chinook tables (see 'mkChinookSourceMetadata')
|
||||||
setup :: Aeson.Value -> Aeson.Value -> TestEnvironment -> IO ()
|
setupChinookSourceAction :: (TestEnvironment, ChinookTestEnv) -> Fixture.SetupAction
|
||||||
setup sourceMetadata backendConfig' testEnvironment = do
|
setupChinookSourceAction = setupCustomSourceAction mkChinookSourceMetadata
|
||||||
|
|
||||||
|
setupCustomSource ::
|
||||||
|
-- | Function that makes a source metadata, taking the 'BackendTypeConfig' and source's configuration as its input parameters
|
||||||
|
(Fixture.BackendTypeConfig -> Aeson.Value -> Aeson.Value) ->
|
||||||
|
(TestEnvironment, ChinookTestEnv) ->
|
||||||
|
IO ()
|
||||||
|
setupCustomSource mkSourceMetadata (testEnv, ChinookTestEnv {..}) = do
|
||||||
|
backendTypeConfig <- getBackendTypeConfig testEnv `onNothing` fail "Unable to find backend type config in this test environment"
|
||||||
|
let sourceMetadata = mkSourceMetadata backendTypeConfig backendSourceConfig
|
||||||
-- Clear and reconfigure the metadata
|
-- Clear and reconfigure the metadata
|
||||||
GraphqlEngine.setSource testEnvironment sourceMetadata (Just backendConfig')
|
GraphqlEngine.setSource testEnv sourceMetadata (Just backendAgentConfig)
|
||||||
|
|
||||||
-- | Teardown the schema and tracking in the most expected way.
|
-- | Teardown the schema and tracking in the most expected way.
|
||||||
teardown :: TestEnvironment -> IO ()
|
teardown :: TestEnvironment -> IO ()
|
||||||
@ -56,15 +111,21 @@ teardown testEnvironment = do
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
referenceSourceConfig :: Aeson.Value
|
mkAgentBackendConfig :: Fixture.BackendTypeConfig -> Aeson.Value
|
||||||
referenceSourceConfig = mkChinookSourceConfig Reference.backendTypeMetadata Reference.sourceConfiguration
|
mkAgentBackendConfig backendTypeConfig =
|
||||||
|
let backendType = Fixture.backendTypeString backendTypeConfig
|
||||||
|
uri = Fixture.backendServerUrl backendTypeConfig
|
||||||
|
in [yaml|
|
||||||
|
dataconnector:
|
||||||
|
*backendType:
|
||||||
|
uri: *uri
|
||||||
|
|]
|
||||||
|
|
||||||
sqliteSourceConfig :: Aeson.Value
|
--------------------------------------------------------------------------------
|
||||||
sqliteSourceConfig = mkChinookSourceConfig Sqlite.backendTypeMetadata Sqlite.sourceConfiguration
|
|
||||||
|
|
||||||
-- | Build a standard Chinook Source given an Agent specific @configuration@ field.
|
-- | Build a standard Chinook Source given an Agent specific @configuration@ field.
|
||||||
mkChinookSourceConfig :: Fixture.BackendTypeConfig -> Aeson.Value -> Aeson.Value
|
mkChinookSourceMetadata :: Fixture.BackendTypeConfig -> Aeson.Value -> Aeson.Value
|
||||||
mkChinookSourceConfig backendTypeMetadata config =
|
mkChinookSourceMetadata backendTypeMetadata config =
|
||||||
let source = Fixture.backendSourceName backendTypeMetadata
|
let source = Fixture.backendSourceName backendTypeMetadata
|
||||||
backendTypeString = Fixture.backendTypeString backendTypeMetadata
|
backendTypeString = Fixture.backendTypeString backendTypeMetadata
|
||||||
in [yaml|
|
in [yaml|
|
||||||
@ -126,7 +187,7 @@ tables:
|
|||||||
using:
|
using:
|
||||||
manual_configuration:
|
manual_configuration:
|
||||||
remote_table: [Customer]
|
remote_table: [Customer]
|
||||||
column_mapping:
|
column_mapping:
|
||||||
EmployeeId: SupportRepId
|
EmployeeId: SupportRepId
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: test-role
|
- role: test-role
|
||||||
@ -161,7 +222,22 @@ tables:
|
|||||||
SupportRep:
|
SupportRep:
|
||||||
Country:
|
Country:
|
||||||
_ceq: [ "$", "Country" ]
|
_ceq: [ "$", "Country" ]
|
||||||
|
- table: [Invoice]
|
||||||
|
array_relationships:
|
||||||
|
- name: InvoiceLines
|
||||||
|
using:
|
||||||
|
manual_configuration:
|
||||||
|
remote_table: [InvoiceLine]
|
||||||
|
column_mapping:
|
||||||
|
InvoiceId: InvoiceId
|
||||||
|
- table: [InvoiceLine]
|
||||||
|
object_relationships:
|
||||||
|
- name: Invoice
|
||||||
|
using:
|
||||||
|
manual_configuration:
|
||||||
|
remote_table: [Invoice]
|
||||||
|
column_mapping:
|
||||||
|
InvoiceId: InvoiceId
|
||||||
|
|
||||||
configuration:
|
configuration:
|
||||||
*config
|
*config
|
||||||
|
@ -4,23 +4,28 @@
|
|||||||
--
|
--
|
||||||
-- NOTE: This module is intended to be imported qualified.
|
-- NOTE: This module is intended to be imported qualified.
|
||||||
module Harness.Backend.DataConnector.Chinook.Reference
|
module Harness.Backend.DataConnector.Chinook.Reference
|
||||||
( agentConfig,
|
( backendTypeConfig,
|
||||||
sourceConfiguration,
|
mkChinookStaticTestEnvironment,
|
||||||
backendTypeMetadata,
|
chinookFixture,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import Control.Monad.Managed (Managed)
|
||||||
import Data.Aeson qualified as Aeson
|
import Data.Aeson qualified as Aeson
|
||||||
|
import Harness.Backend.DataConnector.Chinook (ChinookTestEnv, NameFormatting (..))
|
||||||
|
import Harness.Backend.DataConnector.Chinook qualified as Chinook
|
||||||
import Harness.Quoter.Yaml (yaml)
|
import Harness.Quoter.Yaml (yaml)
|
||||||
import Harness.Test.BackendType qualified as BackendType
|
import Harness.Test.BackendType qualified as BackendType
|
||||||
|
import Harness.Test.Fixture (Fixture (..), FixtureName (..))
|
||||||
|
import Harness.TestEnvironment (TestEnvironment)
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
backendTypeMetadata :: BackendType.BackendTypeConfig
|
backendTypeConfig :: BackendType.BackendTypeConfig
|
||||||
backendTypeMetadata =
|
backendTypeConfig =
|
||||||
BackendType.BackendTypeConfig
|
BackendType.BackendTypeConfig
|
||||||
{ backendType = BackendType.DataConnectorReference,
|
{ backendType = BackendType.DataConnectorReference,
|
||||||
backendSourceName = "chinook_reference",
|
backendSourceName = "chinook_reference",
|
||||||
@ -75,21 +80,27 @@ backendTypeMetadata =
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- | Reference Agent @backend_configs@ field.
|
mkChinookStaticTestEnvironment :: TestEnvironment -> Managed ChinookTestEnv
|
||||||
agentConfig :: Aeson.Value
|
mkChinookStaticTestEnvironment = Chinook.mkChinookStaticTestEnvironment nameFormatting sourceConfiguration
|
||||||
agentConfig =
|
|
||||||
let backendType = BackendType.backendTypeString backendTypeMetadata
|
nameFormatting :: NameFormatting
|
||||||
in [yaml|
|
nameFormatting = NameFormatting id id id
|
||||||
dataconnector:
|
|
||||||
*backendType:
|
|
||||||
uri: "http://127.0.0.1:65005/"
|
|
||||||
|]
|
|
||||||
|
|
||||||
-- | Reference Agent specific @sources@ entry @configuration@ field.
|
-- | Reference Agent specific @sources@ entry @configuration@ field.
|
||||||
sourceConfiguration :: Aeson.Value
|
sourceConfiguration :: Aeson.Value
|
||||||
sourceConfiguration =
|
sourceConfiguration =
|
||||||
[yaml|
|
[yaml|
|
||||||
value: {}
|
value: {}
|
||||||
template:
|
template:
|
||||||
timeout:
|
timeout:
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
chinookFixture :: Fixture ChinookTestEnv
|
||||||
|
chinookFixture =
|
||||||
|
Fixture
|
||||||
|
{ name = Backend backendTypeConfig,
|
||||||
|
mkLocalTestEnvironment = mkChinookStaticTestEnvironment,
|
||||||
|
setupTeardown = \testEnvs ->
|
||||||
|
[Chinook.setupChinookSourceAction testEnvs],
|
||||||
|
customOptions = Nothing
|
||||||
|
}
|
||||||
|
@ -4,24 +4,27 @@
|
|||||||
--
|
--
|
||||||
-- NOTE: This module is intended to be imported qualified.
|
-- NOTE: This module is intended to be imported qualified.
|
||||||
module Harness.Backend.DataConnector.Chinook.Sqlite
|
module Harness.Backend.DataConnector.Chinook.Sqlite
|
||||||
( agentConfig,
|
( backendTypeConfig,
|
||||||
sourceConfiguration,
|
mkChinookCloneTestEnvironment,
|
||||||
backendTypeMetadata,
|
chinookFixture,
|
||||||
formatForeignKeyName,
|
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
import Data.Aeson qualified as Aeson
|
import Control.Monad.Managed (Managed)
|
||||||
|
import Harness.Backend.DataConnector.Chinook (ChinookTestEnv, NameFormatting (..))
|
||||||
|
import Harness.Backend.DataConnector.Chinook qualified as Chinook
|
||||||
import Harness.Quoter.Yaml (yaml)
|
import Harness.Quoter.Yaml (yaml)
|
||||||
import Harness.Test.BackendType qualified as BackendType
|
import Harness.Test.BackendType qualified as BackendType
|
||||||
|
import Harness.Test.Fixture (Fixture (..), FixtureName (..))
|
||||||
|
import Harness.TestEnvironment
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
backendTypeMetadata :: BackendType.BackendTypeConfig
|
backendTypeConfig :: BackendType.BackendTypeConfig
|
||||||
backendTypeMetadata =
|
backendTypeConfig =
|
||||||
BackendType.BackendTypeConfig
|
BackendType.BackendTypeConfig
|
||||||
{ backendType = BackendType.DataConnectorSqlite,
|
{ backendType = BackendType.DataConnectorSqlite,
|
||||||
backendSourceName = "chinook_sqlite",
|
backendSourceName = "chinook_sqlite",
|
||||||
@ -94,28 +97,24 @@ backendTypeMetadata =
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- | Reference Agent @backend_configs@ field.
|
mkChinookCloneTestEnvironment :: TestEnvironment -> Managed ChinookTestEnv
|
||||||
agentConfig :: Aeson.Value
|
mkChinookCloneTestEnvironment = Chinook.mkChinookCloneTestEnvironment nameFormatting
|
||||||
agentConfig =
|
|
||||||
let backendType = BackendType.backendTypeString backendTypeMetadata
|
|
||||||
in [yaml|
|
|
||||||
dataconnector:
|
|
||||||
*backendType:
|
|
||||||
uri: "http://127.0.0.1:65007/"
|
|
||||||
|]
|
|
||||||
|
|
||||||
-- | Sqlite Agent specific @sources@ entry @configuration@ field.
|
nameFormatting :: NameFormatting
|
||||||
sourceConfiguration :: Aeson.Value
|
nameFormatting = NameFormatting id id formatForeignKeyName
|
||||||
sourceConfiguration =
|
|
||||||
[yaml|
|
|
||||||
value:
|
|
||||||
db: "/db.chinook.sqlite"
|
|
||||||
template:
|
|
||||||
timeout:
|
|
||||||
|]
|
|
||||||
|
|
||||||
-- | Construct foreign key relationship names.
|
-- | Construct foreign key relationship names.
|
||||||
formatForeignKeyName :: Text -> Text
|
formatForeignKeyName :: Text -> Text
|
||||||
formatForeignKeyName = \case
|
formatForeignKeyName = \case
|
||||||
"Artist" -> "ArtistId->Artist.ArtistId"
|
"Artist" -> "ArtistId->Artist.ArtistId"
|
||||||
x -> x
|
x -> x
|
||||||
|
|
||||||
|
chinookFixture :: Fixture ChinookTestEnv
|
||||||
|
chinookFixture =
|
||||||
|
Fixture
|
||||||
|
{ name = Backend backendTypeConfig,
|
||||||
|
mkLocalTestEnvironment = mkChinookCloneTestEnvironment,
|
||||||
|
setupTeardown = \testEnvs ->
|
||||||
|
[Chinook.setupChinookSourceAction testEnvs],
|
||||||
|
customOptions = Nothing
|
||||||
|
}
|
||||||
|
@ -14,9 +14,11 @@ where
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
import Data.Aeson qualified as Aeson
|
import Data.Aeson qualified as Aeson
|
||||||
|
import Data.Aeson.KeyMap qualified as KeyMap
|
||||||
import Data.Text qualified as Text
|
import Data.Text qualified as Text
|
||||||
import Data.Text.Extended qualified as Text (commaSeparated)
|
import Data.Text.Extended qualified as Text (commaSeparated)
|
||||||
import Data.Time qualified as Time
|
import Data.Time qualified as Time
|
||||||
|
import Harness.DataConnectorAgent (createClone, deleteClone)
|
||||||
import Harness.Exceptions
|
import Harness.Exceptions
|
||||||
import Harness.GraphqlEngine qualified as GraphqlEngine
|
import Harness.GraphqlEngine qualified as GraphqlEngine
|
||||||
import Harness.Quoter.Yaml (yaml)
|
import Harness.Quoter.Yaml (yaml)
|
||||||
@ -25,7 +27,8 @@ import Harness.Test.Fixture qualified as Fixture
|
|||||||
import Harness.Test.Permissions qualified as Permissions
|
import Harness.Test.Permissions qualified as Permissions
|
||||||
import Harness.Test.Schema (SchemaName)
|
import Harness.Test.Schema (SchemaName)
|
||||||
import Harness.Test.Schema qualified as Schema
|
import Harness.Test.Schema qualified as Schema
|
||||||
import Harness.TestEnvironment (TestEnvironment)
|
import Harness.TestEnvironment (TestEnvironment (..))
|
||||||
|
import Hasura.Backends.DataConnector.API qualified as API
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@ -83,18 +86,18 @@ setupTablesAction ts env =
|
|||||||
(const $ teardown ts (env, ()))
|
(const $ teardown ts (env, ()))
|
||||||
|
|
||||||
-- | Metadata source information for the default Sqlite instance.
|
-- | Metadata source information for the default Sqlite instance.
|
||||||
sourceMetadata :: Aeson.Value
|
sourceMetadata :: API.Config -> Aeson.Value
|
||||||
sourceMetadata =
|
sourceMetadata (API.Config config) =
|
||||||
let source = Fixture.backendSourceName backendTypeMetadata
|
let source = Fixture.backendSourceName backendTypeMetadata
|
||||||
backendType = BackendType.backendTypeString backendTypeMetadata
|
backendType = BackendType.backendTypeString backendTypeMetadata
|
||||||
|
explicitMainConfig = KeyMap.insert "explicit_main_schema" (Aeson.Bool True) config
|
||||||
in [yaml|
|
in [yaml|
|
||||||
name: *source
|
name: *source
|
||||||
kind: *backendType
|
kind: *backendType
|
||||||
tables: []
|
tables: []
|
||||||
configuration:
|
configuration:
|
||||||
db: "/db.sqlite"
|
value: *explicitMainConfig
|
||||||
explicit_main_schema: true
|
|]
|
||||||
|]
|
|
||||||
|
|
||||||
backendConfig :: Aeson.Value
|
backendConfig :: Aeson.Value
|
||||||
backendConfig =
|
backendConfig =
|
||||||
@ -102,15 +105,20 @@ backendConfig =
|
|||||||
in [yaml|
|
in [yaml|
|
||||||
dataconnector:
|
dataconnector:
|
||||||
*backendType:
|
*backendType:
|
||||||
uri: "http://127.0.0.1:65007/"
|
uri: *sqliteAgentUri
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
sqliteAgentUri :: String
|
||||||
|
sqliteAgentUri = "http://127.0.0.1:65007/"
|
||||||
|
|
||||||
-- | Setup the schema in the most expected way.
|
-- | Setup the schema in the most expected way.
|
||||||
-- NOTE: Certain test modules may warrant having their own local version.
|
-- NOTE: Certain test modules may warrant having their own local version.
|
||||||
setup :: [Schema.Table] -> (TestEnvironment, ()) -> IO ()
|
setup :: [Schema.Table] -> (TestEnvironment, ()) -> IO ()
|
||||||
setup tables (testEnvironment, _) = do
|
setup tables (testEnvironment, _) = do
|
||||||
|
-- Create the database clone
|
||||||
|
cloneConfig <- API._dccrConfig <$> createClone sqliteAgentUri testEnvironment (API.DatasetTemplateName "Empty")
|
||||||
-- Clear and reconfigure the metadata
|
-- Clear and reconfigure the metadata
|
||||||
GraphqlEngine.setSource testEnvironment sourceMetadata (Just backendConfig)
|
GraphqlEngine.setSource testEnvironment (sourceMetadata cloneConfig) (Just backendConfig)
|
||||||
-- Setup and track tables
|
-- Setup and track tables
|
||||||
for_ tables $ \table -> do
|
for_ tables $ \table -> do
|
||||||
createTable testEnvironment table
|
createTable testEnvironment table
|
||||||
@ -164,11 +172,15 @@ teardown (reverse -> tables) (testEnvironment, _) = do
|
|||||||
( forFinally_ tables $ \table ->
|
( forFinally_ tables $ \table ->
|
||||||
Schema.untrackRelationships table testEnvironment
|
Schema.untrackRelationships table testEnvironment
|
||||||
)
|
)
|
||||||
-- Then teardown tables
|
( finally
|
||||||
( forFinally_ tables $ \table ->
|
-- Then teardown tables
|
||||||
finally
|
( forFinally_ tables $ \table ->
|
||||||
(untrackTable testEnvironment table)
|
finally
|
||||||
(dropTable testEnvironment table)
|
(untrackTable testEnvironment table)
|
||||||
|
(dropTable testEnvironment table)
|
||||||
|
)
|
||||||
|
-- Then delete the db clone
|
||||||
|
(deleteClone sqliteAgentUri testEnvironment)
|
||||||
)
|
)
|
||||||
|
|
||||||
-- | Call the Metadata API and pass in a Raw SQL statement to the
|
-- | Call the Metadata API and pass in a Raw SQL statement to the
|
||||||
|
43
server/lib/test-harness/src/Harness/DataConnectorAgent.hs
Normal file
43
server/lib/test-harness/src/Harness/DataConnectorAgent.hs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
module Harness.DataConnectorAgent
|
||||||
|
( createClone,
|
||||||
|
deleteClone,
|
||||||
|
createManagedClone,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Control.Exception.Lifted (finally, throwIO)
|
||||||
|
import Control.Monad.Managed (MonadManaged, managed)
|
||||||
|
import Harness.TestEnvironment (TestEnvironment (..))
|
||||||
|
import Hasura.Backends.DataConnector.API qualified as API
|
||||||
|
import Hasura.Prelude
|
||||||
|
import Network.HTTP.Client qualified as Http
|
||||||
|
import Servant (NamedRoutes, Proxy (..))
|
||||||
|
import Servant.Client (Client, ClientM, client, mkClientEnv, parseBaseUrl, runClientM, (//))
|
||||||
|
|
||||||
|
runDataConnectorAgentRequests :: String -> (Client ClientM (NamedRoutes API.Routes) -> ClientM a) -> IO a
|
||||||
|
runDataConnectorAgentRequests agentUri runWithClient = do
|
||||||
|
clientEnv <- mkClientEnv <$> Http.newManager Http.defaultManagerSettings <*> parseBaseUrl agentUri
|
||||||
|
results <- flip runClientM clientEnv $ do
|
||||||
|
runWithClient $ client (Proxy @(NamedRoutes API.Routes))
|
||||||
|
results `onLeft` throwIO
|
||||||
|
|
||||||
|
createClone :: String -> TestEnvironment -> API.DatasetTemplateName -> IO API.DatasetCreateCloneResponse
|
||||||
|
createClone agentUri TestEnvironment {..} templateName = runDataConnectorAgentRequests agentUri $ \dcClient -> do
|
||||||
|
let cloneName = API.DatasetCloneName (tshow uniqueTestId)
|
||||||
|
(dcClient // API._datasets // API._createClone) cloneName (API.DatasetCreateCloneRequest templateName)
|
||||||
|
|
||||||
|
deleteClone :: String -> TestEnvironment -> IO API.DatasetDeleteCloneResponse
|
||||||
|
deleteClone agentUri TestEnvironment {..} = runDataConnectorAgentRequests agentUri $ \dcClient -> do
|
||||||
|
let cloneName = API.DatasetCloneName (tshow uniqueTestId)
|
||||||
|
(dcClient // API._datasets // API._deleteClone) cloneName
|
||||||
|
|
||||||
|
withClone :: String -> TestEnvironment -> API.DatasetTemplateName -> (API.DatasetCreateCloneResponse -> IO a) -> IO a
|
||||||
|
withClone agentUri TestEnvironment {..} templateName useClone = runDataConnectorAgentRequests agentUri $ \dcClient -> do
|
||||||
|
let cloneName = API.DatasetCloneName (tshow uniqueTestId)
|
||||||
|
response <- (dcClient // API._datasets // API._createClone) cloneName (API.DatasetCreateCloneRequest templateName)
|
||||||
|
finally
|
||||||
|
(liftIO $ useClone response)
|
||||||
|
((dcClient // API._datasets // API._deleteClone) cloneName)
|
||||||
|
|
||||||
|
createManagedClone :: MonadManaged m => String -> TestEnvironment -> API.DatasetTemplateName -> m API.DatasetCreateCloneResponse
|
||||||
|
createManagedClone agentUri testEnvironment templateName = managed (withClone agentUri testEnvironment templateName)
|
@ -290,7 +290,7 @@ startServerThread = do
|
|||||||
dataconnector:
|
dataconnector:
|
||||||
foobar:
|
foobar:
|
||||||
display_name: FOOBARDB
|
display_name: FOOBARDB
|
||||||
uri: "http://localhost:65007" |]
|
uri: "http://localhost:65005" |]
|
||||||
thread <-
|
thread <-
|
||||||
Async.async
|
Async.async
|
||||||
( runApp
|
( runApp
|
||||||
|
@ -26,12 +26,14 @@ library
|
|||||||
, hedgehog
|
, hedgehog
|
||||||
, hspec
|
, hspec
|
||||||
, hspec-core
|
, hspec-core
|
||||||
|
, http-client
|
||||||
, http-conduit
|
, http-conduit
|
||||||
, http-types
|
, http-types
|
||||||
, insert-ordered-containers
|
, insert-ordered-containers
|
||||||
, lens
|
, lens
|
||||||
, lens-aeson
|
, lens-aeson
|
||||||
, libyaml
|
, libyaml
|
||||||
|
, lifted-base
|
||||||
, managed
|
, managed
|
||||||
, morpheus-graphql
|
, morpheus-graphql
|
||||||
, mtl
|
, mtl
|
||||||
@ -51,6 +53,7 @@ library
|
|||||||
, safe
|
, safe
|
||||||
, safe-exceptions
|
, safe-exceptions
|
||||||
, servant-server
|
, servant-server
|
||||||
|
, servant-client
|
||||||
, sop-core
|
, sop-core
|
||||||
, stm
|
, stm
|
||||||
, string-interpolate
|
, string-interpolate
|
||||||
@ -125,6 +128,7 @@ library
|
|||||||
Harness.Backend.Postgres
|
Harness.Backend.Postgres
|
||||||
Harness.Backend.Sqlserver
|
Harness.Backend.Sqlserver
|
||||||
Harness.Constants
|
Harness.Constants
|
||||||
|
Harness.DataConnectorAgent
|
||||||
Harness.Env
|
Harness.Env
|
||||||
Harness.Exceptions
|
Harness.Exceptions
|
||||||
Harness.GraphqlEngine
|
Harness.GraphqlEngine
|
||||||
|
Loading…
Reference in New Issue
Block a user