628 lines
12 KiB
Python
628 lines
12 KiB
Python
|
#!/usr/bin/env python
|
||
|
# SPDX-License-Identifier: ISC
|
||
|
|
||
|
#
|
||
|
# test_json.py
|
||
|
# Tests for library function: json_cmp().
|
||
|
#
|
||
|
# Copyright (c) 2017 by
|
||
|
# Network Device Education Foundation, Inc. ("NetDEF")
|
||
|
#
|
||
|
|
||
|
"""
|
||
|
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())
|