From b0e029a8e169b9e658d78ffbfc7830ce53407c26 Mon Sep 17 00:00:00 2001 From: Sungjin Lee Date: Wed, 16 Oct 2024 02:13:25 +0000 Subject: [PATCH] Update to use kfp-server-api version 2 - Fix cannot fetch experiments, runs information - Update test code for kfp-server-api v2.0.5 - Change the '/runs' endpoint to retrieve pipeline information using 'pipeline_id' ISSUE-ID: AIMLFW-166 Change-Id: I7949bef79a891764319f621189270cc59de03417 Signed-off-by: Sungjin Lee --- kfadapter/kfadapter_main.py | 28 ++++--- test/fake_kfp.py | 40 ++++----- test/test_kfadapter_main.py | 193 ++++++++++++++++++++++++-------------------- tox.ini | 6 +- 4 files changed, 144 insertions(+), 123 deletions(-) diff --git a/kfadapter/kfadapter_main.py b/kfadapter/kfadapter_main.py index 8670679..f129690 100644 --- a/kfadapter/kfadapter_main.py +++ b/kfadapter/kfadapter_main.py @@ -86,8 +86,8 @@ def get_experiment(expname): LOGGER.debug("Experiment name is present") LOGGER.debug(exp) - exp_dict['name'] = exp.name - exp_dict['id'] = exp.id + exp_dict['name'] = exp.display_name + exp_dict['id'] = exp.experiment_id except ValueError as err: LOGGER.error(err) raise BadRequest('Experiment name does not exist', status.HTTP_400_BAD_REQUEST,\ @@ -308,7 +308,7 @@ def list_pipelines(): pipeline_list = KFCONNECT_KF_OBJ.get_kf_list_pipelines() pipe_dict['next_page_token'] = pipeline_list.next_page_token pipe_dict['total_size'] = pipeline_list.total_size - + pipelines = [] for pipeline in pipeline_list.pipelines: pipe_super_dict = {} @@ -318,7 +318,7 @@ def list_pipelines(): pipe_super_dict['created_at'] = pipeline.created_at pipelines.append(pipe_super_dict) pipe_dict['pipelines'] = pipelines - + except:# pylint: disable=bare-except tbk = traceback.format_exc() LOGGER.error(tbk) @@ -439,18 +439,22 @@ def list_runs(): runs = KFCONNECT_KF_OBJ.get_kf_list_runs(KFCONNECT_CONFIG_OBJ.kf_dict['kfdefaultns']) for run in runs.runs: + LOGGER.debug(f"Run: {run}") run_super_dict = {} - run_super_dict['run_id'] = run.id + run_super_dict['run_id'] = run.run_id run_super_dict['run_description'] = run.description - run_super_dict['run_status'] = run.status - run_super_dict['experiment_name'] = run.resource_references[0].name - run_super_dict['experiment_id'] = run.resource_references[0].key.id + run_super_dict['run_status'] = run.state + run_super_dict['experiment_id'] = run.experiment_id + + LOGGER.debug(f"Pipeline version reference: {run.pipeline_version_reference}") + LOGGER.debug(f"Pipeline version reference ID: {run.pipeline_version_reference.pipeline_id}") - if len(run.resource_references) > 1: - run_super_dict['pipeline_name'] = run.resource_references[1].name - run_super_dict['pipeline_id'] = run.resource_references[1].key.id + if run.pipeline_version_reference is not None: + pipeline_info = KFCONNECT_KF_OBJ.get_kf_pipeline_desc(run.pipeline_version_reference.pipeline_id) + run_super_dict['pipeline_name'] = pipeline_info.display_name + run_super_dict['pipeline_id'] = pipeline_info.pipeline_id - run_dict[run.name] = run_super_dict + run_dict[run.display_name] = run_super_dict except:# pylint: disable=bare-except tbk = traceback.format_exc() LOGGER.error(tbk) diff --git a/test/fake_kfp.py b/test/fake_kfp.py index c80cd1a..0bd6ac2 100644 --- a/test/fake_kfp.py +++ b/test/fake_kfp.py @@ -18,11 +18,11 @@ from typing import Optional -from kfp_server_api.models.api_list_pipeline_versions_response import ApiListPipelineVersionsResponse -from kfp_server_api.models.api_pipeline_version import ApiPipelineVersion -from kfp_server_api.models.api_experiment import ApiExperiment -from kfp_server_api.models.api_run_detail import ApiRunDetail -from kfp_server_api.models.api_run import ApiRun +from kfp_server_api.models.v2beta1_list_pipeline_versions_response import V2beta1ListPipelineVersionsResponse as ApiListPipelineVersionsResponse +from kfp_server_api.models.v2beta1_pipeline_version import V2beta1PipelineVersion as ApiPipelineVersion +from kfp_server_api.models.v2beta1_experiment import V2beta1Experiment as ApiExperiment +from kfp_server_api.models.v2beta1_run_details import V2beta1RunDetails as ApiRunDetail +from kfp_server_api.models.v2beta1_run import V2beta1Run as ApiRun import kfp_server_api class FakeKfp: @@ -41,9 +41,9 @@ class FakeKfp: exp = ApiExperiment() exp.id = 'ex-id' exp.name = 'exp-name' - return exp + return exp + - def upload_pipeline_version( self, pipeline_package_path, @@ -70,27 +70,27 @@ class FakeKfp: experiment_id=None, namespace=None, filter=None): - + listrun = ApiListRunsResponse() run1 = ApiRun() run1.id(self, 'id') - run1.description(self, 'description') - run1.status(self, 'status') + run1.description(self, 'description') + run1.status(self, 'status') rr0 = ApiResourceReference() rr0.name(self, 'name') key0 = ApiResourceKey() key0.id(self, 'id') rr0.key(self, key0) - + rr1 = ApiResourceReference() rr1.name(self, 'name') key1 = ApiResourceKey() key1.id(self, 'id') rr1.key(key1) - + run1.resource_references(self, rr0) - listrun.runs(self, [run1]) - + listrun.runs(self, [run1]) + return listrun """ @@ -132,7 +132,7 @@ class FakeKfp: service_account: Optional[str] = None, ): return None - + def delete_pipeline(self, pipeline_id): return None @@ -145,7 +145,7 @@ class FakeKfp: page_size=10, sort_by=''): return None - + def upload_pipeline( self, @@ -156,7 +156,7 @@ class FakeKfp: return None def get_pipeline_id(self, name): - + return ['pipelin_id', 'pipelin_id2',] @@ -206,8 +206,8 @@ class FakeNegativeKfp: experiment_name=None, namespace=None): raise ValueError( - 'Either experiment_id or experiment_name is required') - + 'Either experiment_id or experiment_name is required') + class FakeAdditionalKfp: """ def list_pipeline_versions( @@ -231,7 +231,7 @@ class FakeAdditionalKfp: """ def get_pipeline_id(self, name): return None - + def upload_pipeline( self, pipeline_package_path: str = None, diff --git a/test/test_kfadapter_main.py b/test/test_kfadapter_main.py index eae6232..05787d0 100644 --- a/test/test_kfadapter_main.py +++ b/test/test_kfadapter_main.py @@ -18,19 +18,17 @@ import json import io from unittest import TestCase -from mock import patch +from mock import patch, MagicMock from flask_api import status import kfp_server_api -from kfp_server_api.models.api_run import ApiRun -from kfp_server_api.models.api_list_runs_response import ApiListRunsResponse -from kfp_server_api.models.api_experiment import ApiExperiment -from kfp_server_api.models.api_list_pipelines_response import ApiListPipelinesResponse -from kfp_server_api.models.api_pipeline import ApiPipeline -from kfp_server_api.models.api_parameter import ApiParameter -from kfp_server_api.models.api_resource_reference import ApiResourceReference -from kfp_server_api.models.api_resource_key import ApiResourceKey -from kfp_server_api.models.api_pipeline_version import ApiPipelineVersion +from kfp_server_api.models.v2beta1_run import V2beta1Run as ApiRun +from kfp_server_api.models.v2beta1_list_runs_response import V2beta1ListRunsResponse as ApiListRunsResponse +from kfp_server_api.models.v2beta1_experiment import V2beta1Experiment as ApiExperiment +from kfp_server_api.models.v2beta1_list_pipelines_response import V2beta1ListPipelinesResponse as ApiListPipelinesResponse +from kfp_server_api.models.v2beta1_pipeline import V2beta1Pipeline as ApiPipeline +from kfp_server_api.models.v2beta1_runtime_config import V2beta1RuntimeConfig as ApiParameter +from kfp_server_api.models.v2beta1_pipeline_version import V2beta1PipelineVersion as ApiPipelineVersion from kfadapter import kfadapter_main from kfadapter import kfadapter_conf from kfadapter import kfadapter_kfconnect @@ -46,53 +44,72 @@ class testKfadapterApi(TestCase): @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details") - def test_get_experiment(self, mock_get_kf_experiment_details): + def test_get_experiment(self, mock_get_kf_experiment_details): # given exp = ApiExperiment() - exp.name = "exp-name" - exp.id = "exp-id" + exp.display_name = "exp-name" + exp.experiment_id = "exp-id" mock_get_kf_experiment_details.return_value = exp # when - response = self.client.get("/experiments/{}".format(exp.name)) - + response = self.client.get("/experiments/{}".format(exp.display_name)) + # then mock_get_kf_experiment_details.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.get_json()["name"], exp.name) - self.assertEqual(response.get_json()["id"], exp.id) - + self.assertEqual(response.get_json()["name"], exp.display_name) + self.assertEqual(response.get_json()["id"], exp.experiment_id) + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_runs") - def test_get_all_runs(self, mock_get_kf_list_runs): + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_desc") + def test_get_all_runs(self, mock_get_kf_pipeline_desc, mock_get_kf_list_runs): + class PipelineVersionReference: + def __init__(self, pipeline_id, pipeline_version_id): + self.pipeline_id = pipeline_id + self.pipeline_version_id = pipeline_version_id + # given - resources = [ ApiResourceReference() for _ in range(3)] - for i, resource in enumerate(resources) : - resource.name = "rr-name{}".format(i) - resource.key = ApiResourceKey() - resource.key.id = "rr-id{}".format(i) - - runs = [ ApiRun() for _ in range(2)] - for i, run in enumerate(runs) : - run.id = "runid" - run.description = "description" - run.status = "status" - run.resource_references = [resources[i], resources[i+1]] - + runs = [ApiRun() for _ in range(2)] + for i, run in enumerate(runs): + run.run_id = "runid" + run.display_name = f"run-name{i}" + run.description = "description" + run.state = "status" + run.pipeline_version_reference = PipelineVersionReference( + pipeline_id=f"pipeline-id{i}", + pipeline_version_id=f"pipeline-version-id{i}" + ) + run.experiment_id = f"experiment-id{i}" + list_run = ApiListRunsResponse() list_run.runs = runs mock_get_kf_list_runs.return_value = list_run + # Mocking get_kf_pipeline_desc to return a mock pipeline info + def mock_pipeline_desc(pipeline_id): + pipeline = MagicMock() + pipeline.display_name = f"pipeline-name{pipeline_id[-1]}" + pipeline.pipeline_id = pipeline_id + return pipeline + + mock_get_kf_pipeline_desc.side_effect = mock_pipeline_desc + # when response = self.client.get("/runs") + print('response:', response.get_data()) # then mock_get_kf_list_runs.assert_called_once() + mock_get_kf_pipeline_desc.assert_any_call("pipeline-id0") + mock_get_kf_pipeline_desc.assert_any_call("pipeline-id1") self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.get_data(), b'{"null":{"experiment_id":"rr-id1","experiment_name":"rr-name1","pipeline_id":"rr-id2","pipeline_name":"rr-name2","run_description":"description","run_id":"runid","run_status":"status"}}\n') - + self.assertEqual( + response.get_data(), + b'{"run-name0":{"experiment_id":"experiment-id0","pipeline_id":"pipeline-id0","pipeline_name":"pipeline-name0","run_description":"description","run_id":"runid","run_status":"status"},"run-name1":{"experiment_id":"experiment-id1","pipeline_id":"pipeline-id1","pipeline_name":"pipeline-name1","run_description":"description","run_id":"runid","run_status":"status"}}\n' + ) @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_id") def test_get_pipeline_id(self, mock_get_kf_pipeline_id): @@ -103,8 +120,8 @@ class testKfadapterApi(TestCase): # when response = self.client.get("/pipelineIds/{}".format(pipeline_name)) - - # then + + # then mock_get_kf_pipeline_id.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -121,7 +138,7 @@ class testKfadapterApi(TestCase): pipeline_info = ApiPipeline() pipeline_info.pipeline_id = pipeline_id mock_upload_pipeline_with_versions.return_value = pipeline_info - + files = {} files['file'] = (io.BytesIO(b"pipeline-file"), 'pipeline') files['description'] = "pipeline-description" @@ -135,7 +152,7 @@ class testKfadapterApi(TestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.get_json()['name'], pipeline_name) self.assertEqual(response.get_json()['id'], pipeline_id) - + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_pl_versions_by_pl_name") def test_get_pipeline_version(self, mock_get_pl_versions_by_pl_name): @@ -162,7 +179,7 @@ class testKfadapterApi(TestCase): run.display_name = "run-name" run.state = "Running" mock_get_kf_run.return_value = run - + # when response = self.client.get("/runs/{}".format(run.run_id)) @@ -185,12 +202,12 @@ class testKfadapterApi(TestCase): # then self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_pipelines") def test_get_pipelines(self, mock_get_kf_list_pipelines): - #given + #given pipeline = ApiPipeline() pipeline.pipeline_id = "pipeline-id" pipeline.description = "pipeline-description" @@ -204,7 +221,7 @@ class testKfadapterApi(TestCase): pipeline_list.total_size = "total-size" mock_get_kf_list_pipelines.return_value = pipeline_list - + # when response = self.client.get("/pipelines") @@ -212,7 +229,7 @@ class testKfadapterApi(TestCase): mock_get_kf_list_pipelines.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.get_data(), + self.assertEqual(response.get_data(), b'{"next_page_token":"next-page-token","pipelines":[{"created_at":"created-at","description":"pipeline-description","display_name":"pipeline-name","pipeline_id":"pipeline-id"}],"total_size":"total-size"}\n') @@ -233,11 +250,11 @@ class testKfadapterApi(TestCase): pipeline_info.description = "description" pipeline_info.id = pipeline_name pipeline_info.name = pipeline_id - + default_version = ApiPipelineVersion() - default_version.parameters = [params[2], params[3]] + default_version.parameters = [params[2], params[3]] pipeline_info.default_version = default_version - mock_get_kf_pipeline_desc.return_value = pipeline_info + mock_get_kf_pipeline_desc.return_value = pipeline_info # when response = self.client.get("/pipelines/{}".format(pipeline_id)) @@ -264,7 +281,7 @@ class testKfadapterApi(TestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.get_json()["id"], pipeline_id) self.assertEqual(response.get_json()["status"], "Deleted") - + def test_check_liveness(self): # when @@ -279,11 +296,11 @@ class testKfadapterApi(TestCase): @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_experiments") def test_get_experiments(self, mock_get_kf_list_experiments): # given - exp = kfp_server_api.ApiExperiment() + exp = ApiExperiment() exp.display_name = "exp-name" exp.experiment_id = "exp-id" - explist = kfp_server_api.ApiListExperimentsResponse() + explist = kfp_server_api.V2beta1ListExperimentsResponse() explist.experiments = [exp] mock_get_kf_list_experiments.return_value = explist @@ -311,7 +328,7 @@ class testKfadapterApi(TestCase): pipeline_name = "pipeline-name" pipeline_id = "pipeline-id" mock_get_kf_pipeline_id.return_value = pipeline_id - + params = [ ApiParameter() for _ in range(4)] for i, param in enumerate(params) : param.name = "param-name{}".format(i) @@ -322,20 +339,20 @@ class testKfadapterApi(TestCase): pipeline_info.description = "pipeline-description" pipeline_info.id = pipeline_name pipeline_info.name = pipeline_id - + mock_get_kf_pipeline_version_id.return_value = pipeline_id run = {} run["display_name"] = "run-name" run["run_id"] = "run-id" - pipeline_id= "pipeline_id" + pipeline_id= "pipeline_id" pipeline_version_reference= {'pipeline_id': pipeline_id, 'pipeline_version_id': pipeline_id} run["pipeline_version_reference"]=pipeline_version_reference - + run["state"] = "RUNNING" mock_run_kf_pipeline.return_value = run - + job_name = "job_name" dict_job = {} @@ -383,7 +400,7 @@ class testNegativeKfadapterApi(TestCase): mock_get_pl_versions_by_pl_name.assert_called_once() self.assertEqual(response.content_type, "text/html; charset=utf-8") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_pl_versions_by_pl_name") def test_negative_get_versions_for_pipeline_failed_with_unsupported_error(self, mock_get_pl_versions_by_pl_name): @@ -398,8 +415,8 @@ class testNegativeKfadapterApi(TestCase): mock_get_pl_versions_by_pl_name.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") - self.assertEqual(response.get_json()["ext"], 1) + self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") + self.assertEqual(response.get_json()["ext"], 1) @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_desc") @@ -420,7 +437,7 @@ class testNegativeKfadapterApi(TestCase): @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_pipeline_id") - def test_negative_get_pipeline_id_failed_with_value_error(self, mock_get_kf_pipeline_id): + def test_negative_get_pipeline_id_failed_with_value_error(self, mock_get_kf_pipeline_id): # given pipeline_name = "pipeline-name" mock_get_kf_pipeline_id.return_value = None @@ -428,20 +445,20 @@ class testNegativeKfadapterApi(TestCase): # when response = self.client.get("/pipelineIds/{}".format(pipeline_name)) - # then + # then mock_get_kf_pipeline_id.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.get_json()["message"],"PipeLine Name does not exist") self.assertEqual(response.get_json()["payload"],{"error":"No pipeline is found with name pipeline-name","pipe_name":pipeline_name}) - + @patch("kfadapter.kfadapter_kfconnect.KfConnect.upload_pipeline_with_versions") def test_negative_upload_pipeline_failed_with_api_exception(self, mock_upload_pipeline_with_versions): # given pipeline_name = "pipeline-name" - mock_upload_pipeline_with_versions.side_effect = kfp_server_api.exceptions.ApiException + mock_upload_pipeline_with_versions.side_effect = kfp_server_api.exceptions.ApiException files = {} files['file'] = (io.BytesIO(b"pipeline-file"), 'pipeline.zip') @@ -452,12 +469,12 @@ class testNegativeKfadapterApi(TestCase): # then mock_upload_pipeline_with_versions.assert_called_once() - self.assertEqual(response.content_type, "text/html; charset=utf-8") + self.assertEqual(response.content_type, "text/html; charset=utf-8") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) def test_negative_upload_pipeline_failed_cause_empty_file_name(self): - # given + # given pipeline_name = "pipeline-name" files = {} @@ -470,8 +487,8 @@ class testNegativeKfadapterApi(TestCase): self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) self.assertEqual(response.get_json()["message"],"Unsupported error from Kubeflow") - self.assertEqual(response.get_json()["ext"], 1) - + self.assertEqual(response.get_json()["ext"], 1) + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details") def test_negative_get_experiment_failed_cause_no_such_experiment(self, mock_get_kf_experiment_details): @@ -503,8 +520,8 @@ class testNegativeKfadapterApi(TestCase): mock_get_kf_experiment_details.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") - self.assertEqual(response.get_json()["ext"], 1) + self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") + self.assertEqual(response.get_json()["ext"], 1) @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_run") @@ -512,7 +529,7 @@ class testNegativeKfadapterApi(TestCase): # given run_id = "run-id" mock_get_kf_run.side_effect = Exception("") - + # when response = self.client.get("/runs/{}".format(run_id)) @@ -536,15 +553,15 @@ class testNegativeKfadapterApi(TestCase): mock_get_kf_list_runs.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") - self.assertEqual(response.get_json()["ext"], 1) + self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") + self.assertEqual(response.get_json()["ext"], 1) @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_pipelines") def test_negative_get_pipelines_failed_with_unsupported_error(self, mock_get_kf_list_pipelines): # given mock_get_kf_list_pipelines.side_effect = IndexError("") - + # when response = self.client.get("/pipelines") @@ -552,8 +569,8 @@ class testNegativeKfadapterApi(TestCase): mock_get_kf_list_pipelines.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") - self.assertEqual(response.get_json()["ext"], 1) + self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") + self.assertEqual(response.get_json()["ext"], 1) def test_negative_execute_job_failed_cause_less_arguments(self): @@ -567,9 +584,9 @@ class testNegativeKfadapterApi(TestCase): # then self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(response.get_json()["message"], "Less arguments") - self.assertFalse(response.get_json()["payload"]) - + self.assertEqual(response.get_json()["message"], "Less arguments") + self.assertFalse(response.get_json()["payload"]) + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details") def test_negative_execute_job_failed_cause_no_such_experiment(self, mock_get_kf_experiment_details): @@ -582,13 +599,13 @@ class testNegativeKfadapterApi(TestCase): for i, param in enumerate(params) : param.name = "param-name{}".format(i) param.value = "param-value{}".format(i) - + args = {} args[params[0].name] = params[0].value args[params[1].name] = params[1].value - + dict_job["arguments"] = args - dict_job["pipeline_name"] = "pipeline-name" + dict_job["pipeline_name"] = "pipeline-name" dict_job["pipeline_version"] = "2.0.0" dict_job["experiment_name"] = "exp-name" @@ -599,7 +616,7 @@ class testNegativeKfadapterApi(TestCase): mock_get_kf_experiment_details.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") + self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_experiment_details") @@ -611,7 +628,7 @@ class testNegativeKfadapterApi(TestCase): mock_get_kf_experiment_details.return_value = exp mock_get_kf_pipeline_id.return_value = None - + job_name = "job_name" dict_job = {} @@ -619,13 +636,13 @@ class testNegativeKfadapterApi(TestCase): for i, param in enumerate(params) : param.name = "param-name{}".format(i) param.value = "param-value{}".format(i) - + args = {} args[params[0].name] = params[0].value args[params[1].name] = params[1].value - + dict_job["arguments"] = args - dict_job["pipeline_name"] = "pipeline-name" + dict_job["pipeline_name"] = "pipeline-name" dict_job["pipeline_version"] = "2.0.0" dict_job["experiment_name"] = exp_name @@ -637,8 +654,8 @@ class testNegativeKfadapterApi(TestCase): mock_get_kf_pipeline_id.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") - + self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") + @patch("kfadapter.kfadapter_kfconnect.KfConnect.get_kf_list_experiments") def test_negative_get_experiments_failed_with_unsupported_error(self, mock_get_kf_list_experiments): @@ -652,5 +669,5 @@ class testNegativeKfadapterApi(TestCase): mock_get_kf_list_experiments.assert_called_once() self.assertEqual(response.content_type, "application/json") self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") - self.assertEqual(response.get_json()["ext"], 1) + self.assertEqual(response.get_json()["message"], "Unsupported error from Kubeflow") + self.assertEqual(response.get_json()["ext"], 1) diff --git a/tox.ini b/tox.ini index fb8796f..8f793e9 100644 --- a/tox.ini +++ b/tox.ini @@ -30,15 +30,15 @@ deps= mock kfp kfp-pipeline-spec - kfp-server-api==1.8.5 + kfp-server-api Flask Flask-API Flask-Cors requests Werkzeug==2.2.2 - + setenv = cd = {toxinidir}/test -commands = +commands = pip3 install {toxinidir} pytest --cov {toxinidir}/kfadapter --cov-report xml --cov-report term-missing --cov-report html --cov-fail-under=10 --junitxml=/tmp/tests.xml -- 2.16.6