summaryrefslogtreecommitdiffstats
path: root/tests/py/nft-test.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/py/nft-test.py')
-rwxr-xr-xtests/py/nft-test.py156
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