Skip to content

Commit 345b3d2

Browse files
committed
add handling for empty config within a scenario
1 parent b883a55 commit 345b3d2

File tree

3 files changed

+29
-20
lines changed

3 files changed

+29
-20
lines changed

airbyte_cdk/test/standard_tests/_job_runner.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ def run_test_job(
6262
catalog: ConfiguredAirbyteCatalog | dict[str, Any] | None = None,
6363
) -> entrypoint_wrapper.EntrypointOutput:
6464
"""Run a test scenario from provided CLI args and return the result."""
65+
# Use default (empty) scenario if not provided:
66+
test_scenario = test_scenario or ConnectorTestScenario()
67+
6568
if not connector:
6669
raise ValueError("Connector is required")
6770

@@ -81,14 +84,14 @@ def run_test_job(
8184
)
8285

8386
args: list[str] = [verb]
84-
if test_scenario and test_scenario.config_path:
85-
args += ["--config", str(test_scenario.config_path)]
86-
elif test_scenario and test_scenario.config_dict:
87+
config_dict = test_scenario.get_config_dict(empty_if_missing=True)
88+
if config_dict and verb != "spec":
89+
# Write the config to a temp json file and pass the path to the file as an argument.
8790
config_path = (
8891
Path(tempfile.gettempdir()) / "airbyte-test" / f"temp_config_{uuid.uuid4().hex}.json"
8992
)
9093
config_path.parent.mkdir(parents=True, exist_ok=True)
91-
config_path.write_text(orjson.dumps(test_scenario.config_dict).decode())
94+
config_path.write_text(orjson.dumps(config_dict).decode())
9295
args += ["--config", str(config_path)]
9396

9497
catalog_path: Path | None = None
@@ -103,7 +106,7 @@ def run_test_job(
103106
)
104107
catalog_path.parent.mkdir(parents=True, exist_ok=True)
105108
catalog_path.write_text(orjson.dumps(catalog).decode())
106-
elif test_scenario and test_scenario.configured_catalog_path:
109+
elif test_scenario.configured_catalog_path:
107110
catalog_path = Path(test_scenario.configured_catalog_path)
108111

109112
if catalog_path:
@@ -112,18 +115,12 @@ def run_test_job(
112115
# This is a bit of a hack because the source needs the catalog early.
113116
# Because it *also* can fail, we have to redundantly wrap it in a try/except block.
114117

115-
expect_exception = False
116-
if test_scenario and test_scenario.expect_exception:
117-
# If the test scenario expects an exception, we need to set the
118-
# `expect_exception` flag to True.
119-
expect_exception = True
120-
121118
result: entrypoint_wrapper.EntrypointOutput = entrypoint_wrapper._run_command( # noqa: SLF001 # Non-public API
122119
source=connector_obj, # type: ignore [arg-type]
123120
args=args,
124-
expecting_exception=expect_exception,
121+
expecting_exception=test_scenario.expect_exception,
125122
)
126-
if result.errors and not expect_exception:
123+
if result.errors and not test_scenario.expect_exception:
127124
raise AssertionError(
128125
f"Expected no errors but got {len(result.errors)}: \n" + _errors_to_str(result)
129126
)
@@ -138,7 +135,7 @@ def run_test_job(
138135
+ "\n".join([str(msg) for msg in result.connection_status_messages])
139136
+ _errors_to_str(result)
140137
)
141-
if expect_exception:
138+
if test_scenario.expect_exception:
142139
conn_status = result.connection_status_messages[0].connectionStatus
143140
assert conn_status, (
144141
"Expected CONNECTION_STATUS message to be present. Got: \n"
@@ -152,7 +149,7 @@ def run_test_job(
152149
return result
153150

154151
# For all other verbs, we assert check that an exception is raised (or not).
155-
if expect_exception:
152+
if test_scenario.expect_exception:
156153
if not result.errors:
157154
raise AssertionError("Expected exception but got none.")
158155

airbyte_cdk/test/standard_tests/declarative_sources.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ def create_connector(
7373
7474
Subclasses should not need to override this method.
7575
"""
76+
scenario = scenario or ConnectorTestScenario() # Use default (empty) scenario if None
7677
manifest_dict = yaml.safe_load(cls.manifest_yaml_path.read_text())
7778
config = {
7879
"__injected_manifest": manifest_dict,
7980
}
80-
if scenario:
81-
config.update(scenario.get_config_dict())
81+
config.update(scenario.get_config_dict(empty_if_missing=True))
8282

8383
if cls.components_py_path and cls.components_py_path.exists():
8484
os.environ["AIRBYTE_ENABLE_UNSAFE_CODE"] = "true"

airbyte_cdk/test/standard_tests/models/scenario.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from typing import Any, Literal, cast
1414

1515
import yaml
16+
from numpy import empty
1617
from pydantic import BaseModel
1718

1819

@@ -43,18 +44,29 @@ class AcceptanceTestFileTypes(BaseModel):
4344
file_types: AcceptanceTestFileTypes | None = None
4445
status: Literal["succeed", "failed"] | None = None
4546

46-
def get_config_dict(self) -> dict[str, Any]:
47+
def get_config_dict(
48+
self,
49+
*,
50+
empty_if_missing: bool,
51+
) -> dict[str, Any]:
4752
"""Return the config dictionary.
4853
4954
If a config dictionary has already been loaded, return it. Otherwise, load
5055
the config file and return the dictionary.
56+
57+
If `self.config_dict` and `self.config_path` are both `None`:
58+
- return an empty dictionary if `empty_if_missing` is True
59+
- raise a ValueError if `empty_if_missing` is False
5160
"""
52-
if self.config_dict:
61+
if self.config_dict is not None:
5362
return self.config_dict
5463

55-
if self.config_path:
64+
if self.config_path is not None:
5665
return cast(dict[str, Any], yaml.safe_load(self.config_path.read_text()))
5766

67+
if empty_if_missing:
68+
return {}
69+
5870
raise ValueError("No config dictionary or path provided.")
5971

6072
@property

0 commit comments

Comments
 (0)