CSIT for Yang 1.1 actions
[integration/test.git] / csit / libraries / TemplatedRequests.robot
index 928a84f137aeae8afe04c974b44cdb1cc673cbe5..e514d1f10bb5343258f7626dd2db65e132c6cb82 100644 (file)
@@ -110,24 +110,26 @@ Documentation     Resource for supporting http Requests based on data stored in
 ...               perhaps explicit ${ACCEPT_JSON} will be better, even if it sends few bytes more?
 Library           Collections
 Library           OperatingSystem
+Library           String
 Library           RequestsLibrary
 Library           ${CURDIR}/norm_json.py
-Variables         ${CURDIR}/../variables/Variables.py
+Resource          ${CURDIR}/../variables/Variables.robot
 
 *** Variables ***
 # TODO: Make the following list more narrow when streams without Bug 2594 fix (up to beryllium) are no longer used.
+@{ALLOWED_DELETE_STATUS_CODES}    ${200}    ${201}    ${204}    ${404}    # List of integers, not strings. Used by DELETE if the resource may be not present.
 @{ALLOWED_STATUS_CODES}    ${200}    ${201}    ${204}    # List of integers, not strings. Used by both PUT and DELETE (if the resource should have been present).
-@{DATA_VALIDATION_ERROR}    ${500}
+@{DATA_VALIDATION_ERROR}    ${400}    # For testing mildly negative scenarios where ODL reports user error.
 @{DELETED_STATUS_CODE}    ${404}    # List of integers, not strings. Used by DELETE if the resource may be not present.
+# TODO: Add option for delete to require 404.
+@{INTERNAL_SERVER_ERROR}    ${500}    # Only for testing severely negative scenarios where ODL cannot recover.
+@{KEYS_WITH_BITS}    op    # the default list with keys to be sorted when norm_json libray is used
 @{NO_STATUS_CODES}
-@{ALLOWED_DELETE_STATUS_CODES}    ${200}    ${201}    ${204}    ${404}    # List of integers, not strings. Used by DELETE if the resource may be not present.
 @{UNAUTHORIZED_STATUS_CODES}    ${401}    # List of integers, not strings. Used in Keystone Authentication when the user is not authorized to use the requested resource.
-@{KEYS_WITH_BITS}    op    # the default list with keys to be sorted when norm_json libray is used
-# TODO: Add option for delete to require 404.
 
 *** Keywords ***
 Create_Default_Session
-    [Arguments]    ${url}=http://${ODL_SYSTEM_IP}:${RESTCONFPORT}    ${auth}=${AUTH}    ${timeout}=1    ${max_retries}=0
+    [Arguments]    ${url}=http://${ODL_SYSTEM_IP}:${RESTCONFPORT}    ${auth}=${AUTH}    ${timeout}=${DEFAULT_TIMEOUT_HTTP}    ${max_retries}=0
     [Documentation]    Create "default" session to ${url} with authentication and connection parameters.
     ...    This Keyword is in this Resource only so that user do not need to call RequestsLibrary directly.
     RequestsLibrary.Create_Session    alias=default    url=${url}    auth=${auth}    timeout=${timeout}    max_retries=${max_retries}
@@ -196,6 +198,23 @@ Post_As_Json_Templated
     BuiltIn.Run_Keyword_If    ${verify}    Verify_Response_As_Json_Templated    response=${response_text}    folder=${folder}    base_name=response    mapping=${mapping}
     [Return]    ${response_text}
 
