fixing play.py and data change counter
[integration/test.git] / csit / libraries / ConfigViaRestconf.robot
index 189d23e75b817ef06ff0f87f180084d2978dfa7c..8c78556e125d71d6a92ffcaa98bafc5f40989ffc 100644 (file)
@@ -6,20 +6,52 @@ Documentation     Robot keyword library (Resource) for runtime changes to config
 ...               This program and the accompanying materials are made available under the
 ...               terms of the Eclipse Public License v1.0 which accompanies this distribution,
 ...               and is available at http://www.eclipse.org/legal/epl-v10.html
+...
+...
+...               The purpose of this library is to make runtime changes to ODL configuration
+...               easier from Robot suite contributor point of view.
+...
+...               Different ODL parts have varying ways of configuration,
+...               this library affects only the Config Subsystem way.
+...               Config Subsystem has (apart Java APIs mostly available only from inside of ODL)
+...               NETCONF server as its publicly available entry point.
+...               Netconf-connector feature makes this netconf server available for RESTCONF calls.
+...               Unfortunately, URIs and data payloads tend to be quite convoluted,
+...               so using RequestsLibrary directly from test cases is unwieldy.
+...
+...               The main strength of this library are *_Template_Folder_Config_Via_Restconf keywords
+...               User gives a path to directory where files with templates for URI fragment
+...               and XML (or JSON) data are present, and a mapping with substitution to make;
+...               the keywords will take it from there.
+...
+...               Prerequisities:
+...               * netconf-connector feature installed on ODL.
+...               * Setup_Config_Via_Restconf called from suite Setup
+...               (or before any other call to a keyword from this library) at least once.
 Library           OperatingSystem
 Library           RequestsLibrary
 Library           String
+Library           ${CURDIR}/HsfJson/hsf_json.py
 Variables         ${CURDIR}/../variables/Variables.py
 
 *** Variables ***
 # TODO: Make the following list more narrow when Bug 2594 is fixed.
 @{allowed_status_codes}    ${200}    ${201}    ${204}    # List of integers, not strings. Used by both PUT and DELETE.
+${cvr_workspace}    /tmp
 
 *** Keywords ***
 Setup_Config_Via_Restconf
     [Documentation]    Creates Requests session to be used by subsequent keywords.
+    ...    Also remembers worspace to use when needed and two temp files for JSON data.
+    # Check for multiple Setup calls.
+    ${variable_was_set}=    BuiltIn.Get_Variable_Value    ${cvr_actfile}    NEVER
+    BuiltIn.Return_From_Keyword_If    '''${variable_was_set}''' != '''NEVER'''
     # Do not append slash at the end uf URL, Requests would add another, resulting in error.
-    RequestsLibrary.Create_Session    cvr_session    http://${CONTROLLER}:${RESTCONFPORT}${CONTROLLER_CONFIG_MOUNT}    headers=${HEADERS_XML}    auth=${AUTH}
+    RequestsLibrary.Create_Session    cvr_session    http://${ODL_SYSTEM_IP}:${RESTCONFPORT}${CONTROLLER_CONFIG_MOUNT}    headers=${HEADERS_XML}    auth=${AUTH}
+    ${workspace_defined}=    BuiltIn.Run_Keyword_And_return_Status    BuiltIn.Variable_Should_Exist    ${WORKSPACE}
+    BuiltIn.Run_Keyword_If    ${workspace_defined}    BuiltIn.Set_Suite_Variable    ${cvr_workspace}    ${WORKSPACE}
+    BuiltIn.Set_Suite_Variable    ${cvr_actfile}    ${cvr_workspace}${/}actual.json
+    BuiltIn.Set_Suite_Variable    ${cvr_expfile}    ${cvr_workspace}${/}expected.json
 
 Teardown_Config_Via_Restconf
     [Documentation]    Teardown to pair with Setup (otherwise no-op).
@@ -33,6 +65,47 @@ Put_Xml_Template_Folder_Config_Via_Restconf
     ${xml_data}=    Resolve_Xml_Data_From_Template_Folder    ${folder}    ${mapping_as_string}
     Put_Xml_Config_Via_Restconf    ${uri_part}    ${xml_data}
 
