ee453bf221de47a9df532ca188ff1f18c37a9cda
[sdc.git] /
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
20 package org.onap.sdc.frontend.ci.tests.execute.sanity;
21
22 import static org.hamcrest.MatcherAssert.assertThat;
23 import static org.hamcrest.Matchers.empty;
24 import static org.hamcrest.Matchers.hasSize;
25 import static org.hamcrest.Matchers.is;
26 import static org.hamcrest.Matchers.not;
27 import static org.hamcrest.Matchers.notNullValue;
28 import static org.junit.jupiter.api.Assertions.fail;
29
30 import com.aventstack.extentreports.Status;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Map.Entry;
36 import java.util.stream.Collectors;
37 import org.onap.sdc.backend.ci.tests.data.providers.OnboardingDataProviders;
38 import org.onap.sdc.backend.ci.tests.datatypes.enums.ComponentType;
39 import org.onap.sdc.backend.ci.tests.datatypes.enums.ResourceCategoryEnum;
40 import org.onap.sdc.backend.ci.tests.utils.general.ElementFactory;
41 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
42 import org.onap.sdc.frontend.ci.tests.datatypes.ResourceCreateData;
43 import org.onap.sdc.frontend.ci.tests.datatypes.composition.RelationshipInformation;
44 import org.onap.sdc.frontend.ci.tests.exception.UnzipException;
45 import org.onap.sdc.frontend.ci.tests.execute.setup.DriverFactory;
46 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
47 import org.onap.sdc.frontend.ci.tests.execute.setup.SetupCDTest;
48 import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
49 import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
50 import org.onap.sdc.frontend.ci.tests.flow.CreateVfcFlow;
51 import org.onap.sdc.frontend.ci.tests.flow.DownloadToscaCsarFlow;
52 import org.onap.sdc.frontend.ci.tests.flow.composition.CreateRelationshipFlow;
53 import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
54 import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
55 import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
56 import org.onap.sdc.frontend.ci.tests.pages.TopNavComponent;
57 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
58 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
59 import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
60 import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
61 import org.openecomp.sdc.be.model.ComponentInstance;
62 import org.openqa.selenium.WebDriver;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65 import org.testng.annotations.BeforeMethod;
66 import org.testng.annotations.Test;
67 import org.yaml.snakeyaml.Yaml;
68
69 public class ServiceTemplateDesignUiTests extends SetupCDTest {
70
71     private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTemplateDesignUiTests.class);
72
73     private WebDriver webDriver;
74     private TopNavComponent topNavComponent;
75     private HomePage homePage;
76     private List<ResourceCreateData> vfcs = new ArrayList<>();
77     private ResourceCreateData vfResourceCreateData;
78     private ComponentInstance networkFunctionInstance;
79     private ComponentInstance networkServiceInstance;
80
81     @BeforeMethod
82     public void init() {
83         webDriver = DriverFactory.getDriver();
84         topNavComponent = new TopNavComponent(webDriver);
85         homePage = new HomePage(webDriver);
86     }
87
88     @Test(dataProviderClass = OnboardingDataProviders.class, dataProvider = "vfcList")
89     public void importAndCertifyVfc(final String rootFolder, final String vfcFilename) {
90         setLog(vfcFilename);
91         final String resourceName = ElementFactory.addRandomSuffixToName(ElementFactory.getResourcePrefix());
92         final CreateVfcFlow createVfcFlow = createVFC(rootFolder + vfcFilename, resourceName);
93         vfcs.stream().filter(vfc -> vfc.getName().startsWith(resourceName)).findFirst().orElseThrow(
94             () -> new UiTestFlowRuntimeException(String.format("VFCs List should contain a VFC with the expected name %s", resourceName)));
95         final ResourceCreatePage vfcResourceCreatePage = createVfcFlow.getLandedPage()
96             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ResourceCreatePage"));
97         vfcResourceCreatePage.isLoaded();
98         vfcResourceCreatePage.certifyComponent();
99         ExtentTestActions.takeScreenshot(Status.INFO, "vfc-certified",
100             String.format("VFC '%s' was certified", resourceName));
101     }
102
103     @Test(dependsOnMethods = "importAndCertifyVfc")
104     public void runServiceDesign() throws UnzipException {
105         final CreateVfFlow createVfFlow = createVF();
106         final AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToCompositionAndCreateRelationship(createVfFlow);
107         final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
108             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
109         compositionPage.isLoaded();
110         final ComponentPage componentPage = compositionPage.goToGeneral();
111         componentPage.isLoaded();
112         downloadAndVerifyCsarPackage(componentPage);
113     }
114
115     private CreateVfFlow createVF() {
116         final ResourceCreateData vfCreateData = createVfFormData();
117         final CreateVfFlow createVfFlow = new CreateVfFlow(webDriver, vfCreateData);
118         createVfFlow.run(homePage);
119         return createVfFlow;
120     }
121
122     private ResourceCreateData createVfFormData() {
123         vfResourceCreateData = new ResourceCreateData();
124         vfResourceCreateData.setRandomName(ElementFactory.getResourcePrefix() + "-VF");
125         vfResourceCreateData.setCategory(ResourceCategoryEnum.GENERIC_ABSTRACT.getSubCategory());
126         vfResourceCreateData.setTagList(Arrays.asList(vfResourceCreateData.getName(), "createVF"));
127         vfResourceCreateData.setDescription("aDescription");
128         vfResourceCreateData.setVendorName("EST");
129         vfResourceCreateData.setVendorRelease("4.1.1");
130         vfResourceCreateData.setVendorModelNumber("0001");
131         return vfResourceCreateData;
132     }
133
134     private CreateVfcFlow createVFC(final String vfcFullFilename, final String resourceName) {
135         final ResourceCreateData vfcCreateData = createVfcFormData(resourceName);
136         final CreateVfcFlow createVfcFlow = new CreateVfcFlow(webDriver, vfcCreateData, vfcFullFilename);
137         createVfcFlow.run(homePage);
138         ExtentTestActions.takeScreenshot(Status.INFO, "vfc-created", String.format("VFC '%s' was created", resourceName));
139         assertThat(vfcs, notNullValue());
140         vfcs.add(vfcCreateData);
141         return createVfcFlow;
142     }
143
144     private ResourceCreateData createVfcFormData(final String resourceName) {
145         final ResourceCreateData vfcCreateData = new ResourceCreateData();
146         vfcCreateData.setRandomName(resourceName);
147         vfcCreateData.setCategory(ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS.getSubCategory());
148         vfcCreateData.setTagList(Arrays.asList(vfcCreateData.getName(), "importVFC"));
149         vfcCreateData.setDescription("aDescription");
150         vfcCreateData.setVendorName("EST");
151         vfcCreateData.setVendorRelease("4.1.1");
152         vfcCreateData.setVendorModelNumber("0001");
153         return vfcCreateData;
154     }
155
156     private AddNodeToCompositionFlow addNodeToCompositionAndCreateRelationship(final CreateVfFlow createVfFlow) {
157         final ResourceCreatePage resourceCreatePage = createVfFlow.getLandedPage()
158             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ResourceCreatePage"));
159         resourceCreatePage.isLoaded();
160         assertThat(vfcs, hasSize(2));
161         final ComponentData parentComponent = new ComponentData();
162         parentComponent.setName(vfResourceCreateData.getName());
163         parentComponent.setVersion("0.1");
164         parentComponent.setComponentType(ComponentType.RESOURCE);
165
166         // Adds networkFunction to VF composition
167         final ComponentData networkFunction = new ComponentData();
168         networkFunction.setName(vfcs.get(0).getName());
169         networkFunction.setVersion("1.0");
170         networkFunction.setComponentType(ComponentType.RESOURCE);
171         CompositionPage compositionPage = resourceCreatePage.goToComposition();
172         compositionPage.isLoaded();
173         AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToComposition(parentComponent, networkFunction, compositionPage);
174         networkFunctionInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
175             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
176
177         // Adds networkService to VF composition
178         final ComponentData networkService = new ComponentData();
179         networkService.setName(vfcs.get(1).getName());
180         networkService.setVersion("1.0");
181         networkService.setComponentType(ComponentType.RESOURCE);
182         addNodeToCompositionFlow = addNodeToComposition(parentComponent, networkService, compositionPage);
183         networkServiceInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
184             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
185
186         // Creates a dependsOn relationship from networkServiceInstance to networkFunctionInstance
187         createRelationship(compositionPage, networkFunctionInstance.getName(), "tosca.capabilities.Node",
188             networkServiceInstance.getName(), "tosca.capabilities.Node");
189
190         return addNodeToCompositionFlow;
191     }
192
193     public AddNodeToCompositionFlow addNodeToComposition(final ComponentData parentComponent,
194                                                          final ComponentData resourceToAdd,
195                                                          CompositionPage compositionPage) {
196         final AddNodeToCompositionFlow addNodeToCompositionFlow = new AddNodeToCompositionFlow(webDriver, parentComponent, resourceToAdd);
197         compositionPage = (CompositionPage) addNodeToCompositionFlow.run(compositionPage)
198             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected CompositionPage"));
199         compositionPage.isLoaded();
200         ExtentTestActions.takeScreenshot(Status.INFO, "node-added-to-composition",
201             String.format("Resource '%s' was added to composition", resourceToAdd.getName()));
202         return addNodeToCompositionFlow;
203     }
204
205     /**
206      * Creates a DependsOn relationship between the imported VFCs
207      * @param compositionPage Composition Page
208      * @param fromComponentInstanceName VFC - Network Function
209      * @param fromCapability Node Capability
210      * @param toComponentInstanceName  VFC - Network Service
211      * @param toRequirement Node Requirement
212      */
213     private void createRelationship(final CompositionPage compositionPage, final String fromComponentInstanceName,
214                                     final String fromCapability, final String toComponentInstanceName, final String toRequirement) {
215         final RelationshipInformation relationshipInformation =
216             new RelationshipInformation(fromComponentInstanceName, fromCapability, toComponentInstanceName, toRequirement);
217         CreateRelationshipFlow createRelationshipFlow = new CreateRelationshipFlow(webDriver, relationshipInformation);
218         createRelationshipFlow.run(compositionPage).orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a CompositionPage instance"));
219         ExtentTestActions.takeScreenshot(Status.INFO, "relationship",
220             String.format("Relationship from networkFunctionInstance '%s' to networkServiceInstanceResource '%s' was created",
221                 fromComponentInstanceName, toComponentInstanceName));
222     }
223
224     private void downloadAndVerifyCsarPackage(final ComponentPage componentPage) throws UnzipException {
225         final DownloadToscaCsarFlow downloadToscaCsarFlow = downloadToscaCsar(componentPage);
226         final ToscaArtifactsPage toscaArtifactsPage = downloadToscaCsarFlow.getLandedPage()
227             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
228         assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
229         final String downloadedCsarName = toscaArtifactsPage.getDownloadedArtifactList().get(0);
230         checkCsarPackage(vfResourceCreateData.getName(), downloadedCsarName);
231     }
232
233     /**
234      * Download the generated package
235      *
236      * @return DownloadToscaCsarFlow
237      */
238     private DownloadToscaCsarFlow downloadToscaCsar(final ComponentPage componentPage) {
239         final DownloadToscaCsarFlow downloadToscaCsarFlow = new DownloadToscaCsarFlow(webDriver);
240         downloadToscaCsarFlow.run(componentPage);
241         return downloadToscaCsarFlow;
242     }
243
244     /**
245      * Checks if the downloaded Tosca csar includes the node templates for the added VFCs,
246      * the generated service template declared “tosca_simple_yaml_1_3” as its Tosca version,
247      * the generated csar contains the node type definitions for the added VFCs in the Definitions directory,
248      * the interface template contains the relationship declaration
249      * @param vfResourceName VF created
250      * @param downloadedCsarName download Tosca CSAR filename
251      * @throws UnzipException
252      */
253     private void checkCsarPackage(final String vfResourceName, final String downloadedCsarName) throws UnzipException {
254         final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
255         final Map<String, byte[]> filesFromZip = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
256         final String virtualFunctionName = vfResourceName.replace("-", "").toLowerCase();
257         final List<String> expectedDefinitionFolderFileList = getExpectedDefinitionFolderFileList(virtualFunctionName);
258         final Map<String, byte[]> expectedFilesFromZipMap = filesFromZip.entrySet().parallelStream().filter(key -> expectedDefinitionFolderFileList.stream()
259             .anyMatch(filename -> filename.equalsIgnoreCase(key.getKey()))).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
260         final String vfResourceTemplateFile = "Definitions/resource-"+ virtualFunctionName +"-template.yml";
261         final String generatedTemplateFile = expectedFilesFromZipMap.keySet().stream()
262             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
263             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
264         final byte[] toscaTemplateGenerated = filesFromZip.get(generatedTemplateFile);
265         assertThat(toscaTemplateGenerated, is(notNullValue()));
266         verifyGeneratedTemplate(toscaTemplateGenerated, generatedTemplateFile);
267         verifyNodesRelationship(expectedFilesFromZipMap, virtualFunctionName, filesFromZip);
268     }
269
270     private void verifyGeneratedTemplate(final byte[] generatedTemplateData, final String generatedTemplateFile) {
271         final Map<String, Object> templateYamlMap = loadYamlObject(generatedTemplateData);
272         final boolean hasToscaDefinitionVersionEntry = templateYamlMap.containsKey("tosca_definitions_version");
273         assertThat(String.format("'%s' should contain tosca_definitions_version entry", generatedTemplateFile), hasToscaDefinitionVersionEntry, is(true));
274         final String toscaVersion = (String) templateYamlMap.get("tosca_definitions_version");
275         assertThat(String.format("'%s' tosca_definitions_version entry should have tosca_simple_yaml_1_3 value", generatedTemplateFile),
276             toscaVersion.equalsIgnoreCase("tosca_simple_yaml_1_3"));
277         final Map<String, Object> topologyTemplateTosca = getMapEntry(templateYamlMap, "topology_template");
278         assertThat(String.format("'%s' should contain a topology_template entry", generatedTemplateFile), topologyTemplateTosca, is(notNullValue()));
279         final Map<String, Object> nodeTemplatesTosca = getMapEntry(topologyTemplateTosca, "node_templates");
280         assertThat(String.format("'%s' should contain a node_templates entry", generatedTemplateFile), nodeTemplatesTosca, is(notNullValue()));
281         final List<String> nodeTemplateFound = nodeTemplatesTosca.keySet().parallelStream().filter(s -> vfcs.stream()
282             .anyMatch(vfc -> s.startsWith(vfc.getName()))).collect(Collectors.toList());
283         assertThat(String.format("'%s' should contain the node type definitions for the added VFCs '%s'", nodeTemplatesTosca, vfcs), nodeTemplateFound, hasSize(vfcs.size()));
284     }
285
286     private void verifyNodesRelationship(final Map<String, byte[]> expectedFilesFromZipMap, final String virtualFunctionName,
287                                          final Map<String, byte[]> filesFromZip) {
288         final String vfResourceTemplateFile = "Definitions/resource-"+ virtualFunctionName +"-template-interface.yml";
289         final String interfaceTemplateFile = expectedFilesFromZipMap.keySet().stream()
290             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
291             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
292         final byte[] toscaInterfaceTemplateGenerated = filesFromZip.get(interfaceTemplateFile);
293         assertThat(toscaInterfaceTemplateGenerated, is(notNullValue()));
294         final Map<String, Object> interfaceTemplateYamlMap = loadYamlObject(toscaInterfaceTemplateGenerated);
295         final Map<String, Object> nodeTypesYamlMap = getMapEntry(interfaceTemplateYamlMap, "node_types");
296         assertThat(String.format("'%s' should contain a node_types entry", interfaceTemplateYamlMap), nodeTypesYamlMap, is(notNullValue()));
297         final String result = Arrays.asList(nodeTypesYamlMap.values()).toString();
298         assertThat(String.format("'%s' should contain a capabilities entry", nodeTypesYamlMap), result.contains("capabilities"), is(true));
299         assertThat(String.format("'%s' should contain a requirements entry", nodeTypesYamlMap), result.contains("requirements"), is(true));
300         assertThat(String.format("'%s' should contain a relationship entry", nodeTypesYamlMap), result.contains("relationship"), is(true));
301         assertThat(String.format("'%s' should contain a DependsOn relationship value", nodeTypesYamlMap),
302             result.contains("tosca.relationships.DependsOn"), is(true));
303     }
304
305     private List<String> getExpectedDefinitionFolderFileList(final String vfResourceName) {
306         final List<String> expectedDefinitionFolderFileList = new ArrayList<>();
307         vfcs.forEach(vfc -> expectedDefinitionFolderFileList.add("Definitions/resource-"+ vfc.getName() +"-template.yml"));
308         expectedDefinitionFolderFileList.add("Definitions/resource-"+ vfResourceName +"-template.yml");
309         expectedDefinitionFolderFileList.add("Definitions/resource-"+ vfResourceName +"-template-interface.yml");
310         return expectedDefinitionFolderFileList;
311     }
312
313     private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
314         try {
315             return (Map<String, Object>) yamlObj.get(entryName);
316         } catch (final Exception e) {
317             final String errorMsg = String.format("Could not get the '%s' entry.", entryName);
318             LOGGER.error(errorMsg, e);
319             fail(errorMsg + "Error message: " + e.getMessage());
320         }
321         return null;
322     }
323
324     private Map<String, Object> loadYamlObject(final byte[] definitionYamlFile) {
325         return new Yaml().load(new String(definitionYamlFile));
326     }
327
328 }