aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--resources/libraries/python/honeycomb/HcAPIKwInterfaces.py83
-rw-r--r--resources/libraries/python/honeycomb/HoneycombUtil.py66
-rw-r--r--resources/libraries/robot/honeycomb/access_control_lists.robot3
-rw-r--r--resources/libraries/robot/honeycomb/interfaces.robot2
-rw-r--r--resources/libraries/robot/honeycomb/sub_interface.robot3
-rw-r--r--resources/test_data/honeycomb/acl.py2
6 files changed, 64 insertions, 95 deletions
diff --git a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py
index 5658eea146..1e0883db27 100644
--- a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py
+++ b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py
@@ -1313,43 +1313,72 @@ class InterfaceKeywords(object):
node, super_interface, path, None)
@staticmethod
- def compare_data_structures(data, ref, ignore=(), list_order=True):
- """Checks if data obtained from UUT is as expected.
+ def compare_data_structures(data, ref, _path=''):
+ """Checks if data obtained from UUT is as expected. If it is not,
+ proceeds down the list/dictionary tree and finds the point of mismatch.
:param data: Data to be checked.
:param ref: Referential data used for comparison.
- :param ignore: Dictionary keys to be ignored.
- :param list_order: Whether to consider the order of list items\
- in comparison.
+ :param _path: Used in recursive calls, stores the path taken down
+ the JSON tree.
:type data: dict
:type ref: dict
- :type ignore: iterable
- :type list_order: bool
+ :type _path: str
- :raises HoneycombError: If a parameter from referential data is not
- present in operational data or if it has different value.
+ :raises HoneycombError: If the data structures do not match in some way,
+ or if they are not in deserialized JSON format.
"""
- errors = ""
-
- for key, item in ref.items():
- if key in ignore:
- continue
- try:
- if data[key] != item:
- if not list_order and sorted(data[key]) == sorted(item):
- pass
+ if data == ref:
+ return True
+
+ elif isinstance(data, dict) and isinstance(ref, dict):
+ for key in ref:
+ if key not in data:
+ raise HoneycombError(
+ "Key {key} is not present in path {path}. Keys in path:"
+ "{data_keys}".format(
+ key=key,
+ path=_path,
+ data_keys=data.keys()))
+
+ if data[key] != ref[key]:
+ if isinstance(data[key], list) \
+ or isinstance(data[key], dict):
+ InterfaceKeywords.compare_data_structures(
+ data[key], ref[key],
+ _path + '[{0}]'.format(key))
else:
- errors += ("\nThe value of parameter '{0}' is "
- "incorrect. It should be "
- "'{1}' but it is '{2}'".
- format(key, item, data[key]))
- except KeyError:
- errors += ("\nThe parameter '{0}' is not present in "
- "operational data".format(key))
+ raise HoneycombError(
+ "Data mismatch, key {key} in path {path} has value"
+ " {data}, but should be {ref}".format(
+ key=key,
+ path=_path,
+ data=data[key],
+ ref=ref[key]))
+
+ elif isinstance(data, list) and isinstance(ref, list):
+ for item in ref:
+ if item not in data:
+ if isinstance(item, dict):
+ InterfaceKeywords.compare_data_structures(
+ data[0], item,
+ _path + '[{0}]'.format(ref.index(item)))
+ else:
+ raise HoneycombError(
+ "Data mismatch, list item {index} in path {path}"
+ " has value {data}, but should be {ref}".format(
+ index=ref.index(item),
+ path=_path,
+ data=data[0],
+ ref=item))
- if errors:
- raise HoneycombError(errors)
+ else:
+ raise HoneycombError(
+ "Unexpected data type {data_type}, reference type is"
+ " {ref_type}. Must be list or dictionary.".format(
+ data_type=type(data),
+ ref_type=type(ref)))
@staticmethod
def compare_interface_lists(list1, list2):
diff --git a/resources/libraries/python/honeycomb/HoneycombUtil.py b/resources/libraries/python/honeycomb/HoneycombUtil.py
index 747c9dae8e..c290af9a6e 100644
--- a/resources/libraries/python/honeycomb/HoneycombUtil.py
+++ b/resources/libraries/python/honeycomb/HoneycombUtil.py
@@ -27,8 +27,7 @@ from enum import Enum, unique
from robot.api import logger
-from resources.libraries.python.ssh import SSH
-from resources.libraries.python.HTTPRequest import HTTPRequest, HTTPCodes
+from resources.libraries.python.HTTPRequest import HTTPRequest
from resources.libraries.python.constants import Constants as Const
@@ -302,10 +301,7 @@ class HoneycombUtil(object):
base_path = HoneycombUtil.read_path_from_url_file(url_file)
path = base_path + path
status_code, resp = HTTPRequest.get(node, path)
- response = loads(resp)
- if status_code != HTTPCodes.OK:
- HoneycombUtil.read_log_tail(node)
- return status_code, response
+ return status_code, loads(resp)
@staticmethod
def put_honeycomb_data(node, url_file, data, path="",
@@ -343,13 +339,9 @@ class HoneycombUtil(object):
base_path = HoneycombUtil.read_path_from_url_file(url_file)
path = base_path + path
logger.trace(path)
- (status_code, response) = HTTPRequest.put(
+ return HTTPRequest.put(
node=node, path=path, headers=header, payload=data)
- if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
- HoneycombUtil.read_log_tail(node)
- return status_code, response
-
@staticmethod
def post_honeycomb_data(node, url_file, data=None,
data_representation=DataRepresentation.JSON,
@@ -383,13 +375,9 @@ class HoneycombUtil(object):
data = dumps(data)
path = HoneycombUtil.read_path_from_url_file(url_file)
- (status_code, response) = HTTPRequest.post(
+ return HTTPRequest.post(
node=node, path=path, headers=header, payload=data, timeout=timeout)
- if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
- HoneycombUtil.read_log_tail(node)
- return status_code, response
-
@staticmethod
def delete_honeycomb_data(node, url_file, path=""):
"""Delete data from Honeycomb according to given URL.
@@ -407,48 +395,4 @@ class HoneycombUtil(object):
base_path = HoneycombUtil.read_path_from_url_file(url_file)
path = base_path + path
- (status_code, response) = HTTPRequest.delete(node, path)
-
- if status_code != HTTPCodes.OK:
- HoneycombUtil.read_log_tail(node)
- return status_code, response
-
- @staticmethod
- def read_log_tail(node, lines=120):
- """Read the last N lines of the Honeycomb log file and print them
- to robot log.
-
- :param node: Honeycomb node.
- :param lines: Number of lines to read.
- :type node: dict
- :type lines: int
- :returns: Last N log lines.
- :rtype: str
- """
-
- logger.trace(
- "HTTP request failed, "
- "obtaining last {0} lines of Honeycomb log...".format(lines))
-
- ssh = SSH()
- ssh.connect(node)
- cmd = "tail -n {0} /var/log/honeycomb/honeycomb.log".format(lines)
- # ssh also logs the reply on trace level
- (_, stdout, _) = ssh.exec_command(cmd, timeout=30)
-
- return stdout
-
- @staticmethod
- def archive_honeycomb_log(node):
- """Copy honeycomb log file from DUT node to VIRL for archiving.
-
- :param node: Honeycomb node.
- :type node: dict
- """
-
- ssh = SSH()
- ssh.connect(node)
-
- cmd = "cp /var/log/honeycomb/honeycomb.log /scratch/"
-
- ssh.exec_command_sudo(cmd)
+ return HTTPRequest.delete(node, path)
diff --git a/resources/libraries/robot/honeycomb/access_control_lists.robot b/resources/libraries/robot/honeycomb/access_control_lists.robot
index a9ea7dffe6..d24da5bd96 100644
--- a/resources/libraries/robot/honeycomb/access_control_lists.robot
+++ b/resources/libraries/robot/honeycomb/access_control_lists.robot
@@ -12,7 +12,6 @@
# limitations under the License.
*** Variables ***
#TODO: update based on resolution of bug https://jira.fd.io/browse/HONEYCOMB-119
-| @{hc_table_ignore}= | memory_size
*** Settings ***
| Library | resources.libraries.python.Classify
@@ -124,7 +123,7 @@
| | ... | \| ${settings} \|
| | [Arguments] | ${node} | ${settings}
| | ${data}= | Get classify table oper data | ${node} | ${settings['name']}
-| | Compare data structures | ${data} | ${settings} | ignore=${hc_table_ignore}
+| | Compare data structures | ${data} | ${settings}
| ACL table from VAT should be
| | [Documentation] | Retrieves ACL table information from VAT\
diff --git a/resources/libraries/robot/honeycomb/interfaces.robot b/resources/libraries/robot/honeycomb/interfaces.robot
index 027b7d74a3..765aaef7c0 100644
--- a/resources/libraries/robot/honeycomb/interfaces.robot
+++ b/resources/libraries/robot/honeycomb/interfaces.robot
@@ -235,7 +235,7 @@
| | ${api_data}= | interfaceAPI.Get interface oper data | ${node} | ${interface}
| | ${data_neighbors}= | Set Variable | ${api_data['ietf-ip:ipv4']['neighbor']}
| | Compare data structures
-| | ... | ${data_neighbors} | ${neighbors} | list_order=${False}
+| | ... | ${data_neighbors} | ${neighbors}
| | Should be equal | ${neighbor['fib_address']}
| | ... | ${api_data['ietf-ip:ipv4']['neighbor'][0]['ip']}
| | Should be equal | ${neighbor['fib_mac']}
diff --git a/resources/libraries/robot/honeycomb/sub_interface.robot b/resources/libraries/robot/honeycomb/sub_interface.robot
index e9b8aeb008..4a9f5c403b 100644
--- a/resources/libraries/robot/honeycomb/sub_interface.robot
+++ b/resources/libraries/robot/honeycomb/sub_interface.robot
@@ -68,7 +68,6 @@
| | ${api_data}= | interfaceAPI.Get sub interface oper data
| | ... | ${node} | ${super_interface} | ${identifier}
| | interfaceAPI.Compare Data Structures | ${api_data} | ${sub_if_settings}
-| | ... | list_order=${False}
| Sub-interface configuration from Honeycomb should be empty
| | [Documentation] | Retrieves sub-interface configuration through Honeycomb \
@@ -391,7 +390,7 @@
| | ${api_data}= | interfaceAPI.Get tag rewrite oper data
| | ... | ${node} | ${super_if} | ${identifier}
| | interfaceAPI.Compare Data Structures
-| | ... | ${api_data} | ${settings} | list_order=${False}
+| | ... | ${api_data} | ${settings}
| Rewrite tag from VAT should be
| | [Documentation] | Retrieves sub-interface configuration through VAT and\
diff --git a/resources/test_data/honeycomb/acl.py b/resources/test_data/honeycomb/acl.py
index 227330c2a9..ee7f9525b8 100644
--- a/resources/test_data/honeycomb/acl.py
+++ b/resources/test_data/honeycomb/acl.py
@@ -17,7 +17,6 @@
hc_acl_table = {
"name": "acl_table_test",
"nbuckets": 1,
- "memory_size": 100000,
"skip_n_vectors": 0,
"miss_next": "permit",
"mask": "00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:00:00:00:00"
@@ -26,7 +25,6 @@ hc_acl_table = {
hc_acl_table2 = {
"name": "acl_table_test2",
"nbuckets": 2,
- "memory_size": 100000,
"skip_n_vectors": 1,
"next_table": "acl_table_test",
"miss_next": "deny",