Skip to content

Commit

Permalink
[dvslib] Improve support for assert logging (sonic-net#1258)
Browse files Browse the repository at this point in the history
Signed-off-by: Danny Allen <daall@microsoft.com>
  • Loading branch information
daall committed Apr 14, 2020
1 parent 25097d2 commit 53ee2e3
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 17 deletions.
15 changes: 9 additions & 6 deletions tests/dvslib/dvs_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,26 @@ def wait_for_result(polling_function, polling_config):
not, as well as some return value.
Returns:
Any: The output of the polling function, if it is succesful,
None otherwise.
(bool, Any): If the polling function succeeds, then this method
will return True and the output of the polling function. If it
does not succeed within the provided timeout, it will return False
and whatever the output of the polling function was on the final
attempt.
"""
if polling_config.polling_interval == 0:
iterations = 1
else:
iterations = int(polling_config.timeout // polling_config.polling_interval) + 1

for _ in range(iterations):
(status, result) = polling_function()
status, result = polling_function()

if status:
return result
return (True, result)

time.sleep(polling_config.polling_interval)

if polling_config.strict:
assert False
assert False, "Operation timed out after {}s".format(polling_config.timeout)

return None
return (False, result)
111 changes: 100 additions & 11 deletions tests/dvslib/dvs_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,14 @@ def _access_function():
fv_pairs = self.get_entry(table_name, key)
return (bool(fv_pairs), fv_pairs)

return wait_for_result(_access_function, polling_config)
status, result = wait_for_result(_access_function,
self._disable_strict_polling(polling_config))

if not status:
assert not polling_config.strict, \
"Entry not found: key=\"{}\", table=\"{}\"".format(key, table_name)

return result

def wait_for_field_match(self,
table_name,
Expand All @@ -131,9 +138,6 @@ def wait_for_field_match(self,
at `key` in the specified table. This method will wait for the
fields to exist.
Note:
This method does not check for an exact match.
Args:
table_name (str): The name of the table where the entry is
stored.
Expand All @@ -152,12 +156,57 @@ def _access_function():
fv_pairs = self.get_entry(table_name, key)
return (all(fv_pairs.get(k) == v for k, v in expected_fields.items()), fv_pairs)

return wait_for_result(_access_function, polling_config)
status, result = wait_for_result(_access_function,
self._disable_strict_polling(polling_config))

if not status:
assert not polling_config.strict, \
"Expected fields not found: expected={}, received={}, \
key=\"{}\", table=\"{}\"".format(expected_fields, result, key, table_name)

def wait_for_empty_entry(self,
return result

def wait_for_exact_match(self,
table_name,
key,
expected_entry,
polling_config=DEFAULT_POLLING_CONFIG):
"""
Checks if the provided entry matches the entry stored at `key`
in the specified table. This method will wait for the exact entry
to exist.
Args:
table_name (str): The name of the table where the entry is
stored.
key (str): The key that maps to the entry being checked.
expected_entry (dict): The entry we expect to see.
polling_config (PollingConfig): The parameters to use to poll
the db.
Returns:
Dict[str, str]: The entry stored at `key`. If no entry is found,
then an empty Dict will be returned.
"""

def _access_function():
fv_pairs = self.get_entry(table_name, key)
return (fv_pairs == expected_entry, fv_pairs)

status, result = wait_for_result(_access_function,
self._disable_strict_polling(polling_config))

if not status:
assert not polling_config.strict, \
"Exact match not found: expected={}, received={}, \
key=\"{}\", table=\"{}\"".format(expected_entry, result, key, table_name)

return result

def wait_for_deleted_entry(self,
table_name,
key,
polling_config=DEFAULT_POLLING_CONFIG):
"""
Checks if there is any entry stored at `key` in the specified
table. This method will wait for the entry to be empty.
Expand All @@ -169,14 +218,23 @@ def wait_for_empty_entry(self,
the db.
Returns:
bool: True if no entry exists at `key`, False otherwise.
Dict[str, str]: The entry stored at `key`. If no entry is found,
then an empty Dict will be returned.
"""

def _access_function():
fv_pairs = self.get_entry(table_name, key)
return (not bool(fv_pairs), fv_pairs)

return wait_for_result(_access_function, polling_config)
status, result = wait_for_result(_access_function,
self._disable_strict_polling(polling_config))

if not status:
assert not polling_config.strict, \
"Entry still exists: entry={}, key=\"{}\", table=\"{}\""\
.format(result, key, table_name)

return result

def wait_for_n_keys(self,
table_name,
Expand All @@ -203,7 +261,15 @@ def _access_function():
keys = self.get_keys(table_name)
return (len(keys) == num_keys, keys)

return wait_for_result(_access_function, polling_config)
status, result = wait_for_result(_access_function,
self._disable_strict_polling(polling_config))

if not status:
assert not polling_config.strict, \
"Unexpected number of keys: expected={}, received={} ({}), table=\"{}\""\
.format(num_keys, len(result), result, table_name)

return result

def wait_for_matching_keys(self,
table_name,
Expand All @@ -230,7 +296,15 @@ def _access_function():
keys = self.get_keys(table_name)
return (all(key in keys for key in expected_keys), keys)

return wait_for_result(_access_function, polling_config)
status, result = wait_for_result(_access_function,
self._disable_strict_polling(polling_config))

if not status:
assert not polling_config.strict, \
"Expected keys not found: expected={}, received={}, table=\"{}\""\
.format(expected_keys, result, table_name)

return result

def wait_for_deleted_keys(self,
table_name,
Expand All @@ -257,4 +331,19 @@ def _access_function():
keys = self.get_keys(table_name)
return (all(key not in keys for key in deleted_keys), keys)

return wait_for_result(_access_function, polling_config)
status, result = wait_for_result(_access_function,
self._disable_strict_polling(polling_config))

if not status:
assert not polling_config.strict, \
"Unexpected keys found: expected={}, received={}, table=\"{}\""\
.format(deleted_keys, result, table_name)

return result

@staticmethod
def _disable_strict_polling(polling_config):
disabled_config = PollingConfig(polling_interval=polling_config.polling_interval,
timeout=polling_config.timeout,
strict=False)
return disabled_config

0 comments on commit 53ee2e3

Please sign in to comment.