|
24 | 24 | from urllib import request
|
25 | 25 | from datetime import datetime
|
26 | 26 |
|
| 27 | +from google.api_core import operation as ga_operation |
27 | 28 | from google.auth import credentials as auth_credentials
|
28 | 29 | from google.cloud import aiplatform
|
29 | 30 | from google.cloud.aiplatform import base
|
|
43 | 44 | from google.cloud.aiplatform.compat.services import (
|
44 | 45 | pipeline_service_client,
|
45 | 46 | )
|
| 47 | +from google.cloud.aiplatform_v1beta1.types import ( |
| 48 | + pipeline_service as PipelineServiceV1Beta1, |
| 49 | +) |
| 50 | +from google.cloud.aiplatform_v1beta1.services import ( |
| 51 | + pipeline_service as v1beta1_pipeline_service, |
| 52 | +) |
| 53 | +from google.cloud.aiplatform_v1beta1.types import ( |
| 54 | + pipeline_job as v1beta1_pipeline_job, |
| 55 | + pipeline_state as v1beta1_pipeline_state, |
| 56 | + context as v1beta1_context, |
| 57 | +) |
| 58 | +from google.cloud.aiplatform.preview.pipelinejob import ( |
| 59 | + pipeline_jobs as preview_pipeline_jobs, |
| 60 | +) |
46 | 61 | from google.cloud.aiplatform.compat.types import (
|
47 | 62 | pipeline_job as gca_pipeline_job,
|
48 | 63 | pipeline_state as gca_pipeline_state,
|
|
52 | 67 | _TEST_PROJECT = "test-project"
|
53 | 68 | _TEST_LOCATION = "us-central1"
|
54 | 69 | _TEST_PIPELINE_JOB_DISPLAY_NAME = "sample-pipeline-job-display-name"
|
| 70 | +_TEST_PIPELINE_JOB_DISPLAY_NAME_2 = "sample-pipeline-job-display-name-2" |
55 | 71 | _TEST_PIPELINE_JOB_ID = "sample-test-pipeline-202111111"
|
| 72 | +_TEST_PIPELINE_JOB_ID_2 = "sample-test-pipeline-202111112" |
56 | 73 | _TEST_GCS_BUCKET_NAME = "my-bucket"
|
57 | 74 | _TEST_GCS_OUTPUT_DIRECTORY = f"gs://{_TEST_GCS_BUCKET_NAME}/output_artifacts/"
|
58 | 75 | _TEST_CREDENTIALS = auth_credentials.AnonymousCredentials()
|
|
66 | 83 | _TEST_RESERVED_IP_RANGES = ["vertex-ai-ip-range"]
|
67 | 84 |
|
68 | 85 | _TEST_PIPELINE_JOB_NAME = f"projects/{_TEST_PROJECT}/locations/{_TEST_LOCATION}/pipelineJobs/{_TEST_PIPELINE_JOB_ID}"
|
| 86 | +_TEST_PIPELINE_JOB_NAME_2 = f"projects/{_TEST_PROJECT}/locations/{_TEST_LOCATION}/pipelineJobs/{_TEST_PIPELINE_JOB_ID_2}" |
69 | 87 | _TEST_PIPELINE_JOB_LIST_READ_MASK = field_mask.FieldMask(
|
70 | 88 | paths=pipeline_constants._READ_MASK_FIELDS
|
71 | 89 | )
|
@@ -237,6 +255,52 @@ def mock_pipeline_service_create():
|
237 | 255 | yield mock_create_pipeline_job
|
238 | 256 |
|
239 | 257 |
|
| 258 | +@pytest.fixture |
| 259 | +def mock_pipeline_v1beta1_service_batch_delete(): |
| 260 | + with mock.patch.object( |
| 261 | + v1beta1_pipeline_service.PipelineServiceClient, "batch_delete_pipeline_jobs" |
| 262 | + ) as mock_batch_pipeline_jobs: |
| 263 | + mock_batch_pipeline_jobs.return_value = ( |
| 264 | + make_batch_delete_pipeline_jobs_response() |
| 265 | + ) |
| 266 | + mock_lro = mock.Mock(ga_operation.Operation) |
| 267 | + mock_lro.result.return_value = make_batch_delete_pipeline_jobs_response() |
| 268 | + mock_batch_pipeline_jobs.return_value = mock_lro |
| 269 | + yield mock_batch_pipeline_jobs |
| 270 | + |
| 271 | + |
| 272 | +def make_v1beta1_pipeline_job(name: str, state: v1beta1_pipeline_state.PipelineState): |
| 273 | + return v1beta1_pipeline_job.PipelineJob( |
| 274 | + name=name, |
| 275 | + state=state, |
| 276 | + create_time=_TEST_PIPELINE_CREATE_TIME, |
| 277 | + service_account=_TEST_SERVICE_ACCOUNT, |
| 278 | + network=_TEST_NETWORK, |
| 279 | + job_detail=v1beta1_pipeline_job.PipelineJobDetail( |
| 280 | + pipeline_run_context=v1beta1_context.Context( |
| 281 | + name=name, |
| 282 | + ) |
| 283 | + ), |
| 284 | + ) |
| 285 | + |
| 286 | + |
| 287 | +def make_batch_delete_pipeline_jobs_response(): |
| 288 | + response = PipelineServiceV1Beta1.BatchDeletePipelineJobsResponse() |
| 289 | + response.pipeline_jobs.append( |
| 290 | + make_v1beta1_pipeline_job( |
| 291 | + _TEST_PIPELINE_JOB_NAME, |
| 292 | + v1beta1_pipeline_state.PipelineState.PIPELINE_STATE_SUCCEEDED, |
| 293 | + ) |
| 294 | + ) |
| 295 | + response.pipeline_jobs.append( |
| 296 | + make_v1beta1_pipeline_job( |
| 297 | + _TEST_PIPELINE_JOB_NAME_2, |
| 298 | + v1beta1_pipeline_state.PipelineState.PIPELINE_STATE_FAILED, |
| 299 | + ) |
| 300 | + ) |
| 301 | + return response |
| 302 | + |
| 303 | + |
240 | 304 | @pytest.fixture
|
241 | 305 | def mock_pipeline_bucket_exists():
|
242 | 306 | def mock_create_gcs_bucket_for_pipeline_artifacts_if_it_does_not_exist(
|
@@ -1974,3 +2038,44 @@ def test_get_associated_experiment_from_pipeline_returns_experiment(
|
1974 | 2038 | assert associated_experiment.resource_name == _TEST_CONTEXT_NAME
|
1975 | 2039 |
|
1976 | 2040 | assert add_context_children_mock.call_count == 1
|
| 2041 | + |
| 2042 | + @pytest.mark.usefixtures( |
| 2043 | + "mock_pipeline_service_get", |
| 2044 | + "mock_pipeline_v1beta1_service_batch_delete", |
| 2045 | + ) |
| 2046 | + @pytest.mark.parametrize( |
| 2047 | + "job_spec", |
| 2048 | + [ |
| 2049 | + _TEST_PIPELINE_SPEC_JSON, |
| 2050 | + _TEST_PIPELINE_SPEC_YAML, |
| 2051 | + _TEST_PIPELINE_JOB, |
| 2052 | + _TEST_PIPELINE_SPEC_LEGACY_JSON, |
| 2053 | + _TEST_PIPELINE_SPEC_LEGACY_YAML, |
| 2054 | + _TEST_PIPELINE_JOB_LEGACY, |
| 2055 | + ], |
| 2056 | + ) |
| 2057 | + def test_create_two_and_batch_delete_pipeline_jobs_returns_response( |
| 2058 | + self, |
| 2059 | + mock_load_yaml_and_json, |
| 2060 | + mock_pipeline_v1beta1_service_batch_delete, |
| 2061 | + ): |
| 2062 | + aiplatform.init( |
| 2063 | + project=_TEST_PROJECT, |
| 2064 | + staging_bucket=_TEST_GCS_BUCKET_NAME, |
| 2065 | + credentials=_TEST_CREDENTIALS, |
| 2066 | + ) |
| 2067 | + |
| 2068 | + job = preview_pipeline_jobs._PipelineJob( |
| 2069 | + display_name=_TEST_PIPELINE_JOB_DISPLAY_NAME, |
| 2070 | + template_path=_TEST_TEMPLATE_PATH, |
| 2071 | + job_id=_TEST_PIPELINE_JOB_ID, |
| 2072 | + ) |
| 2073 | + |
| 2074 | + response = job.batch_delete( |
| 2075 | + project=_TEST_PROJECT, |
| 2076 | + location=_TEST_LOCATION, |
| 2077 | + names=[_TEST_PIPELINE_JOB_ID, _TEST_PIPELINE_JOB_ID_2], |
| 2078 | + ) |
| 2079 | + |
| 2080 | + assert mock_pipeline_v1beta1_service_batch_delete.call_count == 1 |
| 2081 | + assert len(response.pipeline_jobs) == 2 |
0 commit comments