forked from Mirror/frr
477 lines
11 KiB
Python
Executable file
477 lines
11 KiB
Python
Executable file
#!/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())
|