Blame tests/json_echo/run-test.py

Packit c5a612
#!/usr/bin/python
Packit c5a612
Packit c5a612
from __future__ import print_function
Packit c5a612
import sys
Packit c5a612
import os
Packit c5a612
import json
Packit Service 334769
import argparse
Packit c5a612
Packit c5a612
TESTS_PATH = os.path.dirname(os.path.abspath(__file__))
Packit c5a612
sys.path.insert(0, os.path.join(TESTS_PATH, '../../py/'))
Packit c5a612
Packit c5a612
from nftables import Nftables
Packit c5a612
Packit c5a612
# Change working directory to repository root
Packit c5a612
os.chdir(TESTS_PATH + "/../..")
Packit c5a612
Packit Service 334769
parser = argparse.ArgumentParser(description='Run JSON echo tests')
Packit Service 334769
parser.add_argument('-H', '--host', action='store_true',
Packit Service 334769
                    help='Run tests against installed libnftables.so.1')
Packit Service 334769
parser.add_argument('-l', '--library', default=None,
Packit Service 334769
                    help='Path to libntables.so, overrides --host')
Packit Service 334769
args = parser.parse_args()
Packit Service 334769
Packit Service 334769
check_lib_path = True
Packit Service 334769
if args.library is None:
Packit Service 334769
    if args.host:
Packit Service 334769
        args.library = 'libnftables.so.1'
Packit Service 334769
        check_lib_path = False
Packit Service 334769
    else:
Packit Service 334769
        args.library = 'src/.libs/libnftables.so.1'
Packit Service 334769
Packit Service 334769
if check_lib_path and not os.path.exists(args.library):
Packit Service 334769
    print("Library not found at '%s'." % args.library)
Packit c5a612
    sys.exit(1)
Packit c5a612
Packit Service 334769
nftables = Nftables(sofile = args.library)
Packit c5a612
nftables.set_echo_output(True)
Packit c5a612
Packit c5a612
# various commands to work with
Packit c5a612
Packit c5a612
flush_ruleset = { "flush": { "ruleset": None } }
Packit c5a612
Packit c5a612
list_ruleset = { "list": { "ruleset": None } }
Packit c5a612
Packit c5a612
add_table = { "add": {
Packit c5a612
    "table": {
Packit c5a612
        "family": "inet",
Packit c5a612
        "name": "t",
Packit c5a612
    }
Packit c5a612
}}
Packit c5a612
Packit c5a612
add_chain = { "add": {
Packit c5a612
    "chain": {
Packit c5a612
        "family": "inet",
Packit c5a612
        "table": "t",
Packit c5a612
        "name": "c"
Packit c5a612
    }
Packit c5a612
}}
Packit c5a612
Packit c5a612
add_set = { "add": {
Packit c5a612
    "set": {
Packit c5a612
        "family": "inet",
Packit c5a612
        "table": "t",
Packit c5a612
        "name": "s",
Packit c5a612
        "type": "inet_service"
Packit c5a612
    }
Packit c5a612
}}
Packit c5a612
Packit c5a612
add_rule = { "add": {
Packit c5a612
    "rule": {
Packit c5a612
        "family": "inet",
Packit c5a612
        "table": "t",
Packit c5a612
        "chain": "c",
Packit c5a612
        "expr": [ { "accept": None } ]
Packit c5a612
    }
Packit c5a612
}}
Packit c5a612
Packit c5a612
add_counter = { "add": {
Packit c5a612
    "counter": {
Packit c5a612
        "family": "inet",
Packit c5a612
        "table": "t",
Packit c5a612
        "name": "c"
Packit c5a612
    }
Packit c5a612
}}
Packit c5a612
Packit c5a612
add_quota = { "add": {
Packit c5a612
    "quota": {
Packit c5a612
        "family": "inet",
Packit c5a612
        "table": "t",
Packit c5a612
        "name": "q",
Packit c5a612
        "bytes": 65536
Packit c5a612
    }
Packit c5a612
}}
Packit c5a612
Packit c5a612
# helper functions
Packit c5a612
Packit c5a612
def exit_err(msg):
Packit c5a612
    print("Error: %s" %msg)
Packit c5a612
    sys.exit(1)
Packit c5a612
Packit c5a612
def exit_dump(e, obj):
Packit c5a612
    print("FAIL: {}".format(e))
Packit c5a612
    print("Output was:")
Packit c5a612
    json.dumps(out, sort_keys = True, indent = 4, separators = (',', ': '))
Packit c5a612
    sys.exit(1)
Packit c5a612
Packit c5a612
def do_flush():
Packit c5a612
    rc, out, err = nftables.json_cmd({ "nftables": [flush_ruleset] })
Packit c5a612
    if not rc is 0:
Packit c5a612
        exit_err("flush ruleset failed: {}".format(err))
