Repository navigation
feat(standard-tests): run each acceptance-test-config.yml config with its section's command, and assert the check status and basic_read records #1142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Anatolii Yatsuk (tolik0)
merged 14 commits into
main
from
devin/1788275534-shared-check-assertion
Oct 13, 2026
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
23cb5b7
test: assert reported check status in both standard-test paths
devin-ai-integration[bot] eb48942
fix(standard-tests): follow the CAT `status` contract for `check` in …
tolik0 573df92
fix(standard-tests): no declared `status` means `check` must succeed,…
tolik0 c15960c
docs(standard-tests): point the migration note at 7.35.0
tolik0 d64a79c
feat(standard-tests): run `check` for every config listed in acceptan…
tolik0 e105226
fix(standard-tests)!: run each config with the command of its accepta…
tolik0 1f07a6a
Merge branch 'main' into devin/1788275534-shared-check-assertion
tolik0 64b70dc
docs: retitle the migration section for the next minor release
tolik0 e7332ea
fix(standard-tests): drop the in-process incremental read test
tolik0 35b3bf6
fix(standard-tests): stop collecting the `incremental` section
tolik0 5a12eff
feat(standard-tests): read the streams of a config's configured_catal…
tolik0 a07a090
fix(standard-tests): read a stream listed twice in a declared catalog…
tolik0 f0fad4e
feat(standard-tests): assert per-stream records and record schemas in…
tolik0 b4e470b
Merge branch 'main' into devin/1788275534-shared-check-assertion
tolik0 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # Copyright (c) 2026 Airbyte, Inc., all rights reserved. | ||
| """Shared assertions for Airbyte Standard Tests. | ||
|
|
||
| These assertions are shared between the in-process test runner (`_job_runner.run_test_job`) | ||
| and the Docker-based test suite (`docker_base.DockerConnectorTestSuite`), so that both paths | ||
| enforce the same expectations. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING, Any | ||
|
|
||
| import jsonschema | ||
|
|
||
| from airbyte_cdk.models import Status | ||
| from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput | ||
| from airbyte_cdk.test.models import ExpectedOutcome | ||
|
|
||
| if TYPE_CHECKING: | ||
| from collections.abc import Mapping | ||
|
|
||
|
|
||
| def assert_check_outcome( | ||
| *, | ||
| check_result: EntrypointOutput, | ||
| expected_outcome: ExpectedOutcome, | ||
| connector_name: str, | ||
| ) -> None: | ||
| """Assert that the outcome of `check` matches the scenario's expected outcome. | ||
|
|
||
| A failing `check` reports `status: FAILED` in a `CONNECTION_STATUS` message and still | ||
| exits 0, so exit-code checks alone do not catch it. We therefore assert the reported | ||
| status explicitly, following the `status` semantics of `acceptance-test-config.yml`: | ||
|
|
||
| - `succeed` (`EXPECT_SUCCESS`): a `CONNECTION_STATUS` message with status `SUCCEEDED`. | ||
| - `failed` (`EXPECT_EXCEPTION`): a `CONNECTION_STATUS` message with status `FAILED`. | ||
| - `exception` (`EXPECT_UNCAUGHT_ERROR`): `check` raises, so a `TRACE` error must be present | ||
| and no `SUCCEEDED` status may be reported. A `CONNECTION_STATUS` message is not required. | ||
| - no `status` (`ALLOW_ANY`): treated as `succeed`, matching the CAT default. A config that | ||
| `check` is expected to reject must declare `status: failed` (or `exception`). | ||
|
|
||
| When more than one `CONNECTION_STATUS` message is present, the last one wins. | ||
| """ | ||
| connection_statuses = [ | ||
| message.connectionStatus | ||
| for message in check_result.connection_status_messages | ||
| if message.connectionStatus is not None | ||
| ] | ||
| if expected_outcome.expect_uncaught_error(): | ||
| assert check_result.errors, ( | ||
| f"`check` for connector '{connector_name}' was expected to raise " | ||
| f"(`status: exception`), but emitted no TRACE error. " | ||
| f"Reported statuses: {connection_statuses}" | ||
| ) | ||
| assert not connection_statuses or connection_statuses[-1].status != Status.SUCCEEDED, ( | ||
| f"`check` for connector '{connector_name}' was expected to raise " | ||
| f"(`status: exception`), but reported: {connection_statuses[-1]}" | ||
| ) | ||
| return | ||
|
|
||
| assert connection_statuses, ( | ||
|
tolik0 marked this conversation as resolved.
|
||
| f"`check` for connector '{connector_name}' emitted no CONNECTION_STATUS message. " | ||
| f"A `check` implementation should report its outcome as a CONNECTION_STATUS message " | ||
| f"instead of raising. If raising is the expected outcome for this config, declare " | ||
| f"`status: exception` for it in `acceptance-test-config.yml`.\n" | ||
| + (f"Errors: {check_result.get_formatted_error_message()}\n" if check_result.errors else "") | ||
| + f"Logs: {check_result.logs}" | ||
| ) | ||
| reported_status = connection_statuses[-1].status | ||
| if expected_outcome.expect_exception(): | ||
| assert reported_status == Status.FAILED, ( | ||
| f"`check` for connector '{connector_name}' was expected to fail, but reported: " | ||
| f"{connection_statuses[-1]}" | ||
| ) | ||
| return | ||
|
|
||
| # Both `EXPECT_SUCCESS` and `ALLOW_ANY` (no declared status) require a successful `check`. | ||
| assert reported_status == Status.SUCCEEDED, ( | ||
| f"`check` for connector '{connector_name}' did not succeed: {connection_statuses[-1]}" | ||
| ) | ||
|
|
||
|
|
||
| def assert_config_matches_spec( | ||
| *, | ||
| config: Mapping[str, Any], | ||
| spec_result: EntrypointOutput, | ||
| connector_name: str, | ||
| scenario_id: str, | ||
| ) -> None: | ||
| """Assert that a config validates against the `connectionSpecification` the connector reports. | ||
|
|
||
| This is the CAT `test_config_match_spec` check for configs listed under `spec` in | ||
| `acceptance-test-config.yml`: the connector's own spec must accept the config. The config's | ||
| values never appear in the failure message, since they may be secrets. | ||
| """ | ||
| specs = [message.spec for message in spec_result.spec_messages if message.spec is not None] | ||
| assert len(specs) == 1, ( | ||
| f"Expected exactly one SPEC message from connector '{connector_name}', got {len(specs)}." | ||
| + (f"\nErrors: {spec_result.get_formatted_error_message()}" if spec_result.errors else "") | ||
| ) | ||
| try: | ||
| jsonschema.validate(instance=config, schema=specs[0].connectionSpecification) | ||
| except jsonschema.ValidationError as exc: | ||
| # `exc.message` embeds the offending value; keep it (and the chained exception, whose | ||
| # text includes the instance) out of the test output. | ||
| message = exc.message.replace(repr(exc.instance), "<config value>") | ||
| raise AssertionError( | ||
| f"Config '{scenario_id}' does not match the spec of connector '{connector_name}' " | ||
| f"at `{exc.json_path}`: {message}" | ||
| ) from None | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.