|
8 | 8 | from pytest_mock import MockFixture
|
9 | 9 | from test_utilities.utils import verify_entity_load_and_dump
|
10 | 10 |
|
11 |
| -from azure.ai.ml import MLClient, load_job |
| 11 | +from azure.ai.ml import MLClient, load_job, Output |
12 | 12 | from azure.ai.ml._restclient.v2022_02_01_preview.models import JobBaseData as FebRestJob
|
13 | 13 | from azure.ai.ml._restclient.v2022_10_01_preview.models import JobBase as RestJob
|
14 | 14 | from azure.ai.ml._schema.automl import AutoMLRegressionSchema
|
|
26 | 26 | from azure.ai.ml.entities._job.automl.nlp import TextClassificationJob, TextClassificationMultilabelJob, TextNerJob
|
27 | 27 | from azure.ai.ml.entities._job.automl.tabular import ClassificationJob, ForecastingJob, RegressionJob
|
28 | 28 | from azure.ai.ml.entities._job.pipeline._io import PipelineInput, _GroupAttrDict
|
29 |
| -from azure.ai.ml.exceptions import ValidationException |
| 29 | +from azure.ai.ml.exceptions import ValidationException, UnexpectedAttributeError |
30 | 30 |
|
31 | 31 | from .._util import _PIPELINE_JOB_TIMEOUT_SECOND
|
32 | 32 |
|
@@ -1454,3 +1454,37 @@ def test_comment_in_pipeline(self) -> None:
|
1454 | 1454 | rest_pipeline_dict = pipeline_job._to_rest_object().as_dict()["properties"]
|
1455 | 1455 | assert pipeline_dict["jobs"]["hello_world_component"]["comment"] == "arbitrary string"
|
1456 | 1456 | assert rest_pipeline_dict["jobs"]["hello_world_component"]["comment"] == "arbitrary string"
|
| 1457 | + |
| 1458 | + def test_pipeline_node_default_output(self): |
| 1459 | + test_path = "./tests/test_configs/pipeline_jobs/helloworld_pipeline_job_with_component_output.yml" |
| 1460 | + pipeline: PipelineJob = load_job(source=test_path) |
| 1461 | + |
| 1462 | + test_output_path = "azureml://datastores/workspaceblobstore/paths/azureml/ps_copy_component/outputs/output_dir" |
| 1463 | + |
| 1464 | + # pipeline level output |
| 1465 | + pipeline_output = pipeline.outputs["job_out_path_2"] |
| 1466 | + assert pipeline_output.mode == "upload" |
| 1467 | + |
| 1468 | + # node level output |
| 1469 | + pipeline.jobs["hello_world_component_1"].outputs["component_out_path_1"].path = test_output_path |
| 1470 | + |
| 1471 | + # normal output from component |
| 1472 | + node_output = pipeline.jobs["hello_world_component_1"].outputs["component_out_path_1"] |
| 1473 | + assert node_output.path == test_output_path |
| 1474 | + assert node_output.mode == "mount" |
| 1475 | + |
| 1476 | + # data-binding-expression |
| 1477 | + node_output = pipeline.jobs["merge_component_outputs"].outputs["component_out_path_1"] |
| 1478 | + with pytest.raises(ValidationException, match="<class '.*'> does not support setting path."): |
| 1479 | + node_output.path = test_output_path |
| 1480 | + |
| 1481 | + # non-existent output |
| 1482 | + with pytest.raises( |
| 1483 | + UnexpectedAttributeError, |
| 1484 | + match="Got an unexpected attribute 'component_out_path_non', " |
| 1485 | + "valid attributes: 'component_out_path_1', " |
| 1486 | + "'component_out_path_2', 'component_out_path_3'." |
| 1487 | + ): |
| 1488 | + pipeline.jobs["hello_world_component_1"].outputs["component_out_path_non"] = Output( |
| 1489 | + path=test_output_path, mode="upload" |
| 1490 | + ) |
0 commit comments