2 * ============LICENSE_START======================================================================
3 * Copyright (C) 2023 Nordix Foundation. All rights reserved.
4 * Copyright (C) 2024 OpenInfra Foundation Europe. All rights reserved.
5 * ===============================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ============LICENSE_END========================================================================
20 package com.oransc.rappmanager.models.csar;
22 import static org.assertj.core.api.Assertions.assertThat;
23 import static org.junit.jupiter.api.Assertions.assertEquals;
24 import static org.junit.jupiter.api.Assertions.assertNotNull;
25 import static org.junit.jupiter.api.Assertions.assertNull;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.junit.jupiter.api.Assertions.assertTrue;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.Mockito.doCallRealMethod;
30 import static org.mockito.Mockito.doThrow;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
34 import com.fasterxml.jackson.core.JsonProcessingException;
35 import com.fasterxml.jackson.databind.ObjectMapper;
36 import com.google.gson.JsonSyntaxException;
37 import com.oransc.rappmanager.models.exception.RappHandlerException;
38 import com.oransc.rappmanager.models.rapp.Rapp;
39 import com.oransc.rappmanager.models.rapp.RappResources;
40 import com.oransc.rappmanager.models.rappinstance.RappACMInstance;
41 import com.oransc.rappmanager.models.rappinstance.RappDMEInstance;
42 import com.oransc.rappmanager.models.rappinstance.RappSMEInstance;
43 import java.io.ByteArrayOutputStream;
45 import java.io.FileInputStream;
46 import java.io.IOException;
47 import java.util.List;
49 import java.util.UUID;
50 import java.util.stream.Stream;
51 import org.apache.http.entity.ContentType;
52 import org.json.JSONException;
53 import org.json.JSONObject;
54 import org.junit.jupiter.api.Test;
55 import org.junit.jupiter.params.ParameterizedTest;
56 import org.junit.jupiter.params.provider.Arguments;
57 import org.junit.jupiter.params.provider.MethodSource;
58 import org.junit.jupiter.params.provider.ValueSource;
59 import org.springframework.boot.test.context.SpringBootTest;
60 import org.springframework.boot.test.mock.mockito.SpyBean;
61 import org.springframework.http.HttpStatus;
62 import org.springframework.mock.web.MockMultipartFile;
63 import org.springframework.test.context.ContextConfiguration;
64 import org.springframework.web.multipart.MultipartFile;
67 @ContextConfiguration(classes = {ObjectMapper.class, RappCsarConfigurationHandler.class})
68 class RappCsarConfigurationHandlerTest {
71 RappCsarConfigurationHandler rappCsarConfigurationHandler;
73 String validCsarFileLocation = "src/test/resources/";
75 private final String validRappFile = "valid-rapp-package.csar";
77 private final String invalidRappFile = "invalid-rapp-package.csar";
79 private final String invalidRappNoAsdFile = "invalid-rapp-package-no-asd-yaml.csar";
81 private final String invalidRappEmptyAsdFile = "invalid-rapp-package-empty-asd-yaml.csar";
84 void testCsarPackageValidationSuccess() throws IOException {
85 String rappCsarPath = validCsarFileLocation + File.separator + validRappFile;
86 MultipartFile multipartFile =
87 new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
88 new FileInputStream(rappCsarPath));
89 assertEquals(Boolean.TRUE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
93 @MethodSource("getInvalidCsarPackage")
94 void testCsarPackageValidationFailure(MultipartFile multipartFile) {
95 RappHandlerException exception = assertThrows(RappHandlerException.class,
96 () -> rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
97 assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
101 private static Stream<Arguments> getInvalidCsarPackage() throws IOException {
102 String validCsarFileLocation = "src/test/resources";
103 String rappCsarPath = validCsarFileLocation + File.separator + "invalid-rapp-package.csar";
104 MultipartFile multipartFile =
105 new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
106 new FileInputStream(rappCsarPath));
107 String rappCsarPathNoTosca = validCsarFileLocation + File.separator + "invalid-rapp-package-no-tosca.csar";
108 MultipartFile multipartFileNoTosca = new MockMultipartFile(rappCsarPathNoTosca, rappCsarPathNoTosca,
109 ContentType.MULTIPART_FORM_DATA.getMimeType(), new FileInputStream(rappCsarPathNoTosca));
110 String rappCsarPathNoAsdYaml = validCsarFileLocation + File.separator + "invalid-rapp-package-no-asd-yaml.csar";
111 MultipartFile multipartFileNoAsdYaml = new MockMultipartFile(rappCsarPathNoAsdYaml, rappCsarPathNoAsdYaml,
112 ContentType.MULTIPART_FORM_DATA.getMimeType(), new FileInputStream(rappCsarPathNoAsdYaml));
113 String rappCsarPathMissingArtifact =
114 validCsarFileLocation + File.separator + "invalid-rapp-package-missing-artifact.csar";
115 MultipartFile multipartFileMissingArtifact =
116 new MockMultipartFile(rappCsarPathMissingArtifact, rappCsarPathMissingArtifact,
117 ContentType.MULTIPART_FORM_DATA.getMimeType(),
118 new FileInputStream(rappCsarPathMissingArtifact));
119 String rappCsarPathNoComposition =
120 validCsarFileLocation + File.separator + "invalid-rapp-package-no-acm-composition.csar";
121 MultipartFile multipartFileNoComposition =
122 new MockMultipartFile(rappCsarPathNoComposition, rappCsarPathNoComposition,
123 ContentType.MULTIPART_FORM_DATA.getMimeType(), new FileInputStream(rappCsarPathNoComposition));
124 return Stream.of(Arguments.of(multipartFile), Arguments.of(multipartFileNoTosca),
125 Arguments.of(multipartFileNoAsdYaml), Arguments.of(multipartFileMissingArtifact),
126 Arguments.of(multipartFileNoComposition));
130 void testCsarPackageValidationFailureWithoutOrginalName() {
131 MultipartFile multipartFile = mock(MultipartFile.class);
132 assertEquals(Boolean.FALSE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
136 void testInvalidCsarFileExist() {
137 MultipartFile multipartFile = mock(MultipartFile.class);
138 RappHandlerException exception = assertThrows(RappHandlerException.class,
139 () -> rappCsarConfigurationHandler.isFileExistsInCsar(multipartFile, "INVALID_LOCATION"));
140 assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
144 void testCsarContainsValidAsdFile() throws IOException {
145 String rappCsarPath = validCsarFileLocation + File.separator + validRappFile;
146 MultipartFile multipartFile =
147 new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
148 new FileInputStream(rappCsarPath));
149 assertTrue(rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
153 void testCsarContainsValidAsdFileFailure() throws IOException {
154 String rappCsarPath = validCsarFileLocation + File.separator + invalidRappFile;
155 MultipartFile multipartFile =
156 new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
157 new FileInputStream(rappCsarPath));
158 RappHandlerException exception = assertThrows(RappHandlerException.class,
159 () -> rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
160 assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
164 void testCsarNoAsdFailure() {
165 MultipartFile multipartFile = mock(MultipartFile.class);
166 RappHandlerException exception = assertThrows(RappHandlerException.class,
167 () -> rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
168 assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
172 void testCsarAsdContentInvalidFailure() throws IOException {
173 String rappCsarPath = validCsarFileLocation + File.separator + validRappFile;
174 MultipartFile multipartFile =
175 new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
176 new FileInputStream(rappCsarPath));
177 String invalidJson = "{asasdasd";
178 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
179 byteArrayOutputStream.write(invalidJson.getBytes(), 0, invalidJson.getBytes().length);
180 doCallRealMethod().doReturn(byteArrayOutputStream).when(rappCsarConfigurationHandler)
181 .getFileFromCsar(any(MultipartFile.class), any());
182 RappHandlerException exception = assertThrows(RappHandlerException.class,
183 () -> rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
184 assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
188 void testgetFileFromCsarFailure() throws IOException {
189 MultipartFile multipartFile = mock(MultipartFile.class);
190 when(multipartFile.getInputStream()).thenThrow(new IOException());
191 assertThat(rappCsarConfigurationHandler.getFileFromCsar(multipartFile, null).size()).isZero();
195 void testCsarInstantiationPayload() throws JSONException {
196 Rapp rapp = Rapp.builder().name("").packageName(validRappFile).packageLocation(validCsarFileLocation).build();
197 UUID compositionId = UUID.randomUUID();
198 RappACMInstance rappACMInstance = new RappACMInstance();
199 rappACMInstance.setInstance("kserve-instance");
200 JSONObject jsonObject = new JSONObject(
201 rappCsarConfigurationHandler.getInstantiationPayload(rapp, rappACMInstance, compositionId));
202 assertEquals(jsonObject.get("compositionId"), String.valueOf(compositionId));
206 void testFileListing() {
207 File file = new File(validCsarFileLocation + validRappFile);
208 Set<String> fileListFromCsar = rappCsarConfigurationHandler.getFileListFromCsar(file, "Files/Sme/serviceapis/");
209 assertThat(fileListFromCsar).hasSize(2);
213 void testInvalidFileListing() {
214 File file = new File(validCsarFileLocation);
215 Set<String> fileListFromCsar = rappCsarConfigurationHandler.getFileListFromCsar(file, null);
216 assertThat(fileListFromCsar).isEmpty();
220 void testInvalidFileListingFromCsar() {
221 File file = new File("InvalidFile");
222 ByteArrayOutputStream fileByteArray = rappCsarConfigurationHandler.getFileFromCsar(file, null);
223 assertThat(fileByteArray.size()).isZero();
227 void testListResources() {
228 UUID rappId = UUID.randomUUID();
230 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
232 RappResources rappResources = rappCsarConfigurationHandler.getRappResource(rapp);
233 assertThat(rappResources).isNotNull();
234 assertNotNull(rappResources.getAcm().getCompositionDefinitions());
235 assertThat(rappResources.getAcm().getCompositionInstances()).hasSize(4);
236 assertThat(rappResources.getSme().getProviderFunctions()).hasSize(4);
237 assertThat(rappResources.getSme().getServiceApis()).hasSize(2);
238 assertThat(rappResources.getSme().getInvokers()).hasSize(2);
239 assertThat(rappResources.getDme().getProducerInfoTypes()).hasSize(2);
240 assertThat(rappResources.getDme().getConsumerInfoTypes()).hasSize(2);
241 assertThat(rappResources.getDme().getInfoProducers()).hasSize(2);
242 assertThat(rappResources.getDme().getInfoConsumers()).hasSize(2);
246 void testListInvalidResources() {
247 UUID rappId = UUID.randomUUID();
248 Rapp rapp = Rapp.builder().rappId(rappId).name("").packageName("").packageLocation("").build();
249 RappResources rappResources = rappCsarConfigurationHandler.getRappResource(rapp);
250 assertThat(rappResources).isNotNull();
251 assertNull(rappResources.getAcm());
252 assertNull(rappResources.getSme());
253 assertNull(rappResources.getDme());
257 void testGetAcmCompositionPayload() {
258 UUID rappId = UUID.randomUUID();
259 RappResources rappResources = new RappResources();
260 rappResources.setAcm(RappResources.ACMResources.builder().compositionDefinitions("compositions")
261 .compositionInstances(Set.of()).build());
263 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
264 .rappResources(rappResources).build();
265 String acmCompositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
266 assertNotNull(acmCompositionPayload);
270 void testGetInvalidAcmCompositionPayload() {
271 UUID rappId = UUID.randomUUID();
272 RappResources rappResources = new RappResources();
273 rappResources.setAcm(RappResources.ACMResources.builder().compositionDefinitions("invalidcomposition")
274 .compositionInstances(Set.of()).build());
276 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
277 .rappResources(rappResources).build();
278 String acmCompositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
279 assertEquals("", acmCompositionPayload);
283 void testGetSmeProviderDomainPayload() {
284 UUID rappId = UUID.randomUUID();
285 RappSMEInstance rappSMEInstance = new RappSMEInstance();
286 rappSMEInstance.setProviderFunction("aef-provider-function");
288 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
290 String smeProviderDomainPayload =
291 rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp, rappSMEInstance);
292 assertNotNull(smeProviderDomainPayload);
296 void testGetSmeServiceApiPayload() {
297 UUID rappId = UUID.randomUUID();
298 RappSMEInstance rappSMEInstance = new RappSMEInstance();
299 rappSMEInstance.setServiceApis("api-set-1");
301 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
303 String smeProviderDomainPayload = rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp, rappSMEInstance);
304 assertNotNull(smeProviderDomainPayload);
308 void testGetSmeInvokerPayload() {
309 UUID rappId = UUID.randomUUID();
310 RappSMEInstance rappSMEInstance = new RappSMEInstance();
311 rappSMEInstance.setServiceApis("invoker-app1");
313 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
315 String smeProviderDomainPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp, rappSMEInstance);
316 assertNotNull(smeProviderDomainPayload);
320 void testGetDmeProducerInfoTypePayload() {
321 UUID rappId = UUID.randomUUID();
322 RappDMEInstance rappDMEInstance = new RappDMEInstance();
323 rappDMEInstance.setInfoTypesProducer(Set.of("json-file-data-from-filestore"));
325 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
327 String dmeInfoTypePayload = rappCsarConfigurationHandler.getDmeProducerInfoTypePayload(rapp,
328 rappDMEInstance.getInfoTypesProducer().iterator().next());
329 assertNotNull(dmeInfoTypePayload);
333 void testGetDmeConsumerInfoTypePayload() {
334 UUID rappId = UUID.randomUUID();
335 RappDMEInstance rappDMEInstance = new RappDMEInstance();
336 rappDMEInstance.setInfoTypeConsumer("json-file-data-from-filestore");
338 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
340 String dmeInfoTypePayload =
341 rappCsarConfigurationHandler.getDmeConsumerInfoTypePayload(rapp, rappDMEInstance.getInfoTypeConsumer());
342 assertNotNull(dmeInfoTypePayload);
346 void testGetDmeInfoProducerPayload() {
347 UUID rappId = UUID.randomUUID();
348 RappDMEInstance rappDMEInstance = new RappDMEInstance();
349 rappDMEInstance.setInfoProducer("json-file-data-producer");
351 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
353 String dmeInfoProducerPayload =
354 rappCsarConfigurationHandler.getDmeInfoProducerPayload(rapp, rappDMEInstance.getInfoProducer());
355 assertNotNull(dmeInfoProducerPayload);
359 void testGetDmeInfoConsumerPayload() {
360 UUID rappId = UUID.randomUUID();
361 RappDMEInstance rappDMEInstance = new RappDMEInstance();
362 rappDMEInstance.setInfoConsumer("json-file-consumer");
364 Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
366 String dmeInfoConsumerPayload =
367 rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rapp, rappDMEInstance.getInfoConsumer());
368 assertNotNull(dmeInfoConsumerPayload);
372 void testListDeploymentItems() {
373 Rapp rapp = Rapp.builder().name("").packageName(validRappFile).packageLocation(validCsarFileLocation).build();
374 List<DeploymentItem> deploymentItems = rappCsarConfigurationHandler.getDeploymentItems(rapp);
375 assertEquals(2, deploymentItems.size());
379 @ValueSource(strings = {invalidRappNoAsdFile, invalidRappEmptyAsdFile})
380 void testListDeploymentItemsNoAsd(String packageName) {
381 Rapp rapp = Rapp.builder().name("").packageName(packageName).packageLocation(validCsarFileLocation).build();
382 assertThat(rappCsarConfigurationHandler.getDeploymentItems(rapp)).isEmpty();
386 void testListDeploymentItemsWithException() throws JsonProcessingException {
387 Rapp rapp = Rapp.builder().name("").packageName(validRappFile).packageLocation(validCsarFileLocation).build();
388 doThrow(new JsonSyntaxException("")).when(rappCsarConfigurationHandler).getAsdContentNode(any());
389 assertThat(rappCsarConfigurationHandler.getDeploymentItems(rapp)).isEmpty();
393 void testGetArtifactPayload() {
394 Rapp rapp = Rapp.builder().name("").packageName(validRappFile).packageLocation(validCsarFileLocation).build();
395 assertNotNull(rappCsarConfigurationHandler.getArtifactPayload(rapp,
396 "Artifacts/Deployment/HELM/ransliceassurance-1.0.0.tgz"));