Packit c5a612
Packit c5a612
def do_command(cmd):
Packit c5a612
    if not type(cmd) is list:
Packit c5a612
        cmd = [cmd]
Packit c5a612
    rc, out, err = nftables.json_cmd({ "nftables": cmd })
Packit c5a612
    if not rc is 0:
Packit c5a612
        exit_err("command failed: {}".format(err))
Packit c5a612
    return out
Packit c5a612
Packit c5a612
def do_list_ruleset():
Packit c5a612
    echo = nftables.get_echo_output()
Packit c5a612
    nftables.set_echo_output(False)
Packit c5a612
    out = do_command(list_ruleset)
Packit c5a612
    nftables.set_echo_output(echo)
Packit c5a612
    return out
Packit c5a612
Packit c5a612
def get_handle(output, search):
Packit c5a612
    try:
Packit c5a612
        for item in output["nftables"]:
Packit c5a612
            if "add" in item:
Packit c5a612
                data = item["add"]
Packit c5a612
            elif "insert" in item:
Packit c5a612
                data = item["insert"]
Packit c5a612
            else:
Packit c5a612
                data = item
Packit c5a612
Packit Service 97f4fc
            k = list(search.keys())[0]
Packit c5a612
Packit c5a612
            if not k in data:
Packit c5a612
                continue
Packit c5a612
            found = True
Packit c5a612
            for key in list(search[k].keys()):
Packit c5a612
                if key == "handle":
Packit c5a612
                    continue
Packit c5a612
                if not key in data[k] or search[k][key] != data[k][key]:
Packit c5a612
                    found = False
Packit c5a612
                    break
Packit c5a612
            if not found:
Packit c5a612
                continue
Packit c5a612
Packit c5a612
            return data[k]["handle"]
Packit c5a612
    except Exception as e:
Packit c5a612
        exit_dump(e, output)
Packit c5a612
Packit c5a612
# single commands first
Packit c5a612
Packit c5a612
do_flush()
Packit c5a612
Packit c5a612
print("Adding table t")
Packit c5a612
out = do_command(add_table)
Packit c5a612
handle = get_handle(out, add_table["add"])
Packit c5a612
Packit c5a612
out = do_list_ruleset()
Packit c5a612
handle_cmp = get_handle(out, add_table["add"])
Packit c5a612
Packit c5a612
if handle != handle_cmp:
Packit c5a612
    exit_err("handle mismatch!")
Packit c5a612
Packit c5a612
add_table["add"]["table"]["handle"] = handle
Packit c5a612
Packit c5a612
print("Adding chain c")
Packit c5a612
out = do_command(add_chain)
Packit c5a612
handle = get_handle(out, add_chain["add"])
Packit c5a612
Packit c5a612
out = do_list_ruleset()
Packit c5a612
handle_cmp = get_handle(out, add_chain["add"])
Packit c5a612
Packit c5a612
if handle != handle_cmp:
Packit c5a612
    exit_err("handle mismatch!")
Packit c5a612
Packit c5a612
add_chain["add"]["chain"]["handle"] = handle
Packit c5a612
Packit c5a612
print("Adding set s")
Packit c5a612
out = do_command(add_set)
Packit c5a612
handle = get_handle(out, add_set["add"])
Packit c5a612
Packit c5a612
out = do_list_ruleset()
Packit c5a612
handle_cmp = get_handle(out, add_set["add"])
Packit c5a612
Packit c5a612
if handle != handle_cmp:
Packit c5a612
    exit_err("handle mismatch!")
Packit c5a612
Packit c5a612
add_set["add"]["set"]["handle"] = handle
Packit c5a612
Packit c5a612
print("Adding rule")
Packit c5a612
out = do_command(add_rule)
Packit c5a612
handle = get_handle(out, add_rule["add"])
Packit c5a612
Packit c5a612
out = do_list_ruleset()
Packit c5a612
handle_cmp = get_handle(out, add_rule["add"])
Packit c5a612
Packit c5a612
if handle != handle_cmp:
Packit c5a612
    exit_err("handle mismatch!")
Packit c5a612
Packit c5a612
add_rule["add"]["rule"]["handle"] = handle
Packit c5a612
Packit c5a612
print("Adding counter")
Packit c5a612
out = do_command(add_counter)
Packit c5a612
handle = get_handle(out, add_counter["add"])
Packit c5a612
Packit c5a612
out = do_list_ruleset()
Packit c5a612
handle_cmp = get_handle(out, add_counter["add"])
Packit c5a612
Packit c5a612
if handle != handle_cmp:
Packit c5a612
    exit_err("handle mismatch!")
