[INT] Add testsuite for vnf lifecycle validation 85/94485/9
authorstark, steven <steven.stark@att.com>
Wed, 28 Aug 2019 23:11:53 +0000 (16:11 -0700)
committerDaniel Rose <dr695h@att.com>
Thu, 12 Sep 2019 21:58:03 +0000 (21:58 +0000)
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 <steven.stark@att.com>
docker/Dockerfile
robot/resources/sdnc_interface.robot
robot/resources/test_templates/vnf_instantiation_ovp.robot [new file with mode: 0644]
robot/resources/vid/create_vid_vnf.robot
robot/resources/vid/vid_interface.robot
robot/resources/vvp_validation.robot [new file with mode: 0644]
robot/testsuites/vnf-orchestration-ovp.robot [new file with mode: 0644]

index 786538a..f98a360 100644 (file)
@@ -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
index 198e364..9b56fef 100644 (file)
@@ -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 (file)
index 0000000..ea7b0f9
--- /dev/null
@@ -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 #####
index ea3cf12..575863b 100644 (file)
@@ -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
index bcdc149..0b804c4 100644 (file)
@@ -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 (file)
index 0000000..de4ba69
--- /dev/null
@@ -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 (file)
index 0000000..70d8979
--- /dev/null
@@ -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