diff options
Diffstat (limited to 'tests/topotests/lib/test/test_json.py')
-rwxr-xr-x | tests/topotests/lib/test/test_json.py | 641 |
1 files changed, 641 insertions, 0 deletions
diff --git a/tests/topotests/lib/test/test_json.py b/tests/topotests/lib/test/test_json.py new file mode 100755 index 0000000..7b3c859 --- /dev/null +++ b/tests/topotests/lib/test/test_json.py @@ -0,0 +1,641 @@ +#!/usr/bin/env python + +# +# test_json.py +# Tests for library function: json_cmp(). +# +# Copyright (c) 2017 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Tests for the json_cmp() function. +""" + +import os +import sys +import pytest + +# Save the Current Working Directory to find lib files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../../")) + +# pylint: disable=C0413 +from lib.topotest import json_cmp + + +def test_json_intersect_true(): + "Test simple correct JSON intersections" + + dcomplete = { + "i1": "item1", + "i2": "item2", + "i3": "item3", + "i100": "item4", + } + + dsub1 = { + "i1": "item1", + "i3": "item3", + } + dsub2 = { + "i1": "item1", + "i2": "item2", + } + dsub3 = { + "i100": "item4", + "i2": "item2", + } + dsub4 = { + "i50": None, + "i100": "item4", + } + + assert json_cmp(dcomplete, dsub1) is None + assert json_cmp(dcomplete, dsub2) is None + assert json_cmp(dcomplete, dsub3) is None + assert json_cmp(dcomplete, dsub4) is None + + +def test_json_intersect_false(): + "Test simple incorrect JSON intersections" + + dcomplete = { + "i1": "item1", + "i2": "item2", + "i3": "item3", + "i100": "item4", + } + + # Incorrect value for 'i1' + dsub1 = { + "i1": "item3", + "i3": "item3", + } + # Non-existing key 'i5' + dsub2 = { + "i1": "item1", + "i5": "item2", + } + # Key should not exist + dsub3 = { + "i100": None, + } + + assert json_cmp(dcomplete, dsub1) is not None + assert json_cmp(dcomplete, dsub2) is not None + assert json_cmp(dcomplete, dsub3) is not None + + +def test_json_intersect_multilevel_true(): + "Test multi level correct JSON intersections" + + dcomplete = { + "i1": "item1", + "i2": "item2", + "i3": { + "i100": "item100", + }, + "i4": { + "i41": { + "i411": "item411", + }, + "i42": { + "i421": "item421", + "i422": "item422", + }, + }, + } + + dsub1 = { + "i1": "item1", + "i3": { + "i100": "item100", + }, + "i10": None, + } + dsub2 = { + "i1": "item1", + "i2": "item2", + "i3": {}, + } + dsub3 = { + "i2": "item2", + "i4": { + "i41": { + "i411": "item411", + }, + "i42": { + "i422": "item422", + "i450": None, + }, + }, + } + dsub4 = { + "i2": "item2", + "i4": { + "i41": {}, + "i42": { + "i450": None, + }, + }, + } + dsub5 = { + "i2": "item2", + "i3": { + "i100": "item100", + }, + "i4": { + "i42": { + "i450": None, + } + }, + } + + assert json_cmp(dcomplete, dsub1) is None + assert json_cmp(dcomplete, dsub2) is None + assert json_cmp(dcomplete, dsub3) is None + assert json_cmp(dcomplete, dsub4) is None + assert json_cmp(dcomplete, dsub5) is None + + +def test_json_intersect_multilevel_false(): + "Test multi level incorrect JSON intersections" + + dcomplete = { + "i1": "item1", + "i2": "item2", + "i3": { + "i100": "item100", + }, + "i4": { + "i41": { + "i411": "item411", + }, + "i42": { + "i421": "item421", + "i422": "item422", + }, + }, + } + + # Incorrect sub-level value + dsub1 = { + "i1": "item1", + "i3": { + "i100": "item00", + }, + "i10": None, + } + # Inexistent sub-level + dsub2 = { + "i1": "item1", + "i2": "item2", + "i3": None, + } + # Inexistent sub-level value + dsub3 = { + "i1": "item1", + "i3": { + "i100": None, + }, + } + # Inexistent sub-sub-level value + dsub4 = { + "i4": { + "i41": { + "i412": "item412", + }, + "i42": { + "i421": "item421", + }, + } + } + # Invalid sub-sub-level value + dsub5 = { + "i4": { + "i41": { + "i411": "item411", + }, + "i42": { + "i421": "item420000", + }, + } + } + # sub-sub-level should be value + dsub6 = { + "i4": { + "i41": { + "i411": "item411", + }, + "i42": "foobar", + } + } + + assert json_cmp(dcomplete, dsub1) is not None + assert json_cmp(dcomplete, dsub2) is not None + assert json_cmp(dcomplete, dsub3) is not None + assert json_cmp(dcomplete, dsub4) is not None + assert json_cmp(dcomplete, dsub5) is not None + assert json_cmp(dcomplete, dsub6) is not None + + +def test_json_with_list_sucess(): + "Test successful json comparisons that have lists." + + dcomplete = { + "list": [ + { + "i1": "item 1", + "i2": "item 2", + }, + { + "i10": "item 10", + }, + ], + "i100": "item 100", + } + + # Test list type + dsub1 = { + "list": [], + } + # Test list correct list items + dsub2 = { + "list": [ + { + "i1": "item 1", + }, + ], + "i100": "item 100", + } + # Test list correct list size + dsub3 = { + "list": [ + {}, + {}, + ], + } + + assert json_cmp(dcomplete, dsub1) is None + assert json_cmp(dcomplete, dsub2) is None + assert json_cmp(dcomplete, dsub3) is None + + +def test_json_with_list_failure(): + "Test failed json comparisons that have lists." + + dcomplete = { + "list": [ + { + "i1": "item 1", + "i2": "item 2", + }, + { + "i10": "item 10", + }, + ], + "i100": "item 100", + } + + # Test list type + dsub1 = { + "list": {}, + } + # Test list incorrect list items + dsub2 = { + "list": [ + { + "i1": "item 2", + }, + ], + "i100": "item 100", + } + # Test list correct list size + dsub3 = { + "list": [ + {}, + {}, + {}, + ], + } + + assert json_cmp(dcomplete, dsub1) is not None + assert json_cmp(dcomplete, dsub2) is not None + assert json_cmp(dcomplete, dsub3) is not None + + +def test_json_list_start_success(): + "Test JSON encoded data that starts with a list that should succeed." + + dcomplete = [ + { + "id": 100, + "value": "abc", + }, + { + "id": 200, + "value": "abcd", + }, + { + "id": 300, + "value": "abcde", + }, + ] + + dsub1 = [ + { + "id": 100, + "value": "abc", + } + ] + + dsub2 = [ + { + "id": 100, + "value": "abc", + }, + { + "id": 200, + "value": "abcd", + }, + ] + + dsub3 = [ + { + "id": 300, + "value": "abcde", + } + ] + + dsub4 = [] + + dsub5 = [ + { + "id": 100, + } + ] + + assert json_cmp(dcomplete, dsub1) is None + assert json_cmp(dcomplete, dsub2) is None + assert json_cmp(dcomplete, dsub3) is None + assert json_cmp(dcomplete, dsub4) is None + assert json_cmp(dcomplete, dsub5) is None + + +def test_json_list_start_failure(): + "Test JSON encoded data that starts with a list that should fail." + + dcomplete = [ + {"id": 100, "value": "abc"}, + {"id": 200, "value": "abcd"}, + {"id": 300, "value": "abcde"}, + ] + + dsub1 = [ + { + "id": 100, + "value": "abcd", + } + ] + + dsub2 = [ + { + "id": 100, + "value": "abc", + }, + { + "id": 200, + "value": "abc", + }, + ] + + dsub3 = [ + { + "id": 100, + "value": "abc", + }, + { + "id": 350, + "value": "abcde", + }, + ] + + dsub4 = [ + { + "value": "abcx", + }, + { + "id": 300, + "value": "abcde", + }, + ] + + assert json_cmp(dcomplete, dsub1) is not None + assert json_cmp(dcomplete, dsub2) is not None + assert json_cmp(dcomplete, dsub3) is not None + assert json_cmp(dcomplete, dsub4) is not None + + +def test_json_list_ordered(): + "Test JSON encoded data that should be ordered using the '__ordered__' tag." + + dcomplete = [ + {"id": 1, "value": "abc"}, + "some string", + 123, + ] + + dsub1 = [ + "__ordered__", + "some string", + {"id": 1, "value": "abc"}, + 123, + ] + + assert json_cmp(dcomplete, dsub1) is not None + + +def test_json_list_exact_matching(): + "Test JSON array on exact matching using the 'exact' parameter." + + dcomplete = [ + {"id": 1, "value": "abc"}, + "some string", + 123, + [1, 2, 3], + ] + + dsub1 = [ + "some string", + {"id": 1, "value": "abc"}, + 123, + [1, 2, 3], + ] + + dsub2 = [ + {"id": 1}, + "some string", + 123, + [1, 2, 3], + ] + + dsub3 = [ + {"id": 1, "value": "abc"}, + "some string", + 123, + [1, 3, 2], + ] + + assert json_cmp(dcomplete, dsub1, exact=True) is not None + assert json_cmp(dcomplete, dsub2, exact=True) is not None + + +def test_json_object_exact_matching(): + "Test JSON object on exact matching using the 'exact' parameter." + + dcomplete = { + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], + } + + dsub1 = { + "a": {"id": 1, "value": "abc"}, + "c": 123, + "d": [1, 2, 3], + } + + dsub2 = { + "a": {"id": 1}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], + } + + dsub3 = { + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 3], + } + + assert json_cmp(dcomplete, dsub1, exact=True) is not None + assert json_cmp(dcomplete, dsub2, exact=True) is not None + assert json_cmp(dcomplete, dsub3, exact=True) is not None + + +def test_json_list_asterisk_matching(): + "Test JSON array elements on matching '*' as a placeholder for arbitrary data." + + dcomplete = [ + {"id": 1, "value": "abc"}, + "some string", + 123, + [1, 2, 3], + ] + + dsub1 = [ + "*", + "some string", + 123, + [1, 2, 3], + ] + + dsub2 = [ + {"id": "*", "value": "abc"}, + "some string", + 123, + [1, 2, 3], + ] + + dsub3 = [ + {"id": 1, "value": "abc"}, + "some string", + 123, + [1, "*", 3], + ] + + dsub4 = [ + "*", + "some string", + "*", + [1, 2, 3], + ] + + assert json_cmp(dcomplete, dsub1) is None + assert json_cmp(dcomplete, dsub2) is None + assert json_cmp(dcomplete, dsub3) is None + assert json_cmp(dcomplete, dsub4) is None + + +def test_json_object_asterisk_matching(): + "Test JSON object value elements on matching '*' as a placeholder for arbitrary data." + + dcomplete = { + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], + } + + dsub1 = { + "a": "*", + "b": "some string", + "c": 123, + "d": [1, 2, 3], + } + + dsub2 = { + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, "*", 3], + } + + dsub3 = { + "a": {"id": "*", "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], + } + + dsub4 = { + "a": "*", + "b": "some string", + "c": "*", + "d": [1, 2, 3], + } + + assert json_cmp(dcomplete, dsub1) is None + assert json_cmp(dcomplete, dsub2) is None + assert json_cmp(dcomplete, dsub3) is None + assert json_cmp(dcomplete, dsub4) is None + + +def test_json_list_nested_with_objects(): + + dcomplete = [{"key": 1, "list": [123]}, {"key": 2, "list": [123]}] + + dsub1 = [{"key": 2, "list": [123]}, {"key": 1, "list": [123]}] + + assert json_cmp(dcomplete, dsub1) is None + + +if __name__ == "__main__": + sys.exit(pytest.main()) |