+Post_As_Json_Rfc8040_Templated
+    [Arguments]    ${folder}    ${mapping}={}    ${session}=default    ${verify}=False    ${iterations}=${EMPTY}    ${iter_start}=1
+    ...    ${additional_allowed_status_codes}=${NO_STATUS_CODES}    ${explicit_status_codes}=${NO_STATUS_CODES}    ${http_timeout}=${EMPTY}
+    [Documentation]    Add arguments sensible for JSON data, return Post_Templated response text.
+    ...    Optionally, verification against response.json (no iteration) is called.
+    ...    Only subset of JSON data is verified and returned if JMES path is specified in
+    ...    file ${folder}${/}jmespath.expr.
+    ...    Response status code must be one of values from ${explicit_status_codes} if specified or one of set
+    ...    created from all positive HTTP status codes together with ${additional_allowed_status_codes}.
+    ...    RFC8040 defines RESTCONF protocol, for configuring data defined in YANG version 1
+    ...    or YANG version 1.1, using the datastore concepts defined in NETCONF.
+    ${response_text} =    Post_Templated    folder=${folder}    base_name=data    extension=json    accept=${ACCEPT_EMPTY}    content_type=${HEADERS_YANG_RFC8040_JSON}
+    ...    mapping=${mapping}    session=${session}    normalize_json=True    endline=${\n}    iterations=${iterations}    iter_start=${iter_start}
+    ...    additional_allowed_status_codes=${additional_allowed_status_codes}    explicit_status_codes=${explicit_status_codes}    http_timeout=${http_timeout}
+    BuiltIn.Run_Keyword_If    ${verify}    Verify_Response_As_Json_Templated    response=${response_text}    folder=${folder}    base_name=response    mapping=${mapping}
+    [Return]    ${response_text}
+
 Post_As_Xml_Templated
     [Arguments]    ${folder}    ${mapping}={}    ${session}=default    ${verify}=False    ${iterations}=${EMPTY}    ${iter_start}=1
     ...    ${additional_allowed_status_codes}=${NO_STATUS_CODES}    ${explicit_status_codes}=${NO_STATUS_CODES}    ${http_timeout}=${EMPTY}
@@ -209,9 +228,9 @@ Post_As_Xml_Templated
     [Return]    ${response_text}
 
 Delete_Templated
-    [Arguments]    ${folder}    ${mapping}={}    ${session}=default    ${additional_allowed_status_codes}=${NO_STATUS_CODES}    ${http_timeout}=${EMPTY}
+    [Arguments]    ${folder}    ${mapping}={}    ${session}=default    ${additional_allowed_status_codes}=${NO_STATUS_CODES}    ${http_timeout}=${EMPTY}    ${location}=location
     [Documentation]    Resolve URI from folder, issue DELETE request.
-    ${uri} =    Resolve_Text_From_Template_Folder    folder=${folder}    base_name=location    extension=uri    mapping=${mapping}
+    ${uri} =    Resolve_Text_From_Template_Folder    folder=${folder}    base_name=${location}    extension=uri    mapping=${mapping}
     ${response_text} =    Delete_From_Uri    uri=${uri}    session=${session}    additional_allowed_status_codes=${additional_allowed_status_codes}    http_timeout=${http_timeout}
     [Return]    ${response_text}
 
@@ -291,13 +310,24 @@ Resolve_Jmes_Path
     ${expression} =    BuiltIn.Set Variable If    ${read_jmes_file} == ${true}    ${jmes_expression}    ${EMPTY}
     [Return]    ${expression}
 
+Resolve_Volatiles_Path
+    [Arguments]    ${folder}
+    [Documentation]    Reads Volatiles List from file ${folder}${/}volatiles.list if the file exists and
+    ...    returns the Volatiles List. Empty string is returned otherwise.
+    ${read_volatiles_file} =    BuiltIn.Run Keyword And Return Status    OperatingSystem.File Should Exist    ${folder}${/}volatiles.list
+    Return From Keyword If    ${read_volatiles_file} == ${false}    ${EMPTY}
+    ${volatiles}=    OperatingSystem.Get_File    ${folder}${/}volatiles.list
+    ${volatiles_list}=    String.Split_String    ${volatiles}    ${\n}
+    [Return]    ${volatiles_list}
+
 Get_Templated
     [Arguments]    ${folder}    ${accept}    ${mapping}={}    ${session}=default    ${normalize_json}=False    ${http_timeout}=${EMPTY}
     [Documentation]    Resolve URI from folder, call Get_From_Uri, return response text.
     ${uri} =    Resolve_Text_From_Template_Folder    folder=${folder}    base_name=location    extension=uri    mapping=${mapping}
     ${jmes_expression} =    Resolve_Jmes_Path    ${folder}
