-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[components] Set up test components (#26512)
## Summary & Motivation This PR is an overhaul of testing in `dagster-dg` with the aim of decoupling development of "real" components from the tests of `dg`. - Introduces an alternative set of test components in `dagster-components`. `dagster-components` will only ever load one of its builtin component libraries-- the test or the published components. Test components allow us to ensure coverage over cases like components with no summary/description/params. - Which library gets loaded is controlled via the `use_test_component_lib` to `ComponentRegistry.from_entry_point_discovery`. This in turn can be controlled via the `--use-test-component-lib` CLI param on both the `dagster-dg` and `dagster-components` CLIs. - Many tests are rewritten against the set of test components and are now more precise (for example, check the exact format of the output of the `dg info component-type` command output) - Introduced some new test utilities introduced in `dagster-dg` to make all this easier. ## How I Tested These Changes Unit tests
- Loading branch information
Showing
25 changed files
with
929 additions
and
314 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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
14 changes: 14 additions & 0 deletions
14
python_modules/libraries/dagster-components/dagster_components/utils.py
This file contains 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,14 @@ | ||
import sys | ||
from pathlib import Path | ||
|
||
CLI_BUILTIN_COMPONENT_LIB_KEY = "builtin_component_lib" | ||
|
||
|
||
def ensure_dagster_components_tests_import() -> None: | ||
from dagster_components import __file__ as dagster_components_init_py | ||
|
||
dagster_components_package_root = (Path(dagster_components_init_py) / ".." / "..").resolve() | ||
assert ( | ||
dagster_components_package_root / "dagster_components_tests" | ||
).exists(), "Could not find dagster_components_tests where expected" | ||
sys.path.append(dagster_components_package_root.as_posix()) |
103 changes: 103 additions & 0 deletions
103
..._modules/libraries/dagster-components/dagster_components_tests/cli_tests/test_commands.py
This file contains 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,103 @@ | ||
import json | ||
from pathlib import Path | ||
|
||
from click.testing import CliRunner | ||
from dagster_components.cli import cli | ||
from dagster_components.utils import ensure_dagster_components_tests_import | ||
|
||
ensure_dagster_components_tests_import() | ||
|
||
from dagster_components_tests.utils import temp_code_location_bar | ||
|
||
|
||
# Test that the global --use-test-component-lib flag changes the registered components | ||
def test_global_test_flag(): | ||
runner: CliRunner = CliRunner() | ||
|
||
# standard | ||
result = runner.invoke(cli, ["list", "component-types"]) | ||
assert result.exit_code == 0 | ||
default_result_keys = list(json.loads(result.output).keys()) | ||
assert len(default_result_keys) > 0 | ||
|
||
result = runner.invoke( | ||
cli, ["--builtin-component-lib", "dagster_components.test", "list", "component-types"] | ||
) | ||
assert result.exit_code == 0 | ||
test_result_keys = list(json.loads(result.output).keys()) | ||
assert len(default_result_keys) > 0 | ||
|
||
assert default_result_keys != test_result_keys | ||
|
||
|
||
def test_list_component_types_command(): | ||
runner = CliRunner() | ||
|
||
result = runner.invoke( | ||
cli, ["--builtin-component-lib", "dagster_components.test", "list", "component-types"] | ||
) | ||
assert result.exit_code == 0 | ||
result = json.loads(result.output) | ||
|
||
assert list(result.keys()) == [ | ||
"dagster_components.test.all_metadata_empty_asset", | ||
"dagster_components.test.simple_asset", | ||
"dagster_components.test.simple_pipes_script_asset", | ||
] | ||
|
||
assert result["dagster_components.test.simple_asset"] == { | ||
"name": "simple_asset", | ||
"package": "dagster_components.test", | ||
"summary": "A simple asset that returns a constant string value.", | ||
"description": "A simple asset that returns a constant string value.", | ||
"generate_params_schema": None, | ||
"component_params_schema": { | ||
"properties": { | ||
"asset_key": {"title": "Asset Key", "type": "string"}, | ||
"value": {"title": "Value", "type": "string"}, | ||
}, | ||
"required": ["asset_key", "value"], | ||
"title": "SimpleAssetParams", | ||
"type": "object", | ||
}, | ||
} | ||
|
||
pipes_script_params_schema = { | ||
"properties": { | ||
"asset_key": {"title": "Asset Key", "type": "string"}, | ||
"filename": {"title": "Filename", "type": "string"}, | ||
}, | ||
"required": ["asset_key", "filename"], | ||
"title": "SimplePipesScriptAssetParams", | ||
"type": "object", | ||
} | ||
|
||
assert result["dagster_components.test.simple_pipes_script_asset"] == { | ||
"name": "simple_pipes_script_asset", | ||
"package": "dagster_components.test", | ||
"summary": "A simple asset that runs a Python script with the Pipes subprocess client.", | ||
"description": "A simple asset that runs a Python script with the Pipes subprocess client.\n\nBecause it is a pipes asset, no value is returned.", | ||
"generate_params_schema": pipes_script_params_schema, | ||
"component_params_schema": pipes_script_params_schema, | ||
} | ||
|
||
|
||
def test_generate_component_command(): | ||
runner = CliRunner() | ||
|
||
with temp_code_location_bar(): | ||
result = runner.invoke( | ||
cli, | ||
[ | ||
"--builtin-component-lib", | ||
"dagster_components.test", | ||
"generate", | ||
"component", | ||
"dagster_components.test.simple_pipes_script_asset", | ||
"qux", | ||
"--json-params", | ||
'{"asset_key": "my_asset", "filename": "my_asset.py"}', | ||
], | ||
) | ||
assert result.exit_code == 0 | ||
assert Path("bar/components/qux/my_asset.py").exists() |
7 changes: 7 additions & 0 deletions
7
python_modules/libraries/dagster-components/dagster_components_tests/lib/__init__.py
This file contains 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,7 @@ | ||
from dagster_components_tests.lib.all_metadata_empty_asset import ( | ||
AllMetadataEmptyAsset as AllMetadataEmptyAsset, | ||
) | ||
from dagster_components_tests.lib.simple_asset import SimpleAsset as SimpleAsset | ||
from dagster_components_tests.lib.simple_pipes_script_asset import ( | ||
SimplePipesScriptAsset as SimplePipesScriptAsset, | ||
) |
34 changes: 34 additions & 0 deletions
34
...les/libraries/dagster-components/dagster_components_tests/lib/all_metadata_empty_asset.py
This file contains 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,34 @@ | ||
from typing import TYPE_CHECKING, Any | ||
|
||
from dagster._core.definitions.decorators.asset_decorator import asset | ||
from dagster._core.definitions.definitions_class import Definitions | ||
from dagster._core.execution.context.asset_execution_context import AssetExecutionContext | ||
from dagster_components import Component, ComponentLoadContext, component | ||
from dagster_components.core.component import ComponentGenerateRequest | ||
from dagster_components.core.component_decl_builder import YamlComponentDecl | ||
from dagster_components.generate import generate_component_yaml | ||
from typing_extensions import Self | ||
|
||
if TYPE_CHECKING: | ||
from dagster_components.core.component import ComponentDeclNode | ||
|
||
|
||
@component(name="all_metadata_empty_asset") | ||
class AllMetadataEmptyAsset(Component): | ||
@classmethod | ||
def from_decl_node( | ||
cls, context: "ComponentLoadContext", decl_node: "ComponentDeclNode" | ||
) -> Self: | ||
assert isinstance(decl_node, YamlComponentDecl) | ||
return cls() | ||
|
||
@classmethod | ||
def generate_files(cls, request: ComponentGenerateRequest, params: Any) -> None: | ||
generate_component_yaml(request, params) | ||
|
||
def build_defs(self, context: ComponentLoadContext) -> Definitions: | ||
@asset | ||
def hardcoded_asset(context: AssetExecutionContext): | ||
return 1 | ||
|
||
return Definitions(assets=[hardcoded_asset]) |
Oops, something went wrong.