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
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.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.onap.sdc.frontend.ci.tests.execute.sanity;
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;
30 import com.aventstack.extentreports.Status;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.List;
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;
69 public class ServiceTemplateDesignUiTests extends SetupCDTest {
71 private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTemplateDesignUiTests.class);
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;
83 webDriver = DriverFactory.getDriver();
84 topNavComponent = new TopNavComponent(webDriver);
85 homePage = new HomePage(webDriver);
88 @Test(dataProviderClass = OnboardingDataProviders.class, dataProvider = "vfcList")
89 public void importAndCertifyVfc(final String rootFolder, final String 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));
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);
115 private CreateVfFlow createVF() {
116 final ResourceCreateData vfCreateData = createVfFormData();
117 final CreateVfFlow createVfFlow = new CreateVfFlow(webDriver, vfCreateData);
118 createVfFlow.run(homePage);
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;
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;
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;
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);
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"));
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"));
186 // Creates a dependsOn relationship from networkServiceInstance to networkFunctionInstance
187 createRelationship(compositionPage, networkFunctionInstance.getName(), "tosca.capabilities.Node",
188 networkServiceInstance.getName(), "tosca.capabilities.Node");
190 return addNodeToCompositionFlow;
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;
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
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));
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);
234 * Download the generated package
236 * @return DownloadToscaCsarFlow
238 private DownloadToscaCsarFlow downloadToscaCsar(final ComponentPage componentPage) {
239 final DownloadToscaCsarFlow downloadToscaCsarFlow = new DownloadToscaCsarFlow(webDriver);
240 downloadToscaCsarFlow.run(componentPage);
241 return downloadToscaCsarFlow;
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
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);
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()));
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));
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;
313 private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
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());
324 private Map<String, Object> loadYamlObject(final byte[] definitionYamlFile) {
325 return new Yaml().load(new String(definitionYamlFile));