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 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypeConsumer(), true);
177 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
178 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
179 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
180 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
185 void testDeployrAppInstanceSuccessWithoutConsumer() {
186 Rapp rapp = getRapp(Optional.empty());
187 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
188 rappInstance.getDme().setInfoTypeConsumer(null);
189 rappInstance.getDme().setInfoConsumer(null);
190 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
191 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
192 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
193 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
198 void testDeployrAppInstanceWithoutProducer() {
199 Rapp rapp = getRapp(Optional.empty());
200 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
201 rappInstance.getDme().setInfoTypesProducer(null);
202 rappInstance.getDme().setInfoProducer(null);
203 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypeConsumer(), true);
204 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
205 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
206 assertTrue(dmeDeployer.deployRappInstance(rapp, rappInstance));
211 void testDeployrAppInstanceFailureWithInfoType() {
212 Rapp rapp = getRapp(Optional.empty());
213 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
214 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), false);
215 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
216 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
221 void testDeployrAppInstanceFailureWithInfoProducer() {
222 Rapp rapp = getRapp(Optional.empty());
223 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
224 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
225 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypeConsumer(), true);
226 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), false);
227 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
228 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
233 void testDeployrAppInstanceFailureWithInfoConsumer() {
234 Rapp rapp = getRapp(Optional.empty());
235 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
236 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypesProducer().toArray()[0].toString(), true);
237 getMockServerClientCreateInfoType(rappInstance.getDme().getInfoTypeConsumer(), true);
238 getMockServerClientCreateInfoProducer(rappInstance.getDme().getInfoProducer(), true);
239 getMockServerClientCreateInfoConsumer(rappInstance.getDme().getInfoConsumer(), false);
240 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
241 assertFalse(dmeDeployer.deployRappInstance(rapp, rappInstance));
246 void testUndeployrAppInstanceSuccess() {
247 Rapp rapp = getRapp(Optional.empty());
248 rapp.setState(RappState.PRIMED);
249 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
250 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
251 getMockServerClientDeleteInfoProducer(rappInstance.getDme().getInfoProducer(), true);
252 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
253 assertTrue(dmeDeployer.undeployRappInstance(rapp, rappInstance));
259 void testUndeployrAppInstanceFailureWithInfoProducer() {
260 Rapp rapp = getRapp(Optional.empty());
261 rapp.setState(RappState.PRIMED);
262 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
263 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), true);
264 getMockServerClientDeleteInfoProducer(rappInstance.getDme().getInfoProducer(), false);
265 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
266 assertFalse(dmeDeployer.undeployRappInstance(rapp, rappInstance));
271 void testUndeployrAppInstanceFailureWithInfoConsumer() {
272 Rapp rapp = getRapp(Optional.empty());
273 rapp.setState(RappState.PRIMED);
274 RappInstance rappInstance = rappDmeResourceBuilder.getRappInstance();
275 getMockServerClientDeleteInfoConsumer(rappInstance.getDme().getInfoConsumer(), false);
276 rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
277 assertFalse(dmeDeployer.undeployRappInstance(rapp, rappInstance));
282 void testCreateInfoTypeFailureInvalidInfoType() {
283 Rapp rapp = getRapp(Optional.empty());
284 assertFalse(dmeDeployer.createProducerInfoTypes(rapp, null));
285 assertFalse(dmeDeployer.createConsumerInfoTypes(rapp, null));
289 void testCreateInfoTypeFailureInvalidInfoProducer() {
290 Rapp rapp = getRapp(Optional.empty());
291 assertFalse(dmeDeployer.createInfoProducer(rapp, ""));
295 void testCreateInfoTypeFailureInvalidInfoConsumer() {
296 Rapp rapp = getRapp(Optional.empty());
297 assertFalse(dmeDeployer.createInfoConsumer(rapp, ""));
300 Rapp getRapp(Optional<UUID> rappOptional) {
301 return Rapp.builder().rappId(rappOptional.orElse(UUID.randomUUID())).name("").packageName(validRappFile)
302 .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
305 void getMockServerClientCreateInfoType(String infoType, boolean isSuccess) {
307 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
308 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
310 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
311 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
315 void getMockServerClientCreateInfoProducer(String infoProducer, boolean isSuccess) {
317 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
318 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
320 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
321 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
325 void getMockServerClientCreateInfoConsumer(String infoConsumer, boolean isSuccess) {
327 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
328 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
330 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
331 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
335 void getMockServerClientDeleteInfoProducer(String infoProducer, boolean isSuccess) {
337 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
338 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
340 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
341 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
345 void getMockServerClientDeleteInfoConsumer(String infoConsumer, boolean isSuccess) {
347 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
348 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
350 mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
351 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));