+    ${volatiles_list}=    Resolve_Volatiles_Path    ${folder}
     ${response_text} =    Get_From_Uri    uri=${uri}    accept=${accept}    session=${session}    normalize_json=${normalize_json}    jmes_path=${jmes_expression}
-    ...    http_timeout=${http_timeout}
+    ...    http_timeout=${http_timeout}    keys_with_volatiles=${volatiles_list}
     [Return]    ${response_text}
 
 Put_Templated
@@ -339,6 +369,7 @@ Verify_Response_Templated
 
 Get_From_Uri
     [Arguments]    ${uri}    ${accept}=${ACCEPT_EMPTY}    ${session}=default    ${normalize_json}=False    ${jmes_path}=${EMPTY}    ${http_timeout}=${EMPTY}
+    ...    ${keys_with_volatiles}=${EMPTY}
     [Documentation]    GET data from given URI, check status code and return response text.
     ...    \${accept} is a Python object with headers to use.
     ...    If \${normalize_json}, normalize as JSON text before returning.
@@ -348,7 +379,7 @@ Get_From_Uri
     ...    ELSE    RequestsLibrary.Get_Request    alias=${session}    uri=${uri}    headers=${accept}    timeout=${http_timeout}
     Check_Status_Code    ${response}
     BuiltIn.Run_Keyword_Unless    ${normalize_json}    BuiltIn.Return_From_Keyword    ${response.text}
-    ${text_normalized} =    norm_json.normalize_json_text    ${response.text}    jmes_path=${jmes_path}
+    ${text_normalized} =    norm_json.normalize_json_text    ${response.text}    jmes_path=${jmes_path}    keys_with_volatiles=${keys_with_volatiles}
     [Return]    ${text_normalized}
 
 Put_To_Uri
@@ -397,8 +428,16 @@ Check_Status_Code
     # TODO: Remove overlap with keywords from Utils.robot
     BuiltIn.Log    ${response.text}
     BuiltIn.Log    ${response.status_code}
-    BuiltIn.Run_Keyword_And_Return_If    """${explicit_status_codes}""" != """${NO_STATUS_CODES}"""    Collections.List_Should_Contain_Value    ${explicit_status_codes}    ${response.status_code}
-    ${final_allowd_list} =    Collections.Combine_Lists    ${ALLOWED_STATUS_CODES}    ${additional_allowed_status_codes}
+    # In order to allow other existing keywords to consume this keyword by passing a single non-list status code, we need to
+    # check the type of the argument passed and convert those single non-list codes in to a one item list
+    ${status_codes_type} =    Evaluate    type($additional_allowed_status_codes).__name__
+    ${allowed_status_codes_list} =    Run Keyword If    "${status_codes_type}"!="list"    Create List    ${additional_allowed_status_codes}
+    ...    ELSE    Set Variable    ${additional_allowed_status_codes}
+    ${status_codes_type} =    Evaluate    type($explicit_status_codes).__name__
+    ${explicit_status_codes_list} =    Run Keyword If    "${status_codes_type}"!="list"    Create List    ${explicit_status_codes}
+    ...    ELSE    Set Variable    ${explicit_status_codes}
+    BuiltIn.Run_Keyword_And_Return_If    """${explicit_status_codes_list}""" != """${NO_STATUS_CODES}"""    Collections.List_Should_Contain_Value    ${explicit_status_codes_list}    ${response.status_code}
+    ${final_allowd_list} =    Collections.Combine_Lists    ${ALLOWED_STATUS_CODES}    ${allowed_status_codes_list}
     Collections.List_Should_Contain_Value    ${final_allowd_list}    ${response.status_code}
 
 Join_Two_Headers