CSIT for Yang 1.1 actions 58/84858/6
authoresobmar <mariusz.sobucki@est.tech>
Tue, 1 Oct 2019 16:53:26 +0000 (17:53 +0100)
committeresobmar <mariusz.sobucki@est.tech>
Mon, 7 Oct 2019 17:51:36 +0000 (18:51 +0100)
Change-Id: I49a579fd0231ba74ebbe96ef653fbd6af0a9b65a
JIRA: NETCONF-636
Signed-off-by: mariusz.sobucki@est.tech
csit/libraries/NetconfKeywords.robot
csit/libraries/TemplatedRequests.robot
csit/suites/netconf/CRUD-ACTION/CRUD-ACTION.robot [new file with mode: 0644]
csit/testplans/netconf-userfeatures-magnesium.txt [new file with mode: 0644]
csit/testplans/netconf-userfeatures-sodium.txt [new file with mode: 0644]
csit/variables/Variables.robot
csit/variables/netconf/CRUD/customaction/customaction.xml [new file with mode: 0644]
csit/variables/netconf/CRUD/dataorigaction/location.uri [new file with mode: 0644]
csit/variables/netconf/CRUD/dataorigaction/post_data.json [new file with mode: 0644]
csit/variables/netconf/CRUD/dataorigaction/post_data.xml [new file with mode: 0644]
csit/variables/netconf/CRUD/schemas/example-action@2016-07-07.yang [new file with mode: 0644]

index a47c2c64636f0968a36b4b2ee75c39ed76169bc6..afa32772d2c2769134e79e2bce5b726c34a57a9f 100644 (file)
@@ -141,6 +141,16 @@ NetconfKeywords__Deploy_Additional_Schemas
     SSHLibrary.Put_Directory    ${schemas}    destination=./schemas
     [Return]    --schemas-dir ./schemas
 
+NetconfKeywords__Deploy_Custom_RPC
+    [Arguments]    ${rpc_config}
+    [Documentation]    Internal keyword for Install_And_Start_TestTool
+    ...    This deploys the optional custom rpc file.
+    ...    Drop out of the keyword, returning no command line argument when there
+    ...    is no rpc file to deploy.
+    BuiltIn.Return_From_Keyword_If    '${rpc_config}' == 'none'    ${EMPTY}
+    SSHKeywords.Copy_File_To_Tools_System    ${TOOLS_SYSTEM_1_IP}    ${rpc_config}    /tmp
+    [Return]    --rpc-config /tmp/customaction.xml
+
 NetconfKeywords__Check_Device_Is_Up
     [Arguments]    ${last-port}
     ${count}=    SSHKeywords.Count_Port_Occurences    ${last-port}    LISTEN    java
@@ -152,22 +162,24 @@ NetconfKeywords__Wait_Device_Is_Up_And_Running
     BuiltIn.Wait_Until_Keyword_Succeeds    ${TESTTOOL_BOOT_TIMEOUT}    1s    Check_Device_Up_And_Running    ${number}
 
 Install_And_Start_Testtool
-    [Arguments]    ${device-count}=10    ${debug}=true    ${schemas}=none    ${tool_options}=${EMPTY}    ${java_options}=${TESTTOOL_DEFAULT_JAVA_OPTIONS}    ${mdsal}=true
+    [Arguments]    ${device-count}=10    ${debug}=true    ${schemas}=none    ${rpc_config}=none    ${tool_options}=${EMPTY}    ${java_options}=${TESTTOOL_DEFAULT_JAVA_OPTIONS}
+    ...    ${mdsal}=true
     [Documentation]    Install and run testtool.
     ${filename}=    NexusKeywords.Deploy_Test_Tool    netconf    netconf-testtool
-    Start_Testtool    ${filename}    ${device-count}    ${debug}    ${schemas}    ${tool_options}    ${java_options}
-    ...    ${mdsal}
+    Start_Testtool    ${filename}    ${device-count}    ${debug}    ${schemas}    ${rpc_config}    ${tool_options}
+    ...    ${java_options}    ${mdsal}
 
 Start_Testtool
