diff options
Diffstat (limited to 'tests/py/nft-test.py')
-rwxr-xr-x | tests/py/nft-test.py | 156 |
1 files changed, 75 insertions, 81 deletions
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py index 7998914a..d2d13218 100755 --- a/tests/py/nft-test.py +++ b/tests/py/nft-test.py @@ -15,11 +15,9 @@ import sys import os -import subprocess import argparse import signal -NFT_BIN = os.getenv('NFT', "src/nft") TESTS_PATH = os.path.dirname(os.path.abspath(__file__)) TESTS_DIRECTORY = ["any", "arp", "bridge", "inet", "ip", "ip6"] LOGFILE = "/tmp/nftables-test.log" @@ -57,6 +55,9 @@ class Chain: def __eq__(self, other): return self.__dict__ == other.__dict__ + def __str__(self): + return "%s" % self.name + class Table: """Class that represents a table""" @@ -69,6 +70,9 @@ class Table: def __eq__(self, other): return self.__dict__ == other.__dict__ + def __str__(self): + return "%s %s" % (self.family, self.name) + class Set: """Class that represents a set""" @@ -133,8 +137,8 @@ def table_exist(table, filename, lineno): ''' Exists a table. ''' - cmd = NFT_BIN + " list -nnn table " + table.family + " " + table.name - ret = execute_cmd(cmd, filename, lineno) + cmd = "list table %s" % table + ret = execute_cmd(cmd, filename, lineno, numeric="all") return True if (ret == 0) else False @@ -143,7 +147,7 @@ def table_flush(table, filename, lineno): ''' Flush a table. ''' - cmd = NFT_BIN + " flush table " + table.family + " " + table.name + cmd = "flush table %s" % table execute_cmd(cmd, filename, lineno) return cmd @@ -162,7 +166,7 @@ def table_create(table, filename, lineno): table_list.append(table) # We add a new table - cmd = NFT_BIN + " add table " + table.family + " " + table.name + cmd = "add table %s" % table ret = execute_cmd(cmd, filename, lineno) if ret != 0: @@ -195,15 +199,13 @@ def table_delete(table, filename=None, lineno=None): ''' Deletes a table. ''' - table_info = " " + table.family + " " + table.name + " " - if not table_exist(table, filename, lineno): reason = "Table " + table.name + \ " does not exist but I added it before." print_error(reason, filename, lineno) return -1 - cmd = NFT_BIN + " delete table" + table_info + cmd = "delete table %s" % table ret = execute_cmd(cmd, filename, lineno) if ret != 0: reason = cmd + ": " + "I cannot delete table '" + table.name + \ @@ -224,9 +226,8 @@ def chain_exist(chain, table, filename): ''' Checks a chain ''' - table_info = " " + table.family + " " + table.name + " " - cmd = NFT_BIN + " list -nnn chain" + table_info + chain.name - ret = execute_cmd(cmd, filename, chain.lineno) + cmd = "list chain %s %s" % (table, chain) + ret = execute_cmd(cmd, filename, chain.lineno, numeric="all") return True if (ret == 0) else False @@ -235,16 +236,13 @@ def chain_create(chain, table, filename): ''' Adds a chain ''' - table_info = " " + table.family + " " + table.name + " " - if chain_exist(chain, table, filename): reason = "This chain '" + chain.name + "' exists in " + table.name + \ ". I cannot create two chains with same name." print_error(reason, filename, chain.lineno) return -1 - cmd = NFT_BIN + " add chain" + table_info + chain.name + \ - "\{ " + chain.config + "\; \}" + cmd = "add chain %s %s { %s; }" % (table, chain, chain.config) ret = execute_cmd(cmd, filename, chain.lineno) if ret != 0: @@ -265,22 +263,20 @@ def chain_delete(chain, table, filename=None, lineno=None): ''' Flushes and deletes a chain. ''' - table_info = " " + table.family + " " + table.name + " " - if not chain_exist(chain, table, filename): reason = "The chain " + chain.name + " does not exists in " + \ table.name + ". I cannot delete it." print_error(reason, filename, lineno) return -1 - cmd = NFT_BIN + " flush chain" + table_info + chain.name + cmd = "flush chain %s %s" % (table, chain) ret = execute_cmd(cmd, filename, lineno) if ret != 0: reason = "I cannot flush this chain " + chain.name print_error(reason, filename, lineno) return -1 - cmd = NFT_BIN + " delete chain" + table_info + chain.name + cmd = "delete chain %s %s" % (table, chain) ret = execute_cmd(cmd, filename, lineno) if ret != 0: reason = cmd + "I cannot delete this chain. DD" @@ -323,13 +319,11 @@ def set_add(s, test_result, filename, lineno): print_error(reason, filename, lineno) return -1 - table_handle = " " + table.family + " " + table.name + " " - if s.flags == "": - set_cmd = " " + s.name + " { type " + s.type + "\;}" - else: - set_cmd = " " + s.name + " { type " + s.type + "\; flags " + s.flags + "\; }" + flags = s.flags + if flags != "": + flags = "flags %s; " % flags - cmd = NFT_BIN + " add set" + table_handle + set_cmd + cmd = "add set %s %s { type %s; %s}" % (table, s.name, s.type, flags) ret = execute_cmd(cmd, filename, lineno) if (ret == 0 and test_result == "fail") or \ @@ -365,17 +359,8 @@ def set_add_elements(set_element, set_name, state, filename, lineno): print_error(reason, filename, lineno) return -1 - table_info = " " + table.family + " " + table.name + " " - - element = "" - for e in set_element: - if not element: - element = e - else: - element = element + ", " + e - - set_text = set_name + " { " + element + " }" - cmd = NFT_BIN + " add element" + table_info + set_text + element = ", ".join(set_element) + cmd = "add element %s %s { %s }" % (table, set_name, element) ret = execute_cmd(cmd, filename, lineno) if (state == "fail" and ret == 0) or (state == "ok" and ret != 0): @@ -397,11 +382,8 @@ def set_delete_elements(set_element, set_name, table, filename=None, ''' Deletes elements in a set. ''' - table_info = " " + table.family + " " + table.name + " " - for element in set_element: - set_text = set_name + " {" + element + "}" - cmd = NFT_BIN + " delete element" + table_info + set_text + cmd = "delete element %s %s { %s }" % (table, set_name, element) ret = execute_cmd(cmd, filename, lineno) if ret != 0: reason = "I cannot delete an element" + element + \ @@ -429,8 +411,7 @@ def set_delete(table, filename=None, lineno=None): lineno) # We delete the set. - table_info = " " + table.family + " " + table.name + " " - cmd = NFT_BIN + " delete set " + table_info + " " + set_name + cmd = "delete set %s %s" % (table, set_name) ret = execute_cmd(cmd, filename, lineno) # Check if the set still exists after I deleted it. @@ -446,9 +427,8 @@ def set_exist(set_name, table, filename, lineno): ''' Check if the set exists. ''' - table_info = " " + table.family + " " + table.name + " " - cmd = NFT_BIN + " list -nnn set" + table_info + set_name - ret = execute_cmd(cmd, filename, lineno) + cmd = "list set %s %s" % (table, set_name) + ret = execute_cmd(cmd, filename, lineno, numeric="all") return True if (ret == 0) else False @@ -457,9 +437,8 @@ def _set_exist(s, filename, lineno): ''' Check if the set exists. ''' - table_handle = " " + s.family + " " + s.table + " " - cmd = NFT_BIN + " list -nnn set" + table_handle + s.name - ret = execute_cmd(cmd, filename, lineno) + cmd = "list set %s %s %s" % (s.family, s.table, s.name) + ret = execute_cmd(cmd, filename, lineno, numeric="all") return True if (ret == 0) else False @@ -510,9 +489,7 @@ def obj_add(o, test_result, filename, lineno): print_error(reason, filename, lineno) return -1 - table_handle = " " + table.family + " " + table.name + " " - - cmd = NFT_BIN + " add " + o.type + table_handle + o.name + " " + o.spcf + cmd = "add %s %s %s %s" % (o.type, table, o.name, o.spcf) ret = execute_cmd(cmd, filename, lineno) if (ret == 0 and test_result == "fail") or \ @@ -552,8 +529,7 @@ def obj_delete(table, filename=None, lineno=None): return -1 # We delete the object. - table_info = " " + table.family + " " + table.name + " " - cmd = NFT_BIN + " delete " + o.type + table_info + " " + o.name + cmd = "delete %s %s %s" % (o.type, table, o.name) ret = execute_cmd(cmd, filename, lineno) # Check if the object still exists after I deleted it. @@ -569,9 +545,8 @@ def obj_exist(o, table, filename, lineno): ''' Check if the object exists. ''' - table_handle = " " + table.family + " " + table.name + " " - cmd = NFT_BIN + " list -nnn " + o.type + table_handle + o.name - ret = execute_cmd(cmd, filename, lineno) + cmd = "list %s %s %s" % (o.type, table, o.name) + ret = execute_cmd(cmd, filename, lineno, numeric="all") return True if (ret == 0) else False @@ -580,9 +555,8 @@ def _obj_exist(o, filename, lineno): ''' Check if the object exists. ''' - table_handle = " " + o.family + " " + o.table + " " - cmd = NFT_BIN + " list -nnn " + o.type + table_handle + o.name - ret = execute_cmd(cmd, filename, lineno) + cmd = "list %s %s %s %s" % (o.type, o.family, o.table, o.name) + ret = execute_cmd(cmd, filename, lineno, numeric="all") return True if (ret == 0) else False @@ -697,13 +671,11 @@ def rule_add(rule, filename, lineno, force_all_family_option, filename_path): chain = chain_get_by_name(table_chain) unit_tests += 1 table_flush(table, filename, lineno) - table_info = " " + table.family + " " + table.name + " " payload_log = os.tmpfile() - cmd = NFT_BIN + " add rule --debug=netlink" + table_info + \ - chain.name + " " + rule[0] - ret = execute_cmd(cmd, filename, lineno, payload_log) + cmd = "add rule %s %s %s" % (table, chain, rule[0]) + ret = execute_cmd(cmd, filename, lineno, payload_log, debug="netlink") state = rule[1].rstrip() if (ret in [0,134] and state == "fail") or (ret != 0 and state == "ok"): @@ -740,13 +712,14 @@ def rule_add(rule, filename, lineno, force_all_family_option, filename_path): gotf.name, 1) # Check output of nft - process = subprocess.Popen([NFT_BIN, '-nnns', 'list', 'table', - table.family, table.name], - shell=False, - stdout=subprocess.PIPE, - preexec_fn=preexec) - pre_output = process.communicate() - output = pre_output[0].split(";") + numeric_old = nftables.set_numeric_output("all") + stateless_old = nftables.set_stateless_output(True) + list_cmd = 'list table %s' % table + rc, pre_output, err = nftables.cmd(list_cmd) + nftables.set_numeric_output(numeric_old) + nftables.set_stateless_output(stateless_old) + + output = pre_output.split(";") if len(output) < 2: reason = cmd + ": Listing is broken." print_error(reason, filename, lineno) @@ -755,7 +728,7 @@ def rule_add(rule, filename, lineno, force_all_family_option, filename_path): if not force_all_family_option: return [ret, warning, error, unit_tests] else: - rule_output = output_clean(pre_output[0], chain) + rule_output = output_clean(pre_output, chain) if len(rule) == 3: teoric_exit = rule[2] else: @@ -809,7 +782,8 @@ def signal_handler(signal, frame): signal_received = 1 -def execute_cmd(cmd, filename, lineno, stdout_log=False): +def execute_cmd(cmd, filename, lineno, + stdout_log=False, numeric=False, debug=False): ''' Executes a command, checks for segfaults and returns the command exit code. @@ -817,23 +791,36 @@ def execute_cmd(cmd, filename, lineno, stdout_log=False): :param cmd: string with the command to be executed :param filename: name of the file tested (used for print_error purposes) :param lineno: line number being tested (used for print_error purposes) + :param stdout_log: redirect stdout to this file instead of global log_file + :param numeric: turn numeric output temporarily on + :param debug: temporarily set these debug flags ''' global log_file print >> log_file, "command: %s" % cmd if debug_option: print cmd + if numeric: + numeric_old = nftables.get_numeric_output() + nftables.set_numeric_output(numeric) + if debug: + debug_old = nftables.get_debug() + nftables.set_debug(debug) + + ret, out, err = nftables.cmd(cmd) + if not stdout_log: stdout_log = log_file - ret = subprocess.call(cmd, shell=True, universal_newlines=True, - stderr=log_file, stdout=stdout_log, - preexec_fn=preexec) + stdout_log.write(out) + stdout_log.flush() + log_file.write(err) log_file.flush() - if ret == -11: - reason = "command segfaults: " + cmd - print_error(reason, filename, lineno) + if numeric: + nftables.set_numeric_output(numeric_old) + if debug: + nftables.set_debug(debug_old) return ret @@ -1123,10 +1110,17 @@ def main(): # Change working directory to repository root os.chdir(TESTS_PATH + "/../..") - if not os.path.isfile(NFT_BIN): - print "The nft binary does not exist. You need to build the project." + sys.path.append('py/') + from nftables import Nftables + + if not os.path.exists('src/.libs/libnftables.so'): + print "The nftables library does not exist. " \ + "You need to build the project." return + global nftables + nftables = Nftables('src/.libs/libnftables.so') + test_files = files_ok = run_total = 0 tests = passed = warnings = errors = 0 global log_file |