From b2cb9c1bcc324d3913b552c96d1c7686a7ea6441 Mon Sep 17 00:00:00 2001 From: Youhwan Seol Date: Wed, 22 Feb 2023 14:38:12 +0900 Subject: [PATCH] Add unittests and set mockgen env Change-Id: Ib5b24e977d1986e00346fcd12b7fa61060358589 Signed-off-by: Youhwan Seol --- .gitignore | 3 +- Makefile | 2 + go.mod | 1 + pkg/api/rest_server_test.go | 49 +++ pkg/api/v1/deployment/deployment.go | 1 + pkg/api/v1/deployment/deployment_test.go | 265 +++++++++++++++++ pkg/client/kserve/client.go | 1 + pkg/client/onboard/client.go | 1 + pkg/controller/v1/adapter/controller.go | 1 + pkg/controller/v1/adapter/controller_test.go | 327 +++++++++++++++++++++ sample/invalidServing/inferenceServing/values.yaml | 19 ++ sample/validServing/inferenceServing/Chart.yaml | 23 ++ .../inferenceServing/templates/_helpers.tpl | 77 +++++ .../templates/inferenceservice.yaml | 42 +++ sample/validServing/inferenceServing/values.yaml | 28 ++ 15 files changed, 839 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 pkg/api/rest_server_test.go create mode 100644 pkg/api/v1/deployment/deployment_test.go create mode 100644 pkg/controller/v1/adapter/controller_test.go create mode 100755 sample/invalidServing/inferenceServing/values.yaml create mode 100755 sample/validServing/inferenceServing/Chart.yaml create mode 100755 sample/validServing/inferenceServing/templates/_helpers.tpl create mode 100755 sample/validServing/inferenceServing/templates/inferenceservice.yaml create mode 100755 sample/validServing/inferenceServing/values.yaml diff --git a/.gitignore b/.gitignore index e5902ed..a6de96e 100755 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ docs/_build/ pkg/helm/data/sample-xapp-2.2.0/ *.tgz -go.sum \ No newline at end of file +go.sum +mock*.go diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6c4b98b --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +genmock: + go generate ./... diff --git a/go.mod b/go.mod index c01b951..d290dd0 100755 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( ) require ( + github.com/golang/mock v1.4.4 github.com/spf13/viper v1.7.0 github.com/xeipuuv/gojsonschema v1.2.0 ) diff --git a/pkg/api/rest_server_test.go b/pkg/api/rest_server_test.go new file mode 100644 index 0000000..c6a56ba --- /dev/null +++ b/pkg/api/rest_server_test.go @@ -0,0 +1,49 @@ +/* +================================================================================== + +Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +================================================================================== +*/ + +package api + +import ( + "net/http" + "net/http/httptest" + "testing" + + "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/api/commons/url" + deploymentmock "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/api/v1/deployment/mock" + + "github.com/golang/mock/gomock" +) + +func TestRecivedDeploymentRequest_ExpectCalledDeploymentHandle(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockobj := deploymentmock.NewMockCommand(ctrl) + gomock.InOrder( + mockobj.EXPECT().Deploy(gomock.Any()), + ) + + // pass mockObj to a real object. + deploymentExecutor = mockobj + + ts := httptest.NewServer(setupRouter()) + defer ts.Close() + http.Post(ts.URL+url.V1()+url.IPS(), + "application/json", nil) +} diff --git a/pkg/api/v1/deployment/deployment.go b/pkg/api/v1/deployment/deployment.go index 93df005..3712c46 100644 --- a/pkg/api/v1/deployment/deployment.go +++ b/pkg/api/v1/deployment/deployment.go @@ -30,6 +30,7 @@ import ( "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/controller/v1/adapter" ) +//go:generate mockgen -source=deployment.go -destination=./mock/mock_deployment.go -package=mock type Command interface { Deploy(c *gin.Context) Delete(c *gin.Context) diff --git a/pkg/api/v1/deployment/deployment_test.go b/pkg/api/v1/deployment/deployment_test.go new file mode 100644 index 0000000..6d39143 --- /dev/null +++ b/pkg/api/v1/deployment/deployment_test.go @@ -0,0 +1,265 @@ +/* +================================================================================== + +Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +================================================================================== +*/ + +package deployment + +import ( + "net/http" + "net/http/httptest" + . "net/url" + "testing" + + "github.com/gin-gonic/gin" + "github.com/golang/mock/gomock" + + "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/api/commons/url" + + controllermock "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/controller/v1/adapter/mock" +) + +const ( + testName = "test_name" + testVesrion = "test_version" +) + +func TestReceivedDeploymentRequest_ExpectCalledDeployController(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockobj := controllermock.NewMockCommand(ctrl) + gomock.InOrder( + mockobj.EXPECT().Deploy(testName, testVesrion), + ) + + ipsAdapter = mockobj + + w := httptest.NewRecorder() + + param := Values{} + param.Set("name", testName) + param.Set("version", testVesrion) + + r, err := http.NewRequest("POST", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Deploy(c) +} + +func TestNegativeReceivedDeploymentRequestWithoutVersionQuery_ExpectErrorReturn(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + w := httptest.NewRecorder() + + param := Values{} + param.Set("name", testName) + + r, err := http.NewRequest("POST", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Deploy(c) + + if w.Code == 201 { + t.Errorf("Unexpected Response Code : %d", w.Code) + } +} + +func TestNegativeReceivedDeploymentRequestWithoutNameQuery_ExpectErrorREturn(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + w := httptest.NewRecorder() + + param := Values{} + param.Set("version", testVesrion) + + r, err := http.NewRequest("POST", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Deploy(c) + + if w.Code == http.StatusCreated { + t.Errorf("Unexpected Response Code : %d", w.Code) + } +} + +func TestReceivedDeleteRequest_ExpectCalledDeleteController(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockobj := controllermock.NewMockCommand(ctrl) + gomock.InOrder( + mockobj.EXPECT().Delete(testName), + ) + + ipsAdapter = mockobj + + w := httptest.NewRecorder() + + param := Values{} + param.Set("name", testName) + + r, err := http.NewRequest("DELETE", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Delete(c) +} + +func TestNegativeReceivedDeleteRequestWithoutNameQuery_ExpectErrorReturn(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + w := httptest.NewRecorder() + + param := Values{} + + r, err := http.NewRequest("DELETE", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Delete(c) + + if w.Code == 201 { + t.Errorf("Unexpected Response Code : %d", w.Code) + } +} + +func TestReceivedUpdateRequest_ExpectCalledUpdateController(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockobj := controllermock.NewMockCommand(ctrl) + gomock.InOrder( + mockobj.EXPECT().Update(testName, testVesrion, gomock.Any()), + ) + + ipsAdapter = mockobj + + w := httptest.NewRecorder() + + param := Values{} + param.Set("name", testName) + param.Set("version", testVesrion) + + r, err := http.NewRequest("PUT", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Update(c) +} + +func TestNegativeReceivedUpdateRequestWithoutVersionQuery_ExpectErrorReturn(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + w := httptest.NewRecorder() + + param := Values{} + param.Set("name", testName) + + r, err := http.NewRequest("PUT", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Update(c) + + if w.Code == 201 { + t.Errorf("Unexpected Response Code : %d", w.Code) + } +} + +func TestNegativeReceivedUpdateRequestWithoutNameQuery_ExpectErrorReturn(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + w := httptest.NewRecorder() + + param := Values{} + param.Set("version", testVesrion) + + r, err := http.NewRequest("PUT", url.V1()+url.IPS(), nil) + if err != nil { + t.Errorf("http.NewRequest return Error : %s", err.Error()) + } + r.Header.Set("Content-Type", "application/json") + r.URL.RawQuery = param.Encode() + + c, _ := gin.CreateTestContext(w) + c.Request = r + + deployment := Executor{} + deployment.Update(c) + + if w.Code == 201 { + t.Errorf("Unexpected Response Code : %d", w.Code) + } +} diff --git a/pkg/client/kserve/client.go b/pkg/client/kserve/client.go index c485fa1..3af41f4 100644 --- a/pkg/client/kserve/client.go +++ b/pkg/client/kserve/client.go @@ -37,6 +37,7 @@ const ( var ifsvGetter func(string) (client_v1beta1.InferenceServiceInterface, error) +//go:generate mockgen -source=client.go -destination=./mock/mock_client.go -package=mock type Command interface { Init(kubeconfigPath string) error Create(values types.Values) (string, error) diff --git a/pkg/client/onboard/client.go b/pkg/client/onboard/client.go index 8833cb6..16a7d72 100644 --- a/pkg/client/onboard/client.go +++ b/pkg/client/onboard/client.go @@ -25,6 +25,7 @@ import ( "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/commons/logger" ) +//go:generate mockgen -source=client.go -destination=./mock/mock_client.go -package=mock type Command interface { Get(name string) error Download(name string, version string) (string, error) diff --git a/pkg/controller/v1/adapter/controller.go b/pkg/controller/v1/adapter/controller.go index 2e34cdf..53283b3 100644 --- a/pkg/controller/v1/adapter/controller.go +++ b/pkg/controller/v1/adapter/controller.go @@ -28,6 +28,7 @@ import ( "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/commons/logger" ) +//go:generate mockgen -source=controller.go -destination=./mock/mock_controller.go -package=mock type Command interface { Deploy(name string, version string) (string, error) Delete(name string) error diff --git a/pkg/controller/v1/adapter/controller_test.go b/pkg/controller/v1/adapter/controller_test.go new file mode 100644 index 0000000..ad80a73 --- /dev/null +++ b/pkg/controller/v1/adapter/controller_test.go @@ -0,0 +1,327 @@ +/* +================================================================================== + +Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +================================================================================== +*/ + +package adapter + +import ( + "os" + "testing" + + "github.com/golang/mock/gomock" + "github.com/kserve/kserve/pkg/apis/serving/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + kservemock "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/client/kserve/mock" + onboardmock "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/client/onboard/mock" + "gerrit.o-ran-sc.org/r/aiml-fw/aihp/ips/kserve-adapter/pkg/commons/errors" +) + +const ( + testName = "test_name" + testVersion = "test_version" + samplePath = "/../../../../sample/validServing" + invalidPath = "/../../../../invalid" + invalidYAMLPath = "/../../../../sample/invalidServing" +) + +var ( + sampleIFSV = v1beta1.InferenceService{ + TypeMeta: v1.TypeMeta{}, + ObjectMeta: v1.ObjectMeta{}, + Spec: v1beta1.InferenceServiceSpec{ + Predictor: v1beta1.PredictorSpec{ + ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{}, + Tensorflow: &v1beta1.TFServingSpec{ + PredictorExtensionSpec: v1beta1.PredictorExtensionSpec{}, + }, + }, + }, + Status: v1beta1.InferenceServiceStatus{}, + } +) + +func fakeRemoveFunc(path string) (err error) { + return nil +} + +func TestNegativeCalledDepolyWithInvalidYAMLPath_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + workspace, _ := os.Getwd() + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return(workspace+invalidYAMLPath, nil), + ) + + // pass mockObj to a real object. + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + _, err := exec.Deploy(testName, testVersion) + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} + +func TestNegativeCalledDepolyWithInvalidPath_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + workspace, _ := os.Getwd() + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return(workspace+invalidPath, nil), + ) + + // pass mockObj to a real object. + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + _, err := exec.Deploy(testName, testVersion) + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} + +func TestCalledDepoly_ExpectReturnSuccess(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + kserveMockobj := kservemock.NewMockCommand(ctrl) + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + workspace, _ := os.Getwd() + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return(workspace+samplePath, nil), + kserveMockobj.EXPECT().Create(gomock.Any()), + ) + + // pass mockObj to a real object. + kserveClient = kserveMockobj + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + exec.Deploy(testName, testVersion) +} + +func TestNegativeCalledDepoly_WhenOnboardClientReturnError_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return("", errors.InternalServerError{}), + ) + + // pass mockObj to a real object. + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + _, err := exec.Deploy(testName, testVersion) + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} + +func TestNegativeCalledDepoly_WhenKServeClientReturnError_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + kserveMockobj := kservemock.NewMockCommand(ctrl) + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + workspace, _ := os.Getwd() + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return(workspace+samplePath, nil), + kserveMockobj.EXPECT().Create(gomock.Any()).Return("", errors.InternalServerError{}), + ) + + // pass mockObj to a real object. + kserveClient = kserveMockobj + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + _, err := exec.Deploy(testName, testVersion) + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} + +func TestCalledDelete_ExpectReturnSuccess(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + kserveMockobj := kservemock.NewMockCommand(ctrl) + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + gomock.InOrder( + onboardMockobj.EXPECT().Get(testName).Return(nil), + kserveMockobj.EXPECT().Delete(testName).Return(nil), + ) + + // pass mockObj to a real object. + kserveClient = kserveMockobj + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + err := exec.Delete(testName) + if err != nil { + t.Errorf("Expect error is nil, but error return, %s", err.Error()) + } +} + +func TestNegativeCalledDelete_WhenOnboardClientReturnError_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + gomock.InOrder( + onboardMockobj.EXPECT().Get(testName).Return(errors.IOError{}), + ) + + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + err := exec.Delete(testName) + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} + +func TestNegativeCalledDelete_WhenKServeClientReturnError_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + kserveMockobj := kservemock.NewMockCommand(ctrl) + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + gomock.InOrder( + onboardMockobj.EXPECT().Get(testName).Return(nil), + kserveMockobj.EXPECT().Delete(testName).Return(errors.InternalServerError{}), + ) + + kserveClient = kserveMockobj + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + err := exec.Delete(testName) + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} + +func TestCalledUpdate_ExpectReturnSuccess(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + kserveMockobj := kservemock.NewMockCommand(ctrl) + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + workspace, _ := os.Getwd() + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return(workspace+samplePath, nil), + kserveMockobj.EXPECT().Get(testName).Return(&sampleIFSV, nil), + kserveMockobj.EXPECT().Update(gomock.Any()), + ) + + // pass mockObj to a real object. + kserveClient = kserveMockobj + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + exec.Update(testName, testVersion, "0") +} + +func TestNegativeCalledUpdate_WhenOnboardClientReturnError_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return("", errors.InternalServerError{}), + ) + + // pass mockObj to a real object. + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + _, err := exec.Update(testName, testVersion, "0") + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} + +func TestNegativeCalledUpdate_WhenKServeClientReturnError_ExpectReturnError(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + kserveMockobj := kservemock.NewMockCommand(ctrl) + onboardMockobj := onboardmock.NewMockCommand(ctrl) + + workspace, _ := os.Getwd() + + gomock.InOrder( + onboardMockobj.EXPECT().Download(testName, testVersion).Return(workspace+samplePath, nil), + kserveMockobj.EXPECT().Get(testName).Return(&sampleIFSV, nil), + kserveMockobj.EXPECT().Update(gomock.Any()).Return("", errors.InternalServerError{}), + ) + + // pass mockObj to a real object. + kserveClient = kserveMockobj + onboardClient = onboardMockobj + removeFunc = fakeRemoveFunc + + exec := Executor{} + + _, err := exec.Update(testName, testVersion, "0") + if err == nil { + t.Errorf("Expect error return, but error is nil") + } +} diff --git a/sample/invalidServing/inferenceServing/values.yaml b/sample/invalidServing/inferenceServing/values.yaml new file mode 100755 index 0000000..f7e3d60 --- /dev/null +++ b/sample/invalidServing/inferenceServing/values.yaml @@ -0,0 +1,19 @@ +# ================================================================================== +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ================================================================================== +invalid yaml +!!@ diff --git a/sample/validServing/inferenceServing/Chart.yaml b/sample/validServing/inferenceServing/Chart.yaml new file mode 100755 index 0000000..711a270 --- /dev/null +++ b/sample/validServing/inferenceServing/Chart.yaml @@ -0,0 +1,23 @@ +# ================================================================================== +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ================================================================================== + +apiVersion: v1 +appVersion: "1.0" +description: ML xApp Helm Chart +name: lb +version: 2.0.0 diff --git a/sample/validServing/inferenceServing/templates/_helpers.tpl b/sample/validServing/inferenceServing/templates/_helpers.tpl new file mode 100755 index 0000000..b5505ad --- /dev/null +++ b/sample/validServing/inferenceServing/templates/_helpers.tpl @@ -0,0 +1,77 @@ +# ================================================================================== +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ================================================================================== + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "ricxapp.name" -}} + {{- default .Chart.Name .Values.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ricxapp.fullname" -}} + {{- $name := ( include "ricxapp.name" . ) -}} + {{- $fullname := ( printf "%s-%s" .Release.Namespace $name ) -}} + {{- default $fullname .Values.fullname | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ricxapp.chart" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "ricxapp.namespace" -}} + {{- default .Release.Namespace .Values.nsPrefix -}} +{{- end -}} + + + +{{- define "ricxapp.servicename" -}} + {{- $name := ( include "ricxapp.fullname" . ) -}} + {{- printf "service-%s" $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "ricxapp.configmapname" -}} + {{- $name := ( include "ricxapp.fullname" . ) -}} + {{- printf "configmap-%s" $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "ricxapp.deploymentname" -}} + {{- $name := ( include "ricxapp.fullname" . ) -}} + {{- printf "deployment-%s" $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{- define "ricxapp.containername" -}} + {{- $name := ( include "ricxapp.fullname" . ) -}} + {{- printf "container-%s" $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{- define "ricxapp.imagepullsecret" -}} + {{- $reponame := .repo -}} + {{- $postfix := $reponame | replace "." "-" | replace ":" "-" | replace "/" "-" | trunc 63 | trimSuffix "-" -}} + {{- printf "secret-%s" $postfix -}} +{{- end -}} diff --git a/sample/validServing/inferenceServing/templates/inferenceservice.yaml b/sample/validServing/inferenceServing/templates/inferenceservice.yaml new file mode 100755 index 0000000..c26ba5d --- /dev/null +++ b/sample/validServing/inferenceServing/templates/inferenceservice.yaml @@ -0,0 +1,42 @@ +# ================================================================================== +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ================================================================================== + +apiVersion: {{ quote .Values.api_version }} +kind: "InferenceService" +metadata: + name: {{ .Values.fullname }} + labels: + controller-tools.k8s.io: "1.0" + app: {{ .Values.fullname }} +spec: + predictor: + serviceAccountName: {{ .Values.ric_serviceaccount_name }} + {{- if .Values.max_replicas }} + maxReplicas: {{ .Values.max_replicas }} + {{- end }} + {{- if .Values.max_replicas }} + minReplicas: {{ .Values.min_replicas }} + {{- end }} + {{- if eq .Values.engine "tensorflow" }} + tensorflow: + {{- end }} + storageUri: {{ .Values.storageUri }} + {{- if .Values.resources }} + resources: + {{- toYaml .Values.resources | nindent 10 }} + {{- end -}} diff --git a/sample/validServing/inferenceServing/values.yaml b/sample/validServing/inferenceServing/values.yaml new file mode 100755 index 0000000..1f76f90 --- /dev/null +++ b/sample/validServing/inferenceServing/values.yaml @@ -0,0 +1,28 @@ +# ================================================================================== +# +# Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ================================================================================== + +api_version: serving.kserve.io/v1beta1 +engine: tensorflow +fullname: lb +image_pull_policy: Always +max_replicas: null +min_replicas: null +name: lb +resources: null +ric_serviceaccount_name: ric-sa +storageUri: s3://mlpipeline/artifacts/load-balance-pipeline-5xd67/load-balance-pipeline-5xd67-3012811736/lb -- 2.16.6