From ea4af0caf0a786b9b8d05dc3d2749f965050f398 Mon Sep 17 00:00:00 2001 From: "stark, steven" Date: Wed, 28 Aug 2019 16:11:53 -0700 Subject: [INT] Add testsuite for vnf lifecycle validation The new testsuite is intended for heat-based VNFs going through the OPNFV VNF lifecycle validation. At the end of the test it will package up the results into a tarball for submission to the OVP portal. The testcase uploads a VNF pacakge and - executes the VVP validation scripts - models and distributes in SDC - instantiates via VID - validates the stack in OpenStack WIP instructions available here: https://wiki.onap.org/pages/viewpage.action?pageId=68546123 Issue-ID: INT-1197 Change-Id: I2ef827c64b64bdc7e2259806d86d6272cf77221c Signed-off-by: stark, steven --- docker/Dockerfile | 12 +- robot/resources/sdnc_interface.robot | 41 ++++++ .../test_templates/vnf_instantiation_ovp.robot | 158 +++++++++++++++++++++ robot/resources/vid/create_vid_vnf.robot | 61 ++++++-- robot/resources/vid/vid_interface.robot | 4 +- robot/resources/vvp_validation.robot | 49 +++++++ robot/testsuites/vnf-orchestration-ovp.robot | 129 +++++++++++++++++ 7 files changed, 439 insertions(+), 15 deletions(-) create mode 100644 robot/resources/test_templates/vnf_instantiation_ovp.robot create mode 100644 robot/resources/vvp_validation.robot create mode 100644 robot/testsuites/vnf-orchestration-ovp.robot diff --git a/docker/Dockerfile b/docker/Dockerfile index 786538a8..f98a360c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -28,17 +28,27 @@ RUN apt-get update \ python-setuptools \ python-wheel \ python-pip \ + netbase \ unzip \ x11-utils \ x11-xserver-utils \ xvfb \ xxd \ vim - + +# install python 3 after so it isn't default python version +RUN apt-get install \ + --no-install-recommends \ + --assume-yes \ + python3.7 \ + python3.7-dev \ + python3-pip RUN pip install robotframework==3.1.2 \ && python --version +RUN python3.7 -m pip install virtualenv + # Copy the robot code COPY . /var/opt/ONAP/ COPY lighttpd.conf /etc/lighttpd/lighttpd.conf diff --git a/robot/resources/sdnc_interface.robot b/robot/resources/sdnc_interface.robot index 198e364d..9b56fef4 100644 --- a/robot/resources/sdnc_interface.robot +++ b/robot/resources/sdnc_interface.robot @@ -234,3 +234,44 @@ Login To SDNC Admin GUI Click Button xpath=//button[@type='submit'] Title Should Be SDN-C AdminPortal Log Logged in to ${SDNC_ADMIN_LOGIN_URL} + +Create Preload From JSON + [Documentation] Fill vf-module parameters in an already created preload json file. + [Arguments] ${preload_file} ${api_type} ${vf_module_name} ${vf_module_type} ${vnf_name} ${generic_vnf_type} + Log To Console Uploading ${preload_file} to SDNC + + ${preload_vnf}= Run keyword if "${api_type}"=="gr_api" + ... Preload GR API ${vf_module_name} ${vf_module_type} ${vnf_name} ${generic_vnf_type} ${preload_file} + ... ELSE + ... Preload VNF API ${vf_module_name} ${vf_module_type} ${vnf_name} ${generic_vnf_type} ${preload_file} + + ${uri}= Set Variable If "${api_type}"=="gr_api" ${SDNC_INDEX_PATH}${PRELOAD_GR_TOPOLOGY_OPERATION_PATH} ${SDNC_INDEX_PATH}${PRELOAD_VNF_TOPOLOGY_OPERATION_PATH} + + ${post_resp}= SDNC.Run Post Request ${SDNC_REST_ENDPOINT} ${uri} data=${preload_vnf} auth=${GLOBAL_SDNC_AUTHENTICATION} + Should Be Equal As Strings ${post_resp.json()['output']['response-code']} 200 + [Return] ${post_resp} + +Preload GR API + [Documentation] Retrieves a preload JSON file and fills in service instance values. + [Arguments] ${vnf_name} ${vnf_type} ${generic_vnf_name} ${generic_vnf_type} ${preload_path} + + ${json}= OperatingSystem.Get File ${preload_path} + ${object}= Evaluate json.loads('''${json}''') json + ${req_dict} Create Dictionary vnf-name=${generic_vnf_name} vnf-type=${generic_vnf_type} + set to dictionary ${object["input"]["preload-vf-module-topology-information"]} vnf-topology-identifier-structure=${req_dict} + ${req_dict_new} Create Dictionary vf-module-name=${vnf_name} + set to dictionary ${object["input"]["preload-vf-module-topology-information"]["vf-module-topology"]} vf-module-topology-identifier=${req_dict_new} + ${req_json} Evaluate json.dumps(${object}) json + [Return] ${req_json} + +Preload VNF API + [Documentation] Retrieves a preload JSON file and fills in service instance values. + [Arguments] ${vnf_name} ${vnf_type} ${generic_vnf_name} ${generic_vnf_type} ${preload_path} + + ${json}= OperatingSystem.Get File ${preload_path} + ${object}= Evaluate json.loads('''${json}''') json + ${req_dict} Create Dictionary vnf-name=${vnf_name} vnf-type=${vnf_type} generic-vnf-type=${generic_vnf_type} generic-vnf-name=${generic_vnf_name} + set to dictionary ${object["input"]["vnf-topology-information"]} vnf-topology-identifier=${req_dict} + + ${req_json} Evaluate json.dumps(${object}) json + [Return] ${req_json} diff --git a/robot/resources/test_templates/vnf_instantiation_ovp.robot b/robot/resources/test_templates/vnf_instantiation_ovp.robot new file mode 100644 index 00000000..ea7b0f92 --- /dev/null +++ b/robot/resources/test_templates/vnf_instantiation_ovp.robot @@ -0,0 +1,158 @@ +*** Settings *** +Documentation This test can be used for an arbitrary VNF. +Resource ../vid/vid_interface.robot +Resource ../vid/create_vid_vnf.robot +Resource ../sdnc_interface.robot + +Library ONAPLibrary.Openstack +Library SeleniumLibrary +Library Collections +Library ONAPLibrary.Utilities +Library ONAPLibrary.JSON +Library ONAPLibrary.ServiceMapping WITH NAME ServiceMapping + +*** Keywords *** +Instantiate VNF + [Documentation] Log into VID, create service instance, vnf instance, and module. This handles an arbitrary, single VNF service w/ volume modules. + [Arguments] ${customer_name} ${service} ${service_type} ${service_name} ${service_model_type} ${vnf_type} ${vf_modules} ${catalog_resources} ${product_family} ${tenant_name} ${lcp_region} ${cloud_owner} ${project_name} ${owning_entity} ${api_type} ${line_of_business}=LOB-Demonstration ${platform}=Platform-Demonstration + ${uuid}= Generate UUID4 + ${list}= Create List + ${report_data}= Create List + Setup Browser + Login To VID GUI api_type=${api_type} + + Log Creating ${service_name} in VID console=yes + ${service_instance_id}= Wait Until Keyword Succeeds 900s 5s Create VID Service Instance ${customer_name} ${service_model_type} ${service_type} ${service_name} ${project_name} ${owning_entity} + + Validate Service Instance ${service_instance_id} ${service_type} ${customer_name} + ServiceMapping.Set Directory default ${GLOBAL_SERVICE_MAPPING_DIRECTORY} + ${vnflist}= ServiceMapping.Get Service Vnf Mapping default ${service} + ${vnf_name_index}= Set Variable 0 + ${vf_module_name_list}= Create List + ${uuid}= Evaluate str("${uuid}")[:8] + + ##### INSTANTIATING VNF IN VID ##### + :FOR ${vnf} IN @{vnflist} + # APPC max is 50 characters + \ ${vnf_name}= Catenate Ete_${vnf}_${uuid}_${vnf_name_index} + \ ${generic_vnf_type}= Set Variable ${service_name}/${vnf_type} ${vnf_name_index} + \ ${vnf_name_index}= Evaluate ${vnf_name_index} + 1 + \ Log Creating VNF ${vnf_name} in VID console=yes + \ Wait Until Keyword Succeeds 900s 5s Create VID VNF ${service_instance_id} ${vnf_name} ${product_family} ${lcp_region} ${tenant_name} ${vnf_type} ${CUSTOMER_NAME} line_of_business=${line_of_business} platform=${platform} cloud_owner_uc=${cloud_owner} + + #### Calling Keyword To Create Each Module #### + \ ${report_data}= Loop and Create Modules in VID ${vf_modules} ${vnf_name} ${generic_vnf_type} ${service_instance_id} ${lcp_region} ${tenant_name} ${cloud_owner} ${customer_name} ${vnf} ${catalog_resources} + + [Return] ${report_data} + +Loop and Create Modules in VID + [Documentation] Loops through the VF modules in a VNF and instantiates in VID + [Arguments] ${vf_modules} ${vnf_name} ${generic_vnf_type} ${service_instance_id} ${lcp_region} ${tenant_name} ${cloud_owner} ${customer_name} ${vnf} ${resources} + ${temp_list_for_report} Create List + + ### Base Module + :FOR ${module} IN @{vf_modules} + \ ${vf_module_type}= Get From Dictionary ${module} name + \ ${template_name}= Get Heat Template Name From Catalog Resource ${resources} ${vnf} ${vf_module_type} + \ ${preload_file} ${isBase}= Retrieve Module Preload and isBase ${template_name} + \ ${temp_dict_for_report} = Run Keyword If "${isBase}"=="true" Create Module in VID ${vnf_name} ${template_name} ${vf_module_type} ${generic_vnf_type} ${preload_file} ${service_instance_id} ${lcp_region} ${tenant_name} ${customer_name} ${cloud_owner} + \ Run Keyword If "${isBase}"=="true" Append To List ${temp_list_for_report} ${temp_dict_for_report} + + ### Incremental Modules + :FOR ${module} IN @{vf_modules} + \ ${vf_module_type}= Get From Dictionary ${module} name + \ ${template_name}= Get Heat Template Name From Catalog Resource ${resources} ${vnf} ${vf_module_type} + \ ${preload_file} ${isBase}= Retrieve Module Preload and isBase ${template_name} + \ ${temp_dict_for_report} = Run Keyword If "${isBase}"=="false" Create Module in VID ${vnf_name} ${template_name} ${vf_module_type} ${generic_vnf_type} ${preload_file} ${service_instance_id} ${lcp_region} ${tenant_name} ${customer_name} ${cloud_owner} + \ Run Keyword If "${isBase}"=="false" Append To List ${temp_list_for_report} ${temp_dict_for_report} + + [Return] ${temp_list_for_report} + +Create Module in VID + [Arguments] ${vnf_name} ${template_name} ${vf_module_type} ${generic_vnf_type} ${preload_file} ${service_instance_id} ${lcp_region} ${tenant_name} ${customer_name} ${cloud_owner} + + ${vf_module_name}= Catenate Vfmodule_${vnf_name}_${template_name} + ${vf_module_name}= Remove String ${vf_module_name} .yaml .yml + ${Module_name}= Set Variable + ${api_type}= Retrieve Manifest Data api_type + + Create Preload From JSON ${BUILD_DIR}/preloads/${preload_file} ${api_type} ${vf_module_name} ${vf_module_type} ${vnf_name} ${generic_vnf_type} + + ${temp_dict_for_report} Create Dictionary stack_name=${vf_module_name} template_name=${BUILD_DIR}/templates/${template_name} preload_name=${BUILD_DIR}/preloads/${preload_file} + + Log Creating ${vf_module_name} in VID console=yes + ${vf_module_id}= Create VID VNF module ${service_instance_id} ${vf_module_name} ${lcp_region} ${tenant_name} ${vf_module_type} ${customer_name} ${vnf_name} cloud_owner_uc=${cloud_owner} + [Return] ${temp_dict_for_report} + +Retrieve Module Preload and isBase + [Arguments] ${file_name} + ${json}= OperatingSystem.Get File ${BUILD_DIR}/vnf-details.json + ${object}= Evaluate json.loads('''${json}''') json + :FOR ${vnf} IN @{object["modules"]} + \ ${module_present}= set variable True + \ ${file_name_m}= set variable ${vnf["filename"]} + \ ${preload_name}= set variable if '${file_name_m}' == '${file_name}' ${vnf["preload"]} + \ ${isBase}= set variable if '${file_name_m}' == '${file_name}' ${vnf["isBase"]} + \ Exit For Loop If '${file_name_m}' == '${file_name}' + \ ${module_present}= set variable False + Return From Keyword If ${module_present}==True ${preload_name} ${isBase} + Fail msg=ERROR: A module with the file name: ${file_name} is not present. + +##### Getting The Heat Template Name From the Module ID, using the catalog data ##### +Get Heat Template Name From Catalog Resource + [Documentation] Searching through the catalog resources looking for the heat template name + [Arguments] ${resources} ${vnf} ${module_id} + + ${keys}= Get Dictionary Keys ${resources} + ${artifact_ids}= Get Artifact IDs From CSAR ${resources} ${vnf} ${module_id} + + :FOR ${key} IN @{keys} + \ ${cr}= Get From Dictionary ${resources} ${key} + \ ${artifacts}= Set Variable ${cr['allArtifacts']} + \ ${artifactName}= Get Artifact Name From Artifacts ${artifacts} ${artifact_ids} + \ Return From Keyword If "${artifactName}" != "NOTFOUND" ${artifactName} + +Get Artifact Name From Artifacts + [Arguments] ${artifacts} ${artifact_ids} + + ${keys}= Get Dictionary Keys ${artifacts} + + :FOR ${key} IN @{keys} + \ ${artifact}= Get From Dictionary ${artifacts} ${key} + \ ${artifactType}= Get From Dictionary ${artifact} artifactType + \ ${csar_id}= Set Variable '' + \ ${csar_id}= Run Keyword If "${artifactType}"=="HEAT" Get From Dictionary ${artifact} artifactUUID + \ ${artifactName}= Run Keyword If $csar_id in $artifact_ids Get From Dictionary ${artifact} artifactName + \ Return From Keyword If $csar_id in $artifact_ids ${artifactName} + + [Return] NOTFOUND + +Get Artifact IDs From CSAR + [Documentation] Looking for the artifact ID for a given module + [Arguments] ${resources} ${vnf} ${module_id} + + ${keys}= Get Dictionary Keys ${resources} + + :FOR ${key} IN @{keys} + \ ${cr}= Get From Dictionary ${resources} ${key} + \ ${groups}= Set Variable ${cr['groups']} + \ ${artifact_ids}= Get Artifact IDs From Module ${groups} ${module_id} + \ Return From Keyword If ${artifact_ids} is not None ${artifact_ids} + + ${empty_list}= Create List + + [Return] ${empty_list} + +Get Artifact IDs From Module + [Arguments] ${groups} ${module_id} + + :FOR ${group} IN @{groups} + \ ${invariant_name}= Get From Dictionary ${group} invariantName + \ ${artifact_ids}= Create List + \ ${artifact_ids}= Run Keyword If "${invariant_name}"== "${module_id}" Get From Dictionary ${group} artifactsUuid + \ Return From Keyword If ${artifact_ids} is not None ${artifact_ids} + + ${empty_list}= Create List + + [Return] ${empty_list} +##### End of catalog manipulation ##### diff --git a/robot/resources/vid/create_vid_vnf.robot b/robot/resources/vid/create_vid_vnf.robot index ea3cf123..575863bd 100644 --- a/robot/resources/vid/create_vid_vnf.robot +++ b/robot/resources/vid/create_vid_vnf.robot @@ -12,11 +12,13 @@ Library ONAPLibrary.SO WITH NAME SO *** Keywords *** Create VID VNF [Documentation] Creates a VNF instance using VID for passed instance id with the passed service instance name - [Arguments] ${service_instance_id} ${service_instance_name} ${product_family} ${lcp_region} ${tenant} ${vnf_type} ${customer} ${line_of_business}=LOB-Demonstration ${platform}=Platform-Demonstration + [Arguments] ${service_instance_id} ${service_instance_name} ${product_family} ${lcp_region} ${tenant} ${vnf_type} ${customer} ${line_of_business}=LOB-Demonstration ${platform}=Platform-Demonstration ${cloud_owner_uc}=${GLOBAL_AAI_CLOUD_OWNER} Go To VID HOME Click Link xpath=//div[@heading = 'Search for Existing Service Instances']/a Wait Until Page Contains Please search by timeout=${GLOBAL_VID_UI_TIMEOUT_MEDIUM} + Input Text When Enabled //input[@name='selectedServiceInstance'] ${service_instance_id} + Select From List By Label //select[@ng-model='selectedserviceinstancetype'] Service Instance Id Select From List By Label //select[@ng-model='selectedCustomer'] ${customer} Click On Button When Enabled //button[contains(text(),'Submit')] Wait Until Page Contains Element link=View/Edit timeout=${GLOBAL_VID_UI_TIMEOUT_MEDIUM} @@ -37,7 +39,6 @@ Create VID VNF Input Text xpath=//input[@parameter-id='instanceName'] ${service_instance_name} Select From List By Label xpath=//select[@parameter-id='productFamily'] ${product_family} # Fix for Dublin - ${cloud_owner_uc}= Convert To Uppercase ${GLOBAL_AAI_CLOUD_OWNER} Select From List By Label xpath=//select[@parameter-id='lcpRegion'] ${lcp_region} (${cloud_owner_uc}) Select From List By Label xpath=//select[@parameter-id='tenant'] ${tenant} Select From List When Enabled //select[@parameter-id='lineOfBusiness'] ${line_of_business} @@ -52,7 +53,7 @@ Create VID VNF [Return] ${instance_id} Delete VID VNF - [Arguments] ${service_instance_id} ${lcp_region} ${tenant} ${vnf_instance_id} + [Arguments] ${service_instance_id} ${lcp_region} ${tenant} ${vnf_instance_id} ${cloud_owner_uc}=${GLOBAL_AAI_CLOUD_OWNER} Go To VID HOME Click Link xpath=//div[@heading = 'Search for Existing Service Instances']/a Wait Until Page Contains Please search by timeout=60s @@ -68,7 +69,6 @@ Delete VID VNF Wait Until Page Contains Element xpath=//div[@class='statusLine'] timeout=${GLOBAL_VID_UI_TIMEOUT_LONG} Wait Until Element Is Not Visible xpath=//div[@class='statusLine aaiHidden'] timeout=${GLOBAL_VID_UI_TIMEOUT_MEDIUM} Click On Element When Visible xpath=//li/div[contains(.,'${vnf_instance_id}')]/a/span[@class='glyphicon glyphicon-remove'] timeout=${GLOBAL_VID_UI_TIMEOUT_LONG} - ${cloud_owner_uc}= Convert To Uppercase ${GLOBAL_AAI_CLOUD_OWNER} Select From List By Label xpath=//select[@parameter-id='lcpRegion'] ${lcp_region} (${cloud_owner_uc}) Select From List By Label xpath=//select[@parameter-id='tenant'] ${tenant} Click Element xpath=//div[@class='buttonRow']/button[@ngx-enabled='true'] @@ -80,19 +80,47 @@ Delete VID VNF ${resp}= SO.Run Polling Get Request ${GLOBAL_SO_ENDPOINT} ${GLOBAL_SO_STATUS_PATH}${request_id} auth=${auth} Create VID VNF module - [Arguments] ${service_instance_id} ${vf_module_name} ${lcp_region} ${TENANT} ${VNF_TYPE} ${customer} ${vnf_name} + [Arguments] ${service_instance_id} ${vf_module_name} ${lcp_region} ${TENANT} ${VNF_TYPE} ${customer} ${vnf_name} ${cloud_owner_uc}=${GLOBAL_AAI_CLOUD_OWNER} Go To VID HOME Click Link xpath=//div[@heading = 'Search for Existing Service Instances']/a Wait Until Page Contains Please search by timeout=${GLOBAL_VID_UI_TIMEOUT_MEDIUM} Wait Until Page Contains Element xpath=//div[@class='statusLine aaiHidden'] timeout=${GLOBAL_VID_UI_TIMEOUT_MEDIUM} # If we don't wait for this control to be enabled, the submit results in a 'not found' pop-up (UnexpectedAlertPresentException) + Input Text When Enabled //input[@name='selectedServiceInstance'] ${service_instance_id} + Select From List By Label //select[@ng-model='selectedserviceinstancetype'] Service Instance Id Select From List By Label //select[@ng-model='selectedCustomer'] ${customer} Click On Button When Enabled //button[contains(text(),'Submit')] Wait Until Page Contains Element link=View/Edit timeout=${GLOBAL_VID_UI_TIMEOUT_MEDIUM} Click Element link=View/Edit + Wait Until Keyword Succeeds 300s 5s Wait For Add VF Module + + ### Optionally checking if Volume Group option is there ### + + ## first checking if the VNF has ANY volume modules + ${volume_status} ${value} Run Keyword And Ignore Error Wait Until Element Is Visible //button[contains(text(),'Add Volume Group')] timeout=15s + Run Keyword If '${volume_status}' == 'PASS' Click Element xpath=//div[contains(.,'${vnf_name}')]/div/button[contains(.,'Add Volume Group')] + + ## now checking that this specific module has volumes + ${volume_module_status} ${value} Run Keyword And Ignore Error Wait Until Element Is Visible link=${VNF_TYPE} timeout=15s + ${uuid}= Generate UUID4 + ${vf_module_volume_name}= Evaluate str("${uuid}")[:8] + ${vf_module_volume_name}= Set Variable If '${volume_module_status}' == 'PASS' volume_${vf_module_volume_name} None + Run Keyword If '${volume_module_status}' == 'PASS' Log Volumes found for ${vf_module_name} console=yes + Run Keyword If '${volume_module_status}' == 'PASS' Fill Module Form And Submit ${vf_module_volume_name} ${lcp_region} ${TENANT} ${VNF_TYPE} cloud_owner_uc=${cloud_owner_uc} + ## sleep to give VID a chance to update Volume Group + Run Keyword If '${volume_module_status}' == 'PASS' Sleep 30s + + ### end volume stuff ### + Click Element xpath=//div[contains(.,'${vnf_name}')]/div/button[contains(.,'Add VF-Module')] + ${instance_id}= Fill Module Form And Submit ${vf_module_name} ${lcp_region} ${TENANT} ${VNF_TYPE} cloud_owner_uc=${cloud_owner_uc} volume_group=${vf_module_volume_name} + [Return] ${instance_id} + +Fill Module Form And Submit + [Documentation] Separating this so volume module can use as well. + [Arguments] ${vf_module_name} ${lcp_region} ${tenant} ${vnf_type} ${cloud_owner_uc}=${GLOBAL_AAI_CLOUD_OWNER} ${volume_group}=None # This is where firefox breaks. Th elink never becomes visible when run with the script. Click Element link=${vnf_type} @@ -102,22 +130,29 @@ Create VID VNF module ## Without this sleep, the input text below gets immediately wiped out. ## Wait Until Angular Ready just sleeps for its timeout value Sleep 10s - Input Text xpath=//input[@parameter-id='instanceName'] ${vf_module_name} - ${cloud_owner_uc}= Convert To Uppercase ${GLOBAL_AAI_CLOUD_OWNER} + Input Text xpath=//input[@parameter-id='instanceName'] ${vf_module_name} Select From List By Label xpath=//select[@parameter-id='lcpRegion'] ${lcp_region} (${cloud_owner_uc}) Select From List By Label xpath=//select[@parameter-id='tenant'] ${tenant} - Wait Until Element Is Visible xpath=//input[@parameter-id='sdncPreload'] ${GLOBAL_VID_UI_TIMEOUT_SHORT} - Wait Until Element Is Enabled xpath=//input[@parameter-id='sdncPreload'] ${GLOBAL_VID_UI_TIMEOUT_SHORT} - Select Checkbox xpath=//input[@parameter-id='sdncPreload'] + + ### Volume Stuff ### + ${status} ${value} Run Keyword And Ignore Error Wait Until Element Is Visible xpath=//select[@parameter-id='availableVolumeGroup'] 15s + Run Keyword If '${status}' == 'PASS' Select From List By Label xpath=//select[@parameter-id='availableVolumeGroup'] ${volume_group} + ### End Volume Stuff + + ${status} ${value} Run Keyword And Ignore Error Wait Until Element Is Visible xpath=//input[@parameter-id='sdncPreload'] ${GLOBAL_VID_UI_TIMEOUT_SHORT} + Run Keyword If '${status}' == 'PASS' Wait Until Element Is Enabled xpath=//input[@parameter-id='sdncPreload'] ${GLOBAL_VID_UI_TIMEOUT_SHORT} + Run Keyword If '${status}' == 'PASS' Select Checkbox xpath=//input[@parameter-id='sdncPreload'] + Capture Page Screenshot + Log Submitting vf module instance ${vf_module_name} in VID console=yes Click On Button When Enabled //button[contains(text(),'Confirm')] - Wait Until Element Contains xpath=//pre[@class = 'log ng-binding'] requestState timeout=${GLOBAL_VID_UI_TIMEOUT_LONG} + Wait Until Element Contains xpath=//pre[@class = 'log ng-binding'] requestState timeout=300s ${response text}= Get Text xpath=//pre[@class = 'log ng-binding'] Click On Button When Enabled //button[contains(text(),'Close')] ${instance_id}= Parse Instance Id ${response text} ${request_id}= Parse Request Id ${response text} - ${auth}= Create List ${GLOBAL_SO_USERNAME} ${GLOBAL_SO_PASSWORD} - ${resp}= SO.Run Polling Get Request ${GLOBAL_SO_ENDPOINT} ${GLOBAL_SO_STATUS_PATH}${request_id} auth=${auth} + ${auth}= Create List ${GLOBAL_SO_USERNAME} ${GLOBAL_SO_PASSWORD} + ${resp}= SO.Run Polling Get Request ${GLOBAL_SO_ENDPOINT} ${GLOBAL_SO_STATUS_PATH}${request_id} auth=${auth} [Return] ${instance_id} Wait For Add VF Module diff --git a/robot/resources/vid/vid_interface.robot b/robot/resources/vid/vid_interface.robot index bcdc1494..0b804c48 100644 --- a/robot/resources/vid/vid_interface.robot +++ b/robot/resources/vid/vid_interface.robot @@ -37,6 +37,7 @@ Run VID Get Request Login To VID GUI [Documentation] Logs in to VID GUI + [Arguments] ${api_type}=vnf_api # Setup Browser Now being managed by test case ##Setup Browser Go To ${VID_LOGIN_URL} @@ -50,7 +51,8 @@ Login To VID GUI Input Password xpath=//input[@id='password'] ${GLOBAL_VID_PASSWORD} Click Button xpath=//input[@id='loginBtn'] Wait Until Page Contains Welcome to VID ${GLOBAL_SELENIUM_BROWSER_WAIT_TIMEOUT} - Select From List By Label //select[@id='selectTestApi'] VNF_API (old) + Run Keyword If "${api_type}"=="vnf_api" Select From List By Label //select[@id='selectTestApi'] VNF_API (old) + Run Keyword If "${api_type}"=="gr_api" Select From List By Label //select[@id='selectTestApi'] GR_API (new) Log Logged in to ${VID_ENDPOINT}${VID_ENV} Go To VID HOME diff --git a/robot/resources/vvp_validation.robot b/robot/resources/vvp_validation.robot new file mode 100644 index 00000000..de4ba69a --- /dev/null +++ b/robot/resources/vvp_validation.robot @@ -0,0 +1,49 @@ +*** Settings *** +Documentation The main interface for interacting with SDC. It handles low level stuff like managing the http request library and DCAE required fields +Library OperatingSystem +Library ONAPLibrary.SO WITH NAME SO +Library ONAPLibrary.HeatVNFValidation WITH NAME HeatVNFValidation +Library ONAPLibrary.VVPValidation WITH NAME VVPValidation + +*** Variables *** +${CLOUD_CONFIG_PATH} /cloudSite + +*** Keywords *** +Run VVP Validation Scripts + [Documentation] Creates virtualenv and clones VVP scripts to build_dir, executes VVP validation scripts against a template directory, results stored in output directory. + [Arguments] ${build_dir} ${heat_template_directory} ${output_directory} + + VVPValidation.validate ${build_dir} ${heat_template_directory} ${output_directory} + +Run VNF Instantiation Report + [Documentation] Validates that a stack was created correctly, used for OVP portal submission. + [Arguments] ${region_id} ${vnf_details} ${os_password} ${vnf_name} + ${auth}= Create List ${GLOBAL_SO_CATDB_USERNAME} ${GLOBAL_SO_PASSWORD} + ${get_resp}= SO.Run Get Request ${GLOBAL_SO_CATDB_ENDPOINT} ${CLOUD_CONFIG_PATH}/${region_id} auth=${auth} + + ${object}= Evaluate json.loads('''${get_resp.text}''') json + ${auth_url} = Set Variable ${object["identityService"]["identity_url"]} + ${user_id} = Set Variable ${object["identityService"]["mso_id"]} + ${region_id} = Set Variable ${object["region_id"]} + ${tenant_id} = Set Variable ${object["identityService"]["admin_tenant"]} + ${identity_server_type}= Set Variable ${object["identityService"]["identity_server_type"]} + ${identity_server_type}= Set Variable If '${identity_server_type}' == 'KEYSTONE_V3' v3 v2.0 + + Set Global Variable ${GLOBAL_INJECTED_OPENSTACK_KEYSTONE_API_VERSION} ${identity_server_type} + Set Global Variable ${GLOBAL_INJECTED_KEYSTONE} ${auth_url} + Set Global Variable ${GLOBAL_INJECTED_OPENSTACK_PROJECT_NAME} ${tenant_id} + + Run Openstack Auth Request mytest username=${user_id} password=${os_password} + + ${token}= Get Openstack Token mytest + ${orchestration_url}= Get Openstack Service Url mytest orchestration + + ${report}= HeatVNFValidation.validate ${orchestration_url} ${token} ${vnf_details} ${vnf_name} + + ${status}= Get From Dictionary ${report} summary + + ${json_string}= evaluate json.dumps(${report}, indent=4) json + OperatingSystem.Create File ${OUTPUTDIR}/summary/stack_report.json content=${json_string} + + Run Keyword If '${status}' == 'FAILED' Fail Stack Validation Failed + [Return] ${report} diff --git a/robot/testsuites/vnf-orchestration-ovp.robot b/robot/testsuites/vnf-orchestration-ovp.robot new file mode 100644 index 00000000..70d89791 --- /dev/null +++ b/robot/testsuites/vnf-orchestration-ovp.robot @@ -0,0 +1,129 @@ +*** Settings *** +Documentation The main driver for instantiating a generic VNF +Test Teardown Teardown Test + +Library OperatingSystem +Library Process +Library ArchiveLibrary +Library Collections +Library String +Library DateTime +Library ONAPLibrary.ServiceMapping WITH NAME ServiceMapping +Library ONAPLibrary.Utilities +Resource ../resources/test_templates/vnf_orchestration_test_template.robot +Resource ../resources/test_templates/vnf_instantiation_ovp.robot +Resource ../resources/global_properties.robot +Resource ../resources/vvp_validation.robot + +*** Variables *** +${OVP_BUILD_TAG} vnf-validation-${GLOBAL_BUILD_NUMBER} +${OVP_VERSION} 2019.09 +${VNF_CHKSUM} +${SDC_ASSETS_DIRECTORY} ${GLOBAL_HEAT_TEMPLATES_FOLDER} + +${BUILD_DIR}= /tmp/vnfdata.${GLOBAL_BUILD_NUMBER} + +*** Test Cases *** +VNF Instantiation + [Documentation] Instantiate Generic VNF + [Tags] instantiate_vnf_ovp + [Timeout] 3000 + + #### Executing VVP Validation Scripts #### + Run VVP Validation Scripts ${BUILD_DIR} ${BUILD_DIR}/templates/ ${OUTPUTDIR}/summary + + #### Creating Runtime Service Mapping Data From Manifest #### + ${new_vnf_name}= Add Service Mapping + + #### Runtime Service Name #### + ${new_vnf_service_name}= Set Variable ${new_vnf_name}_${GLOBAL_BUILD_NUMBER} + + #### Getting Manifest Data #### + ${subscriber}= Retrieve Manifest Data subscriber + ${service_type}= Retrieve Manifest Data service_type + ${tenant_name}= Retrieve Manifest Data tenant_name + ${region_id}= Retrieve Manifest Data region_id + ${cloud_owner}= Retrieve Manifest Data cloud_owner + ${project_name}= Retrieve Manifest Data project_name + ${owning_entity}= Retrieve Manifest Data owning_entity + ${platform}= Retrieve Manifest Data platform + ${line_of_business}= Retrieve Manifest Data line_of_business + ${api_type}= Retrieve Manifest Data api_type + ${os_password}= Retrieve Manifest Data os_password + + #### Copying Heat Templates To Assett Directory #### + Copy Files ${BUILD_DIR}/templates/* ${SDC_ASSETS_DIRECTORY}/${new_vnf_name}/ + + Log Modeling Service ${new_vnf_service_name} console=yes + ${catalog_service_name} ${catalog_resource_name} ${vf_modules} ${catalog_resources} ${catalog_resource_ids} ${catalog_service_id}= Model Distribution For Directory ${new_vnf_name} ${new_vnf_service_name} + + #### VID Stuff #### + Log Instantiating Service ${new_vnf_service_name} console=yes + ${vnf_details}= Instantiate VNF ${subscriber} ${new_vnf_name} ${service_type} ${new_vnf_service_name} ${catalog_service_name} ${catalog_resource_name} ${vf_modules} ${catalog_resources} ${service_type} ${tenant_name} ${region_id} ${cloud_owner} ${project_name} ${owning_entity} ${api_type} platform=${platform} line_of_business=${line_of_business} + + # sleeping after instantiation, seems to occasionally have some issues if running validation immediately + Sleep 30 + + Run VNF Instantiation Report ${region_id} ${vnf_details} ${os_password} ${new_vnf_name} + +*** Keywords *** +Add Service Mapping + [Documentation] Adding service mapping for this VNF at runtime. This replicates service_mapping.json. + ${json}= OperatingSystem.Get File ${BUILD_DIR}/vnf-details.json + ${object}= Evaluate json.loads('''${json}''') json + + ${vnf_name}= Set Variable ${object["vnf_name"]} + + ${module_list}= Set Variable ${object["modules"]} + + ${template_mapping_list} Create List + ${module_index}= Set Variable 0 + + :FOR ${module} IN @{module_list} + \ ${empty_dict} Create Dictionary + \ ${base}= Set Variable ${module["isBase"]} + \ ${filename}= Set Variable ${module["filename"]} + \ ${index}= Set Variable If '${base}'=='true' 0 ${module_index} + 1 + \ ${name}= Remove String ${filename} .yaml .yml + \ ${preload}= Set Variable ${module["preload"]} + \ set to dictionary ${empty_dict} isBase=${base} template="" vnf_index=${index} name_pattern=${name} preload_file=${preload} + \ Append To List ${template_mapping_list} ${empty_dict} + + ${GLOBAL_SERVICE_TEMPLATE_MAPPING} Create Dictionary + ${GLOBAL_SERVICE_FOLDER_MAPPING} Create Dictionary + ${GLOBAL_SERVICE_VNF_MAPPING} Create Dictionary + ${GLOBAL_SERVICE_GEN_NEUTRON_NETWORK_MAPPING} Create Dictionary + ${GLOBAL_SERVICE_DEPLOYMENT_ARTIFACT_MAPPING} Create Dictionary + ${SERVICE_MAPPING} Create Dictionary + + set to dictionary ${GLOBAL_SERVICE_TEMPLATE_MAPPING} ${vnf_name}=${template_mapping_list} + + ${folder_mapping_list} Create List + Append To List ${folder_mapping_list} ${vnf_name} + set to dictionary ${GLOBAL_SERVICE_FOLDER_MAPPING} ${vnf_name}=${folder_mapping_list} + + ${service_mapping_list} Create List + Append To List ${service_mapping_list} ${vnf_name} + set to dictionary ${GLOBAL_SERVICE_VNF_MAPPING} ${vnf_name}=${service_mapping_list} + + ${neutron_mapping_list} Create List + set to dictionary ${GLOBAL_SERVICE_GEN_NEUTRON_NETWORK_MAPPING} ${vnf_name}=${neutron_mapping_list} + + ${deployment_mapping_list} Create List + set to dictionary ${GLOBAL_SERVICE_DEPLOYMENT_ARTIFACT_MAPPING} ${vnf_name}=${deployment_mapping_list} + + set to dictionary ${SERVICE_MAPPING} GLOBAL_SERVICE_FOLDER_MAPPING=${GLOBAL_SERVICE_FOLDER_MAPPING} GLOBAL_SERVICE_VNF_MAPPING=${GLOBAL_SERVICE_VNF_MAPPING} GLOBAL_SERVICE_GEN_NEUTRON_NETWORK_MAPPING=${GLOBAL_SERVICE_GEN_NEUTRON_NETWORK_MAPPING} GLOBAL_SERVICE_DEPLOYMENT_ARTIFACT_MAPPING=${GLOBAL_SERVICE_DEPLOYMENT_ARTIFACT_MAPPING} GLOBAL_SERVICE_TEMPLATE_MAPPING=${GLOBAL_SERVICE_TEMPLATE_MAPPING} GLOBAL_VALIDATE_NAME_MAPPING= + + ${json_string}= evaluate json.dumps(${SERVICE_MAPPING}) json + OperatingSystem.Create File ${GLOBAL_SERVICE_MAPPING_DIRECTORY}/${vnf_name}/service_mapping.json ${json_string} + [Return] ${vnf_name} + +Retrieve Manifest Data + [Arguments] ${required_key} + ${json}= OperatingSystem.Get File ${BUILD_DIR}/vnf-details.json + ${object}= Evaluate json.loads('''${json}''') json + Dictionary Should Contain Key ${object} ${required_key} msg=ERROR: key "${required_key}" not found in the manifest. + [Return] ${object["${required_key}"]} + +Teardown Test + Remove Directory ${BUILD_DIR} recursive=True -- cgit 1.2.3-korg