From 14bae8c7171d71dea238a269c0648dd19056822a Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Tue, 19 Sep 2017 17:04:54 -0300 Subject: [PATCH 1/5] topogen: remove unused import --- lib/topogen.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/topogen.py b/lib/topogen.py index aaad5d49d7d7..e7e30e187da7 100644 --- a/lib/topogen.py +++ b/lib/topogen.py @@ -46,7 +46,6 @@ import grp import platform import pwd -import re import subprocess from mininet.net import Mininet From e87a86cbcb64134a895dd9cf94a1e46ec65bb4a1 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 18 Sep 2017 22:14:27 -0300 Subject: [PATCH 2/5] topotest: remove unused json_cmp unused parameter --- lib/topotest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/topotest.py b/lib/topotest.py index 4093c85e2d9a..a41350614d95 100644 --- a/lib/topotest.py +++ b/lib/topotest.py @@ -58,7 +58,7 @@ def has_errors(self): return len(self.errors) > 0 -def json_cmp(d1, d2, reason=False): +def json_cmp(d1, d2): """ JSON compare function. Receives two parameters: * `d1`: json value From b8cd60a575e1baa61fe96f87d1ea9f79f2d3f9ad Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Wed, 20 Sep 2017 12:04:23 -0300 Subject: [PATCH 3/5] topotest: allow passing options to difflib Extend the topotest diff functions to allow receiving difflib options. --- lib/topotest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/topotest.py b/lib/topotest.py index a41350614d95..8063598ebaf8 100644 --- a/lib/topotest.py +++ b/lib/topotest.py @@ -198,20 +198,20 @@ def pid_exists(pid): else: return True -def get_textdiff(text1, text2, title1="", title2=""): +def get_textdiff(text1, text2, title1="", title2="", **opts): "Returns empty string if same or formatted diff" diff = '\n'.join(difflib.unified_diff(text1, text2, - fromfile=title1, tofile=title2)) + fromfile=title1, tofile=title2, **opts)) # Clean up line endings diff = os.linesep.join([s for s in diff.splitlines() if s]) return diff -def difflines(text1, text2, title1='', title2=''): +def difflines(text1, text2, title1='', title2='', **opts): "Wrapper for get_textdiff to avoid string transformations." text1 = ('\n'.join(text1.rstrip().splitlines()) + '\n').splitlines(1) text2 = ('\n'.join(text2.rstrip().splitlines()) + '\n').splitlines(1) - return get_textdiff(text1, text2, title1, title2) + return get_textdiff(text1, text2, title1, title2, **opts) def get_file(content): """ From 093673d7f623db1fccaeeffff872438328991863 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Tue, 19 Sep 2017 17:05:07 -0300 Subject: [PATCH 4/5] topotest: json_cmp_result split error lines When the API user wanted to show newlines we have to break them manually to get the propper format. --- lib/topotest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/topotest.py b/lib/topotest.py index 8063598ebaf8..5dbef7432fb7 100644 --- a/lib/topotest.py +++ b/lib/topotest.py @@ -51,7 +51,8 @@ def __init__(self): def add_error(self, error): "Append error message to the result" - self.errors.append(error) + for line in error.splitlines(): + self.errors.append(line) def has_errors(self): "Returns True if there were errors, otherwise False." From f3d92e031fde9571f631fe9f6c2a83508604a6a1 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 18 Sep 2017 22:19:10 -0300 Subject: [PATCH 5/5] topotest: improve json error messages Show a diff of the JSON values instead of dumping the whole data structures. --- lib/topotest.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/topotest.py b/lib/topotest.py index 5dbef7432fb7..0e0a1e8876d6 100644 --- a/lib/topotest.py +++ b/lib/topotest.py @@ -22,6 +22,7 @@ # OF THIS SOFTWARE. # +import json import os import errno import re @@ -58,6 +59,17 @@ def has_errors(self): "Returns True if there were errors, otherwise False." return len(self.errors) > 0 +def json_diff(d1, d2): + """ + Returns a string with the difference between JSON data. + """ + json_format_opts = { + 'indent': 4, + 'sort_keys': True, + } + dstr1 = json.dumps(d1, **json_format_opts) + dstr2 = json.dumps(d2, **json_format_opts) + return difflines(dstr2, dstr1, title1='Expected value', title2='Current value', n=0) def json_cmp(d1, d2): """ @@ -110,8 +122,9 @@ def json_cmp(d1, d2): if len(nd2[key]) > len(nd1[key]): result.add_error( '{}["{}"] too few items '.format(parent, key) + - '(have ({}) "{}", expected ({}) "{}")'.format( - len(nd1[key]), str(nd1[key]), len(nd2[key]), str(nd2[key]))) + '(have {}, expected {}:\n {})'.format( + len(nd1[key]), len(nd2[key]), + json_diff(nd1[key], nd2[key]))) continue # List all unmatched items errors @@ -131,15 +144,15 @@ def json_cmp(d1, d2): # If there are unmatched items, error out. if unmatched: result.add_error( - '{}["{}"] value is different (have "{}", expected "{}")'.format( - parent, key, str(nd1[key]), str(nd2[key]))) + '{}["{}"] value is different (\n{})'.format( + parent, key, json_diff(nd1[key], nd2[key]))) continue # Compare JSON values if nd1[key] != nd2[key]: result.add_error( - '{}["{}"] value is different (have "{}", expected "{}")'.format( - parent, key, str(nd1[key]), str(nd2[key]))) + '{}["{}"] value is different (\n{})'.format( + parent, key, json_diff(nd1[key], nd2[key]))) continue if result.has_errors():