+Get_Xml_Template_Folder_Config_Via_Restconf
+    [Arguments]    ${folder}    ${mapping_as_string}={}
+    [Documentation]    Resolve URI from folder, GET from controller config in XML form.
+    ${uri_part}=    Resolve_URI_From_Template_Folder    ${folder}    ${mapping_as_string}
+    ${xml_data}=    Get_Xml_Config_Via_Restconf    ${uri_part}
+    [Return]    ${xml_data}
+
+Get_Json_Template_Folder_Config_Via_Restconf
+    [Arguments]    ${folder}    ${mapping_as_string}={}
+    [Documentation]    Resolve URI from folder, GET from controller config in JSON form.
+    ${uri_part}=    Resolve_URI_From_Template_Folder    ${folder}    ${mapping_as_string}
+    ${json_string}=    Get_Json_Config_Via_Restconf    ${uri_part}
+    [Return]    ${json_string}
+
+Verify_Xml_Template_Folder_Config_Via_Restconf
+    [Arguments]    ${folder}    ${mapping_as_string}={}
+    [Documentation]    Resolve URI from folder, GET from controller config, compare to expected data.
+    # FIXME: This is subject to pseudorandom field ordering issue, use with care.
+    ${expected_data}=    Resolve_Xml_Data_From_Template_Folder    ${folder}    ${mapping_as_string}
+    ${actual_data}=    Get_Xml_Template_Folder_Config_Via_Restconf    ${folder}    ${mapping_as_string}
+    BuiltIn.Should_Be_Equal    ${actual_data}    ${expected_data}
+
+Verify_Json_Template_Folder_Config_Via_Restconf
+    [Arguments]    ${folder}    ${mapping_as_string}={}
+    [Documentation]    Resolve URI from folder, GET from controller config, compare to expected data as normalized JSONs.
+    ${expected}=    Resolve_Json_Data_From_Template_Folder    ${folder}    ${mapping_as_string}
+    ${actual}=    Get_Json_Template_Folder_Config_Via_Restconf    ${folder}    ${mapping_as_string}
+    Normalize_Jsons_And_Compare    ${actual}    ${expected}
+
+Normalize_Jsons_And_Compare
+    [Arguments]    ${actual_raw}    ${expected_raw}
+    [Documentation]    Use HsfJson to normalize both arguments, compute and Log diff, fail if diff is non-empty.
+    ...    This keywords assumes ${WORKSPACE} is defined as a suite variable.
+    ${actual_normalized}=    hsf_json.Hsf_Json    ${actual_raw}
+    ${expected_normalized}=    hsf_json.Hsf_Json    ${expected_raw}
+    OperatingSystem.Create_File    ${cvr_expfile}    ${expected_normalized}
+    OperatingSystem.Create_File    ${cvr_actfile}    ${actual_normalized}
+    ${diff}=    OperatingSystem.Run    diff -du '${cvr_expfile}' '${cvr_actfile}'
+    BuiltIn.Log    ${diff}
+    BuiltIn.Should_Be_Empty    ${diff}
+
 Delete_Xml_Template_Folder_Config_Via_Restconf
     [Arguments]    ${folder}    ${mapping_as_string}={}
     [Documentation]    Resolve URI from folder, DELETE from controller config.
@@ -42,19 +115,30 @@ Delete_Xml_Template_Folder_Config_Via_Restconf
 Resolve_URI_From_Template_Folder
     [Arguments]    ${folder}    ${mapping_as_string}
     [Documentation]    Read URI template from folder, strip endline, make changes according to mapping, return the result.
-    ${uri_template}=    OperatingSystem.Get_File    ${folder}${/}config.uri
+    ${status}    ${uri_template}=    BuiltIn.Run_Keyword_And_Ignore_Error    OperatingSystem.Get_File    ${folder}${/}config.uri.${ODL_STREAM}
+    ${uri_template}=     BuiltIn.Run Keyword If     '${status}' != 'PASS'    OperatingSystem.Get_File    ${folder}${/}config.uri    ELSE   BuiltIn.Set Variable    ${uri_template}
     BuiltIn.Log    ${uri_template}
     ${uri_part}=    Strip_Endline_And_Apply_Substitutions_From_Mapping    ${uri_template}    ${mapping_as_string}
     [Return]    ${uri_part}
 
 Resolve_Xml_Data_From_Template_Folder
     [Arguments]    ${folder}    ${mapping_as_string}
-    [Documentation]    Read data template from folder, strip endline, make changes according to mapping, return the result.
-    ${data_template}=    OperatingSystem.Get_File    ${folder}${/}data.xml
+    [Documentation]    Read XML data template from folder, strip endline, make changes according to mapping, return the result.
+    ${status}    ${data_template}=    BuiltIn.Run_Keyword_And_Ignore_Error    OperatingSystem.Get_File    ${folder}${/}data.xml.${ODL_STREAM}
+    ${data_template}=     BuiltIn.Run Keyword If     '${status}' != 'PASS'    OperatingSystem.Get_File    ${folder}${/}data.xml    ELSE   BuiltIn.Set Variable    ${data_template}
     BuiltIn.Log    ${data_template}
     ${xml_data}=    Strip_Endline_And_Apply_Substitutions_From_Mapping    ${data_template}    ${mapping_as_string}
     [Return]    ${xml_data}
 
+Resolve_Json_Data_From_Template_Folder
+    [Arguments]    ${folder}    ${mapping_as_string}
+    [Documentation]    Read JSON data template from folder, strip endline, make changes according to mapping, return the result.
+    ${status}    ${data_template}=    BuiltIn.Run_Keyword_And_Ignore_Error    OperatingSystem.Get_File    ${folder}${/}data.json.${ODL_STREAM}
+    ${data_template}=     BuiltIn.Run Keyword If     '${status}' != 'PASS'    OperatingSystem.Get_File    ${folder}${/}data.json    ELSE   BuiltIn.Set Variable    ${data_template}
+    BuiltIn.Log    ${data_template}
+    ${json_data}=    Strip_Endline_And_Apply_Substitutions_From_Mapping    ${data_template}    ${mapping_as_string}
+    [Return]    ${json_data}
+
 Strip_Endline_And_Apply_Substitutions_From_Mapping
     [Arguments]    ${template_as_string}    ${mapping_as_string}
     [Documentation]    Strip endline, apply substitutions, Log and return the result.
@@ -81,17 +165,37 @@ Put_Xml_Config_Via_Restconf
     [Documentation]    Put XML data to given controller-config URI, check reponse text is empty and status_code is one of allowed ones.
     BuiltIn.Log    ${uri_part}
     BuiltIn.Log    ${xml_data}
-    ${response}=    RequestsLibrary.Put    cvr_session    ${uri_part}    data=${xml_data}
+    ${response}=    RequestsLibrary.Put Request    cvr_session    ${uri_part}    data=${xml_data}
     BuiltIn.Log    ${response.text}
     BuiltIn.Log    ${response.status_code}
     BuiltIn.Should_Be_Empty    ${response.text}
     BuiltIn.Should_Contain    ${allowed_status_codes}    ${response.status_code}
 
+Get_Xml_Config_Via_Restconf
+    [Arguments]    ${uri_part}
+    [Documentation]    Get XML data from given controller-config URI, check status_code is one of allowed ones, return response text.
+    BuiltIn.Log    ${uri_part}
+    ${response}=    RequestsLibrary.Get Request    cvr_session    ${uri_part}    headers=${ACCEPT_XML}
+    BuiltIn.Log    ${response.text}
+    BuiltIn.Log    ${response.status_code}
+    BuiltIn.Should_Contain    ${allowed_status_codes}    ${response.status_code}
+    [Return]    ${response.text}
+
+Get_Json_Config_Via_Restconf
+    [Arguments]    ${uri_part}
+    [Documentation]    Get XML data from given controller-config URI, check status_code is one of allowed ones, return response text.
+    BuiltIn.Log    ${uri_part}
+    ${response}=    RequestsLibrary.Get Request    cvr_session    ${uri_part}    headers=${ACCEPT_JSON}
+    BuiltIn.Log    ${response.text}
+    BuiltIn.Log    ${response.status_code}
+    BuiltIn.Should_Contain    ${allowed_status_codes}    ${response.status_code}
+    [Return]    ${response.text}
+
 Delete_Config_Via_Restconf
     [Arguments]    ${uri_part}
     [Documentation]    Delete resource at controller-config URI, check reponse text is empty and status_code is 204.
     BuiltIn.Log    ${uri_part}
-    ${response}=    RequestsLibrary.Delete    cvr_session    ${uri_part}
+    ${response}=    RequestsLibrary.Delete Request    cvr_session    ${uri_part}
     BuiltIn.Log    ${response.text}
     BuiltIn.Should_Be_Empty    ${response.text}
     BuiltIn.Should_Contain    ${allowed_status_codes}    ${response.status_code}
@@ -116,4 +220,5 @@ Post_Xml_Config_Via_Restconf
     ${response}=    RequestsLibrary.Post_Request    cvr_session    ${uri_part}    data=${xml_data}
     BuiltIn.Log    ${response.text}
     BuiltIn.Should_Be_Empty    ${response.text}
+    # TODO: status_code is integrer, so compare to ${204}. Also, there is a Improvement for 201 to be a better code.
     BuiltIn.Should_Be_Equal_As_Strings    ${response.status_code}    204