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