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.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
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.springframework.beans.factory.annotation.Autowired;
55 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
56 import org.springframework.boot.test.context.SpringBootTest;
57 import org.springframework.boot.test.mock.mockito.SpyBean;
58 import org.springframework.http.HttpMethod;
59 import org.springframework.http.HttpStatus;
60 import org.springframework.http.MediaType;
61 import org.springframework.test.web.client.ExpectedCount;
62 import org.springframework.test.web.client.MockRestServiceServer;
63 import org.springframework.web.client.RestTemplate;
65 @SpringBootTest(classes = {DmeConfiguration.class, DmeDeployer.class, BeanTestConfiguration.class,
66 RappCsarConfigurationHandler.class, RappCacheService.class, RappInstanceStateMachineConfig.class,
67 RappInstanceStateMachine.class})
68 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
70 class DmeDeployerTest {
72 MockRestServiceServer mockServer;
74 DmeDeployer dmeDeployer;
76 RestTemplate restTemplate;
78 DmeConfiguration dmeConfiguration;
80 RappInstanceStateMachine rappInstanceStateMachine;
82 RappDmeResourceBuilder rappDmeResourceBuilder = new RappDmeResourceBuilder();
84 private static final String validRappFile = "valid-rapp-package.csar";
85 private static final String validRappFileNewInfoType = "valid-rapp-package-new-info-type.csar";
86 String validCsarFileLocation = "src/test/resources/";
87 ObjectMapper objectMapper = new ObjectMapper();
89 String URI_INFO_TYPES, URI_INFO_TYPE, URI_INFO_PRODUCER, URI_INFO_CONSUMER;
93 URI_INFO_TYPES = dmeConfiguration.getBaseUrl() + "/data-producer/v1/info-types";
94 URI_INFO_TYPE = dmeConfiguration.getBaseUrl() + "/data-producer/v1/info-types/%s";
95 URI_INFO_PRODUCER = dmeConfiguration.getBaseUrl() + "/data-producer/v1/info-producers/%s";
96 URI_INFO_CONSUMER = dmeConfiguration.getBaseUrl() + "/data-consumer/v1/info-jobs/%s";
101 mockServer = MockRestServiceServer.createServer(restTemplate);
105 @MethodSource("getSuccessParamsWithUnavailableInfoTypes")
106 void testPrimeRappSuccessWithUnavailableInfoType(String rappFile, boolean result) throws JsonProcessingException {
107 RappResources rappResources = rappDmeResourceBuilder.getResources();
108 Rapp rapp = getRapp(Optional.empty());
109 rapp.setPackageName(rappFile);
110 rapp.setRappResources(rappResources);
111 List<String> infoTypes = List.of();
112 mockServer.expect(ExpectedCount.once(), requestTo(URI_INFO_TYPES)).andExpect(method(HttpMethod.GET)).andRespond(
113 withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
114 .body(objectMapper.writeValueAsString(infoTypes)));
115 assertTrue(dmeDeployer.primeRapp(rapp));
116 if (rappFile.equals(validRappFileNewInfoType)) {
119 assertEquals(rapp.getIsDmeValid(), result);
122 private static Stream<Arguments> getSuccessParamsWithUnavailableInfoTypes() {
123 return Stream.of(Arguments.of(validRappFile, true), Arguments.of(validRappFileNewInfoType, false));
127 @MethodSource("getSuccessParamsWithAvailableInfoTypes")
128 void testPrimeRappSuccessWithValidInfoType(String rappFile, boolean result) throws JsonProcessingException {
129 RappResources rappResources = rappDmeResourceBuilder.getResources();
130 Rapp rapp = getRapp(Optional.empty());
131 rapp.setPackageName(rappFile);
132 rapp.setRappResources(rappResources);
133 List<String> infoTypes = List.of("new-info-type-not-available");
134 mockServer.expect(ExpectedCount.once(), requestTo(URI_INFO_TYPES)).andExpect(method(HttpMethod.GET)).andRespond(
135 withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
136 .body(objectMapper.writeValueAsString(infoTypes)));
137 assertTrue(dmeDeployer.primeRapp(rapp));
138 if (rappFile.equals(validRappFileNewInfoType)) {
141 assertEquals(rapp.getIsDmeValid(), result);
144 private static Stream<Arguments> getSuccessParamsWithAvailableInfoTypes() {
145 return Stream.of(Arguments.of(validRappFile, true), Arguments.of(validRappFileNewInfoType, true));
149 void testPrimeRappFailure() {
150 RappResources rappResources = rappDmeResourceBuilder.getResources();
151 RappResources.DMEResources dme = rappResources.getDme();
152 Set<String> infoProducers = new HashSet<>(rappResources.getDme().getInfoProducers());
153 infoProducers.add("invalid-producer-not-available-in-rapp");
154 dme.setInfoProducers(infoProducers);
155 rappResources.setDme(dme);
156 Rapp rapp = getRapp(Optional.empty());
157 rapp.setRappResources(rappResources);
158 assertFalse(dmeDeployer.primeRapp(rapp));
159 assertFalse(rapp.getIsDmeValid());
163 void testDeprimeRapp() {
164 Rapp rapp = getRapp(Optional.empty());
165 rapp.setIsDmeValid(true);
166 assertTrue(dmeDeployer.deprimeRapp(rapp));
167 assertNull(rapp.getIsDmeValid());
171 void testDeployrAppInstanceSuccess() {
172 Rapp rapp = getRapp(Optional.empty());
173 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
174 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
175 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
176 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
177 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
178 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
183 void testDeployrAppInstanceSuccessWithoutConsumer() {
184 Rapp rapp = getRapp(Optional.empty());
185 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
186 rappInstance.getDme().setInfoTypeConsumer(null);
187 rappInstance.getDme().setInfoConsumer(null);
188 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
189 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
190 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
191 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
196 void testDeployrAppInstanceWithoutProducer() {
197 Rapp rapp = getRapp(Optional.empty());
198 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
199 rappInstance.getDme().setInfoTypesProducer(null);
200 rappInstance.getDme().setInfoProducer(null);
201 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypeConsumer(), true);
202 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
203 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
204 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
209 void testDeployrAppInstanceFailureWithInfoType() {
210 Rapp rapp = getRapp(Optional.empty());
211 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
212 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), false);
213 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
214 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
219 void testDeployrAppInstanceFailureWithInfoProducer() {
220 Rapp rapp = getRapp(Optional.empty());
221 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
222 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
223 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), false);
224 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
225 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
230 void testDeployrAppInstanceFailureWithInfoConsumer() {
231 Rapp rapp = getRapp(Optional.empty());
232 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
233 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
234 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
235 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), false);
236 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
237 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
242 void testUndeployrAppInstanceSuccess() {
243 Rapp rapp = getRapp(Optional.empty());
244 rapp.setState(RappState.PRIMED);
245 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
246 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
247 getMockServerClientDeleteInfoProducer(rappInstance.getDme().getInfoProducer(), true);
248 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
249 assertTrue(dmeDeployer.undeployRappInstance(rapp, rappInstance));
255 void testUndeployrAppInstanceFailureWithInfoProducer() {
256 Rapp rapp = getRapp(Optional.empty());
257 rapp.setState(RappState.PRIMED);
258 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
259 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
260 getMockServerClientDeleteInfoProducer(rappInstance.getDme().getInfoProducer(), false);
261 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
262 assertFalse(dmeDeployer.undeployRappInstance(rapp, rappInstance));
267 void testUndeployrAppInstanceFailureWithInfoConsumer() {
268 Rapp rapp = getRapp(Optional.empty());
269 rapp.setState(RappState.PRIMED);
270 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
271 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), false);
272 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
273 assertFalse(dmeDeployer.undeployRappInstance(rapp, rappInstance));
278 void testCreateInfoTypeFailureInvalidInfoType() {
279 Rapp rapp = getRapp(Optional.empty());
280 assertFalse(dmeDeployer.createInfoTypes(rapp, null));
284 void testCreateInfoTypeFailureInvalidInfoProducer() {
285 Rapp rapp = getRapp(Optional.empty());
286 assertFalse(dmeDeployer.createInfoProducer(rapp, ""));
290 void testCreateInfoTypeFailureInvalidInfoConsumer() {
291 Rapp rapp = getRapp(Optional.empty());
292 assertFalse(dmeDeployer.createInfoConsumer(rapp, ""));
295 Rapp getRapp(Optional<UUID> rappOptional) {
296 return Rapp.builder().rappId(rappOptional.orElse(UUID.randomUUID())).name("").packageName(validRappFile)
297 .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
300 void getMockServerClientCreateInfoType(String infoType, boolean isSuccess) {
302 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
303 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
305 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
306 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
310 void getMockServerClientCreateInfoProducer(String infoProducer, boolean isSuccess) {
312 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
313 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
315 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
316 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
320 void getMockServerClientCreateInfoConsumer(String infoConsumer, boolean isSuccess) {
322 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
323 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
325 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
326 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
330 void getMockServerClientDeleteInfoProducer(String infoProducer, boolean isSuccess) {
332 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
333 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
335 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
336 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
340 void getMockServerClientDeleteInfoConsumer(String infoConsumer, boolean isSuccess) {
342 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
343 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
345 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
346 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));