Skip to content

feat(cli,mcp): add destination-smoke-test command and MCP tool#998

Merged
Aaron ("AJ") Steers (aaronsteers) merged 5 commits intomainfrom
devin/1773861379-destination-smoke-test
Mar 18, 2026
Merged

feat(cli,mcp): add destination-smoke-test command and MCP tool#998
Aaron ("AJ") Steers (aaronsteers) merged 5 commits intomainfrom
devin/1773861379-destination-smoke-test

Conversation

@aaronsteers
Copy link
Contributor

@aaronsteers Aaron ("AJ") Steers (aaronsteers) commented Mar 18, 2026

Summary

Adds a new pyab destination-smoke-test CLI command and a corresponding destination_smoke_test MCP tool. Both send synthetic data from the existing SourceSmokeTest (15 predefined scenarios covering type variations, null handling, naming edge cases, etc.) to a destination connector via Destination.write() and report pass/fail as structured JSON.

This is the execution layer for destination regression testing — it answers "does this destination accept the smoke test data without errors?" No readback or comparison is performed (that's a future increment).

Architecture: Shared logic lives in airbyte/_util/destination_smoke_tests.py — both CLI and MCP are thin presentation layers that delegate to run_destination_smoke_test(). Neither imports from the other.

Scenario keywords:

  • fast (default) — all fast predefined scenarios, excluding large_batch_stream
  • all — every predefined scenario including large_batch_stream
  • Comma-separated list — explicit subset of scenario names

CLI usage:

pyab destination-smoke-test \
    --destination=destination-snowflake \
    --config=./secrets/snowflake.json

pyab destination-smoke-test \
    --destination=destination-dev-null \
    --scenarios=basic_types,null_handling

pyab destination-smoke-test \
    --destination=destination-snowflake \
    --config=./secrets/snowflake.json --scenarios=all

MCP tool: Same functionality exposed as destination_smoke_test in the local tools module, returning a structured DestinationSmokeTestResult Pydantic model. Also supports custom_scenarios as inline dicts and docker_image override.

Updates since last revision

  • Stream status TRACE messages (bug fix to smoke test source). JDK-based destinations (e.g. destination-dev-null) require STARTED/RUNNING/COMPLETE stream status trace messages per the Airbyte protocol. The smoke test source was only emitting RECORD messages, causing all JDK destinations to fail with TransientErrorException: streams did not receive a terminal stream status message. Fixed in source.py by emitting the required TRACE messages around each stream's records.
  • fast/all scenario keywords implemented with fast as default. Empty scenario lists are normalized to fast.
  • Tested locally against destination-dev-null — 28 records across 13 fast streams delivered successfully, exit code 0.

Review & Testing Checklist for Human

  • Stream status TRACE messages are correct. This fix modifies source.py (shipped in PR feat(cli): add source-smoke-test CLI #996). The sequence is STARTED → RUNNING → records → COMPLETE per stream. Verify this matches the protocol expectations for both JDK and Python CDK destinations — the order matters and incorrect ordering could cause different failures on other destinations.
  • Test against a real credentialed destination (e.g. Snowflake, MotherDuck). The local test only covered destination-dev-null which is a no-op sink — it validates protocol compliance but not actual data delivery.
  • Review MCP Docker auto-detection divergence. When no docker_image is specified and Docker is installed, the MCP tool defaults to docker_image=True. The CLI instead delegates to _resolve_destination_job which has slightly different resolution logic. Confirm this divergence is acceptable.
  • Error sanitization fallback. _sanitize_error() uses get_message() for PyAirbyte exceptions but falls back to str(ex) for others. Third-party exceptions could theoretically include config details.

Recommended test plan

# 1. Install from branch
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1773861379-destination-smoke-test'

# 2. Quick smoke test (no credentials needed)
pyab destination-smoke-test --destination=destination-dev-null

# 3. With scenario filtering
pyab destination-smoke-test --destination=destination-dev-null --scenarios=basic_types,null_handling

# 4. All scenarios including large batch
pyab destination-smoke-test --destination=destination-dev-null --scenarios=all

# 5. Against a real destination
pyab destination-smoke-test --destination=destination-snowflake --config=./secrets/snowflake.json

# 6. Verify exit code on failure (bad config)
pyab destination-smoke-test --destination=destination-snowflake; echo "exit: $?"

Notes

  • The DestinationSmokeTestResult model and _sanitize_error helper are exported from the shared module for potential reuse by the ops repo test harness.
  • The stream status fix also affects the smoke test source when used standalone (not just via this new command). This is a net positive — it was broken for all JDK destinations before this fix.

Link to Devin session: https://app.devin.ai/sessions/9c72389579884c06bf18cef11c4550e8
Requested by: Aaron ("AJ") Steers (@aaronsteers)

Summary by CodeRabbit

New Features

  • Added a CLI command to run destination smoke tests with configurable scenarios and customization options
  • Support for custom test scenarios via direct parameters or external files
  • Smoke test results displayed as JSON output with execution metrics and delivery details
  • Added stream status lifecycle tracking during test execution

Adds a new `pyab destination-smoke-test` CLI command and a corresponding
`destination_smoke_test` MCP tool that send synthetic smoke test data
to a destination connector and report success/failure.

Both use the existing SourceSmokeTest (15 predefined scenarios) via
PyAirbyte's Destination.write() orchestration. Supports:
- Destination resolution (name, Docker image, local executable)
- Destination config via file, inline YAML, or secret reference
- Scenario filtering via --scenario-filter
- Large batch inclusion via --include-large-batch
- Custom scenario injection via --custom-scenarios (CLI) or custom_scenarios param (MCP)
- Structured JSON output with success/failure, record counts, timing, errors

Co-Authored-By: AJ Steers <aj@airbyte.io>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@octavia-bot
Copy link

octavia-bot bot commented Mar 18, 2026

Note

📝 PR Converted to Draft

More info...

Thank you for creating this PR. As a policy to protect our engineers' time, Airbyte requires all PRs to be created first in draft status. Your PR has been automatically converted to draft status in respect for this policy.

As soon as your PR is ready for formal review, you can proceed to convert the PR to "ready for review" status by clicking the "Ready for review" button at the bottom of the PR page.

To skip draft status in future PRs, please include [ready] in your PR title or add the skip-draft-status label when creating your PR.

@octavia-bot octavia-bot bot marked this pull request as draft March 18, 2026 19:24
@github-actions
Copy link

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

Testing This PyAirbyte Version

You can test this version of PyAirbyte using the following:

# Run PyAirbyte CLI from this branch:
uvx --from 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1773861379-destination-smoke-test' pyairbyte --help

# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1773861379-destination-smoke-test'

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /fix-pr - Fixes most formatting and linting issues
  • /uv-lock - Updates uv.lock file
  • /test-pr - Runs tests with the updated PyAirbyte
  • /prerelease - Builds and publishes a prerelease version to PyPI
📚 Show Repo Guidance

Helpful Resources

Community Support

Questions? Join the #pyairbyte channel in our Slack workspace.

📝 Edit this welcome message.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

@github-actions
Copy link

github-actions bot commented Mar 18, 2026

PyTest Results (Fast Tests Only, No Creds)

343 tests  ±0   343 ✅ ±0   5m 49s ⏱️ +10s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit f624c99. ± Comparison against base commit 803fc93.

♻️ This comment has been updated with latest results.

This comment was marked as resolved.

…ings, sanitize errors, destructive=True

Co-Authored-By: AJ Steers <aj@airbyte.io>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

Adds a destination smoke-test feature: new utilities to build a smoke-test Source and run writes to a resolved Destination, plus CLI and MCP entrypoints that execute the test, return a structured JSON result (success, records_delivered, elapsed_seconds, error), and exit non‑zero on failure.

Changes

Cohort / File(s) Summary
CLI command
airbyte/cli/pyab.py
Added destination-smoke-test Click command; imports json and run_destination_smoke_test; resolves destination, runs smoke tests, prints indented JSON, and exits non‑zero on failure.
MCP tool
airbyte/mcp/local.py
Added destination_smoke_test(...) function and imports (get_destination, run_destination_smoke_test, DestinationSmokeTestResult) to resolve destination/config, determine docker image, assemble scenarios, call runner, and return a structured result. (Duplicate insertion points present in diff.)
Smoke-test utilities
airbyte/_util/destination_smoke_tests.py
New module: DestinationSmokeTestResult Pydantic model, get_smoke_test_source (scenarios/custom file merging/validation), _sanitize_error, and run_destination_smoke_test which creates source, invokes destination.write, times execution, and returns sanitized results.
Smoke-test source
airbyte/cli/smoke_test_source/source.py
Emit stream lifecycle trace messages: added _stream_status_message and updated read() to yield STARTED, RUNNING, and COMPLETE stream status messages; consolidated custom-scenarios validation message.
Imports / wiring
airbyte/cli/pyab.py, airbyte/mcp/local.py
Added necessary imports and registered CLI/MCP wiring to expose smoke-test functionality.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as CLI / MCP
    participant Source as SmokeTest Source
    participant Destination as Destination Connector
    participant Result as Result Builder

    User->>CLI: invoke destination-smoke-test(dest, config, scenarios)
    CLI->>Destination: resolve & initialize destination (config / docker image)
    CLI->>Source: construct smoke source (scenarios / custom)
    CLI->>CLI: start timer
    Source->>Destination: stream test records (write)
    Destination-->>Source: acknowledge / record counts
    Source-->>CLI: finish (records_delivered / error)
    CLI->>CLI: stop timer
    CLI->>Result: assemble DestinationSmokeTestResult
    Result-->>User: print JSON and exit (non‑zero if failure)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Would you like me to flag and remove the duplicate destination_smoke_test declarations in airbyte/mcp/local.py, wdyt?

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding a new destination-smoke-test command to both CLI and MCP with specific focus on the two primary additions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1773861379-destination-smoke-test
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
airbyte/mcp/local.py (3)

971-976: Duplicate call to resolve_list_of_strings

resolve_list_of_strings(scenario_filter) is already called at line 940 and stored in resolved_filter. Could we reuse that result here instead of calling the function again, wdyt?

♻️ Proposed fix to reuse the resolved filter
     scenarios_str: str
-    if scenario_filter:
-        resolved = resolve_list_of_strings(scenario_filter)
-        scenarios_str = ",".join(resolved) if resolved else "all_fast"
+    if resolved_filter:
+        scenarios_str = ",".join(resolved_filter)
     else:
         scenarios_str = "all_fast"

Note: You'll also need to move resolved_filter declaration to before the try block so it's accessible here, or refactor to compute it once at the start.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@airbyte/mcp/local.py` around lines 971 - 976, The code is redundantly calling
resolve_list_of_strings(scenario_filter) twice; compute resolved_filter once
(using resolve_list_of_strings(scenario_filter)) before the try block so it’s in
scope, then replace the second call with that variable when building
scenarios_str (set scenarios_str = ",".join(resolved_filter) if resolved_filter
else "all_fast"); ensure any moved declaration still has correct error handling
or fallbacks and that references to scenario_filter, resolved_filter,
resolve_list_of_strings, and scenarios_str are updated accordingly.

915-920: Missing config_spec_jsonschema in config resolution - is this intentional?

Other MCP tools in this file (e.g., validate_connector_config, list_source_streams) pass config_spec_jsonschema to resolve_connector_config for schema-based validation. This function omits it. Is this intentional because the destination connector validates the config downstream anyway, or would it be worth fetching the spec first for early validation, wdyt?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@airbyte/mcp/local.py` around lines 915 - 920, The call to
resolve_connector_config is missing the config_spec_jsonschema argument used
elsewhere for early schema validation; update the call in this block to pass the
connector spec JSON schema (as other functions like validate_connector_config
and list_source_streams do) by fetching or reusing the destination spec (e.g.,
via the same get_*_spec helper used elsewhere) and supply it as
config_spec_jsonschema to resolve_connector_config so the destination config is
validated against its JSON schema before continuing.

966-968: Consider including traceback in error for debugging?

Other MCP tools in this file capture traceback.format_exc() for debugging purposes. The current approach only captures str(ex). For debugging connector issues, a full traceback might be helpful. Would it be worth adding it to the error field or logging it separately, wdyt?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@airbyte/mcp/local.py` around lines 966 - 968, In the except Exception as ex
block where error_message = str(ex), change handling to include the full
traceback for debugging: import traceback at top (if not present), call
traceback.format_exc() inside the except and either append or replace
error_message with that value (e.g., error_message =
f"{str(ex)}\n{traceback.format_exc()}") or log traceback separately via the same
logger used elsewhere; update references to error_message so the stored/returned
error includes the traceback for connector debugging.
airbyte/cli/pyab.py (1)

825-836: Minor inconsistency with MCP result structure

The CLI result dict conditionally includes the error key only on failure (lines 833-834), while the MCP DestinationSmokeTestResult model always includes error (defaulting to None). This slight schema difference could affect consumers expecting a consistent structure. Would it make sense to always include "error": None for consistency with the MCP tool, or is the current behavior preferred for CLI output, wdyt?

♻️ Optional: Always include error key for consistency
     result = {
         "success": success,
         "destination": _get_connector_name(destination),
         "records_delivered": records_delivered,
         "scenarios_requested": scenario_filter or "all_fast",
         "include_large_batch": include_large_batch,
         "elapsed_seconds": round(elapsed, 2),
+        "error": error_message,
     }
-    if error_message:
-        result["error"] = error_message
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@airbyte/cli/pyab.py` around lines 825 - 836, The CLI builds a result dict in
the smoke test flow that only adds the "error" key when error_message is truthy,
which differs from the MCP DestinationSmokeTestResult that always includes error
(possibly None); update the result construction around the result = {...} block
so it always sets result["error"] = error_message (which may be None) before
echoing via click.echo(json.dumps(result, indent=2)), ensuring the CLI output
structure matches DestinationSmokeTestResult and keeping symbols like result,
error_message, DestinationSmokeTestResult, and click.echo in mind when making
the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@airbyte/cli/pyab.py`:
- Around line 825-836: The CLI builds a result dict in the smoke test flow that
only adds the "error" key when error_message is truthy, which differs from the
MCP DestinationSmokeTestResult that always includes error (possibly None);
update the result construction around the result = {...} block so it always sets
result["error"] = error_message (which may be None) before echoing via
click.echo(json.dumps(result, indent=2)), ensuring the CLI output structure
matches DestinationSmokeTestResult and keeping symbols like result,
error_message, DestinationSmokeTestResult, and click.echo in mind when making
the change.

In `@airbyte/mcp/local.py`:
- Around line 971-976: The code is redundantly calling
resolve_list_of_strings(scenario_filter) twice; compute resolved_filter once
(using resolve_list_of_strings(scenario_filter)) before the try block so it’s in
scope, then replace the second call with that variable when building
scenarios_str (set scenarios_str = ",".join(resolved_filter) if resolved_filter
else "all_fast"); ensure any moved declaration still has correct error handling
or fallbacks and that references to scenario_filter, resolved_filter,
resolve_list_of_strings, and scenarios_str are updated accordingly.
- Around line 915-920: The call to resolve_connector_config is missing the
config_spec_jsonschema argument used elsewhere for early schema validation;
update the call in this block to pass the connector spec JSON schema (as other
functions like validate_connector_config and list_source_streams do) by fetching
or reusing the destination spec (e.g., via the same get_*_spec helper used
elsewhere) and supply it as config_spec_jsonschema to resolve_connector_config
so the destination config is validated against its JSON schema before
continuing.
- Around line 966-968: In the except Exception as ex block where error_message =
str(ex), change handling to include the full traceback for debugging: import
traceback at top (if not present), call traceback.format_exc() inside the except
and either append or replace error_message with that value (e.g., error_message
= f"{str(ex)}\n{traceback.format_exc()}") or log traceback separately via the
same logger used elsewhere; update references to error_message so the
stored/returned error includes the traceback for connector debugging.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 098234f2-e81f-4e12-bca7-0b86fb416889

📥 Commits

Reviewing files that changed from the base of the PR and between 803fc93 and a224601.

📒 Files selected for processing (2)
  • airbyte/cli/pyab.py
  • airbyte/mcp/local.py

devin-ai-integration[bot]

This comment was marked as resolved.

- Move DestinationSmokeTestResult, get_smoke_test_source, run_destination_smoke_test
  into shared module used by both CLI and MCP
- Fix incorrect scenario names in CLI help text (bug: names didn't match actual scenarios)
- Remove duplicated orchestration logic from CLI and MCP
- CLI and MCP are now thin presentation layers over the shared implementation

Co-Authored-By: AJ Steers <aj@airbyte.io>
coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@devin-ai-integration
Copy link
Contributor

Addressed the actionable bot findings in commits 93f021a and c725831:

Fixed (real bugs/edge cases):

  • Empty scenarios list edge case: now normalized to "fast" before calling get_smoke_test_source, so display and behavior are consistent
  • Scenario names in CLI help text: corrected to match actual names from _scenarios.py
  • 'fast' and 'all' keywords implemented with 'fast' as default per AJ's direction

Acknowledged but not acting on (bot suggestions, not bugs):

  • Wrapping _resolve_destination_job (CLI) and resolve_connector_config/get_destination (MCP) in try/except for structured error output: these are reasonable hardening suggestions but not bugs. The shared run_destination_smoke_test() function already catches write errors and returns structured results. Config/destination resolution failures are input validation errors that should surface as normal exceptions (Click handles these gracefully for CLI, MCP framework handles them for the tool). Can revisit if AJ wants this.

…tinations

Co-Authored-By: AJ Steers <aj@airbyte.io>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
airbyte/cli/smoke_test_source/source.py (1)

327-343: Nice helper for stream status messages!

The implementation looks good. One small observation: this method doesn't use self, so it could be a @staticmethod if you wanted to be more explicit about that—but totally fine as-is too. What do you think, wdyt?

Also, I noticed there's a similar get_stream_status_message function in airbyte/_message_iterators.py (context snippet 1), though that one appears to be specifically for success/complete status only. Your method is more flexible with the status parameter, so the duplication is justified here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@airbyte/cli/smoke_test_source/source.py` around lines 327 - 343, The
_stream_status_message method doesn't use self, so mark it as a `@staticmethod`
and remove the unused self parameter: add the `@staticmethod` decorator above
_stream_status_message and change its signature from (self, stream_name: str,
status: AirbyteStreamStatus) to (stream_name: str, status: AirbyteStreamStatus);
keep the function body and return value exactly the same so callers can continue
invoking it as a bound method or via the class.
airbyte/_util/destination_smoke_tests.py (2)

145-153: Reasonable error sanitization approach!

Using get_message() for PyAirbyte exceptions avoids leaking config/context data (as confirmed in the PyAirbyteError context snippet showing it only returns the message attribute).

For the fallback at line 153, str(ex) is used for non-PyAirbyte exceptions. Standard library exceptions typically don't include sensitive config data, but if a third-party library exception happens to include such data in its __str__, it could potentially be exposed. This is probably an acceptable tradeoff for debuggability—just wanted to flag it. Do you think it's worth adding a note in the docstring about this edge case, wdyt?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@airbyte/_util/destination_smoke_tests.py` around lines 145 - 153, Update the
_sanitize_error function docstring to note the tradeoff: it uses
ex.get_message() for PyAirbyte exceptions (e.g. PyAirbyteError) to avoid leaking
config/context, and falls back to str(ex) for other exception types which may,
in rare third‑party cases, include sensitive data; explicitly document this edge
case and the intentional choice for better debuggability so reviewers know this
is an accepted risk.

137-142: Consider documenting the source-smoke-test prerequisite.

The smoke test already raises a descriptive AirbyteConnectorExecutableNotFoundError if the executable isn't on PATH (via the executor utility), so the error handling is in good shape. However, it might be worth adding a note in the docstring or README that users need source-smoke-test installed to use run_destination_smoke_test(). This would prevent users from wondering what's missing when they hit that error, wdyt?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@airbyte/_util/destination_smoke_tests.py` around lines 137 - 142, Add
documentation that the helper expects the external executable
"source-smoke-test" on PATH: update the docstring for run_destination_smoke_test
(or the module-level docstring) to state that get_source is invoked with
local_executable="source-smoke-test" and users must have that executable
installed/available on PATH before running run_destination_smoke_test();
optionally add a short note to the README pointing to installation instructions
for the source-smoke-test binary.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@airbyte/_util/destination_smoke_tests.py`:
- Around line 145-153: Update the _sanitize_error function docstring to note the
tradeoff: it uses ex.get_message() for PyAirbyte exceptions (e.g.
PyAirbyteError) to avoid leaking config/context, and falls back to str(ex) for
other exception types which may, in rare third‑party cases, include sensitive
data; explicitly document this edge case and the intentional choice for better
debuggability so reviewers know this is an accepted risk.
- Around line 137-142: Add documentation that the helper expects the external
executable "source-smoke-test" on PATH: update the docstring for
run_destination_smoke_test (or the module-level docstring) to state that
get_source is invoked with local_executable="source-smoke-test" and users must
have that executable installed/available on PATH before running
run_destination_smoke_test(); optionally add a short note to the README pointing
to installation instructions for the source-smoke-test binary.

In `@airbyte/cli/smoke_test_source/source.py`:
- Around line 327-343: The _stream_status_message method doesn't use self, so
mark it as a `@staticmethod` and remove the unused self parameter: add the
`@staticmethod` decorator above _stream_status_message and change its signature
from (self, stream_name: str, status: AirbyteStreamStatus) to (stream_name: str,
status: AirbyteStreamStatus); keep the function body and return value exactly
the same so callers can continue invoking it as a bound method or via the class.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7948578b-2991-44b0-b35b-7d5efa40bd1b

📥 Commits

Reviewing files that changed from the base of the PR and between 93f021a and f624c99.

📒 Files selected for processing (4)
  • airbyte/_util/destination_smoke_tests.py
  • airbyte/cli/pyab.py
  • airbyte/cli/smoke_test_source/source.py
  • airbyte/mcp/local.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • airbyte/mcp/local.py
  • airbyte/cli/pyab.py

@github-actions
Copy link

PyTest Results (Full)

413 tests  ±0   395 ✅ ±0   25m 21s ⏱️ -11s
  1 suites ±0    18 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit f624c99. ± Comparison against base commit 803fc93.

@aaronsteers Aaron ("AJ") Steers (aaronsteers) merged commit 00ab7ca into main Mar 18, 2026
23 checks passed
@aaronsteers Aaron ("AJ") Steers (aaronsteers) deleted the devin/1773861379-destination-smoke-test branch March 18, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants