Improve testing stability
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / components / impl / OutputsBusinessLogicTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2021, Nordix Foundation. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.components.impl;
21
22 import static org.assertj.core.api.Assertions.assertThat;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.fail;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.eq;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31
32 import fj.data.Either;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.stream.Collectors;
39 import org.apache.commons.collections.CollectionUtils;
40 import org.junit.jupiter.api.BeforeEach;
41 import org.junit.jupiter.api.Test;
42 import org.mockito.InjectMocks;
43 import org.mockito.Mock;
44 import org.mockito.MockitoAnnotations;
45 import org.openecomp.sdc.be.components.attribute.AttributeDeclarationOrchestrator;
46 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
47 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
48 import org.openecomp.sdc.be.components.validation.UserValidations;
49 import org.openecomp.sdc.be.config.ConfigurationManager;
50 import org.openecomp.sdc.be.dao.api.ActionStatus;
51 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
52 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
53 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
54 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
55 import org.openecomp.sdc.be.impl.ComponentsUtils;
56 import org.openecomp.sdc.be.model.ComponentInstOutputsMap;
57 import org.openecomp.sdc.be.model.ComponentInstance;
58 import org.openecomp.sdc.be.model.ComponentInstanceOutput;
59 import org.openecomp.sdc.be.model.ComponentInstanceAttribOutput;
60 import org.openecomp.sdc.be.model.ComponentParametersView;
61 import org.openecomp.sdc.be.model.OutputDefinition;
62 import org.openecomp.sdc.be.model.LifecycleStateEnum;
63 import org.openecomp.sdc.be.model.Service;
64 import org.openecomp.sdc.be.model.User;
65 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
66 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
67 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
68 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
69 import org.openecomp.sdc.be.model.operations.impl.AttributeOperation;
70 import org.openecomp.sdc.be.user.UserBusinessLogic;
71 import org.openecomp.sdc.common.impl.ExternalConfiguration;
72 import org.openecomp.sdc.common.impl.FSConfigurationSource;
73 import org.openecomp.sdc.exception.ResponseFormat;
74
75 class OutputsBusinessLogicTest {
76
77     private static final String COMPONENT_INSTANCE_ID = "instanceId";
78     private static final String COMPONENT_ID = "componentId";
79     private static final String USER_ID = "userId";
80     private static final String OUTPUT_ID = "outputId";
81     private static final String OUTPUT_TYPE = "string";
82     private static final String LISTOUTPUT_NAME = "listOutput";
83     private static final String LISTOUTPUT_SCHEMA_TYPE = "org.onap.datatypes.listoutput";
84     private static final String LISTOUTPUT_PROP1_NAME = "prop1";
85     private static final String LISTOUTPUT_PROP1_TYPE = "string";
86     private static final String LISTOUTPUT_PROP2_NAME = "prop2";
87     private static final String LISTOUTPUT_PROP2_TYPE = "integer";
88     private static final String OLD_VALUE = "old value";
89     private static final String NEW_VALUE = "new value";
90     private final ConfigurationManager configurationManager =
91         new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be"));
92
93     @Mock
94     private ComponentsUtils componentsUtilsMock;
95
96     @Mock
97     private UserBusinessLogic userAdminMock;
98
99     @Mock
100     private ToscaOperationFacade toscaOperationFacadeMock;
101
102     @Mock
103     private UserValidations userValidations;
104
105     @Mock
106     private IGraphLockOperation graphLockOperation;
107
108     @Mock
109     private AttributeDeclarationOrchestrator attributeDeclarationOrchestrator;
110
111     @Mock
112     private ApplicationDataTypeCache applicationDataTypeCache;
113
114     @Mock
115     private AttributeOperation attributeOperation;
116
117     @Mock
118     private JanusGraphDao janusGraphDao;
119
120     @InjectMocks
121     private OutputsBusinessLogic testInstance;
122
123     private Service service;
124
125     private Map<String, List<ComponentInstanceOutput>> instanceOutputMap;
126     private List<ComponentInstanceOutput> outputsList;
127
128     @BeforeEach
129     public void setUp() {
130         MockitoAnnotations.openMocks(this);
131         service = new Service();
132         service.setUniqueId(COMPONENT_ID);
133         service.setLastUpdaterUserId(USER_ID);
134         service.setIsDeleted(false);
135         service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
136
137         testInstance.setUserValidations(userValidations);
138         testInstance.setToscaOperationFacade(toscaOperationFacadeMock);
139         testInstance.setGraphLockOperation(graphLockOperation);
140         testInstance.setComponentsUtils(componentsUtilsMock);
141         testInstance.setJanusGraphDao(janusGraphDao);
142         testInstance.setApplicationDataTypeCache(applicationDataTypeCache);
143         testInstance.setAttributeOperation(attributeOperation);
144
145         // add a ComponentInstance
146         final ComponentInstance componentInstance = new ComponentInstance();
147         componentInstance.setUniqueId(COMPONENT_INSTANCE_ID);
148         service.setComponentInstances(Collections.singletonList(componentInstance));
149
150         instanceOutputMap = new HashMap<>();
151         final ComponentInstanceOutput componentInstanceOutput = new ComponentInstanceOutput();
152         componentInstanceOutput.setOutputId(OUTPUT_ID);
153         componentInstanceOutput.setName(OUTPUT_ID);
154         outputsList = Collections.singletonList(componentInstanceOutput);
155         instanceOutputMap.put(COMPONENT_INSTANCE_ID, outputsList);
156         instanceOutputMap.put("someOutputId", Collections.singletonList(new ComponentInstanceOutput()));
157         service.setComponentInstancesOutputs(instanceOutputMap);
158         when(userValidations.validateUserExists(USER_ID)).thenReturn(new User());
159         when(userAdminMock.getUser(USER_ID, false)).thenReturn(new User());
160     }
161
162     @Test
163     void getComponentInstanceOutputs_ComponentInstanceNotExist() {
164         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(Either.left(service));
165         final Either<List<ComponentInstanceOutput>, ResponseFormat> componentInstanceOutputs = testInstance
166             .getComponentInstanceOutputs(USER_ID, COMPONENT_ID, "nonExisting");
167         assertThat(componentInstanceOutputs.isRight()).isTrue();
168         verify(componentsUtilsMock).getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
169     }
170
171     @Test
172     void getComponentInstanceOutputs_emptyOutputsMap() {
173         service.setComponentInstancesOutputs(Collections.emptyMap());
174         getComponents_emptyOutputs(service);
175     }
176
177     @Test
178     void getComponentInstanceOutputs_nullOutputsMap() {
179         service.setComponentInstancesOutputs(null);
180         getComponents_emptyOutputs(service);
181     }
182
183     @Test
184     void getComponentInstanceOutputs_instanceHasNoOutputs() {
185         service.setComponentInstancesOutputs(Collections.singletonMap("someOutputId", new ArrayList<>()));
186         getComponents_emptyOutputs(service);
187     }
188
189     @Test
190     void getComponentInstanceOutputs() {
191         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(Either.left(service));
192         final Either<List<ComponentInstanceOutput>, ResponseFormat> componentInstanceOutputs = testInstance
193             .getComponentInstanceOutputs(USER_ID, COMPONENT_ID, COMPONENT_INSTANCE_ID);
194         assertEquals("outputId", componentInstanceOutputs.left().value().get(0).getOutputId());
195     }
196
197     @Test
198     void testDeclareAttributes() {
199         service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
200         service.setLastUpdaterUserId(USER_ID);
201         final ComponentInstOutputsMap componentInstOutputsMap = new ComponentInstOutputsMap();
202         final Map<String, List<ComponentInstanceAttribOutput>> propertiesForDeclaration = new HashMap<>();
203         propertiesForDeclaration.put(COMPONENT_ID, getPropertiesListForDeclaration());
204
205         final List<OutputDefinition> declaredPropertiesToOutputs = getDeclaredProperties();
206         initMockitoStubbings(declaredPropertiesToOutputs);
207
208         final Either<List<OutputDefinition>, ResponseFormat> declaredPropertiesEither =
209             testInstance.declareAttributes(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, componentInstOutputsMap);
210
211         assertThat(declaredPropertiesEither.isLeft()).isTrue();
212
213         final List<OutputDefinition> declaredProperties = declaredPropertiesEither.left().value();
214         assertThat(CollectionUtils.isNotEmpty(declaredProperties)).isTrue();
215         assertEquals(1, declaredProperties.size());
216         assertEquals(declaredProperties, declaredPropertiesToOutputs);
217     }
218
219     @Test
220     void testDeclareAttributes_fail() {
221         service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
222         service.setLastUpdaterUserId(USER_ID);
223         final ComponentInstOutputsMap componentInstOutputsMap = new ComponentInstOutputsMap();
224         final Map<String, List<ComponentInstanceAttribOutput>> propertiesForDeclaration = new HashMap<>();
225         propertiesForDeclaration.put(COMPONENT_ID, getPropertiesListForDeclaration());
226
227         final List<OutputDefinition> declaredPropertiesToOutputs = getDeclaredProperties();
228         initMockitoStubbings(declaredPropertiesToOutputs);
229         when(attributeDeclarationOrchestrator.declareAttributesToOutputs(any(), any())).thenThrow(ByResponseFormatComponentException.class);
230         final Either<List<OutputDefinition>, ResponseFormat> declaredPropertiesEither =
231             testInstance.declareAttributes(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, componentInstOutputsMap);
232
233         assertThat(declaredPropertiesEither.isRight()).isTrue();
234
235     }
236
237     private void initMockitoStubbings(List<OutputDefinition> declaredPropertiesToOutputs) {
238         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(
239             Either.left(service));
240         when(attributeDeclarationOrchestrator.declareAttributesToOutputs(any(), any())).thenReturn(Either.left(
241             declaredPropertiesToOutputs));
242         when(toscaOperationFacadeMock.addOutputsToComponent(any(), any())).thenReturn(Either.left(declaredPropertiesToOutputs));
243         when(janusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK);
244         when(graphLockOperation.lockComponent(any(), any())).thenReturn(StorageOperationStatus.OK);
245         when(graphLockOperation.unlockComponent(any(), any())).thenReturn(StorageOperationStatus.OK);
246     }
247
248     private void getComponents_emptyOutputs(Service service) {
249         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(Either.left(service));
250         final Either<List<ComponentInstanceOutput>, ResponseFormat> componentInstanceOutputs = testInstance
251             .getComponentInstanceOutputs(USER_ID, COMPONENT_ID, COMPONENT_INSTANCE_ID);
252         assertEquals(Collections.emptyList(), componentInstanceOutputs.left().value());
253     }
254
255     private List<ComponentInstanceAttribOutput> getPropertiesListForDeclaration() {
256         return outputsList.stream().map(this::getPropertyForDeclaration).collect(Collectors.toList());
257     }
258
259     private ComponentInstanceAttribOutput getPropertyForDeclaration(ComponentInstanceOutput componentInstanceOutput) {
260         final ComponentInstanceAttribOutput propOutput = new ComponentInstanceAttribOutput();
261         propOutput.setOutput(componentInstanceOutput);
262         propOutput.setAttributesName(componentInstanceOutput.getName());
263
264         return propOutput;
265     }
266
267     private List<OutputDefinition> getDeclaredProperties() {
268         return outputsList.stream().map(OutputDefinition::new).collect(Collectors.toList());
269     }
270
271     private OutputDefinition setUpListOutput() {
272         final OutputDefinition listOutput = new OutputDefinition();
273         listOutput.setName(LISTOUTPUT_NAME);
274         listOutput.setType("list");
275         return listOutput;
276     }
277
278     @Test
279     void test_deleteOutput_listOutput_fail_getComponent() throws Exception {
280         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
281             .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
282         when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND)).thenReturn(ActionStatus.RESOURCE_NOT_FOUND);
283
284         try {
285             testInstance.deleteOutput(COMPONENT_ID, USER_ID, LISTOUTPUT_NAME);
286         } catch (ComponentException e) {
287             assertEquals(ActionStatus.RESOURCE_NOT_FOUND, e.getActionStatus());
288             verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
289             return;
290         }
291         fail();
292     }
293
294     @Test
295     void test_deleteOutput_listOutput_fail_validateOutput() throws Exception {
296         final OutputDefinition listOutput = setUpListOutput();
297         final String outputId = COMPONENT_ID + "." + listOutput.getName();
298         listOutput.setUniqueId(outputId);
299         service.setOutputs(Collections.singletonList(listOutput));
300         final String NONEXIST_OUTPUT_NAME = "myOutput";
301
302         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
303             .thenReturn(Either.left(service));
304
305         try {
306             testInstance.deleteOutput(COMPONENT_ID, USER_ID, NONEXIST_OUTPUT_NAME);
307         } catch (ComponentException e) {
308             assertEquals(ActionStatus.OUTPUT_IS_NOT_CHILD_OF_COMPONENT, e.getActionStatus());
309             verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
310             return;
311         }
312         fail();
313     }
314
315     @Test
316     void test_deleteOutput_listOutput_fail_lockComponent() throws Exception {
317         final OutputDefinition listOutput = setUpListOutput();
318         final String outputId = COMPONENT_ID + "." + listOutput.getName();
319         listOutput.setUniqueId(outputId);
320         service.setOutputs(Collections.singletonList(listOutput));
321
322         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
323             .thenReturn(Either.left(service));
324         when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.NOT_FOUND);
325         when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, ComponentTypeEnum.SERVICE))
326             .thenReturn(ActionStatus.SERVICE_NOT_FOUND);
327
328         try {
329             testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
330         } catch (ComponentException e) {
331             assertEquals(ActionStatus.SERVICE_NOT_FOUND, e.getActionStatus());
332             verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
333             verify(graphLockOperation, times(1)).lockComponent(COMPONENT_ID, NodeTypeEnum.Service);
334             return;
335         }
336         fail();
337     }
338
339     @Test
340     void test_deleteOutput_listOutput_fail_deleteOutput() throws Exception {
341         final OutputDefinition listOutput = setUpListOutput();
342         final String outputId = COMPONENT_ID + "." + listOutput.getName();
343         listOutput.setUniqueId(outputId);
344         service.setOutputs(Collections.singletonList(listOutput));
345
346         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
347             .thenReturn(Either.left(service));
348         when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK);
349         when(toscaOperationFacadeMock.deleteOutputOfResource(service, listOutput.getName())).thenReturn(StorageOperationStatus.BAD_REQUEST);
350         when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST)).thenReturn(ActionStatus.INVALID_CONTENT);
351
352         try {
353             testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
354         } catch (ComponentException e) {
355             assertEquals(ActionStatus.INVALID_CONTENT, e.getActionStatus());
356             verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
357             verify(graphLockOperation, times(1)).lockComponent(COMPONENT_ID, NodeTypeEnum.Service);
358             verify(toscaOperationFacadeMock, times(1)).deleteOutputOfResource(service, listOutput.getName());
359             return;
360         }
361         fail();
362     }
363
364     @Test
365     void test_deleteOutput_output_fail_unDeclare() throws Exception {
366         final OutputDefinition listOutput = setUpListOutput();
367         final String outputId = COMPONENT_ID + "." + listOutput.getName();
368         listOutput.setUniqueId(outputId);
369         service.setOutputs(Collections.singletonList(listOutput));
370
371         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
372             .thenReturn(Either.left(service));
373         when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK);
374         when(toscaOperationFacadeMock.deleteOutputOfResource(service, listOutput.getName())).thenReturn(StorageOperationStatus.OK);
375         when(attributeDeclarationOrchestrator.unDeclareAttributesAsOutputs(service, listOutput)).thenReturn(StorageOperationStatus.BAD_REQUEST);
376         when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST)).thenReturn(ActionStatus.INVALID_CONTENT);
377
378         try {
379             testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
380         } catch (ComponentException e) {
381             assertEquals(ActionStatus.INVALID_CONTENT, e.getActionStatus());
382             verify(attributeDeclarationOrchestrator, times(1)).unDeclareAttributesAsOutputs(service, listOutput);
383             return;
384         }
385         fail();
386     }
387
388     @Test
389     void test_deleteOutput_output_success() throws Exception {
390         final OutputDefinition listOutput = setUpListOutput();
391         final String outputId = COMPONENT_ID + "." + listOutput.getName();
392         listOutput.setUniqueId(outputId);
393         service.setOutputs(Collections.singletonList(listOutput));
394
395         when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
396             .thenReturn(Either.left(service));
397         when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK);
398         when(toscaOperationFacadeMock.deleteOutputOfResource(service, listOutput.getName())).thenReturn(StorageOperationStatus.OK);
399         when(attributeDeclarationOrchestrator.unDeclareAttributesAsOutputs(service, listOutput)).thenReturn(StorageOperationStatus.OK);
400
401         testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
402         verify(attributeDeclarationOrchestrator, times(1)).unDeclareAttributesAsOutputs(service, listOutput);
403     }
404
405 }