2 * ============LICENSE_START======================================================================
3 * Copyright (C) 2023 Nordix Foundation. All rights reserved.
4 * ===============================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 * ============LICENSE_END========================================================================
19 package com.oransc.rappmanager.dme.service;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertNull;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
26 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
27 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
29 import com.fasterxml.jackson.core.JsonProcessingException;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31 import com.oransc.rappmanager.dme.configuration.DmeConfiguration;
32 import com.oransc.rappmanager.models.cache.RappCacheService;
33 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
34 import com.oransc.rappmanager.models.rapp.Rapp;
35 import com.oransc.rappmanager.models.rapp.RappDmeResourceBuilder;
36 import com.oransc.rappmanager.models.rapp.RappResources;
37 import com.oransc.rappmanager.models.rapp.RappState;
38 import com.oransc.rappmanager.models.rappinstance.RappInstance;
39 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
40 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachineConfig;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Optional;
45 import java.util.UUID;
46 import java.util.stream.Stream;
47 import org.junit.jupiter.api.BeforeAll;
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50 import org.junit.jupiter.api.TestInstance;
51 import org.junit.jupiter.params.ParameterizedTest;
52 import org.junit.jupiter.params.provider.Arguments;
53 import org.junit.jupiter.params.provider.MethodSource;
54 import org.junit.jupiter.params.provider.ValueSource;
55 import org.springframework.beans.factory.annotation.Autowired;
56 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
57 import org.springframework.boot.test.context.SpringBootTest;
58 import org.springframework.boot.test.mock.mockito.SpyBean;
59 import org.springframework.http.HttpMethod;
60 import org.springframework.http.HttpStatus;
61 import org.springframework.http.MediaType;
62 import org.springframework.test.web.client.ExpectedCount;
63 import org.springframework.test.web.client.MockRestServiceServer;
64 import org.springframework.web.client.RestTemplate;
66 @SpringBootTest(classes = {DmeConfiguration.class, DmeDeployer.class, BeanTestConfiguration.class,
67 RappCsarConfigurationHandler.class, RappCacheService.class, RappInstanceStateMachineConfig.class,
68 RappInstanceStateMachine.class})
69 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
71 class DmeDeployerTest {
73 MockRestServiceServer mockServer;
75 DmeDeployer dmeDeployer;
77 RestTemplate restTemplate;
79 DmeConfiguration dmeConfiguration;
81 RappInstanceStateMachine rappInstanceStateMachine;
83 RappDmeResourceBuilder rappDmeResourceBuilder = new RappDmeResourceBuilder();
85 private static final String validRappFile = "valid-rapp-package.csar";
86 private static final String validRappFileNewInfoType = "valid-rapp-package-new-info-type.csar";
87 String validCsarFileLocation = "src/test/resources/";
88 ObjectMapper objectMapper = new ObjectMapper();
90 String URI_INFO_TYPES, URI_INFO_TYPE, URI_INFO_PRODUCER, URI_INFO_CONSUMER;
94 URI_INFO_TYPES = dmeConfiguration.getBaseUrl() + "/data-producer/v1/info-types";
95 URI_INFO_TYPE = dmeConfiguration.getBaseUrl() + "/data-producer/v1/info-types/%s";
96 URI_INFO_PRODUCER = dmeConfiguration.getBaseUrl() + "/data-producer/v1/info-producers/%s";
97 URI_INFO_CONSUMER = dmeConfiguration.getBaseUrl() + "/data-consumer/v1/info-jobs/%s";
102 mockServer = MockRestServiceServer.createServer(restTemplate);
106 @MethodSource("getSuccessParamsWithUnavailableInfoTypes")
107 void testPrimeRappSuccessWithUnavailableInfoType(String rappFile, boolean isSuccess)
108 throws JsonProcessingException {
109 RappResources rappResources = rappDmeResourceBuilder.getResources();
110 Rapp rapp = getRapp(Optional.empty());
111 rapp.setPackageName(rappFile);
112 rapp.setRappResources(rappResources);
113 List<String> infoTypes = List.of();
114 mockServer.expect(ExpectedCount.once(), requestTo(URI_INFO_TYPES)).andExpect(method(HttpMethod.GET)).andRespond(
115 withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
116 .body(objectMapper.writeValueAsString(infoTypes)));
117 assertTrue(dmeDeployer.primeRapp(rapp));
118 if (rappFile.equals(validRappFileNewInfoType)) {
122 assertNull(rapp.getReason());
124 assertNotNull(rapp.getReason());
128 private static Stream<Arguments> getSuccessParamsWithUnavailableInfoTypes() {
129 return Stream.of(Arguments.of(validRappFile, true), Arguments.of(validRappFileNewInfoType, false));
133 @ValueSource(strings = {validRappFile, validRappFileNewInfoType})
134 void testPrimeRappSuccessWithValidInfoType(String rappFile) throws JsonProcessingException {
135 RappResources rappResources = rappDmeResourceBuilder.getResources();
136 Rapp rapp = getRapp(Optional.empty());
137 rapp.setPackageName(rappFile);
138 rapp.setRappResources(rappResources);
139 List<String> infoTypes = List.of("new-info-type-not-available");
140 mockServer.expect(ExpectedCount.once(), requestTo(URI_INFO_TYPES)).andExpect(method(HttpMethod.GET)).andRespond(
141 withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
142 .body(objectMapper.writeValueAsString(infoTypes)));
143 assertTrue(dmeDeployer.primeRapp(rapp));
144 if (rappFile.equals(validRappFileNewInfoType)) {
147 assertNull(rapp.getReason());
151 void testPrimeRappFailure() {
152 RappResources rappResources = rappDmeResourceBuilder.getResources();
153 RappResources.DMEResources dme = rappResources.getDme();
154 Set<String> infoProducers = new HashSet<>(rappResources.getDme().getInfoProducers());
155 infoProducers.add("invalid-producer-not-available-in-rapp");
156 dme.setInfoProducers(infoProducers);
157 rappResources.setDme(dme);
158 Rapp rapp = getRapp(Optional.empty());
159 rapp.setRappResources(rappResources);
160 assertFalse(dmeDeployer.primeRapp(rapp));
161 assertFalse(rapp.getReason().isEmpty());
165 void testDeprimeRapp() {
166 Rapp rapp = getRapp(Optional.empty());
167 assertTrue(dmeDeployer.deprimeRapp(rapp));
168 assertNull(rapp.getReason());
172 void testDeployrAppInstanceSuccess() {
173 Rapp rapp = getRapp(Optional.empty());
174 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
175 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
176 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
177 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
178 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
179 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
184 void testDeployrAppInstanceSuccessWithoutConsumer() {
185 Rapp rapp = getRapp(Optional.empty());
186 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
187 rappInstance.getDme().setInfoTypeConsumer(null);
188 rappInstance.getDme().setInfoConsumer(null);
189 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
190 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
191 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
192 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
197 void testDeployrAppInstanceWithoutProducer() {
198 Rapp rapp = getRapp(Optional.empty());
199 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
200 rappInstance.getDme().setInfoTypesProducer(null);
201 rappInstance.getDme().setInfoProducer(null);
202 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypeConsumer(), true);
203 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
204 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
205 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
210 void testDeployrAppInstanceFailureWithInfoType() {
211 Rapp rapp = getRapp(Optional.empty());
212 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
213 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), false);
214 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
215 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
220 void testDeployrAppInstanceFailureWithInfoProducer() {
221 Rapp rapp = getRapp(Optional.empty());
222 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
223 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
224 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), false);
225 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
226 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
231 void testDeployrAppInstanceFailureWithInfoConsumer() {
232 Rapp rapp = getRapp(Optional.empty());
233 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
234 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
235 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
236 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), false);
237 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
238 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
243 void testUndeployrAppInstanceSuccess() {
244 Rapp rapp = getRapp(Optional.empty());
245 rapp.setState(RappState.PRIMED);
246 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
247 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
248 getMockServerClientDeleteInfoProducer(rappInstance.getDme().getInfoProducer(), true);
249 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
250 assertTrue(dmeDeployer.undeployRappInstance(rapp, rappInstance));
256 void testUndeployrAppInstanceFailureWithInfoProducer() {
257 Rapp rapp = getRapp(Optional.empty());
258 rapp.setState(RappState.PRIMED);
259 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
260 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
261 getMockServerClientDeleteInfoProducer(rappInstance.getDme().getInfoProducer(), false);
262 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
263 assertFalse(dmeDeployer.undeployRappInstance(rapp, rappInstance));
268 void testUndeployrAppInstanceFailureWithInfoConsumer() {
269 Rapp rapp = getRapp(Optional.empty());
270 rapp.setState(RappState.PRIMED);
271 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
272 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), false);
273 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
274 assertFalse(dmeDeployer.undeployRappInstance(rapp, rappInstance));
279 void testCreateInfoTypeFailureInvalidInfoType() {
280 Rapp rapp = getRapp(Optional.empty());
281 assertFalse(dmeDeployer.createInfoTypes(rapp, null));
285 void testCreateInfoTypeFailureInvalidInfoProducer() {
286 Rapp rapp = getRapp(Optional.empty());
287 assertFalse(dmeDeployer.createInfoProducer(rapp, ""));
291 void testCreateInfoTypeFailureInvalidInfoConsumer() {
292 Rapp rapp = getRapp(Optional.empty());
293 assertFalse(dmeDeployer.createInfoConsumer(rapp, ""));
296 Rapp getRapp(Optional<UUID> rappOptional) {
297 return Rapp.builder().rappId(rappOptional.orElse(UUID.randomUUID())).name("").packageName(validRappFile)
298 .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
301 void getMockServerClientCreateInfoType(String infoType, boolean isSuccess) {
303 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
304 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
306 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
307 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
311 void getMockServerClientCreateInfoProducer(String infoProducer, boolean isSuccess) {
313 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
314 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
316 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
317 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
321 void getMockServerClientCreateInfoConsumer(String infoConsumer, boolean isSuccess) {
323 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
324 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
326 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
327 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
331 void getMockServerClientDeleteInfoProducer(String infoProducer, boolean isSuccess) {
333 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
334 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
336 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
337 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
341 void getMockServerClientDeleteInfoConsumer(String infoConsumer, boolean isSuccess) {
343 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
344 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
346 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
347 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));