Packit c5a612
Packit c5a612
add_counter["add"]["counter"]["handle"] = handle
Packit c5a612
Packit c5a612
print("Adding quota")
Packit c5a612
out = do_command(add_quota)
Packit c5a612
handle = get_handle(out, add_quota["add"])
Packit c5a612
Packit c5a612
out = do_list_ruleset()
Packit c5a612
handle_cmp = get_handle(out, add_quota["add"])
Packit c5a612
Packit c5a612
if handle != handle_cmp:
Packit c5a612
    exit_err("handle mismatch!")
Packit c5a612
Packit c5a612
add_quota["add"]["quota"]["handle"] = handle
Packit c5a612
Packit c5a612
# adjust names and add items again
Packit c5a612
# Note: Handles are per-table, hence add renamed objects to first table
Packit c5a612
#       to make sure assigned handle differs from first run.
Packit c5a612
Packit c5a612
add_table["add"]["table"]["name"] = "t2"
Packit c5a612
add_chain["add"]["chain"]["name"] = "c2"
Packit c5a612
add_set["add"]["set"]["name"] = "s2"
Packit c5a612
add_counter["add"]["counter"]["name"] = "c2"
Packit c5a612
add_quota["add"]["quota"]["name"] = "q2"
Packit c5a612
Packit c5a612
print("Adding table t2")
Packit c5a612
out = do_command(add_table)
Packit c5a612
handle = get_handle(out, add_table["add"])
Packit c5a612
if handle == add_table["add"]["table"]["handle"]:
Packit c5a612
   exit_err("handle not changed in re-added table!")
Packit c5a612
Packit c5a612
print("Adding chain c2")
Packit c5a612
out = do_command(add_chain)
Packit c5a612
handle = get_handle(out, add_chain["add"])
Packit c5a612
if handle == add_chain["add"]["chain"]["handle"]:
Packit c5a612
   exit_err("handle not changed in re-added chain!")
Packit c5a612
Packit c5a612
print("Adding set s2")
Packit c5a612
out = do_command(add_set)
Packit c5a612
handle = get_handle(out, add_set["add"])
Packit c5a612
if handle == add_set["add"]["set"]["handle"]:
Packit c5a612
   exit_err("handle not changed in re-added set!")
Packit c5a612
Packit c5a612
print("Adding rule again")
Packit c5a612
out = do_command(add_rule)
Packit c5a612
handle = get_handle(out, add_rule["add"])
Packit c5a612
if handle == add_rule["add"]["rule"]["handle"]:
Packit c5a612
   exit_err("handle not changed in re-added rule!")
Packit c5a612
Packit c5a612
print("Adding counter c2")
Packit c5a612
out = do_command(add_counter)
Packit c5a612
handle = get_handle(out, add_counter["add"])
Packit c5a612
if handle == add_counter["add"]["counter"]["handle"]:
Packit c5a612
   exit_err("handle not changed in re-added counter!")
Packit c5a612
Packit c5a612
print("Adding quota q2")
Packit c5a612
out = do_command(add_quota)
Packit c5a612
handle = get_handle(out, add_quota["add"])
Packit c5a612
if handle == add_quota["add"]["quota"]["handle"]:
Packit c5a612
   exit_err("handle not changed in re-added quota!")
Packit c5a612
Packit c5a612
# now multiple commands
Packit c5a612
Packit c5a612
# reset name changes again
Packit c5a612
add_table["add"]["table"]["name"] = "t"
Packit c5a612
add_chain["add"]["chain"]["name"] = "c"
Packit c5a612
add_set["add"]["set"]["name"] = "s"
Packit c5a612
add_counter["add"]["counter"]["name"] = "c"
Packit c5a612
add_quota["add"]["quota"]["name"] = "q"
Packit c5a612
Packit c5a612
do_flush()
Packit c5a612
Packit c5a612
print("doing multi add")
Packit c5a612
add_multi = [ add_table, add_chain, add_set, add_rule ]
Packit c5a612
out = do_command(add_multi)
Packit c5a612
Packit c5a612
thandle = get_handle(out, add_table["add"])
Packit c5a612
chandle = get_handle(out, add_chain["add"])
Packit c5a612
shandle = get_handle(out, add_set["add"])
Packit c5a612
rhandle = get_handle(out, add_rule["add"])
Packit c5a612
Packit c5a612
out = do_list_ruleset()
Packit c5a612
Packit c5a612
if thandle != get_handle(out, add_table["add"]):
Packit c5a612
    exit_err("table handle mismatch!")
Packit c5a612
Packit c5a612
if chandle != get_handle(out, add_chain["add"]):
Packit c5a612
    exit_err("chain handle mismatch!")
Packit c5a612
Packit c5a612
if shandle != get_handle(out, add_set["add"]):
Packit c5a612
    exit_err("set handle mismatch!")
Packit c5a612
Packit c5a612
if rhandle != get_handle(out, add_rule["add"]):
Packit c5a612
    exit_err("rule handle mismatch!")