-    [Arguments]    ${filename}    ${device-count}=10    ${debug}=true    ${schemas}=none    ${tool_options}=${EMPTY}    ${java_options}=${TESTTOOL_DEFAULT_JAVA_OPTIONS}
-    ...    ${mdsal}=true
+    [Arguments]    ${filename}    ${device-count}=10    ${debug}=true    ${schemas}=none    ${rpc_config}=none    ${tool_options}=${EMPTY}
+    ...    ${java_options}=${TESTTOOL_DEFAULT_JAVA_OPTIONS}    ${mdsal}=true
     [Documentation]    Arrange to collect tool's output into a log file.
     ...    Will use specific ${schemas} unless argument resolves to 'none',
     ...    which signifies that there are no additional schemas to be deployed.
     ...    If so the directory for the additional schemas is deleted on the
     ...    remote machine and the additional schemas argument is left out.
     ${schemas_option}=    NetconfKeywords__Deploy_Additional_Schemas    ${schemas}
-    ${command}=    NexusKeywords.Compose_Full_Java_Command    ${java_options} -jar ${filename} ${tool_options} --device-count ${device-count} --debug ${debug} ${schemas_option} --md-sal ${mdsal}
+    ${rpc_config_option}=    NetconfKeywords__Deploy_Custom_RPC    ${rpc_config}
+    ${command}=    NexusKeywords.Compose_Full_Java_Command    ${java_options} -jar ${filename} ${tool_options} --device-count ${device-count} --debug ${debug} ${schemas_option} ${rpc_config_option} --md-sal ${mdsal}
     BuiltIn.Log    Running testtool: ${command}
     ${logfile}=    Utils.Get_Log_File_Name    testtool
     BuiltIn.Set_Suite_Variable    ${testtool_log}    ${logfile}
