aboutsummaryrefslogtreecommitdiffstats
path: root/participant/participant-impl/participant-impl-kserve/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'participant/participant-impl/participant-impl-kserve/src/test')
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java125
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java78
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/KserveClientTest.java196
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/rest/ActuatorControllerTest.java97
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonActuatorController.java107
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonTestData.java60
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/ToscaUtils.java51
-rwxr-xr-xparticipant/participant-impl/participant-impl-kserve/src/test/resources/application-test.yaml17
8 files changed, 731 insertions, 0 deletions
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java
new file mode 100755
index 000000000..0743e0429
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java
@@ -0,0 +1,125 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.kserve.handler;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import io.kubernetes.client.openapi.ApiException;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.acm.participant.kserve.exception.KserveException;
+import org.onap.policy.clamp.acm.participant.kserve.k8s.KserveClient;
+import org.onap.policy.clamp.acm.participant.kserve.utils.CommonTestData;
+import org.onap.policy.clamp.acm.participant.kserve.utils.ToscaUtils;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+class AcElementHandlerTest {
+
+ private final KserveClient kserveClient = mock(KserveClient.class);
+
+ @InjectMocks
+ @Spy
+ private AutomationCompositionElementHandler automationCompositionElementHandler =
+ new AutomationCompositionElementHandler(kserveClient);
+
+ @Mock
+ private ParticipantIntermediaryApi participantIntermediaryApi;
+
+ @Mock
+ private ExecutorService executor;
+ @Mock
+ private Future<String> result;
+
+ private final CommonTestData commonTestData = new CommonTestData();
+
+ private static ToscaServiceTemplate serviceTemplate;
+ private static final String KSERVE_AUTOMATION_COMPOSITION_ELEMENT =
+ "onap.policy.clamp.ac.element.KserveAutomationCompositionElement";
+
+ @BeforeAll
+ static void init() {
+ serviceTemplate = ToscaUtils.readAutomationCompositionFromTosca();
+ }
+
+ @BeforeEach
+ void startMocks() throws KserveException, ExecutionException, InterruptedException, IOException, ApiException {
+ doReturn(true).when(kserveClient).deployInferenceService(any(), any());
+ doReturn(true).when(automationCompositionElementHandler)
+ .checkInferenceServiceStatus(any(), any(), anyInt(), anyInt());
+ }
+
+ @Test
+ void test_automationCompositionElementStateChange() throws PfModelException {
+ var automationCompositionId = commonTestData.getAutomationCompositionId();
+ var element = commonTestData.getAutomationCompositionElement();
+ var automationCompositionElementId = element.getId();
+
+
+ var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+ automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element,
+ nodeTemplatesMap.get(KSERVE_AUTOMATION_COMPOSITION_ELEMENT).getProperties());
+
+ assertDoesNotThrow(() -> automationCompositionElementHandler.undeploy(automationCompositionId,
+ automationCompositionElementId));
+
+ }
+
+ @Test
+ void test_AutomationCompositionElementUpdate() {
+ var element = commonTestData.getAutomationCompositionElement();
+
+ var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+ assertDoesNotThrow(
+ () -> automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element,
+ nodeTemplatesMap.get(KSERVE_AUTOMATION_COMPOSITION_ELEMENT).getProperties()));
+ }
+
+ @Test
+ void test_checkInferenceServiceStatus() throws ExecutionException, InterruptedException {
+ doReturn(result).when(executor).submit(any(Runnable.class), any());
+ doReturn("Done").when(result).get();
+ doReturn(true).when(result).isDone();
+ ToscaConceptIdentifier automationCompositionId = new ToscaConceptIdentifier();
+ AutomationCompositionElement element = new AutomationCompositionElement();
+ assertDoesNotThrow(
+ () -> automationCompositionElementHandler.checkInferenceServiceStatus("sklearn-iris", "kserve-test", 1,
+ 1));
+ }
+}
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java
new file mode 100755
index 000000000..3ef89a7c1
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/InferenceServiceValidatorTest.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.kserve.k8s;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+
+import io.kubernetes.client.openapi.ApiException;
+import java.io.IOException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.onap.policy.clamp.acm.participant.kserve.exception.KserveException;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+
+@ExtendWith(SpringExtension.class)
+class InferenceServiceValidatorTest {
+
+ private static int TIMEOUT = 2;
+ private static int STATUS_CHECK_INTERVAL = 1;
+
+ @MockBean
+ private KserveClient kserveClient;
+
+ String inferenceSvcName = "inference-test";
+ String namespace = "test";
+
+ @Test
+ void test_runningPodState() throws IOException, ApiException {
+ doReturn("True").when(kserveClient).getInferenceServiceStatus(any(), any());
+ var inferenceServiceValidator =
+ new InferenceServiceValidator(inferenceSvcName, namespace, TIMEOUT, STATUS_CHECK_INTERVAL,
+ kserveClient);
+ assertDoesNotThrow(inferenceServiceValidator::run);
+ }
+
+ @Test
+ void test_EmptyPodState() throws IOException, ApiException {
+ doReturn("").when(kserveClient).getInferenceServiceStatus(any(), any());
+ var inferenceServiceValidator =
+ new InferenceServiceValidator("", namespace, TIMEOUT, STATUS_CHECK_INTERVAL,
+ kserveClient);
+ assertThatThrownBy(inferenceServiceValidator::run).isInstanceOf(KserveException.class)
+ .hasMessage("Error verifying the status of the inference service. Exiting");
+ }
+
+ @Test
+ void test_PodFailureState() throws IOException, ApiException {
+ doReturn("False").when(kserveClient).getInferenceServiceStatus(any(), any());
+ var inferenceServiceValidator =
+ new InferenceServiceValidator(inferenceSvcName, namespace, TIMEOUT, STATUS_CHECK_INTERVAL,
+ kserveClient);
+ assertThatThrownBy(inferenceServiceValidator::run).isInstanceOf(KserveException.class)
+ .hasMessage("Error verifying the status of the inference service. Exiting");
+ }
+
+}
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/KserveClientTest.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/KserveClientTest.java
new file mode 100755
index 000000000..c9be352db
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/k8s/KserveClientTest.java
@@ -0,0 +1,196 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.kserve.k8s;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.apis.CustomObjectsApi;
+import java.io.IOException;
+import okhttp3.Call;
+import okhttp3.MediaType;
+import okhttp3.Protocol;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import org.apache.http.HttpStatus;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class KserveClientTest {
+
+ @SpyBean
+ private KserveClient kserveClient;
+
+ String namespace = "kserve-test";
+
+ String inferenceServiceName = "sklearn-iris";
+
+ final Call remoteCall = mock(Call.class);
+
+ final CustomObjectsApi customObjectsApi = mock(CustomObjectsApi.class);
+
+ @MockBean
+ ApiClient apiClient;
+
+ @BeforeAll
+ void initialize() {
+ kserveClient.customObjectsApi = customObjectsApi;
+ }
+
+
+ @Test
+ void test_deployInferenceServiceValidResponse() throws IOException, ApiException {
+ String jsonContent =
+ "{\"apiVersion\": \"serving.kserve.io/v1beta1\",\"kind\": \"InferenceService\",\"metadata\": "
+ + "{\"name\": \"" + inferenceServiceName
+ + "\"},\"spec\": {\"predictor\": {\"model\":{\"modelFormat\": "
+ + "{\"name\": \"sklearn\"},\"storageUri\": "
+ + "\"gs://kfserving-examples/models/sklearn/1.0/model\"}}}}";
+
+ var response = getResponse(HttpStatus.SC_OK);
+ when(remoteCall.execute()).thenReturn(response);
+ when(customObjectsApi.createNamespacedCustomObjectCall(any(), any(), any(), any(), any(), any(), any(), any(),
+ any())).thenReturn(remoteCall);
+ assertTrue(kserveClient.deployInferenceService(namespace, jsonContent));
+ }
+
+ @Test
+ void test_deployInferenceServiceInvalidResponse() throws IOException, ApiException {
+ String jsonContent =
+ "{\"apiVersion\": \"serving.kserve.io/v1beta1\",\"kind\": \"InferenceService\",\"metadata\": "
+ + "{\"name\": \"" + inferenceServiceName
+ + "\"},\"spec\": {\"predictor\": {\"model\":{\"modelFormat\": "
+ + "{\"name\": \"sklearn\"},\"storageUri\": "
+ + "\"gs://kfserving-examples/models/sklearn/1.0/model\"}}}}";
+
+ var response = getResponse(HttpStatus.SC_BAD_REQUEST);
+ when(remoteCall.execute()).thenReturn(response);
+ when(customObjectsApi.createNamespacedCustomObjectCall(any(), any(), any(), any(), any(), any(), any(), any(),
+ any())).thenReturn(remoteCall);
+ assertFalse(kserveClient.deployInferenceService(namespace, jsonContent));
+ }
+
+ @Test
+ void test_deployInvalidInferenceService() throws IOException, ApiException {
+ doThrow(new ApiException("Error in deploying the service")).when(kserveClient)
+ .deployInferenceService(any(), any());
+ assertThatThrownBy(() -> kserveClient.deployInferenceService(namespace, "")).isInstanceOf(ApiException.class);
+ }
+
+ @Test
+ void test_undeployInferenceServiceValidResponse() throws IOException, ApiException {
+
+ var response = getResponse(HttpStatus.SC_OK);
+ when(remoteCall.execute()).thenReturn(response);
+ when(customObjectsApi.deleteNamespacedCustomObjectCall(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), any(), any())).thenReturn(remoteCall);
+ assertTrue(kserveClient.undeployInferenceService(namespace, inferenceServiceName));
+ }
+
+ @Test
+ void test_undeployInferenceServiceInvalidResponse() throws IOException, ApiException {
+
+ var response = getResponse(HttpStatus.SC_BAD_REQUEST);
+ when(remoteCall.execute()).thenReturn(response);
+ when(customObjectsApi.deleteNamespacedCustomObjectCall(any(), any(), any(), any(), any(), any(), any(), any(),
+ any(), any(), any())).thenReturn(remoteCall);
+ assertFalse(kserveClient.undeployInferenceService(namespace, inferenceServiceName));
+ }
+
+ @Test
+ void test_getInferenceServiceStatusValidResponse() throws IOException, ApiException {
+
+ var response = getResponse(HttpStatus.SC_OK, getInferenceServiceResponseBody("True"));
+ when(remoteCall.execute()).thenReturn(response);
+ when(customObjectsApi.getNamespacedCustomObjectCall(any(), any(), any(), any(), any(), any())).thenReturn(
+ remoteCall);
+ assertEquals("True", kserveClient.getInferenceServiceStatus(namespace, inferenceServiceName));
+ }
+
+ @Test
+ void test_getInferenceServiceStatusFalseResponse() throws IOException, ApiException {
+
+ var response = getResponse(HttpStatus.SC_OK, getInferenceServiceResponseBody("False"));
+ when(remoteCall.execute()).thenReturn(response);
+ when(customObjectsApi.getNamespacedCustomObjectCall(any(), any(), any(), any(), any(), any())).thenReturn(
+ remoteCall);
+ assertEquals("False", kserveClient.getInferenceServiceStatus(namespace, inferenceServiceName));
+ }
+
+ @Test
+ void test_getInferenceServiceStatusInvalidResponse() throws IOException, ApiException {
+
+ var response = getResponse(HttpStatus.SC_BAD_REQUEST, "");
+ when(remoteCall.execute()).thenReturn(response);
+ when(customObjectsApi.getNamespacedCustomObjectCall(any(), any(), any(), any(), any(), any())).thenReturn(
+ remoteCall);
+ assertEquals("false", kserveClient.getInferenceServiceStatus(namespace, inferenceServiceName));
+ }
+
+ Response getResponse(int code) {
+ return getResponse(code, "{}");
+ }
+
+ Response getResponse(int code, String body) {
+ return new Response.Builder().request(new Request.Builder().url("http://test").build())
+ .protocol(Protocol.HTTP_1_1).code(code).message("")
+ .body(ResponseBody.create(body, MediaType.parse("application/json"))).build();
+ }
+
+ String getInferenceServiceResponseBody(String status) {
+ return "{ \"apiVersion\": \"serving.kserve.io/v1beta1\", \"kind\": \"InferenceService\", \"spec\": "
+ + "{ \"predictor\": { \"model\": { \"modelFormat\": { \"name\": \"sklearn\" }, \"name\": \"\", "
+ + "\"resources\": {}, \"storageUri\": \"gs://kfserving-examples/models/sklearn/1.0/model\" } } "
+ + "}, \"status\": { \"address\": { \"url\": \"http://sklearn-iris.kserve-test.svc.cluster.local\""
+ + " }, \"components\": { \"predictor\": { \"latestCreatedRevision\": \"1\", \"url\": "
+ + "\"http://sklearn-iris-predictor-default-kserve-test.example.com\" } }, \"conditions\": [ "
+ + "{ \"lastTransitionTime\": \"2023-02-15T13:39:16Z\", \"status\": \"" + status
+ + "\", \"type\": "
+ + "\"IngressReady\" }, { \"lastTransitionTime\": \"2023-02-15T13:39:16Z\", \"status\": " + "\""
+ + status + "\", \"type\": \"PredictorReady\" }, { \"lastTransitionTime\": "
+ + "\"2023-02-15T13:39:16Z\", \"status\": \"" + status + "\", \"type\": \"Ready\" } ], "
+ + "\"modelStatus\": { \"copies\": { \"failedCopies\": 0, \"totalCopies\": 1 }, \"states\": "
+ + "{ \"activeModelState\": \"Loaded\", \"targetModelState\": \"Loaded\" }, \"transitionStatus\":"
+ + "\"UpToDate\" }, \"observedGeneration\": 1, \"url\": "
+ + " \"http://sklearn-iris-kserve-test.example.com\" } }";
+ }
+
+}
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/rest/ActuatorControllerTest.java
new file mode 100755
index 000000000..0cabac793
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/rest/ActuatorControllerTest.java
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021-2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.kserve.rest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import io.kubernetes.client.openapi.ApiClient;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.onap.policy.clamp.acm.participant.kserve.utils.CommonActuatorController;
+import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@AutoConfigureMetrics
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+class ActuatorControllerTest extends CommonActuatorController {
+
+ private static final String HEALTH_ENDPOINT = "health";
+ private static final String METRICS_ENDPOINT = "metrics";
+ private static final String PROMETHEUS_ENDPOINT = "prometheus";
+
+ @MockBean
+ ApiClient apiClient;
+
+ @LocalServerPort
+ private int randomServerPort;
+
+ @BeforeEach
+ public void setUpPort() {
+ super.setHttpPrefix(randomServerPort);
+ }
+
+ @Test
+ void testGetHealth_Unauthorized() throws Exception {
+ assertUnauthorizedActGet(HEALTH_ENDPOINT);
+ }
+
+ @Test
+ void testGetMetrics_Unauthorized() throws Exception {
+ assertUnauthorizedActGet(METRICS_ENDPOINT);
+ }
+
+ @Test
+ void testGetPrometheus_Unauthorized() throws Exception {
+ assertUnauthorizedActGet(PROMETHEUS_ENDPOINT);
+ }
+
+ @Test
+ void testGetHealth() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT);
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ void testGetMetrics() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT);
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ void testGePrometheus() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT);
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ }
+
+}
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonActuatorController.java
new file mode 100755
index 000000000..b83a13897
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonActuatorController.java
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.kserve.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.onap.policy.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.utils.network.NetworkUtil;
+
+/**
+ * Class to perform Rest unit tests.
+ */
+public class CommonActuatorController {
+
+ public static final String SELF = NetworkUtil.getHostname();
+ public static final String CONTEXT_PATH = "onap/policy/clamp/acm/kserveparticipant/";
+
+ private static String httpPrefix;
+
+ /**
+ * Sends a request to an actuator endpoint.
+ *
+ * @param endpoint the target endpoint
+ * @return a request builder
+ */
+ protected Invocation.Builder sendActRequest(final String endpoint) {
+ return sendFqeRequest(httpPrefix + CONTEXT_PATH + endpoint, true);
+ }
+
+ /**
+ * Sends a request to an actuator endpoint, without any authorization header.
+ *
+ * @param endpoint the target endpoint
+ * @return a request builder
+ */
+ protected Invocation.Builder sendNoAuthActRequest(final String endpoint) {
+ return sendFqeRequest(httpPrefix + CONTEXT_PATH + endpoint, false);
+ }
+
+ /**
+ * Sends a request to a fully qualified endpoint.
+ *
+ * @param fullyQualifiedEndpoint the fully qualified target endpoint
+ * @param includeAuth if authorization header should be included
+ * @return a request builder
+ */
+ protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) {
+ final Client client = ClientBuilder.newBuilder().build();
+
+ client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
+ client.register(GsonMessageBodyHandler.class);
+
+ if (includeAuth) {
+ client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34"));
+ }
+
+ final WebTarget webTarget = client.target(fullyQualifiedEndpoint);
+
+ return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN);
+ }
+
+ /**
+ * Assert that GET call to actuator endpoint is Unauthorized.
+ *
+ * @param endPoint the endpoint
+ */
+ protected void assertUnauthorizedActGet(final String endPoint) {
+ Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke();
+ assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus());
+ }
+
+ /**
+ * Set Up httpPrefix.
+ *
+ * @param port the port
+ */
+ protected void setHttpPrefix(int port) {
+ httpPrefix = "http://" + SELF + ":" + port + "/";
+ }
+
+}
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonTestData.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonTestData.java
new file mode 100755
index 000000000..076738ac4
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/CommonTestData.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * Modifications Copyright (C) 2022 AT&T Intellectual Property. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.kserve.utils;
+
+import java.util.List;
+import java.util.UUID;
+import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+public class CommonTestData {
+
+ private static final String TEST_KEY_NAME = "org.onap.domain.database.KserveAutomationCompositionElement";
+
+ private static final List<UUID> AC_ID_LIST = List.of(UUID.randomUUID(), UUID.randomUUID());
+
+ /**
+ * Get a automationComposition Element.
+ *
+ * @return automationCompositionElement object
+ */
+ public AcElementDeploy getAutomationCompositionElement() {
+ var element = new AcElementDeploy();
+ element.setId(UUID.randomUUID());
+ element.setDefinition(new ToscaConceptIdentifier(TEST_KEY_NAME, "1.0.1"));
+ element.setOrderedState(DeployOrder.DEPLOY);
+ return element;
+ }
+
+ /**
+ * Get automation composition id.
+ *
+ * @return ToscaConceptIdentifier automationCompositionId
+ */
+ public UUID getAutomationCompositionId() {
+ return AC_ID_LIST.get(0);
+ }
+
+}
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/ToscaUtils.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/ToscaUtils.java
new file mode 100755
index 000000000..e2b00e4c9
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/utils/ToscaUtils.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.kserve.utils;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.onap.policy.common.utils.coder.YamlJsonTranslator;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * Util class for Test scope.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ToscaUtils {
+
+ private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
+ private static final String TOSCA_TEMPLATE_YAML = "clamp/acm/test/participant-kserve.yaml";
+
+
+ /**
+ * Read a service template yaml.
+ * @return ToscaServiceTemplate
+ */
+ public static ToscaServiceTemplate readAutomationCompositionFromTosca() {
+ return serializeAutomationCompositionYaml();
+ }
+
+ private static ToscaServiceTemplate serializeAutomationCompositionYaml() {
+ String automationCompositionString = ResourceUtils.getResourceAsString(ToscaUtils.TOSCA_TEMPLATE_YAML);
+ return yamlTranslator.fromYaml(automationCompositionString, ToscaServiceTemplate.class);
+ }
+}
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/resources/application-test.yaml b/participant/participant-impl/participant-impl-kserve/src/test/resources/application-test.yaml
new file mode 100755
index 000000000..8452ed071
--- /dev/null
+++ b/participant/participant-impl/participant-impl-kserve/src/test/resources/application-test.yaml
@@ -0,0 +1,17 @@
+participant:
+ intermediaryParameters:
+ reportingTimeIntervalMs: 120000
+ description: Participant Description
+ participantId: 101c62b3-8918-41b9-a747-d21eb79c6c04
+ clampAutomationCompositionTopics:
+ topicSources:
+ - topic: POLICY-ACRUNTIME-PARTICIPANT
+ servers:
+ - ${topicServer:localhost}
+ topicCommInfrastructure: dmaap
+ fetchTimeout: 15000
+ topicSinks:
+ - topic: POLICY-ACRUNTIME-PARTICIPANT
+ servers:
+ - ${topicServer:localhost}
+ topicCommInfrastructure: dmaap \ No newline at end of file