Fix 'Wrong Inputs creation on (Add Service)'
[sdc.git] / integration-tests / src / test / java / org / onap / sdc / frontend / ci / tests / execute / sanity / EtsiNetworkServiceUiTests.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
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.hasKey;
25 import static org.hamcrest.Matchers.hasSize;
26 import static org.hamcrest.Matchers.is;
27 import static org.hamcrest.Matchers.not;
28 import static org.hamcrest.Matchers.notNullValue;
29 import static org.junit.Assert.fail;
30
31 import com.aventstack.extentreports.Status;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Map.Entry;
36 import java.util.Optional;
37 import java.util.Set;
38 import org.apache.commons.io.FilenameUtils;
39 import org.junit.jupiter.api.Assertions;
40 import org.onap.sdc.backend.ci.tests.datatypes.enums.ComponentType;
41 import org.onap.sdc.backend.ci.tests.datatypes.enums.PackageTypeEnum;
42 import org.onap.sdc.backend.ci.tests.datatypes.enums.ServiceCategoriesEnum;
43 import org.onap.sdc.backend.ci.tests.utils.general.ElementFactory;
44 import org.onap.sdc.frontend.ci.tests.datatypes.CategorySelect;
45 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
46 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentProperty;
47 import org.onap.sdc.frontend.ci.tests.datatypes.ModelName;
48 import org.onap.sdc.frontend.ci.tests.datatypes.ServiceCreateData;
49 import org.onap.sdc.frontend.ci.tests.datatypes.VspCreateData;
50 import org.onap.sdc.frontend.ci.tests.datatypes.VspOnboardingProcedure;
51 import org.onap.sdc.frontend.ci.tests.datatypes.composition.RelationshipInformation;
52 import org.onap.sdc.frontend.ci.tests.exception.UnzipException;
53 import org.onap.sdc.frontend.ci.tests.execute.setup.DriverFactory;
54 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
55 import org.onap.sdc.frontend.ci.tests.execute.setup.SetupCDTest;
56 import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
57 import org.onap.sdc.frontend.ci.tests.flow.CheckComponentPropertiesFlow;
58 import org.onap.sdc.frontend.ci.tests.flow.CreateResourceFromVspFlow;
59 import org.onap.sdc.frontend.ci.tests.flow.CreateServiceFlow;
60 import org.onap.sdc.frontend.ci.tests.flow.CreateVlmFlow;
61 import org.onap.sdc.frontend.ci.tests.flow.CreateVspFlow;
62 import org.onap.sdc.frontend.ci.tests.flow.DownloadCsarArtifactFlow;
63 import org.onap.sdc.frontend.ci.tests.flow.EditComponentInputsFlow;
64 import org.onap.sdc.frontend.ci.tests.flow.ImportVspFlow;
65 import org.onap.sdc.frontend.ci.tests.flow.composition.CreateRelationshipFlow;
66 import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
67 import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
68 import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
69 import org.onap.sdc.frontend.ci.tests.pages.ServiceComponentPage;
70 import org.onap.sdc.frontend.ci.tests.pages.TopNavComponent;
71 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent;
72 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent.CompositionDetailTabName;
73 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
74 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionRequirementsCapabilitiesTab;
75 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
76 import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
77 import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
78 import org.openecomp.sdc.be.model.ComponentInstance;
79 import org.openqa.selenium.WebDriver;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82 import org.testng.annotations.Test;
83 import org.yaml.snakeyaml.Yaml;
84
85 public class EtsiNetworkServiceUiTests extends SetupCDTest {
86
87     private static final Logger LOGGER = LoggerFactory.getLogger(EtsiNetworkServiceUiTests.class);
88
89     private WebDriver webDriver;
90     private ComponentInstance virtualLinkableVnf1;
91     private ComponentInstance virtualLinkableVnf2;
92     private ComponentInstance nsVirtualLink;
93
94     @Test
95     public void etsiNetworkServiceTest() throws UnzipException {
96         webDriver = DriverFactory.getDriver();
97
98         createVlm();
99         final String resourceName = createVsp();
100         ResourceCreatePage resourceCreatePage = importVsp(resourceName);
101         resourceCreatePage = createAndCertifyVf(resourceName, resourceCreatePage);
102         resourceCreatePage.isLoaded();
103         final HomePage homePage = resourceCreatePage.goToHomePage();
104         homePage.isLoaded();
105
106         final ServiceCreateData serviceCreateData = createServiceFormData();
107         final CreateServiceFlow createServiceFlow = createService(serviceCreateData);
108
109         final CheckComponentPropertiesFlow checkComponentPropertiesFlow = checkServiceProperties();
110         ComponentPage componentPage = checkComponentPropertiesFlow.getLandedPage()
111             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ServiceComponentPage"));
112
113         //adding node
114         componentPage = addNodesAndCreateRelationships(resourceName, serviceCreateData, componentPage);
115
116         final Map<String, Object> inputToEditMap = createInputToEditMap();
117         editInputs(componentPage, inputToEditMap);
118
119         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = downloadCsarArtifact(componentPage);
120         final ToscaArtifactsPage toscaArtifactsPage = downloadCsarArtifactFlow.getLandedPage()
121             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
122
123         assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
124
125         final String downloadedCsarName = toscaArtifactsPage.getDownloadedArtifactList().get(0);
126         checkEtsiNsPackage(createServiceFlow.getServiceCreateData().getName(), downloadedCsarName, inputToEditMap);
127     }
128
129     private ServiceComponentPage addNodesAndCreateRelationships(final String resourceName, final ServiceCreateData serviceCreateData,
130                                                                 final ComponentPage componentPage) {
131         //add first VF node
132         final ComponentData parentComponent = new ComponentData();
133         parentComponent.setName(serviceCreateData.getName());
134         parentComponent.setVersion("0.1");
135         parentComponent.setComponentType(ComponentType.SERVICE);
136         final ComponentData resourceToAdd = new ComponentData();
137         resourceToAdd.setName(resourceName);
138         resourceToAdd.setVersion("1.0");
139         resourceToAdd.setComponentType(ComponentType.RESOURCE);
140         CompositionPage compositionPage = componentPage.goToComposition();
141         AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToComposition(parentComponent, resourceToAdd, compositionPage);
142         virtualLinkableVnf1 = addNodeToCompositionFlow.getCreatedComponentInstance()
143             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
144         //add second VF node
145         addNodeToCompositionFlow = addNodeToComposition(parentComponent, resourceToAdd, compositionPage);
146         virtualLinkableVnf2 = addNodeToCompositionFlow.getCreatedComponentInstance()
147             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
148         //add NsVirtualLink node
149         final ComponentData nsVirtualLinkToAdd = new ComponentData();
150         nsVirtualLinkToAdd.setName("NsVirtualLink");
151         nsVirtualLinkToAdd.setVersion("1.0");
152         nsVirtualLinkToAdd.setComponentType(ComponentType.RESOURCE);
153         addNodeToCompositionFlow = addNodeToComposition(parentComponent, nsVirtualLinkToAdd, compositionPage);
154         nsVirtualLink = addNodeToCompositionFlow.getCreatedComponentInstance()
155             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
156
157         //create a relationship from NsVirtualLink to first VF
158         final String virtualLinkableCapability = "tosca.capabilities.nfv.VirtualLinkable";
159         compositionPage = createRelationship(compositionPage, nsVirtualLink.getName(), virtualLinkableCapability,
160             virtualLinkableVnf1.getName(), virtualLinkableCapability);
161         CreateRelationshipFlow createRelationshipFlow;
162         //create a relationship from NsVirtualLink to second VF
163         final RelationshipInformation relationshipInfoVirtualLinkToVnf2 =
164             new RelationshipInformation(nsVirtualLink.getName(), virtualLinkableCapability, virtualLinkableVnf2.getName(), virtualLinkableCapability);
165         createRelationshipFlow = new CreateRelationshipFlow(webDriver, relationshipInfoVirtualLinkToVnf2);
166         compositionPage = (CompositionPage) createRelationshipFlow.run(compositionPage)
167             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a CompositionPage instance"));
168         final ServiceComponentPage serviceComponentPage = compositionPage.goToServiceGeneral();
169         serviceComponentPage.isLoaded();
170         return serviceComponentPage;
171     }
172
173     private ResourceCreatePage createAndCertifyVf(final String resourceName, final ResourceCreatePage resourceCreatePage) {
174         final CreateResourceFromVspFlow createResourceFlow = new CreateResourceFromVspFlow(webDriver, resourceName);
175         final ResourceCreatePage resourceCreatePage1 = createResourceFlow.run(resourceCreatePage)
176             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
177         resourceCreatePage1.isLoaded();
178         final CompositionPage compositionPage = resourceCreatePage1.goToComposition();
179         compositionPage.isLoaded();
180         //selecting node
181         final String mgmtPortNodeName = "mgmt_port";
182         compositionPage.selectNode(mgmtPortNodeName);
183         final CompositionDetailSideBarComponent detailSideBar = compositionPage.getDetailSideBar();
184         detailSideBar.isLoaded();
185         //going to requirements and capabilities tab and externalizing requirement
186         final CompositionRequirementsCapabilitiesTab compositionRequirementsCapabilitiesTab =
187             (CompositionRequirementsCapabilitiesTab) detailSideBar.selectTab(CompositionDetailTabName.REQUIREMENTS_CAPABILITIES);
188         compositionRequirementsCapabilitiesTab.isLoaded();
189         ExtentTestActions.takeScreenshot(Status.INFO, "requirement-capabilities-tab-loaded", "Requirement and Capabilities tab is loaded");
190         compositionRequirementsCapabilitiesTab.clickOnRequirements();
191         final String externalVirtualLinkRequirement = "external_virtual_link";
192         getExtendTest().log(Status.INFO,
193             String.format("Externalizing requirement '%s' in node '%s'", externalVirtualLinkRequirement, mgmtPortNodeName));
194         compositionRequirementsCapabilitiesTab.toggleRequirementAsExternal(externalVirtualLinkRequirement);
195         ExtentTestActions.takeScreenshot(Status.INFO, "requirement-externalized",
196             String.format("Requirement '%s' of node '%s' was externalized", externalVirtualLinkRequirement, mgmtPortNodeName));
197
198         final ComponentPage componentPage = compositionPage.goToGeneral();
199         componentPage.isLoaded();
200         componentPage.certifyComponent();
201         return resourceCreatePage1;
202     }
203
204     private CompositionPage createRelationship(final CompositionPage compositionPage, final String fromComponentInstanceName,
205                                                final String fromCapability, final String toComponentInstanceName, final String toRequirement) {
206         final RelationshipInformation relationshipInformation =
207             new RelationshipInformation(fromComponentInstanceName, fromCapability, toComponentInstanceName, toRequirement);
208         CreateRelationshipFlow createRelationshipFlow = new CreateRelationshipFlow(webDriver, relationshipInformation);
209         return (CompositionPage) createRelationshipFlow.run(compositionPage)
210             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a CompositionPage instance"));
211     }
212
213     private ResourceCreatePage importVsp(final String resourceName) {
214         final ImportVspFlow importVspFlow = new ImportVspFlow(webDriver, resourceName);
215         return importVspFlow.run()
216             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
217     }
218
219     private String createVsp() {
220         final String resourceName = ElementFactory.addRandomSuffixToName(ElementFactory.getResourcePrefix());
221         final String virtualLinkableVnf = "etsi-vnf-virtual-linkable.csar";
222         final String rootFolder = org.onap.sdc.backend.ci.tests.utils.general.FileHandling.getPackageRepositoryPath(PackageTypeEnum.VNF);
223         var vspCreateData = new VspCreateData();
224         vspCreateData.setName(resourceName);
225         vspCreateData.setCategory(CategorySelect.COMMON_NETWORK_RESOURCES);
226         vspCreateData.setDescription("description");
227         vspCreateData.setOnboardingProcedure(VspOnboardingProcedure.NETWORK_PACKAGE);
228         final CreateVspFlow createVspFlow = new CreateVspFlow(webDriver, vspCreateData, virtualLinkableVnf, rootFolder);
229         createVspFlow.run(new TopNavComponent(webDriver));
230         return resourceName;
231     }
232
233     private void createVlm() {
234         getExtendTest().log(Status.INFO, "Creating a VLM");
235         final CreateVlmFlow createVlmFlow = new CreateVlmFlow(webDriver);
236         createVlmFlow.run();
237     }
238
239     public AddNodeToCompositionFlow addNodeToComposition(final ComponentData parentComponent, final ComponentData resourceToAdd,
240                                                          CompositionPage compositionPage) {
241
242         final AddNodeToCompositionFlow addNodeToCompositionFlow = new AddNodeToCompositionFlow(webDriver, parentComponent, resourceToAdd);
243         addNodeToCompositionFlow.run(compositionPage);
244         return addNodeToCompositionFlow;
245     }
246
247     private CreateServiceFlow createService(final ServiceCreateData serviceCreateData) {
248         final CreateServiceFlow createServiceFlow = new CreateServiceFlow(webDriver, serviceCreateData);
249         createServiceFlow.run(new HomePage(webDriver));
250         return createServiceFlow;
251     }
252
253     private CheckComponentPropertiesFlow checkServiceProperties() {
254         final Set<ComponentProperty<?>> componentPropertySet = Set.of(
255             new ComponentProperty<>("descriptor_id"),
256             new ComponentProperty<>("designer"),
257             new ComponentProperty<>("flavour_id"),
258             new ComponentProperty<>("invariant_id"),
259             new ComponentProperty<>("name"),
260             new ComponentProperty<>("ns_profile"),
261             new ComponentProperty<>("version"),
262             new ComponentProperty<>("service_availability_level")
263         );
264
265         final var checkVfPropertiesFlow = new CheckComponentPropertiesFlow(componentPropertySet, webDriver);
266         checkVfPropertiesFlow.run();
267         return checkVfPropertiesFlow;
268     }
269
270     private DownloadCsarArtifactFlow downloadCsarArtifact(final ComponentPage componentPage) {
271         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = new DownloadCsarArtifactFlow(webDriver);
272         downloadCsarArtifactFlow.run(componentPage);
273         return downloadCsarArtifactFlow;
274     }
275
276     private Map<String, Object> createInputToEditMap() {
277         final Map<String, Object> inputsMap = new HashMap<>();
278         inputsMap.put("descriptor_id", "new descriptor_id");
279         inputsMap.put("designer", "new designer");
280         inputsMap.put("flavour_id", "new flavour_id");
281         inputsMap.put("invariant_id", "new invariant_id");
282         inputsMap.put("name", "new name");
283         inputsMap.put("service_availability_level", 123);
284         inputsMap.put("version", "new version");
285         return inputsMap;
286     }
287
288     private void editInputs(final ComponentPage componentPage, final Map<String, Object> inputsMap) {
289         final EditComponentInputsFlow editComponentInputsFlow = new EditComponentInputsFlow(webDriver, inputsMap);
290         editComponentInputsFlow.run(componentPage);
291     }
292
293     private ServiceCreateData createServiceFormData() {
294         final ServiceCreateData serviceCreateData = new ServiceCreateData();
295         serviceCreateData.setRandomName("EtsiNfvNetworkService");
296         serviceCreateData.setModel(ModelName.DEFAULT_MODEL_NAME.getName());
297         serviceCreateData.setCategory(ServiceCategoriesEnum.ETSI_NFV_NETWORK_SERVICE.getValue());
298         serviceCreateData.setEtsiVersion("2.5.1");
299         serviceCreateData.setDescription("aDescription");
300         return serviceCreateData;
301     }
302
303     private void checkEtsiNsPackage(final String serviceName, final String downloadedCsarName, final Map<String, Object> expectedInputMap)
304         throws UnzipException {
305         final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
306         final Map<String, byte[]> filesFromZip = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
307         final Optional<String> etsiPackageEntryOpt =
308             filesFromZip.keySet().stream().filter(s -> s.startsWith("Artifacts/ETSI_PACKAGE")).findFirst();
309         if (etsiPackageEntryOpt.isEmpty()) {
310             Assertions.fail("Could not find the NSD package in Artifacts/ETSI_PACKAGE");
311         }
312         final String nodeType = String.format("org.openecomp.service.%s",
313             serviceName.substring(0, 1).toUpperCase() + serviceName.substring(1).toLowerCase());
314         final String etsiPackageEntry = etsiPackageEntryOpt.get();
315         final String nsdPackageBaseName = FilenameUtils.getBaseName(etsiPackageEntry);
316         final String nsdCsarFile = nsdPackageBaseName + ".csar";
317         final byte[] etsiPackageBytes = filesFromZip.get(etsiPackageEntry);
318         if (etsiPackageEntry.endsWith(".zip")) {
319             final Map<String, byte[]> nsPackageFileMap = FileHandling.getFilesFromZip(etsiPackageBytes);
320             assertThat("Expecting 3 files inside the NSD CSAR, the CSAR itself and its signature and certificate",
321                 nsPackageFileMap.size(), is(3));
322             assertThat("Expecting the NSD CSAR file " + nsdCsarFile, nsPackageFileMap, hasKey(nsdCsarFile));
323             final String nsdCsarSignature = nsdPackageBaseName + ".cms";
324             assertThat("Expecting the NSD CSAR signature " + nsdCsarSignature, nsPackageFileMap, hasKey(nsdCsarSignature));
325             final String nsdCertificate = nsdPackageBaseName + ".cert";
326             assertThat("Expecting the NSD CSAR certificate " + nsdCertificate, nsPackageFileMap, hasKey(nsdCertificate));
327             checkNsCsar(nsdPackageBaseName, nodeType, nsPackageFileMap.get(nsdCsarFile), expectedInputMap);
328             return;
329         }
330         if (etsiPackageEntry.endsWith(".csar")) {
331             final Map<String, byte[]> nsPackageFileMap = FileHandling.getFilesFromZip(etsiPackageBytes);
332             checkNsCsar(nsdPackageBaseName, nodeType, nsPackageFileMap.get(nsdCsarFile), expectedInputMap);
333             return;
334         }
335         fail(String.format("Unexpected ETSI NS PACKAGE entry '%s'. Expecting a '.csar' or '.zip'", etsiPackageEntry));
336     }
337
338     private void checkNsCsar(final String expectedServiceName, final String expectedServiceNodeType,
339                              final byte[] nsCsar, final Map<String, Object> expectedInputMap) throws UnzipException {
340         final Map<String, byte[]> csarFileMap = FileHandling.getFilesFromZip(nsCsar);
341
342         final String mainDefinitionFile = String.format("Definitions/%s.yaml", expectedServiceName);
343         final byte[] mainDefinitionFileBytes = csarFileMap.get(mainDefinitionFile);
344         if (mainDefinitionFileBytes == null) {
345             fail(String.format("Could not find the Main Definition file in '%s'", mainDefinitionFile));
346         }
347
348         final Map<String, Object> mainDefinitionYamlMap = loadYamlObject(mainDefinitionFileBytes);
349         final Map<String, Object> topologyTemplateTosca = getMapEntry(mainDefinitionYamlMap, "topology_template");
350         assertThat(String.format("'%s' should contain a topology_template entry", mainDefinitionFile), topologyTemplateTosca, notNullValue());
351         final Map<String, Object> substitutionMappingsTosca = getMapEntry(topologyTemplateTosca, "substitution_mappings");
352         assertThat(String.format("'%s' should contain a substitution_mappings entry", mainDefinitionFile), substitutionMappingsTosca, notNullValue());
353         final String nodeType = (String) substitutionMappingsTosca.get("node_type");
354         assertThat("substitution_mappings->node_type should be as expected", nodeType, is(expectedServiceNodeType));
355
356         final Map<String, Object> nodeTemplatesTosca = getMapEntry(topologyTemplateTosca, "node_templates");
357         assertThat(String.format("'%s' should contain a node_templates entry", mainDefinitionFile), nodeTemplatesTosca, notNullValue());
358
359         checkVirtualLinkableNode(mainDefinitionFile, virtualLinkableVnf1, nodeTemplatesTosca);
360         checkVirtualLinkableNode(mainDefinitionFile, virtualLinkableVnf2, nodeTemplatesTosca);
361         //checking tosca.nodes.nfv.NsVirtualLink node
362         final Map<String, Object> nsVirtualLinkNode = getMapEntry(nodeTemplatesTosca, nsVirtualLink.getName());
363         assertThat(String.format("'%s' should contain a '%s' entry in node_templates", mainDefinitionFile, nsVirtualLink.getName()),
364             nsVirtualLinkNode, notNullValue());
365         assertThat(String.format("Type from '%s' should be as expected", nsVirtualLink.getName()),
366             nsVirtualLinkNode.get("type"), is("tosca.nodes.nfv.NsVirtualLink"));
367
368         //checking the main service node
369         final Map<String, Object> serviceNodeTemplate = getMapEntry(nodeTemplatesTosca, expectedServiceNodeType);
370         assertThat(String.format("'%s' should contain a '%s' entry in node_templates", mainDefinitionFile, expectedServiceNodeType),
371             serviceNodeTemplate, notNullValue());
372         final Map<String, Object> properties = getMapEntry(serviceNodeTemplate, "properties");
373         assertThat(String.format("'%s' node template in '%s' should contain a properties entry", expectedServiceNodeType, mainDefinitionFile),
374             properties, notNullValue());
375         assertThat(String.format("'%s' node template should contain '%s' properties", expectedServiceNodeType, expectedInputMap.size()),
376             properties.size(), is(expectedInputMap.size()));
377         for (final Entry<String, Object> expectedPropertyEntry : expectedInputMap.entrySet()) {
378             final String expectedPropertyName = expectedPropertyEntry.getKey();
379             assertThat(String.format("'%s' node template should contain the property '%s'", expectedServiceNodeType, expectedPropertyName),
380                 properties, hasKey(expectedPropertyName));
381             final Object expectedPropertyValue = expectedPropertyEntry.getValue();
382             if (expectedPropertyValue != null) {
383                 final Object actualPropertyValue = properties.get(expectedPropertyName);
384                 final String msg = String.format("The property '%s', in '%s' node template should have the expected value '%s'",
385                     expectedPropertyName, expectedServiceNodeType, expectedPropertyValue);
386                 assertThat(msg, actualPropertyValue, is(expectedPropertyValue));
387             }
388         }
389     }
390
391     private void checkVirtualLinkableNode(final String mainDefinitionFileName, final ComponentInstance virtualLinkableVnf,
392                                           final Map<String, Object> nodeTemplatesTosca) {
393         final Map<String, Object> virtualLinkableVnfNode = getMapEntry(nodeTemplatesTosca, virtualLinkableVnf.getName());
394         assertThat(String.format("'%s' should contain a '%s' entry in node_templates", mainDefinitionFileName, virtualLinkableVnf.getName()),
395             virtualLinkableVnfNode, notNullValue());
396         assertThat(String.format("Type from '%s' should be as expected", virtualLinkableVnf.getName()),
397             virtualLinkableVnfNode.get("type"), is("org.openecomp.resource.EtsiVnfVirtualLinkable"));
398         final Object requirementsObj = virtualLinkableVnfNode.get("requirements");
399         assertThat(String.format("'%s' should contain a requirements entry in node_templates", virtualLinkableVnf.getName()),
400             requirementsObj, notNullValue());
401         if (!(requirementsObj instanceof List)) {
402             fail(String.format("Requirements in '%s' is not a list", virtualLinkableVnf.getName()));
403         }
404         final var requirements = (List<Map<String, Object>>) requirementsObj;
405         assertThat(String.format("'%s' should contain only one requirement", virtualLinkableVnf.getName()), requirements, hasSize(1));
406         final Map<String, Object> externalVirtualLinkRequirement = getMapEntry(requirements.get(0), "external_virtual_link");
407         assertThat(String.format("'%s' should contain the requirement 'external_virtual_link'", virtualLinkableVnf.getName()),
408             externalVirtualLinkRequirement, notNullValue());
409         assertThat(
410             String.format("Requirement 'external_virtual_link' in '%s' should contain the capability 'virtual_linkable'",
411                 virtualLinkableVnf.getName()),
412             externalVirtualLinkRequirement.get("capability"), is("virtual_linkable"));
413         assertThat(
414             String.format("Requirement 'external_virtual_link' in '%s' should relate to the node '%s'",
415                 virtualLinkableVnf.getName(), nsVirtualLink.getName()),
416             externalVirtualLinkRequirement.get("node"), is(nsVirtualLink.getName()));
417     }
418
419     private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
420         try {
421             return (Map<String, Object>) yamlObj.get(entryName);
422         } catch (final Exception e) {
423             final String errorMsg = String.format("Could not get the '%s' entry.", entryName);
424             LOGGER.error(errorMsg, e);
425             fail(errorMsg + "Error message: " + e.getMessage());
426         }
427         return null;
428     }
429
430     private Map<String, Object> loadYamlObject(final byte[] mainDefinitionFileBytes) {
431         return new Yaml().load(new String(mainDefinitionFileBytes));
432     }
433
434 }