index 17ad4b7c857d3ca191fd7a81ccd279280150a6a5..e514d1f10bb5343258f7626dd2db65e132c6cb82 100644 (file)
@@ -198,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}
diff --git a/csit/suites/netconf/CRUD-ACTION/CRUD-ACTION.robot b/csit/suites/netconf/CRUD-ACTION/CRUD-ACTION.robot
new file mode 100644 (file)
index 0000000..d5d00e7
--- /dev/null
@@ -0,0 +1,121 @@
+*** Settings ***
+Documentation     netconf-connector CRUD-Action test suite.
+...
+...               Copyright (c) 2019 Ericsson Software Technology AB. All rights reserved.
+...
+...               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
+...
+...
+...               Perform basic operations (Create, Read, Update and Delete or CRUD) on device
+...               data mounted onto a netconf connector using RPC for node supporting Yang 1.1
+...               addition and see if invoking Action Operation work.
+Suite Setup       Setup_Everything
+Suite Teardown    Teardown_Everything
+Test Setup        SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+Library           Collections
+Library           RequestsLibrary
+Library           OperatingSystem
+Library           String
+Library           SSHLibrary    timeout=10s
+Resource          ${CURDIR}/../../../libraries/CompareStream.robot
+Resource          ${CURDIR}/../../../libraries/FailFast.robot
+Resource          ${CURDIR}/../../../libraries/NetconfKeywords.robot
+Resource          ${CURDIR}/../../../libraries/SetupUtils.robot
+Resource          ${CURDIR}/../../../libraries/TemplatedRequests.robot
+Resource          ${CURDIR}/../../../variables/Variables.robot
+
+*** Variables ***
+${DIRECTORY_WITH_TEMPLATE_FOLDERS}    ${CURDIR}/../../../variables/netconf/CRUD
+${DEVICE_NAME}    netconf-test-device
+${DEVICE_TYPE_RPC}    rpc-device
+${DEVICE_TYPE_RPC_CREATE}    rpc-create-device
+${DEVICE_TYPE_RPC_DELETE}    rpc-delete-device
+${USE_NETCONF_CONNECTOR}    ${False}
+${DELETE_LOCATION}    delete_location
+${RPC_FILE}       ${CURDIR}/../../../variables/netconf/CRUD/customaction/customaction.xml
+
+*** Test Cases ***
+Check_Device_Is_Not_Configured_At_Beginning
+    [Documentation]    Sanity check making sure our device is not there. Fail if found.
+    [Tags]    critical
+    NetconfKeywords.Check_Device_Has_No_Netconf_Connector    ${DEVICE_NAME}
+
+Configure_Device_On_Netconf
+    [Documentation]    Make request to configure a testtool device on Netconf connector.
+    [Tags]    critical
+    NetconfKeywords.Configure_Device_In_Netconf    ${DEVICE_NAME}    device_type=${DEVICE_TYPE}    http_timeout=2    http_method=post
+
+Check_ODL_Has_Netconf_Connector_For_Device
+    [Documentation]    Get the list of configured devices and search for our device there. Fail if not found.
+    [Tags]    critical
+    ${count} =    NetconfKeywords.Count_Netconf_Connectors_For_Device    ${DEVICE_NAME}
+    Builtin.Should_Be_Equal_As_Strings    ${count}    1
+
+Wait_For_Device_To_Become_Connected
+    [Documentation]    Wait until the device becomes available through Netconf.
+    NetconfKeywords.Wait_Device_Connected    ${DEVICE_NAME}
+
+Check_Device_Data_Is_Empty
+    [Documentation]    Get the device data and make sure it is empty.
+    Run_Keyword_If_Less_Than_Neon    Check_Config_Data    <data xmlns\="${ODL_NETCONF_NAMESPACE}"></data>
+    Run_Keyword_If_At_Least_Neon    Check_Config_Data    <data xmlns\="${ODL_NETCONF_NAMESPACE}"/>
+
+Invoke_Yang1.1_Action_Via_Xml_Post
+    [Documentation]    Send a sample test data label into the device and check that the request went OK.
+    ${template_as_string} =    BuiltIn.Set_Variable    {'DEVICE_NAME': '${DEVICE_NAME}'}
+    TemplatedRequests.Post_As_Xml_Templated    ${DIRECTORY_WITH_TEMPLATE_FOLDERS}${/}dataorigaction    ${template_as_string}
+
+Invoke_Yang1.1_Action_Via_Json_Post
+    [Documentation]    Send a sample test data label into the device and check that the request went OK.
+    ${template_as_string} =    BuiltIn.Set_Variable    {'DEVICE_NAME': '${DEVICE_NAME}'}
+    TemplatedRequests.Post_As_Json_RFC8040_Templated    ${DIRECTORY_WITH_TEMPLATE_FOLDERS}${/}dataorigaction    ${template_as_string}
+
+Deconfigure_Device_From_Netconf
+    [Documentation]    Make request to deconfigure the testtool device on Netconf connector.
+    [Tags]    critical
+    [Setup]    SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+    CompareStream.Run_Keyword_If_At_Most_Nitrogen    NetconfKeywords.Remove_Device_From_Netconf    ${DEVICE_NAME}    location=${DELETE_LOCATION}
+    CompareStream.Run_Keyword_If_At_Least_Oxygen    NetconfKeywords.Configure_Device_In_Netconf    ${DEVICE_NAME}    device_type=${DEVICE_TYPE_RPC_DELETE}    http_timeout=2    http_method=post
+
+Check_Device_Going_To_Be_Gone_After_Deconfiguring
+    [Documentation]    Check that the device is really going to be gone. Fail
+    ...    if found after one minute. This is an expected behavior as the
+    ...    delete request is sent to the config subsystem which then triggers
+    ...    asynchronous destruction of the netconf connector referring to the
+    ...    device and the device's data. This test makes sure this
+    ...    asynchronous operation does not take unreasonable amount of time
+    ...    by making sure that both the netconf connector and the device's
+    ...    data is gone before reporting success.
+    [Tags]    critical
+    NetconfKeywords.Wait_Device_Fully_Removed    ${DEVICE_NAME}
+
+*** Keywords ***
+Setup_Everything
+    [Documentation]    Initialize SetupUtils. Setup everything needed for the test cases.
+    SetupUtils.Setup_Utils_For_Setup_And_Teardown
+    RequestsLibrary.Create_Session    operational    http://${ODL_SYSTEM_IP}:${RESTCONFPORT}${OPERATIONAL_API}    auth=${AUTH}
+    NetconfKeywords.Setup_Netconf_Keywords
+    ${DEVICE_TYPE_RPC} =    BuiltIn.Set_Variable_If    """${USE_NETCONF_CONNECTOR}""" == """True"""    default    ${DEVICE_TYPE_RPC}
+    ${DEVICE_TYPE} =    CompareStream.Set_Variable_If_At_Most_Nitrogen    ${DEVICE_TYPE_RPC}    ${DEVICE_TYPE_RPC_CREATE}
+    BuiltIn.Set_Suite_Variable    ${DEVICE_TYPE}
+    OperatingSystem.File Should Exist    ${RPC_FILE}
+    NetconfKeywords.Install_And_Start_Testtool    device-count=1    schemas=${CURDIR}/../../../variables/netconf/CRUD/schemas    rpc_config=${RPC_FILE}
+
+Teardown_Everything
+    [Documentation]    Teardown the test infrastructure, perform cleanup and release all resources.
+    RequestsLibrary.Delete_All_Sessions
+    BuiltIn.Run_Keyword_And_Ignore_Error    NetconfKeywords.Stop_Testtool
+
+Get_Config_Data
+    [Documentation]    Get and return the config data from the device.
+    ${url} =    Builtin.Set_Variable    ${CONFIG_API}/network-topology:network-topology/topology/topology-netconf/node/${DEVICE_NAME}/yang-ext:mount
+    ${data} =    TemplatedRequests.Get_As_Xml_From_Uri    ${url}
+    [Return]    ${data}
+
+Check_Config_Data
+    [Arguments]    ${expected}    ${contains}=False
+    ${data} =    Get_Config_Data
+    BuiltIn.Run_Keyword_Unless    ${contains}    BuiltIn.Should_Be_Equal_As_Strings    ${data}    ${expected}
+    BuiltIn.Run_Keyword_If    ${contains}    BuiltIn.Should_Contain    ${data}    ${expected}
diff --git a/csit/testplans/netconf-userfeatures-magnesium.txt b/csit/testplans/netconf-userfeatures-magnesium.txt
new file mode 100644 (file)
index 0000000..4766d7a
--- /dev/null
@@ -0,0 +1,9 @@
+# Place the suites in run order:
+integration/test/csit/suites/netconf/ready
+integration/test/csit/suites/netconf/apidocs
+integration/test/csit/suites/netconf/MDSAL
+integration/test/csit/suites/netconf/CRUD
+integration/test/csit/suites/netconf/CRUD-ACTION
+integration/test/csit/suites/netconf/notifications
+integration/test/csit/suites/netconf/KeyAuth
+
diff --git a/csit/testplans/netconf-userfeatures-sodium.txt b/csit/testplans/netconf-userfeatures-sodium.txt
new file mode 100644 (file)
index 0000000..4766d7a
--- /dev/null
@@ -0,0 +1,9 @@
+# Place the suites in run order:
+integration/test/csit/suites/netconf/ready
+integration/test/csit/suites/netconf/apidocs
+integration/test/csit/suites/netconf/MDSAL
+integration/test/csit/suites/netconf/CRUD
+integration/test/csit/suites/netconf/CRUD-ACTION
+integration/test/csit/suites/netconf/notifications
+integration/test/csit/suites/netconf/KeyAuth
+
index 2f887c8599613beb08cb8b153be15578721709cf..b02836c201edcddc5560211b60ed25cd5a6bc4c7 100644 (file)
@@ -92,6 +92,7 @@ ${GET_DASHBOARDRECORD}    /restconf/operational/dashboardrule:dashboardRecord/
 ${GET_INTENTS_URI}    /retconf/config/intent:intents    # FIXME: Move to a separate Nemo-related Resource and add description.
 &{HEADERS}        Content-Type=application/json    # Deprecated. Sometimes conflicts with argument name. TODO: Migrate most suites to TemplatedRequests, then chose a more descriptive name.
 &{HEADERS_YANG_JSON}    Content-Type=application/yang.data+json    # Content type for JSON data, used to work around Requests auto-serialization. TODO: Hide into more specific Resource if possible.
