/
alt3rmann
/
graphql-engine
Обзор
Документация
Войти
/
alt3rmann
/
graphql-engine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
server/lib/api-tests/src/Test/API/Metadata/InconsistentSpec.hs
337 строк
12 KB
Daniel Chambers
Fix source metadata getting erased if the source is inconsistent when the source update is performed
04 фев 2025, 06:20
04 фев 2025, 06:20
277f1d8
Код
Авторство
О чём код?
{-# LANGUAGE QuasiQuotes #-} module Test.API.Metadata.InconsistentSpec (spec) where import Data.Aeson (Value) import Data.List.NonEmpty qualified as NE import Data.Maybe qualified as Maybe import Harness.Backend.Postgres qualified as Postgres import Harness.GraphqlEngine (postMetadata, postMetadataWithStatus, postMetadata_) import Harness.Quoter.Yaml import Harness.Schema qualified as Schema import Harness.Test.BackendType qualified as BackendType import Harness.Test.Fixture qualified as Fixture import Harness.TestEnvironment import Harness.Yaml qualified as Yaml import Hasura.Prelude import Test.Hspec spec :: SpecWith GlobalTestEnvironment spec = Fixture.run ( NE.fromList [ (Fixture.fixture $ Fixture.Backend Postgres.backendTypeMetadata) { Fixture.setupTeardown = \(testEnvironment, _) -> [ Postgres.setupTablesAction [] testEnvironment, dropTablesBeforeAndAfter testEnvironment, setupMetadata testEnvironment ] } ] ) tests table :: Schema.Table table = (Schema.table "table1") {Schema.tableColumns = [Schema.column "id" Schema.TInt]} tests :: SpecWith TestEnvironment tests = do describe "reloading the metadata" do it "flags missing tables as inconsistent" \testEnvironment -> do let shouldReturnYaml :: IO Value -> Value -> IO () shouldReturnYaml = Yaml.shouldReturnYaml testEnvironment Postgres.createTable testEnvironment table postMetadata testEnvironment (replaceMetadataWithTable testEnvironment) `shouldReturnYaml` [yaml| is_consistent: true inconsistent_objects: [] |] Postgres.dropTable testEnvironment table postMetadata testEnvironment reloadMetadata `shouldReturnYaml` expectedInconsistentYaml (Just "success") testEnvironment it "recognizes when tables have become consistent" \testEnvironment -> do let shouldReturnYaml :: IO Value -> Value -> IO () shouldReturnYaml = Yaml.shouldReturnYaml testEnvironment postMetadata testEnvironment (replaceMetadataWithTable testEnvironment) `shouldReturnYaml` expectedInconsistentYaml Nothing testEnvironment Postgres.createTable testEnvironment table postMetadata testEnvironment reloadMetadata `shouldReturnYaml` [yaml| message: success is_consistent: true |] -- To be removed once the test fixtures can automatically clean this up. Postgres.dropTable testEnvironment table describe "replacing the metadata" do it "flags missing tables as inconsistent" \testEnvironment -> do let shouldReturnYaml :: IO Value -> Value -> IO () shouldReturnYaml = Yaml.shouldReturnYaml testEnvironment postMetadata testEnvironment (replaceMetadataWithTable testEnvironment) `shouldReturnYaml` expectedInconsistentYaml Nothing testEnvironment it "recognizes when tables have become consistent" \testEnvironment -> do let shouldReturnYaml :: IO Value -> Value -> IO () shouldReturnYaml = Yaml.shouldReturnYaml testEnvironment postMetadata testEnvironment (replaceMetadataWithTable testEnvironment) `shouldReturnYaml` expectedInconsistentYaml Nothing testEnvironment Postgres.createTable testEnvironment table postMetadata testEnvironment (replaceMetadataWithTable testEnvironment) `shouldReturnYaml` [yaml| is_consistent: true inconsistent_objects: [] |] Postgres.dropTable testEnvironment table describe "replacing metadata with already present inconsistency" do it "drop table for an already inconsistent table with event trigger" \testEnvironment -> do let shouldReturnYaml :: IO Value -> Value -> IO () shouldReturnYaml = Yaml.shouldReturnYaml testEnvironment Postgres.createTable testEnvironment table _ <- postMetadata testEnvironment (setupMetadataWithTableAndEventTrigger testEnvironment) Postgres.dropTable testEnvironment table postMetadata testEnvironment (replaceMetadataDropInconsistentTable testEnvironment) `shouldReturnYaml` [yaml| is_consistent: true inconsistent_objects: [] |] it "drop source for an already inconsistent source" \testEnvironment -> do let shouldReturnYaml :: IO Value -> Value -> IO () shouldReturnYaml = Yaml.shouldReturnYaml testEnvironment _ <- postMetadata testEnvironment (setupMetadataWithInconsistentSource testEnvironment) postMetadata testEnvironment repaceMetadataRemoveInconsistentSource `shouldReturnYaml` [yaml| is_consistent: true inconsistent_objects: [] |] describe "updating a source that is already inconsistent" do it "should fail to update the source" \testEnvironment -> do let shouldReturnYaml :: IO Value -> Value -> IO () shouldReturnYaml = Yaml.shouldReturnYaml testEnvironment _ <- postMetadata testEnvironment (setupMetadataWithInconsistentSource testEnvironment) postMetadataWithStatus 400 testEnvironment (addSourceWithIncorrectConnectionString testEnvironment) `shouldReturnYaml` [yaml| code: invalid-configuration error: "Inconsistent object: connection error" internal: - definition: postgres message: | missing "=" after "postgresbusted://postgres:postgres@postgres:5432/another_non_existent_db" in connection info string name: source postgres reason: "Inconsistent object: connection error" type: source path: $.args |] reloadMetadata :: Value reloadMetadata = [yaml| type: reload_metadata args: reload_sources: true |] replaceMetadataWithTable :: TestEnvironment -> Value replaceMetadataWithTable testEnvironment = [yaml| type: replace_metadata args: allow_inconsistent_metadata: true metadata: version: 3 sources: - name: *sourceName kind: postgres tables: - table: schema: *schemaName name: *tableName configuration: *sourceConfiguration |] where backendTypeMetadata = Maybe.fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment sourceConfiguration = Postgres.defaultSourceConfiguration testEnvironment sourceName = Fixture.backendSourceName backendTypeMetadata schemaName = Schema.getSchemaName testEnvironment tableName = Schema.tableName table setupMetadataWithInconsistentSource :: TestEnvironment -> Value setupMetadataWithInconsistentSource testEnvironment = [yaml| type: replace_metadata args: allow_inconsistent_metadata: true metadata: version: 3 sources: - name: *sourceName kind: postgres tables: - table: schema: *schemaName name: *tableName configuration: connection_info: database_url: postgres://postgres:postgres@postgres:5432/non_existent_db pool_settings: {} |] where backendTypeMetadata = Maybe.fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment sourceName = Fixture.backendSourceName backendTypeMetadata schemaName = Schema.getSchemaName testEnvironment tableName = Schema.tableName table addSourceWithIncorrectConnectionString :: TestEnvironment -> Value addSourceWithIncorrectConnectionString testEnvironment = [yaml| type: pg_add_source args: name: *sourceName configuration: connection_info: database_url: postgresbusted://postgres:postgres@postgres:5432/another_non_existent_db pool_settings: {} replace_configuration: true |] where backendTypeMetadata = Maybe.fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment sourceName = Fixture.backendSourceName backendTypeMetadata repaceMetadataRemoveInconsistentSource :: Value repaceMetadataRemoveInconsistentSource = [yaml| type: replace_metadata args: allow_inconsistent_metadata: true metadata: version: 3 sources: [] |] setupMetadataWithTableAndEventTrigger :: TestEnvironment -> Value setupMetadataWithTableAndEventTrigger testEnvironment = [yaml| type: replace_metadata args: allow_inconsistent_metadata: true metadata: version: 3 sources: - name: *sourceName kind: postgres tables: - table: schema: *schemaName name: *tableName event_triggers: - name: foo-trigger definition: insert: columns: '*' retry_conf: interval_sec: 10 num_retries: 0 timeout_sec: 60 webhook: https://httpbin.org/post configuration: *sourceConfiguration |] where backendTypeMetadata = Maybe.fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment sourceConfiguration = Postgres.defaultSourceConfiguration testEnvironment sourceName = Fixture.backendSourceName backendTypeMetadata schemaName = Schema.getSchemaName testEnvironment tableName = Schema.tableName table replaceMetadataDropInconsistentTable :: TestEnvironment -> Value replaceMetadataDropInconsistentTable testEnvironment = [yaml| type: replace_metadata args: allow_inconsistent_metadata: true metadata: version: 3 sources: - name: *sourceName kind: postgres tables: [] configuration: *sourceConfiguration |] where backendTypeMetadata = Maybe.fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment sourceConfiguration = Postgres.defaultSourceConfiguration testEnvironment sourceName = Fixture.backendSourceName backendTypeMetadata expectedInconsistentYaml :: Maybe Text -> TestEnvironment -> Value expectedInconsistentYaml message testEnvironment = [interpolateYaml| #{messageYaml} is_consistent: false inconsistent_objects: - definition: schema: #{schemaName} name: #{tableName} type: table name: "table #{schemaName}.#{tableName} in source #{sourceName}" reason: "Inconsistent object: no such table/view exists in source: \"#{schemaName}.#{tableName}\"" |] where messageYaml = maybe "" ("message: " <>) message backendTypeMetadata = Maybe.fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment sourceName = Fixture.backendSourceName backendTypeMetadata schemaName = Schema.getSchemaName testEnvironment tableName = Schema.tableName table setupMetadata :: TestEnvironment -> Fixture.SetupAction setupMetadata testEnvironment = do let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment sourceName = Fixture.backendSourceName backendTypeMetadata sourceConfiguration = Postgres.defaultSourceConfiguration testEnvironment setup :: IO () setup = postMetadata_ testEnvironment [yaml| type: replace_metadata args: metadata: version: 3 sources: - name: *sourceName kind: postgres tables: [] configuration: *sourceConfiguration |] teardown :: IO () teardown = setup Fixture.SetupAction setup \_ -> teardown dropTablesBeforeAndAfter :: TestEnvironment -> Fixture.SetupAction dropTablesBeforeAndAfter testEnvironment = do Fixture.SetupAction action (const action) where action = case BackendType.backendType <$> (getBackendTypeConfig testEnvironment) of Just Fixture.Postgres -> Postgres.dropTableIfExists testEnvironment table Just b -> fail $ "Unknown backend:" <> show b Nothing -> fail $ "Unknown backend."