From 2aa67c33dde69ae69dd69facaf319a1045638da1 Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Mon, 23 Feb 2026 09:02:05 +0100 Subject: [PATCH] Add integration tests - test end to end http communication towards AAI and Multicloud Issue-ID: SO-4240 Change-Id: Ic2aedad93f4899d8874903b9ec1d9c6961053091 Signed-off-by: Fiete Ostkamp --- .../client/MulticloudClientIntegrationTest.java | 258 +++++++++++++++++++ .../cnf/rest/CnfAdapterRestIntegrationTest.java | 276 +++++++++++++++++++++ .../__files/multicloud/allInstancesResponse.json | 12 + .../__files/multicloud/createInstanceResponse.json | 5 + .../__files/multicloud/emptyResponse.json | 1 + .../__files/multicloud/getHealthCheckResponse.json | 5 + .../__files/multicloud/getInstanceResponse.json | 4 + .../multicloud/getInstanceStatusResponse.json | 4 + .../__files/multicloud/instanceStatusResponse.json | 4 + .../__files/multicloud/notFoundResponse.json | 3 + .../multicloud/queryInstanceResourcesResponse.json | 10 + .../multicloud/startHealthCheckResponse.json | 4 + .../multicloud/subscriptionExistsResponse.json | 3 + .../__files/multicloud/subscriptionResponse.json | 4 + .../multicloud/upgradeInstanceResponse.json | 3 + 15 files changed, 596 insertions(+) create mode 100644 so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientIntegrationTest.java create mode 100644 so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestIntegrationTest.java create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/allInstancesResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/createInstanceResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/emptyResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/getHealthCheckResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceStatusResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/instanceStatusResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/notFoundResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/queryInstanceResourcesResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/startHealthCheckResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionExistsResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionResponse.json create mode 100644 so-cnf-adapter-application/src/test/resources/__files/multicloud/upgradeInstanceResponse.json diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientIntegrationTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientIntegrationTest.java new file mode 100644 index 0000000..794446d --- /dev/null +++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientIntegrationTest.java @@ -0,0 +1,258 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2026 Deutsche Telekom. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.cnf.client; + +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.adapters.cnf.model.InstanceResponse; +import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest; +import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheck; +import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheckSimple; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceStatus; +import org.onap.so.adapters.cnf.model.synchronization.SubscriptionRequest; +import org.onap.so.adapters.cnf.model.synchronization.SubscriptionResponse; +import org.onap.so.client.exception.BadResponseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.SocketUtils; + +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit.WireMockRule; + +@SpringBootTest +@RunWith(SpringRunner.class) +public class MulticloudClientIntegrationTest { + + private static int wireMockPort = SocketUtils.findAvailableTcpPort(); + + @ClassRule + public static WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(wireMockPort)); + + @Autowired + private MulticloudClient multicloudClient; + + @Before + public void setUp() { + WireMock.reset(); + } + + @DynamicPropertySource + static void configureProperties(DynamicPropertyRegistry registry) { + registry.add("multicloud.endpoint", () -> "http://localhost:" + wireMockPort); + registry.add("spring.security.usercredentials[0].username", () -> "test"); + registry.add("spring.security.usercredentials[0].password", () -> "test"); + registry.add("spring.security.usercredentials[0].role", () -> "ACTUATOR"); + } + + @Test + public void thatAllInstancesCanBeRetrieved() throws BadResponseException { + WireMock.stubFor(WireMock.get(WireMock.urlEqualTo("/v1/instance")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/allInstancesResponse.json"))); + + List instances = multicloudClient.getAllInstances(); + + assertEquals(2, instances.size()); + assertEquals("inst-1", instances.get(0).getId()); + assertEquals("inst-2", instances.get(1).getId()); + WireMock.verify(WireMock.getRequestedFor(WireMock.urlEqualTo("/v1/instance")) + .withHeader("Accept", WireMock.equalTo("application/json"))); + } + + @Test + public void thatEmptyListReturnedWhenNoDocumentsFound() throws BadResponseException { + WireMock.stubFor(WireMock.get(WireMock.urlEqualTo("/v1/instance")) + .willReturn(WireMock.aResponse() + .withStatus(500) + .withBody("no documents for given ID"))); + + List instances = multicloudClient.getAllInstances(); + + assertTrue(instances.isEmpty()); + } + + @Test + public void thatInstanceStatusCanBeRetrieved() throws BadResponseException { + WireMock.stubFor(WireMock.get(WireMock.urlEqualTo("/v1/instance/test-inst/status")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/instanceStatusResponse.json"))); + + K8sRbInstanceStatus status = multicloudClient.getInstanceStatus("test-inst"); + + assertEquals(3, status.getResourceCount()); + assertTrue(status.isReady()); + WireMock.verify(WireMock.getRequestedFor(WireMock.urlEqualTo("/v1/instance/test-inst/status"))); + } + + @Test + public void thatSubscriptionCanBeRegistered() throws BadResponseException { + WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/v1/instance/test-inst/status/subscription")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/subscriptionResponse.json"))); + + SubscriptionRequest request = new SubscriptionRequest(); + request.setName("test-sub"); + request.setCallbackUrl("http://callback"); + request.setMinNotifyInterval(10); + + SubscriptionResponse response = multicloudClient.registerSubscription("test-inst", request); + + assertEquals("test-sub", response.getName()); + WireMock.verify(WireMock.postRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/status/subscription")) + .withHeader("Content-Type", WireMock.equalTo("application/json")) + .withRequestBody(WireMock.matchingJsonPath("$.name", WireMock.equalTo("test-sub"))) + .withRequestBody(WireMock.matchingJsonPath("$['callback-url']", + WireMock.equalTo("http://callback")))); + } + + @Test + public void thatSubscriptionExistenceCanBeChecked() throws BadResponseException { + WireMock.stubFor(WireMock.get( + WireMock.urlEqualTo("/v1/instance/test-inst/status/subscription/test-sub")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/subscriptionExistsResponse.json"))); + + assertTrue(multicloudClient.hasSubscription("test-inst", "test-sub")); + WireMock.verify(WireMock.getRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/status/subscription/test-sub"))); + } + + @Test + public void thatHasSubscriptionReturnsFalseWhenNotFound() throws BadResponseException { + WireMock.stubFor(WireMock.get( + WireMock.urlEqualTo("/v1/instance/test-inst/status/subscription/missing")) + .willReturn(WireMock.aResponse() + .withStatus(500) + .withBody("no documents for given ID"))); + + assertFalse(multicloudClient.hasSubscription("test-inst", "missing")); + } + + @Test + public void thatSubscriptionCanBeDeleted() throws BadResponseException { + WireMock.stubFor(WireMock.delete( + WireMock.urlEqualTo("/v1/instance/test-inst/status/subscription/test-sub")) + .willReturn(WireMock.aResponse().withStatus(200))); + + multicloudClient.deleteSubscription("test-inst", "test-sub"); + + WireMock.verify(WireMock.deleteRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/status/subscription/test-sub"))); + } + + @Test + public void thatInstanceCanBeUpgraded() throws BadResponseException { + WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/v1/instance/test-inst/upgrade")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/upgradeInstanceResponse.json"))); + + MulticloudInstanceRequest upgradeRequest = new MulticloudInstanceRequest(); + upgradeRequest.setRbName("test-rb"); + upgradeRequest.setRbVersion("v1"); + upgradeRequest.setProfileName("default"); + upgradeRequest.setCloudRegion("region-1"); + + String result = multicloudClient.upgradeInstance("test-inst", upgradeRequest); + + assertNotNull(result); + assertTrue(result.contains("test-inst")); + WireMock.verify(WireMock.postRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/upgrade")) + .withRequestBody(WireMock.matchingJsonPath("$['rb-name']", + WireMock.equalTo("test-rb"))) + .withRequestBody(WireMock.matchingJsonPath("$['rb-version']", + WireMock.equalTo("v1"))) + .withRequestBody(WireMock.matchingJsonPath("$['profile-name']", + WireMock.equalTo("default")))); + } + + @Test + public void thatHealthCheckCanBeStarted() throws BadResponseException { + WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/v1/instance/test-inst/healthcheck")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/startHealthCheckResponse.json"))); + + K8sRbInstanceHealthCheckSimple result = + multicloudClient.startInstanceHealthCheck("test-inst"); + + assertEquals("hc-1", result.getId()); + assertEquals("RUNNING", result.getStatus()); + WireMock.verify(WireMock.postRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/healthcheck"))); + } + + @Test + public void thatHealthCheckCanBeRetrieved() throws BadResponseException { + WireMock.stubFor(WireMock.get( + WireMock.urlEqualTo("/v1/instance/test-inst/healthcheck/hc-1")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/getHealthCheckResponse.json"))); + + K8sRbInstanceHealthCheck result = + multicloudClient.getInstanceHealthCheck("test-inst", "hc-1"); + + assertEquals("test-inst", result.getInstanceId()); + assertEquals("hc-1", result.getHealthcheckId()); + assertEquals("STOPPED", result.getStatus()); + } + + @Test + public void thatHealthCheckCanBeDeleted() throws BadResponseException { + WireMock.stubFor(WireMock.delete( + WireMock.urlEqualTo("/v1/instance/test-inst/healthcheck/hc-1")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withBody(""))); + + multicloudClient.deleteInstanceHealthCheck("test-inst", "hc-1"); + + WireMock.verify(WireMock.deleteRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/healthcheck/hc-1"))); + } +} diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestIntegrationTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestIntegrationTest.java new file mode 100644 index 0000000..84a6bfe --- /dev/null +++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestIntegrationTest.java @@ -0,0 +1,276 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2026 Deutsche Telekom. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.cnf.rest; + +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; +import org.onap.so.adapters.cnf.model.CheckInstanceRequest; +import org.onap.so.adapters.cnf.model.InstanceRequest; +import org.onap.so.adapters.cnf.model.upgrade.InstanceUpgradeRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.SocketUtils; + +import com.github.tomakehurst.wiremock.client.BasicCredentials; +import com.github.tomakehurst.wiremock.client.VerificationException; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit.WireMockRule; + +/** + * Integration tests for {@link CnfAdapterRest} that start from HTTP requests + * to the controller endpoints and verify that the correct outbound requests + * are made to the Multicloud K8s Plugin (stubbed by WireMock). + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class CnfAdapterRestIntegrationTest { + + private static int wireMockPort = SocketUtils.findAvailableTcpPort(); + + @ClassRule + public static WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(wireMockPort)); + + @Autowired + private TestRestTemplate restTemplate; + + @Before + public void setUp() { + WireMock.reset(); + } + + @DynamicPropertySource + static void configureProperties(DynamicPropertyRegistry registry) { + registry.add("multicloud.endpoint", () -> "http://localhost:" + wireMockPort); + registry.add("spring.security.usercredentials[0].username", () -> "test"); + registry.add("spring.security.usercredentials[0].password", () -> "test"); + registry.add("spring.security.usercredentials[0].role", () -> "ACTUATOR"); + } + + @Test + public void thatInstanceCanBeCreated() { + WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/v1/instance")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/createInstanceResponse.json"))); + + BpmnInstanceRequest request = new BpmnInstanceRequest(); + request.setModelInvariantId("rb-name-1"); + request.setModelCustomizationId("rb-version-1"); + request.setK8sRBProfileName("profile-1"); + request.setCloudRegionId("region-1"); + request.setK8sRBInstanceReleaseName("test-release"); + + ResponseEntity response = restTemplate.postForEntity( + "/api/cnf-adapter/v1/instance", request, String.class); + + assertEquals(200, response.getStatusCodeValue()); + assertNotNull(response.getBody()); + assertTrue(response.getBody().contains("new-inst")); + WireMock.verify(WireMock.postRequestedFor(WireMock.urlEqualTo("/v1/instance")) + .withRequestBody(WireMock.matchingJsonPath("$['rb-name']", + WireMock.equalTo("rb-name-1"))) + .withRequestBody(WireMock.matchingJsonPath("$['rb-version']", + WireMock.equalTo("rb-version-1"))) + .withRequestBody(WireMock.matchingJsonPath("$['profile-name']", + WireMock.equalTo("profile-1"))) + .withRequestBody(WireMock.matchingJsonPath("$['cloud-region']", + WireMock.equalTo("region-1")))); + } + + @Test + public void thatInstanceCanBeRetrievedById() { + WireMock.stubFor(WireMock.get(WireMock.urlEqualTo("/v1/instance/inst-1")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/getInstanceResponse.json"))); + + ResponseEntity response = restTemplate.getForEntity( + "/api/cnf-adapter/v1/instance/{instID}", String.class, "inst-1"); + + assertEquals(200, response.getStatusCodeValue()); + assertTrue(response.getBody().contains("inst-1")); + WireMock.verify(WireMock.getRequestedFor(WireMock.urlEqualTo("/v1/instance/inst-1"))); + } + + @Test + public void thatInstanceCanBeDeleted() { + WireMock.stubFor(WireMock.delete(WireMock.urlEqualTo("/v1/instance/inst-1")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/emptyResponse.json"))); + + ResponseEntity response = restTemplate.exchange( + "/api/cnf-adapter/v1/instance/{instID}", HttpMethod.DELETE, + null, String.class, "inst-1"); + + assertEquals(200, response.getStatusCodeValue()); + WireMock.verify(WireMock.deleteRequestedFor( + WireMock.urlEqualTo("/v1/instance/inst-1"))); + } + + @Test + public void thatInstanceStatusCanBeRetrieved() { + WireMock.stubFor(WireMock.get(WireMock.urlEqualTo("/v1/instance/inst-1/status")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/getInstanceStatusResponse.json"))); + + ResponseEntity response = restTemplate.getForEntity( + "/api/cnf-adapter/v1/instance/{instID}/status", String.class, "inst-1"); + + assertEquals(200, response.getStatusCodeValue()); + assertTrue(response.getBody().contains("resourceCount")); + WireMock.verify(WireMock.getRequestedFor( + WireMock.urlEqualTo("/v1/instance/inst-1/status"))); + } + + @Test + public void thatInstanceResourcesCanBeQueried() { + WireMock.stubFor(WireMock.get(WireMock.urlPathEqualTo("/v1/instance/inst-1/query")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/queryInstanceResourcesResponse.json"))); + + ResponseEntity response = restTemplate.getForEntity( + "/api/cnf-adapter/v1/instance/{instanceId}/query?Kind={kind}&ApiVersion={apiVersion}", + String.class, "inst-1", "Pod", "v1"); + + assertEquals(200, response.getStatusCodeValue()); + assertTrue(response.getBody().contains("test-pod")); + WireMock.verify(WireMock.getRequestedFor( + WireMock.urlPathEqualTo("/v1/instance/inst-1/query")) + .withQueryParam("Kind", WireMock.equalTo("Pod")) + .withQueryParam("ApiVersion", WireMock.equalTo("v1"))); + } + + @Test + public void thatInstanceCanBeUpgraded() { + WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/v1/instance/test-inst/upgrade")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/upgradeInstanceResponse.json"))); + + InstanceUpgradeRequest upgradeRequest = new InstanceUpgradeRequest(); + upgradeRequest.setModelInvariantId("rb-name-1"); + upgradeRequest.setModelCustomizationId("rb-version-1"); + upgradeRequest.setK8sRBProfileName("default"); + upgradeRequest.setCloudRegionId("region-1"); + + ResponseEntity response = restTemplate.postForEntity( + "/api/cnf-adapter/v1/instance/{instanceID}/upgrade", + upgradeRequest, String.class, "test-inst"); + + assertEquals(200, response.getStatusCodeValue()); + assertNotNull(response.getBody()); + WireMock.verify(WireMock.postRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/upgrade")) + .withRequestBody(WireMock.matchingJsonPath("$['rb-name']", + WireMock.equalTo("rb-name-1"))) + .withRequestBody(WireMock.matchingJsonPath("$['profile-name']", + WireMock.equalTo("default")))); + } + + @Test + public void thatStatusCheckCallsMulticloudAndSendsCallback() throws InterruptedException { + WireMock.stubFor(WireMock.get(WireMock.urlEqualTo("/v1/instance/test-inst/status")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBodyFile("multicloud/instanceStatusResponse.json"))); + + WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/callback")) + .willReturn(WireMock.aResponse().withStatus(200))); + + CheckInstanceRequest statusCheckRequest = new CheckInstanceRequest(); + InstanceRequest instanceRequest = new InstanceRequest(); + instanceRequest.setInstanceId("test-inst"); + statusCheckRequest.setInstances(Collections.singletonList(instanceRequest)); + statusCheckRequest.setCallbackUrl("http://localhost:" + wireMockPort + "/callback"); + + ResponseEntity response = restTemplate.postForEntity( + "/api/cnf-adapter/v1/statuscheck", statusCheckRequest, String.class); + + assertEquals(202, response.getStatusCodeValue()); + + awaitWireMockCallback("/callback"); + + WireMock.verify(WireMock.getRequestedFor( + WireMock.urlEqualTo("/v1/instance/test-inst/status"))); + WireMock.verify(WireMock.postRequestedFor(WireMock.urlEqualTo("/callback")) + .withHeader("Content-Type", WireMock.containing("text/plain")) + .withBasicAuth(new BasicCredentials("test", "test"))); + } + + @Test + public void thatCreateInstanceReturns500OnMulticloud404() { + WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/v1/instance")) + .willReturn(WireMock.aResponse() + .withStatus(404) + .withBodyFile("multicloud/notFoundResponse.json"))); + + BpmnInstanceRequest request = new BpmnInstanceRequest(); + request.setModelInvariantId("rb-name-1"); + request.setModelCustomizationId("rb-version-1"); + request.setK8sRBProfileName("profile-1"); + request.setCloudRegionId("region-1"); + + ResponseEntity response = restTemplate.postForEntity( + "/api/cnf-adapter/v1/instance", request, String.class); + + assertEquals(500, response.getStatusCodeValue()); + } + + /** + * Poll WireMock until the expected callback POST arrives (max 10 seconds). + */ + private void awaitWireMockCallback(String url) throws InterruptedException { + for (int i = 0; i < 50; i++) { + try { + WireMock.verify(WireMock.postRequestedFor(WireMock.urlEqualTo(url))); + return; + } catch (VerificationException e) { + Thread.sleep(200); + } + } + } +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/allInstancesResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/allInstancesResponse.json new file mode 100644 index 0000000..385efc0 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/allInstancesResponse.json @@ -0,0 +1,12 @@ +[ + { + "id": "inst-1", + "namespace": "default", + "release-name": "rel-1" + }, + { + "id": "inst-2", + "namespace": "test", + "release-name": "rel-2" + } +] diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/createInstanceResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/createInstanceResponse.json new file mode 100644 index 0000000..e97475d --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/createInstanceResponse.json @@ -0,0 +1,5 @@ +{ + "id": "new-inst", + "namespace": "default", + "release-name": "test-release" +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/emptyResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/emptyResponse.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/emptyResponse.json @@ -0,0 +1 @@ +{} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/getHealthCheckResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/getHealthCheckResponse.json new file mode 100644 index 0000000..21e3192 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/getHealthCheckResponse.json @@ -0,0 +1,5 @@ +{ + "instance-id": "test-inst", + "healthcheck-id": "hc-1", + "status": "STOPPED" +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceResponse.json new file mode 100644 index 0000000..7dd7ee3 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceResponse.json @@ -0,0 +1,4 @@ +{ + "id": "inst-1", + "namespace": "default" +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceStatusResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceStatusResponse.json new file mode 100644 index 0000000..a7c5836 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/getInstanceStatusResponse.json @@ -0,0 +1,4 @@ +{ + "resourceCount": 5, + "ready": false +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/instanceStatusResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/instanceStatusResponse.json new file mode 100644 index 0000000..8024029 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/instanceStatusResponse.json @@ -0,0 +1,4 @@ +{ + "resourceCount": 3, + "ready": true +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/notFoundResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/notFoundResponse.json new file mode 100644 index 0000000..5244ecd --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/notFoundResponse.json @@ -0,0 +1,3 @@ +{ + "error": "not found" +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/queryInstanceResourcesResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/queryInstanceResourcesResponse.json new file mode 100644 index 0000000..ebb52e5 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/queryInstanceResourcesResponse.json @@ -0,0 +1,10 @@ +[ + { + "Name": "test-pod", + "GVK": { + "Group": "", + "Version": "v1", + "Kind": "Pod" + } + } +] diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/startHealthCheckResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/startHealthCheckResponse.json new file mode 100644 index 0000000..b9917e7 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/startHealthCheckResponse.json @@ -0,0 +1,4 @@ +{ + "healthcheck-id": "hc-1", + "status": "RUNNING" +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionExistsResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionExistsResponse.json new file mode 100644 index 0000000..847150f --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionExistsResponse.json @@ -0,0 +1,3 @@ +{ + "name": "test-sub" +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionResponse.json new file mode 100644 index 0000000..7dd3484 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/subscriptionResponse.json @@ -0,0 +1,4 @@ +{ + "name": "test-sub", + "callback-url": "http://callback" +} diff --git a/so-cnf-adapter-application/src/test/resources/__files/multicloud/upgradeInstanceResponse.json b/so-cnf-adapter-application/src/test/resources/__files/multicloud/upgradeInstanceResponse.json new file mode 100644 index 0000000..b7e4461 --- /dev/null +++ b/so-cnf-adapter-application/src/test/resources/__files/multicloud/upgradeInstanceResponse.json @@ -0,0 +1,3 @@ +{ + "id": "test-inst" +} -- 2.16.6