+&{HEADERS_YANG_RFC8040_JSON}    Content-Type=application/yang-data+json
 &{HEADERS_XML}    Content-Type=application/xml    # Content type for XML data. TODO: Hide into more specific Resource if possible.
 ${KARAF_PROMPT_LOGIN}    opendaylight-user    # This is used for karaf console login.
 ${ICMP_TYPE}      135
diff --git a/csit/variables/netconf/CRUD/customaction/customaction.xml b/csit/variables/netconf/CRUD/customaction/customaction.xml
new file mode 100644 (file)
index 0000000..987a708
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rpcs>
+   <rpc>
+      <input>
+         <action xmlns="urn:ietf:params:xml:ns:yang:1">
+            <interfaces xmlns="https://example.com/ns/example-action">
+               <interface>
+                  <name>eth1</name>
+                  <reset>
+                     <delay>600</delay>
+                  </reset>
+               </interface>
+            </interfaces>
+         </action>
+      </input>
+      <output>
+         <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:sys="https://example.com/ns/example-action">
+            <ok />
+         </rpc-reply>
+      </output>
+   </rpc>
+</rpcs>
+
diff --git a/csit/variables/netconf/CRUD/dataorigaction/location.uri b/csit/variables/netconf/CRUD/dataorigaction/location.uri
new file mode 100644 (file)
index 0000000..16fbf19
--- /dev/null
@@ -0,0 +1 @@
+rests/data/network-topology:network-topology/topology=topology-netconf/node=$DEVICE_NAME/yang-ext:mount/example-action:interfaces/interface=eth1/reset
diff --git a/csit/variables/netconf/CRUD/dataorigaction/post_data.json b/csit/variables/netconf/CRUD/dataorigaction/post_data.json
new file mode 100644 (file)
index 0000000..50a8ffd
--- /dev/null
@@ -0,0 +1,6 @@
+{
+   "example-action:input":{
+      "delay":600
+   }
+}
+
diff --git a/csit/variables/netconf/CRUD/dataorigaction/post_data.xml b/csit/variables/netconf/CRUD/dataorigaction/post_data.xml
new file mode 100644 (file)
index 0000000..972bf9d
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<input xmlns="https://example.com/ns/example-action">
+  <delay>600</delay>
+</input>
+
diff --git a/csit/variables/netconf/CRUD/schemas/example-action@2016-07-07.yang b/csit/variables/netconf/CRUD/schemas/example-action@2016-07-07.yang
new file mode 100644 (file)
index 0000000..0614638
--- /dev/null
@@ -0,0 +1,89 @@
+module example-action {
+  yang-version 1.1;
+  namespace "https://example.com/ns/example-action";
+  prefix act;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "Example, Inc.";
+  contact
+    "support at example.com";
+  description
+    "Example Actions Data Model Module.";
+
+  revision 2016-07-07 {
+    description
+      "Initial version.";
+    reference
+      "example.com document 2-9973.";
+  }
+
+  container interfaces {
+    description
+      "System interfaces.";
+    list interface {
+      key "name";
+      description
+        "One interface entry.";
+      leaf name {
+        type string;
+        description
+          "Interface name.";
+      }
+
+      action reset {
+        description
+          "Reset an interface.";
+        input {
+          leaf delay {
+            type uint32;
+            units "seconds";
+            default "0";
+            description
+              "Number of seconds to wait before starting the
+               interface reset.";
+          }
+        }
+      }
+
+      action get-last-reset-time {
+        description
+          "Retrieve the last interface reset time.";
+
+        output {
+          leaf last-reset {
+            type yang:date-and-time;
+            mandatory true;
+            description
+              "Date and time of the last interface reset, or
+               the last reboot time of the device.";
+          }
+        }
+      }
+    }
+  }
+  rpc reboot {
+    description "Reboot operation.";
+    input {
+      leaf delay {
+        type uint32;
+        units "seconds";
+        default 0;
+        description "Number of seconds to wait before initiating the reboot operation.";
+      }
+      leaf message {
+        type string;
+        description "Log message to display when reboot is started.";
+      }
+      leaf language {
+        type string;
+        description "Language identifier string.";
+        reference "RFC 5646.";
+      }
+    }
+  }
+}
+