Service Import - Node Template Interface Definitions
[sdc.git] / integration-tests / src / test / java / org / onap / sdc / frontend / ci / tests / execute / sanity / ImportVfcUiTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation
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  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19 package org.onap.sdc.frontend.ci.tests.execute.sanity;
20
21 import static org.hamcrest.MatcherAssert.assertThat;
22 import static org.hamcrest.Matchers.empty;
23 import static org.hamcrest.Matchers.emptyString;
24 import static org.hamcrest.Matchers.not;
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertFalse;
27 import static org.junit.jupiter.api.Assertions.assertNotNull;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.junit.jupiter.api.Assertions.fail;
30
31 import com.aventstack.extentreports.Status;
32 import java.util.Arrays;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Optional;
36 import org.apache.commons.collections.MapUtils;
37 import org.onap.sdc.backend.ci.tests.datatypes.enums.ComponentType;
38 import org.onap.sdc.backend.ci.tests.datatypes.enums.ResourceCategoryEnum;
39 import org.onap.sdc.backend.ci.tests.utils.general.ElementFactory;
40 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
41 import org.onap.sdc.frontend.ci.tests.datatypes.ModelName;
42 import org.onap.sdc.frontend.ci.tests.datatypes.ResourceCreateData;
43 import org.onap.sdc.frontend.ci.tests.exception.UnzipException;
44 import org.onap.sdc.frontend.ci.tests.execute.setup.DriverFactory;
45 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
46 import org.onap.sdc.frontend.ci.tests.execute.setup.SetupCDTest;
47 import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
48 import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
49 import org.onap.sdc.frontend.ci.tests.flow.CreateVfcFlow;
50 import org.onap.sdc.frontend.ci.tests.flow.DownloadCsarArtifactFlow;
51 import org.onap.sdc.frontend.ci.tests.flow.GoToInterfaceDefinitionPageFlow;
52 import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
53 import org.onap.sdc.frontend.ci.tests.pages.AttributeModal;
54 import org.onap.sdc.frontend.ci.tests.pages.AttributesPage;
55 import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
56 import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
57 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent;
58 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent.CompositionDetailTabName;
59 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInformationTab;
60 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsTab;
61 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
62 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal;
63 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
64 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionPage;
65 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
66 import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
67 import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
68 import org.openecomp.sdc.be.model.ComponentInstance;
69 import org.openqa.selenium.WebDriver;
70 import org.testng.annotations.BeforeClass;
71 import org.testng.annotations.Test;
72 import org.yaml.snakeyaml.Yaml;
73
74 public class ImportVfcUiTest extends SetupCDTest {
75
76     private String filePath;
77     private WebDriver webDriver;
78     private HomePage homePage;
79     private ResourceCreateData vfcCreateData;
80     private ResourceCreateData vfCreateData;
81     private ComponentInstance createdComponentInstance;
82     private final String vfcCategory = ResourceCategoryEnum.NETWORK_L4.getSubCategory();
83
84     @BeforeClass
85     public void beforeClass() {
86         filePath = FileHandling.getFilePath("VFCs/");
87         webDriver = DriverFactory.getDriver();
88         homePage = new HomePage(webDriver);
89     }
90
91     @Test
92     public void importVFC_createVF_addVFC2VF_test() throws UnzipException {
93         ComponentPage componentPage;
94         // TC - Import VFC with root namespace
95         String fileName = "org.openecomp.resource.VFC-root.yml";
96         CreateVfcFlow createVfcFlow = createVFC(fileName, ModelName.DEFAULT_MODEL_NAME.getName(), vfcCategory);
97
98         componentPage = createVfcFlow.getLandedPage().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
99         componentPage.isLoaded();
100         componentPage.certifyComponent();
101         componentPage.isLoaded();
102
103         Map<String, Object> yamlObject = downloadToscaArtifact(componentPage);
104         checkMetadata(yamlObject, vfcCreateData);
105         checkNodeTypes(yamlObject);
106         homePage.getTopNavComponent().clickOnHome();
107
108         // TC - Import hierarchy of VFCs
109         fileName = "org.openecomp.resource.VFC-child.yml";
110         createVfcFlow = createVFC(fileName, ModelName.DEFAULT_MODEL_NAME.getName(), vfcCategory);
111         componentPage = createVfcFlow.getLandedPage().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
112         componentPage.isLoaded();
113
114         componentPage = manageAttributes(componentPage);
115         componentPage.isLoaded();
116         componentPage.certifyComponent();
117         componentPage.isLoaded();
118
119         yamlObject = downloadToscaArtifact(componentPage);
120         checkMetadata(yamlObject, vfcCreateData);
121         checkNodeTypes(yamlObject);
122
123         componentPage = viewInterfaceDefinitionFromVFC(componentPage);
124         componentPage.isLoaded();
125
126         homePage.getTopNavComponent().clickOnHome();
127
128         // TC - Import VFC with interface inputs
129         // TC - Import VFC with attributes
130         final CreateVfFlow createVfFlow = createVF();
131         componentPage = createVfFlow.getLandedPage().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
132         componentPage.isLoaded();
133
134         final CompositionPage compositionPage = addInterfaceOperations(componentPage);
135         componentPage = compositionPage.goToGeneral();
136         componentPage.isLoaded();
137         componentPage.certifyComponent();
138         componentPage.isLoaded();
139
140         yamlObject = downloadToscaArtifact(componentPage);
141         checkMetadata(yamlObject, vfCreateData);
142         checkTopologyTemplate(yamlObject);
143
144     }
145
146     private ComponentPage viewInterfaceDefinitionFromVFC(final ComponentPage componentPage) {
147         final GoToInterfaceDefinitionPageFlow goToInterfaceDefinitionPageFlow = new GoToInterfaceDefinitionPageFlow(webDriver);
148         goToInterfaceDefinitionPageFlow.run(componentPage);
149         final InterfaceDefinitionPage interfaceDefinitionPage = goToInterfaceDefinitionPageFlow.getLandedPage()
150             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return InterfaceDefinitionPage"));
151         final var operationName = "create";
152         assertTrue(interfaceDefinitionPage.isInterfaceDefinitionOperationPresent(operationName));
153         final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal =
154             interfaceDefinitionPage.clickOnInterfaceDefinitionOperation(operationName);
155         interfaceDefinitionOperationsModal.isLoaded(true);
156         ExtentTestActions
157             .takeScreenshot(Status.INFO, "clickOnOInterfaceOperation", "Interface Definition Operation Modal opened");
158         checkInterfaceDefinitionData(interfaceDefinitionOperationsModal);
159         interfaceDefinitionOperationsModal.clickOnCancel();
160         return interfaceDefinitionPage;
161     }
162
163     @Test
164     public void importVfcWithModel() {
165         final String fileName = "VFC-For-Model.yaml";
166         final CreateVfcFlow createVfcFlow = createVFC(fileName, ModelName.ETSI_SOL001_v2_5_1.getName(), vfcCategory);
167         final ComponentPage componentPage = createVfcFlow.getLandedPage()
168             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
169         componentPage.isLoaded();
170         componentPage.certifyComponent();
171         componentPage.isLoaded();
172     }
173
174     private void checkInterfaceDefinitionData(final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal) {
175         assertFalse(interfaceDefinitionOperationsModal.getDescription().isEmpty());
176         assertEquals("path/to/my/implementation.sh", interfaceDefinitionOperationsModal.getImplementationName());
177         final List<InputData> inputList = interfaceDefinitionOperationsModal.getInputs();
178         assertTrue(inputList.stream().anyMatch(inputData -> "first".equals(inputData.getName())), "Input of name 'first' expected");
179     }
180
181     private ComponentPage manageAttributes(final ComponentPage componentPage) {
182         final AttributesPage attributesPage = componentPage.goToAttributes();
183         attributesPage.isLoaded();
184
185         assertTrue(attributesPage.isAttributePresent("test_1"));
186         assertTrue(attributesPage.isAttributePresent("test_2"));
187         assertTrue(attributesPage.isAttributePresent("test_3"));
188         assertTrue(attributesPage.isAttributePresent("test_4"));
189
190         attributesPage.deleteAttribute("test_2");
191         assertFalse(attributesPage.isAttributePresent("test_2"));
192         ExtentTestActions.takeScreenshot(Status.INFO, "attributesPage.deleteAttribute", "Attribute 'test_2' successfully deleted");
193         attributesPage.addAttribute(new AttributeModal.AttributeData("test_9", "Additional attribute added from UI", "string", "one More Attribute"));
194         attributesPage.isLoaded();
195         assertTrue(attributesPage.isAttributePresent("test_9"));
196         ExtentTestActions.takeScreenshot(Status.INFO, "attributesPage.addAttribute", "Additional Attribute 'test_9' successfully added");
197
198         attributesPage.editAttribute(new AttributeModal.AttributeData("test_9", "Additional attribute added from UI".toUpperCase(), "string",
199             "one More Attribute".toUpperCase()));
200         attributesPage.isLoaded();
201         assertTrue(attributesPage.isAttributePresent("test_9"));
202         ExtentTestActions.takeScreenshot(Status.INFO, "attributesPage.editAttribute", "Additional Attribute 'test_9' successfully altered");
203
204         return attributesPage.clickOnGeneralMenuItem(ResourceCreatePage.class);
205     }
206
207     private CompositionPage addInterfaceOperations(final ComponentPage componentPage) {
208         final AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToCompositionFlow(componentPage);
209         final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
210             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
211         final CompositionDetailSideBarComponent detailSideBar = compositionPage.getDetailSideBar();
212         detailSideBar.isLoaded();
213
214         createdComponentInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
215             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ComponentInstance"));
216
217         compositionPage.selectNode(createdComponentInstance.getName());
218
219         CompositionInterfaceOperationsTab compositionInterfaceOperationsTab =
220             (CompositionInterfaceOperationsTab) detailSideBar.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
221         compositionInterfaceOperationsTab.isLoaded();
222         ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab", "Composition Interface Operations Tab opened");
223         assertTrue(compositionInterfaceOperationsTab.isOperationPresent("create"));
224         InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
225         compositionInterfaceOperationsModal.isLoaded();
226         ExtentTestActions
227             .takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
228         compositionInterfaceOperationsModal.deleteInput("first");
229         ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.clickOnDelete", "Input deleted");
230
231         List<InputData> inputDataList = List.of(
232             new InputData("stringInput", "string", "1"),
233             new InputData("booleanInput", "boolean", true),
234             new InputData("integerInput", "integer", 1)
235         );
236         final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData =
237             new InterfaceDefinitionOperationsModal.InterfaceOperationsData(
238                 "This is CREATE operation", "fullPath/to/my/newImplementation.sh", inputDataList
239             );
240         compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData);
241         compositionInterfaceOperationsTab.isLoaded();
242
243         final CompositionInformationTab compositionInformationTab =
244             (CompositionInformationTab) detailSideBar.selectTab(CompositionDetailTabName.INFORMATION);
245         compositionInformationTab.isLoaded();
246
247         compositionInterfaceOperationsTab =
248             (CompositionInterfaceOperationsTab) detailSideBar.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
249         compositionInterfaceOperationsTab.isLoaded();
250
251         assertTrue(compositionInterfaceOperationsTab.isOperationPresent("create"));
252         assertTrue(compositionInterfaceOperationsTab.isDescriptionPresent());
253         ExtentTestActions.takeScreenshot(Status.INFO, "isDescriptionPresent", "Description is present");
254         compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
255         compositionInterfaceOperationsModal.isLoaded();
256         ExtentTestActions
257             .takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
258
259         checkCompositionInterfaceOperations(compositionInterfaceOperationsModal, interfaceOperationsData);
260         compositionInterfaceOperationsModal.clickOnCancel();
261         compositionInterfaceOperationsTab.isLoaded();
262         return compositionPage;
263     }
264
265     private AddNodeToCompositionFlow addNodeToCompositionFlow(final ComponentPage componentPage) {
266         componentPage.isLoaded();
267         final ComponentData parentComponent = new ComponentData();
268         parentComponent.setName(vfCreateData.getName());
269         parentComponent.setVersion("0.1");
270         parentComponent.setComponentType(ComponentType.RESOURCE);
271         final ComponentData componentToAdd = new ComponentData();
272         componentToAdd.setName(vfcCreateData.getName());
273         componentToAdd.setVersion("1.0");
274         componentToAdd.setComponentType(ComponentType.RESOURCE);
275         final AddNodeToCompositionFlow addNodeToCompositionFlow = new AddNodeToCompositionFlow(webDriver, parentComponent, componentToAdd);
276         addNodeToCompositionFlow.run(componentPage.goToComposition());
277         return addNodeToCompositionFlow;
278     }
279
280     private Map<String, Object> downloadToscaArtifact(final ComponentPage componentPage) throws UnzipException {
281         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = downloadCsarArtifact(componentPage);
282         final ToscaArtifactsPage toscaArtifactsPage = downloadCsarArtifactFlow.getLandedPage()
283             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
284
285         assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
286         final String downloadedCsarName = toscaArtifactsPage.getDownloadedArtifactList().get(0);
287         final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
288         final Map<String, byte[]> filesFromZip = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
289         final Optional<String> resourceEntryOpt = filesFromZip.keySet().stream()
290             .filter(s -> s.equals("Definitions/" + downloadedCsarName.replace("-csar.csar", "-template.yml")))
291             .findFirst();
292         if (resourceEntryOpt.isEmpty()) {
293             fail("Could not find the resource package in Definitions");
294         }
295         return loadYamlObject(filesFromZip.get(resourceEntryOpt.get()));
296     }
297
298     private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
299         try {
300             return (Map<String, Object>) yamlObj.get(entryName);
301         } catch (final Exception e) {
302             final String errorMsg = String.format("Could not get the '%s' entry.", entryName);
303             fail(errorMsg + "Error message: " + e.getMessage());
304         }
305         return null;
306     }
307
308     private Map<String, Object> loadYamlObject(final byte[] mainDefinitionFileBytes) {
309         return new Yaml().load(new String(mainDefinitionFileBytes));
310     }
311
312     private DownloadCsarArtifactFlow downloadCsarArtifact(final ComponentPage componentPage) {
313         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = new DownloadCsarArtifactFlow(webDriver);
314         downloadCsarArtifactFlow.setWaitBeforeGetTheFile(5L);
315         downloadCsarArtifactFlow.run(componentPage);
316         return downloadCsarArtifactFlow;
317     }
318
319     private CreateVfcFlow createVFC(final String fileName, final String model, final String category) {
320         vfcCreateData = createVfcFormData(model, category);
321         final CreateVfcFlow createVfcFlow = new CreateVfcFlow(webDriver, vfcCreateData, filePath + fileName);
322         createVfcFlow.run(homePage);
323         return createVfcFlow;
324     }
325
326     private CreateVfFlow createVF() {
327         vfCreateData = createVfFormData();
328         final CreateVfFlow createVfFlow = new CreateVfFlow(webDriver, vfCreateData);
329         createVfFlow.run(homePage);
330         return createVfFlow;
331     }
332
333     private ResourceCreateData createVfcFormData(final String model, final String category) {
334         final ResourceCreateData vfcCreateData = new ResourceCreateData();
335         vfcCreateData.setRandomName(ElementFactory.getResourcePrefix() + "-VFC");
336         vfcCreateData.setModel(model);
337         vfcCreateData.setCategory(category);
338         vfcCreateData.setTagList(Arrays.asList(vfcCreateData.getName(), "importVFC"));
339         vfcCreateData.setDescription("aDescription");
340         vfcCreateData.setVendorName("Ericsson");
341         vfcCreateData.setVendorRelease("1.2.3");
342         vfcCreateData.setVendorModelNumber("4.5.6");
343         return vfcCreateData;
344     }
345
346     private ResourceCreateData createVfFormData() {
347         final ResourceCreateData vfCreateData = new ResourceCreateData();
348         vfCreateData.setRandomName(ElementFactory.getResourcePrefix() + "-VF");
349         vfCreateData.setCategory(ResourceCategoryEnum.NETWORK_L4.getSubCategory());
350         vfCreateData.setTagList(Arrays.asList(vfCreateData.getName(), "createVF"));
351         vfCreateData.setDescription("aDescription");
352         vfCreateData.setVendorName("Ericsson");
353         vfCreateData.setVendorRelease("6.5.4");
354         vfCreateData.setVendorModelNumber("3.2.1");
355         return vfCreateData;
356     }
357
358     private void checkMetadata(final Map<String, Object> map, final ResourceCreateData createdData) {
359         final Map<String, Object> metadata = getMapEntry(map, "metadata");
360
361         assertEquals(createdData.getName(), metadata.get("name"));
362         assertEquals(createdData.getDescription(), metadata.get("description"));
363         assertEquals("Network L4+", metadata.get("category"));
364         assertThat((String) metadata.get("type"), not(emptyString()));
365         assertEquals(createdData.getCategory(), metadata.get("subcategory"));
366         assertEquals(createdData.getVendorName(), metadata.get("resourceVendor"));
367         assertEquals(createdData.getVendorRelease(), metadata.get("resourceVendorRelease"));
368         assertEquals(createdData.getVendorModelNumber(), metadata.get("reourceVendorModelNumber"));
369     }
370
371     private void checkNodeTypes(final Map<String, Object> map) {
372         final Map<String, Object> mapEntry = getMapEntry(map, "node_types");
373         final Map<String, Object> nodeTypes = getMapEntry(mapEntry, mapEntry.keySet().iterator().next());
374
375         assertFalse(MapUtils.isEmpty(nodeTypes));
376         assertEquals("aDescription", nodeTypes.get("description"));
377
378         final Map<String, Object> properties = getMapEntry(nodeTypes, "properties");
379         assertFalse(MapUtils.isEmpty(properties));
380
381         final Map<String, Object> attributes = getMapEntry(nodeTypes, "attributes");
382         assertFalse(MapUtils.isEmpty(attributes));
383
384         final Map<String, Object> interfaces = getMapEntry(nodeTypes, "interfaces");
385         assertFalse(MapUtils.isEmpty(interfaces));
386
387     }
388
389     private void checkTopologyTemplate(final Map<String, Object> map) {
390         final Map<String, Object> topologyTemplate = getMapEntry(map, "topology_template");
391         assertNotNull(topologyTemplate);
392
393         final Map<String, Object> inputs = getMapEntry(topologyTemplate, "inputs");
394         assertFalse(MapUtils.isEmpty(inputs));
395
396         final Map<String, Object> nodeTemplates = getMapEntry(topologyTemplate, "node_templates");
397         assertFalse(MapUtils.isEmpty(nodeTemplates));
398
399         final Map<String, Object> attributes = getMapEntry((Map<String, Object>) nodeTemplates.get(createdComponentInstance.getName()), "attributes");
400         assertTrue(MapUtils.isEmpty(attributes));
401
402         final Map<String, Object> substitutionMappings = getMapEntry(topologyTemplate, "substitution_mappings");
403         assertFalse(MapUtils.isEmpty(substitutionMappings));
404
405     }
406
407     private void checkCompositionInterfaceOperations(final InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal,
408                                                      final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
409         assertEquals(interfaceOperationsData.getDescription(), compositionInterfaceOperationsModal.getDescription());
410         assertEquals(interfaceOperationsData.getImplementationName(), compositionInterfaceOperationsModal.getImplementationName());
411         interfaceOperationsData.getInputList().forEach(inputData -> {
412             final boolean hasInput = compositionInterfaceOperationsModal.getInputs().stream()
413                 .anyMatch(inputData1 -> inputData1.getName().equals(inputData.getName()));
414             assertTrue(hasInput, String.format("Expecting input '%s'", inputData.getName()));
415         });
416     }
417 }