e85fbe3e254cbc888d76f57debb9020736e7e69c
[nonrtric/plt/rappmanager.git] / rapp-manager-dme / src / test / java / com / oransc / rappmanager / dme / service / DmeDeployerTest.java
1 /*-
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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========================================================================
17  */
18
19 package com.oransc.rappmanager.dme.service;
20
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;
28
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;
44 import java.util.Set;
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;
65
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)
70 @AutoConfigureMockMvc
71 class DmeDeployerTest {
72
73     MockRestServiceServer mockServer;
74     @SpyBean
75     DmeDeployer dmeDeployer;
76     @Autowired
77     RestTemplate restTemplate;
78     @Autowired
79     DmeConfiguration dmeConfiguration;
80     @SpyBean
81     RappInstanceStateMachine rappInstanceStateMachine;
82
83     RappDmeResourceBuilder rappDmeResourceBuilder = new RappDmeResourceBuilder();
84
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();
89
90     String URI_INFO_TYPES, URI_INFO_TYPE, URI_INFO_PRODUCER, URI_INFO_CONSUMER;
91
92     @BeforeAll
93     void initACMURI() {
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";
98     }
99
100     @BeforeEach
101     public void init() {
102         mockServer = MockRestServiceServer.createServer(restTemplate);
103     }
104
105     @ParameterizedTest
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)) {
119             mockServer.verify();
120         }
121         if (isSuccess) {
122             assertNull(rapp.getReason());
123         } else {
124             assertNotNull(rapp.getReason());
125         }
126     }
127
128     private static Stream<Arguments> getSuccessParamsWithUnavailableInfoTypes() {
129         return Stream.of(Arguments.of(validRappFile, true), Arguments.of(validRappFileNewInfoType, false));
130     }
131
132     @ParameterizedTest
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)) {
145             mockServer.verify();
146         }
147         assertNull(rapp.getReason());
148     }
149
150     @Test
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());
162     }
163
164     @Test
165     void testDeprimeRapp() {
166         Rapp rapp = getRapp(Optional.empty());
167         assertTrue(dmeDeployer.deprimeRapp(rapp));
168         assertNull(rapp.getReason());
169     }
170
171     @Test
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));
181         mockServer.verify();
182     }
183
184     @Test
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));
194         mockServer.verify();
195     }
196
197     @Test
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));
207         mockServer.verify();
208     }
209
210     @Test
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));
217         mockServer.verify();
218     }
219
220     @Test
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));
229         mockServer.verify();
230     }
231
232     @Test
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));
242         mockServer.verify();
243     }
244
245     @Test
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));
254         mockServer.verify();
255     }
256
257
258     @Test
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));
267         mockServer.verify();
268     }
269
270     @Test
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));
278         mockServer.verify();
279     }
280
281     @Test
282     void testCreateInfoTypeFailureInvalidInfoType() {
283         Rapp rapp = getRapp(Optional.empty());
284         assertFalse(dmeDeployer.createProducerInfoTypes(rapp, null));
285         assertFalse(dmeDeployer.createConsumerInfoTypes(rapp, null));
286     }
287
288     @Test
289     void testCreateInfoTypeFailureInvalidInfoProducer() {
290         Rapp rapp = getRapp(Optional.empty());
291         assertFalse(dmeDeployer.createInfoProducer(rapp, ""));
292     }
293
294     @Test
295     void testCreateInfoTypeFailureInvalidInfoConsumer() {
296         Rapp rapp = getRapp(Optional.empty());
297         assertFalse(dmeDeployer.createInfoConsumer(rapp, ""));
298     }
299
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();
303     }
304
305     void getMockServerClientCreateInfoType(String infoType, boolean isSuccess) {
306         if (isSuccess) {
307             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
308                     .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
309         } else {
310             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_TYPE, infoType)))
311                     .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
312         }
313     }
314
315     void getMockServerClientCreateInfoProducer(String infoProducer, boolean isSuccess) {
316         if (isSuccess) {
317             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
318                     .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
319         } else {
320             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
321                     .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
322         }
323     }
324
325     void getMockServerClientCreateInfoConsumer(String infoConsumer, boolean isSuccess) {
326         if (isSuccess) {
327             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
328                     .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.CREATED));
329         } else {
330             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
331                     .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
332         }
333     }
334
335     void getMockServerClientDeleteInfoProducer(String infoProducer, boolean isSuccess) {
336         if (isSuccess) {
337             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
338                     .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
339         } else {
340             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_PRODUCER, infoProducer)))
341                     .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
342         }
343     }
344
345     void getMockServerClientDeleteInfoConsumer(String infoConsumer, boolean isSuccess) {
346         if (isSuccess) {
347             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
348                     .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
349         } else {
350             mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INFO_CONSUMER, infoConsumer)))
351                     .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
352         }
353     }
354
355 }