diff mbox series

[nft,v8] tests: py: add netns feature

Message ID 20190617141558.2994-1-shekhar250198@gmail.com
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series [nft,v8] tests: py: add netns feature | expand

Commit Message

Shekhar Sharma June 17, 2019, 2:15 p.m. UTC
This patch adds the netns feature to the 'nft-test.py' file.


Signed-off-by: Shekhar Sharma <shekhar250198@gmail.com>
---
The version history of the patch is :
v1: add the netns feature
v2: use format() method to simplify print statements.
v3: updated the shebang
v4: resent the same with small changes
v5&v6: resent with small changes
v7: netns commands changed for passing the netns name via netns argument.
v8: correct typo error 

 tests/py/nft-test.py | 140 +++++++++++++++++++++++++++++++------------
 1 file changed, 101 insertions(+), 39 deletions(-)

Comments

Eric Garver June 18, 2019, 2:47 p.m. UTC | #1
On Mon, Jun 17, 2019 at 07:45:58PM +0530, Shekhar Sharma wrote:
> This patch adds the netns feature to the 'nft-test.py' file.
> 
> 
> Signed-off-by: Shekhar Sharma <shekhar250198@gmail.com>
> ---
> The version history of the patch is :
> v1: add the netns feature
> v2: use format() method to simplify print statements.
> v3: updated the shebang
> v4: resent the same with small changes
> v5&v6: resent with small changes
> v7: netns commands changed for passing the netns name via netns argument.
> v8: correct typo error 
> 
>  tests/py/nft-test.py | 140 +++++++++++++++++++++++++++++++------------
>  1 file changed, 101 insertions(+), 39 deletions(-)
> 
> diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
> index 09d00dba..bf5e64c0 100755
> --- a/tests/py/nft-test.py
> +++ b/tests/py/nft-test.py
[..]
> @@ -1359,6 +1417,13 @@ def main():
>                          dest='enable_schema',
>                          help='verify json input/output against schema')
>  
> +    parser.add_argument('-N', '--netns', action='store_true',
> +                        help='Test namespace path')

AFAICS, this new option is not being used - it's not passed to
run_test_file() or other functions. Will that be done in a follow up
patch?

> +
> +    parser.add_argument('-v', '--version', action='version',
> +                        version='1.0',
> +                        help='Print the version information')
> +
>      args = parser.parse_args()
>      global debug_option, need_fix_option, enable_json_option, enable_json_schema
>      debug_option = args.debug
[..]
> @@ -1434,18 +1499,15 @@ def main():
>              run_total += file_unit_run
>  
>      if test_files == 0:
> -        print "No test files to run"
> +        print("No test files to run")
>      else:
>          if not specific_file:
>              if force_all_family_option:
> -                print "%d test files, %d files passed, %d unit tests, " \
> -                      "%d total executed, %d error, %d warning" \
> -                      % (test_files, files_ok, tests, run_total, errors,
> -                         warnings)
> +                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
> +                print("{} total executed, {} error, {} warning".format(run_total, errors, warnings))
>              else:
> -                print "%d test files, %d files passed, %d unit tests, " \
> -                      "%d error, %d warning" \
> -                      % (test_files, files_ok, tests, errors, warnings)
> +                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
> +                print("{} error, {} warning".format(errors, warnings))
>  

Please drop this hunk. It was already addressed in your patch "[PATCH
nft v7 1/2]tests:py: conversion to  python3". As such this patch doesn't
apply on top of your previous patch.
Shekhar Sharma June 18, 2019, 5:06 p.m. UTC | #2
Hi Eric!
On Tue, Jun 18, 2019 at 8:17 PM Eric Garver <eric@garver.life> wrote:
>
> On Mon, Jun 17, 2019 at 07:45:58PM +0530, Shekhar Sharma wrote:
> > This patch adds the netns feature to the 'nft-test.py' file.
> >
> >
> > Signed-off-by: Shekhar Sharma <shekhar250198@gmail.com>
> > ---
> > The version history of the patch is :
> > v1: add the netns feature
> > v2: use format() method to simplify print statements.
> > v3: updated the shebang
> > v4: resent the same with small changes
> > v5&v6: resent with small changes
> > v7: netns commands changed for passing the netns name via netns argument.
> > v8: correct typo error
> >
> >  tests/py/nft-test.py | 140 +++++++++++++++++++++++++++++++------------
> >  1 file changed, 101 insertions(+), 39 deletions(-)
> >
> > diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
> > index 09d00dba..bf5e64c0 100755
> > --- a/tests/py/nft-test.py
> > +++ b/tests/py/nft-test.py
> [..]
> > @@ -1359,6 +1417,13 @@ def main():
> >                          dest='enable_schema',
> >                          help='verify json input/output against schema')
> >
> > +    parser.add_argument('-N', '--netns', action='store_true',
> > +                        help='Test namespace path')
>
> AFAICS, this new option is not being used - it's not passed to
> run_test_file() or other functions. Will that be done in a follow up
> patch?
>

True. I just saw that '-N', '-V' are also not added in the lines below
this as in
debug_option= args.debug
i need to add that as well and then use it in the functions.
I think that will be covered in another patch.

> > +
> > +    parser.add_argument('-v', '--version', action='version',
> > +                        version='1.0',
> > +                        help='Print the version information')
> > +
> >      args = parser.parse_args()
> >      global debug_option, need_fix_option, enable_json_option, enable_json_schema
> >      debug_option = args.debug
> [..]
> > @@ -1434,18 +1499,15 @@ def main():
> >              run_total += file_unit_run
> >
> >      if test_files == 0:
> > -        print "No test files to run"
> > +        print("No test files to run")
> >      else:
> >          if not specific_file:
> >              if force_all_family_option:
> > -                print "%d test files, %d files passed, %d unit tests, " \
> > -                      "%d total executed, %d error, %d warning" \
> > -                      % (test_files, files_ok, tests, run_total, errors,
> > -                         warnings)
> > +                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
> > +                print("{} total executed, {} error, {} warning".format(run_total, errors, warnings))
> >              else:
> > -                print "%d test files, %d files passed, %d unit tests, " \
> > -                      "%d error, %d warning" \
> > -                      % (test_files, files_ok, tests, errors, warnings)
> > +                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
> > +                print("{} error, {} warning".format(errors, warnings))
> >
>
> Please drop this hunk. It was already addressed in your patch "[PATCH
> nft v7 1/2]tests:py: conversion to  python3". As such this patch doesn't
> apply on top of your previous patch.

Ok. Will re-post the patch with out this bit.

Thanks!
Shekhar
Shekhar Sharma June 18, 2019, 5:10 p.m. UTC | #3
On Tue, Jun 18, 2019 at 10:36 PM shekhar sharma <shekhar250198@gmail.com> wrote:
>
> Hi Eric!
> On Tue, Jun 18, 2019 at 8:17 PM Eric Garver <eric@garver.life> wrote:
> >
> > On Mon, Jun 17, 2019 at 07:45:58PM +0530, Shekhar Sharma wrote:
> > > This patch adds the netns feature to the 'nft-test.py' file.
> > >
> > >
> > > Signed-off-by: Shekhar Sharma <shekhar250198@gmail.com>
> > > ---
> > > The version history of the patch is :
> > > v1: add the netns feature
> > > v2: use format() method to simplify print statements.
> > > v3: updated the shebang
> > > v4: resent the same with small changes
> > > v5&v6: resent with small changes
> > > v7: netns commands changed for passing the netns name via netns argument.
> > > v8: correct typo error
> > >
> > >  tests/py/nft-test.py | 140 +++++++++++++++++++++++++++++++------------
> > >  1 file changed, 101 insertions(+), 39 deletions(-)
> > >
> > > diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
> > > index 09d00dba..bf5e64c0 100755
> > > --- a/tests/py/nft-test.py
> > > +++ b/tests/py/nft-test.py
> > [..]
> > > @@ -1359,6 +1417,13 @@ def main():
> > >                          dest='enable_schema',
> > >                          help='verify json input/output against schema')
> > >
> > > +    parser.add_argument('-N', '--netns', action='store_true',
> > > +                        help='Test namespace path')
> >
> > AFAICS, this new option is not being used - it's not passed to
> > run_test_file() or other functions. Will that be done in a follow up
> > patch?
> >
>
> True. I just saw that '-N', '-V' are also not added in the lines below
> this as in
> debug_option= args.debug
> i need to add that as well and then use it in the functions.
> I think that will be covered in another patch.
>
> > > +
> > > +    parser.add_argument('-v', '--version', action='version',
> > > +                        version='1.0',
> > > +                        help='Print the version information')
> > > +
> > >      args = parser.parse_args()
> > >      global debug_option, need_fix_option, enable_json_option, enable_json_schema
> > >      debug_option = args.debug
> > [..]
> > > @@ -1434,18 +1499,15 @@ def main():
> > >              run_total += file_unit_run
> > >
> > >      if test_files == 0:
> > > -        print "No test files to run"
> > > +        print("No test files to run")
> > >      else:
> > >          if not specific_file:
> > >              if force_all_family_option:
> > > -                print "%d test files, %d files passed, %d unit tests, " \
> > > -                      "%d total executed, %d error, %d warning" \
> > > -                      % (test_files, files_ok, tests, run_total, errors,
> > > -                         warnings)
> > > +                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
> > > +                print("{} total executed, {} error, {} warning".format(run_total, errors, warnings))
> > >              else:
> > > -                print "%d test files, %d files passed, %d unit tests, " \
> > > -                      "%d error, %d warning" \
> > > -                      % (test_files, files_ok, tests, errors, warnings)
> > > +                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
> > > +                print("{} error, {} warning".format(errors, warnings))
> > >
> >
> > Please drop this hunk. It was already addressed in your patch "[PATCH
> > nft v7 1/2]tests:py: conversion to  python3". As such this patch doesn't
> > apply on top of your previous patch.
>
I forgot to add the netns argument in one of the statements in the
previous version (as suggested by jones) so i corrected that in this.
Sorry i forgot to mention this in the last mail :-).



> Ok. Will re-post the patch with out this bit.
>
> Thanks!
> Shekhar
diff mbox series

Patch

diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
index 09d00dba..bf5e64c0 100755
--- a/tests/py/nft-test.py
+++ b/tests/py/nft-test.py
@@ -1,4 +1,4 @@ 
-#!/usr/bin/python2
+#!/usr/bin/env python
 #
 # (C) 2014 by Ana Rey Botello <anarey@gmail.com>
 #
@@ -13,6 +13,7 @@ 
 # Thanks to the Outreach Program for Women (OPW) for sponsoring this test
 # infrastructure.
 
+from __future__ import print_function
 import sys
 import os
 import argparse
@@ -172,27 +173,31 @@  def print_differences_error(filename, lineno, cmd):
     print_error(reason, filename, lineno)
 
 
-def table_exist(table, filename, lineno):
+def table_exist(table, filename, lineno, netns=""):
     '''
     Exists a table.
     '''
     cmd = "list table %s" % table
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
     ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
 
-def table_flush(table, filename, lineno):
+def table_flush(table, filename, lineno, netns=""):
     '''
     Flush a table.
     '''
     cmd = "flush table %s" % table
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns, cmd)
     execute_cmd(cmd, filename, lineno)
 
     return cmd
 
 
-def table_create(table, filename, lineno):
+def table_create(table, filename, lineno, netns=""):
     '''
     Adds a table.
     '''
@@ -206,6 +211,8 @@  def table_create(table, filename, lineno):
 
     # We add a new table
     cmd = "add table %s" % table
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
     ret = execute_cmd(cmd, filename, lineno)
 
     if ret != 0:
@@ -234,7 +241,7 @@  def table_create(table, filename, lineno):
     return 0
 
 
-def table_delete(table, filename=None, lineno=None):
+def table_delete(table, filename=None, lineno=None, netns=""):
     '''
     Deletes a table.
     '''
@@ -244,6 +251,8 @@  def table_delete(table, filename=None, lineno=None):
         return -1
 
     cmd = "delete table %s" % table
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
     ret = execute_cmd(cmd, filename, lineno)
     if ret != 0:
         reason = "%s: I cannot delete table %s. Giving up!" % (cmd, table)
@@ -259,17 +268,19 @@  def table_delete(table, filename=None, lineno=None):
     return 0
 
 
-def chain_exist(chain, table, filename):
+def chain_exist(chain, table, filename, netns=""):
     '''
     Checks a chain
     '''
     cmd = "list chain %s %s" % (table, chain)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
     ret = execute_cmd(cmd, filename, chain.lineno)
 
     return True if (ret == 0) else False
 
 
-def chain_create(chain, table, filename):
+def chain_create(chain, table, filename, netns=""):
     '''
     Adds a chain
     '''
@@ -280,6 +291,8 @@  def chain_create(chain, table, filename):
         return -1
 
     cmd = "add chain %s %s" % (table, chain)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
     if chain.config:
         cmd += " { %s; }" % chain.config
 
@@ -298,7 +311,7 @@  def chain_create(chain, table, filename):
     return 0
 
 
-def chain_delete(chain, table, filename=None, lineno=None):
+def chain_delete(chain, table, filename=None, lineno=None, netns=""):
     '''
     Flushes and deletes a chain.
     '''
@@ -309,6 +322,9 @@  def chain_delete(chain, table, filename=None, lineno=None):
         return -1
 
     cmd = "flush chain %s %s" % (table, chain)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
     ret = execute_cmd(cmd, filename, lineno)
     if ret != 0:
         reason = "I cannot " + cmd
@@ -316,6 +332,8 @@  def chain_delete(chain, table, filename=None, lineno=None):
         return -1
 
     cmd = "delete chain %s %s" % (table, chain)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
     ret = execute_cmd(cmd, filename, lineno)
     if ret != 0:
         reason = "I cannot " + cmd
@@ -341,7 +359,7 @@  def chain_get_by_name(name):
     return chain
 
 
-def set_add(s, test_result, filename, lineno):
+def set_add(s, test_result, filename, lineno, netns=""):
     '''
     Adds a set.
     '''
@@ -363,6 +381,9 @@  def set_add(s, test_result, filename, lineno):
             flags = "flags %s; " % flags
 
         cmd = "add set %s %s { type %s;%s %s}" % (table, s.name, s.type, s.timeout, flags)
+        if netns:
+            cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
         ret = execute_cmd(cmd, filename, lineno)
 
         if (ret == 0 and test_result == "fail") or \
@@ -380,7 +401,7 @@  def set_add(s, test_result, filename, lineno):
     return 0
 
 
-def set_add_elements(set_element, set_name, state, filename, lineno):
+def set_add_elements(set_element, set_name, state, filename, lineno, netns=""):
     '''
     Adds elements to the set.
     '''
@@ -400,6 +421,9 @@  def set_add_elements(set_element, set_name, state, filename, lineno):
 
         element = ", ".join(set_element)
         cmd = "add element %s %s { %s }" % (table, set_name, element)
+        if netns:
+            cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
         ret = execute_cmd(cmd, filename, lineno)
 
         if (state == "fail" and ret == 0) or (state == "ok" and ret != 0):
@@ -417,12 +441,15 @@  def set_add_elements(set_element, set_name, state, filename, lineno):
 
 
 def set_delete_elements(set_element, set_name, table, filename=None,
-                        lineno=None):
+                        lineno=None, netns=""):
     '''
     Deletes elements in a set.
     '''
     for element in set_element:
         cmd = "delete element %s %s { %s }" % (table, set_name, element)
+        if netns:
+            cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
         ret = execute_cmd(cmd, filename, lineno)
         if ret != 0:
             reason = "I cannot delete element %s " \
@@ -433,7 +460,7 @@  def set_delete_elements(set_element, set_name, table, filename=None,
     return 0
 
 
-def set_delete(table, filename=None, lineno=None):
+def set_delete(table, filename=None, lineno=None, netns=""):
     '''
     Deletes set and its content.
     '''
@@ -451,6 +478,9 @@  def set_delete(table, filename=None, lineno=None):
 
         # We delete the set.
         cmd = "delete set %s %s" % (table, set_name)
+        if netns:
+            cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
         ret = execute_cmd(cmd, filename, lineno)
 
         # Check if the set still exists after I deleted it.
@@ -462,21 +492,27 @@  def set_delete(table, filename=None, lineno=None):
     return 0
 
 
-def set_exist(set_name, table, filename, lineno):
+def set_exist(set_name, table, filename, lineno, netns=""):
     '''
     Check if the set exists.
     '''
     cmd = "list set %s %s" % (table, set_name)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
     ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
 
-def _set_exist(s, filename, lineno):
+def _set_exist(s, filename, lineno, netns=""):
     '''
     Check if the set exists.
     '''
     cmd = "list set %s %s %s" % (s.family, s.table, s.name)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
     ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
@@ -510,7 +546,7 @@  def set_check_element(rule1, rule2):
     return cmp(rule1[end1:], rule2[end2:])
 
 
-def obj_add(o, test_result, filename, lineno):
+def obj_add(o, test_result, filename, lineno, netns=""):
     '''
     Adds an object.
     '''
@@ -529,6 +565,9 @@  def obj_add(o, test_result, filename, lineno):
             return -1
 
         cmd = "add %s %s %s %s" % (o.type, table, o.name, o.spcf)
+        if netns:
+            cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
         ret = execute_cmd(cmd, filename, lineno)
 
         if (ret == 0 and test_result == "fail") or \
@@ -555,7 +594,7 @@  def obj_add(o, test_result, filename, lineno):
         print_error(reason, filename, lineno)
         return -1
 
-def obj_delete(table, filename=None, lineno=None):
+def obj_delete(table, filename=None, lineno=None, netns=""):
     '''
     Deletes object.
     '''
@@ -569,6 +608,9 @@  def obj_delete(table, filename=None, lineno=None):
 
         # We delete the object.
         cmd = "delete %s %s %s" % (o.type, table, o.name)
+        if netns:
+            cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
         ret = execute_cmd(cmd, filename, lineno)
 
         # Check if the object still exists after I deleted it.
@@ -580,21 +622,27 @@  def obj_delete(table, filename=None, lineno=None):
     return 0
 
 
-def obj_exist(o, table, filename, lineno):
+def obj_exist(o, table, filename, lineno, netns=""):
     '''
     Check if the object exists.
     '''
     cmd = "list %s %s %s" % (o.type, table, o.name)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
     ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
 
 
-def _obj_exist(o, filename, lineno):
+def _obj_exist(o, filename, lineno, netns=""):
     '''
     Check if the object exists.
     '''
     cmd = "list %s %s %s %s" % (o.type, o.family, o.table, o.name)
+    if netns:
+        cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
     ret = execute_cmd(cmd, filename, lineno)
 
     return True if (ret == 0) else False
@@ -696,7 +744,7 @@  def json_validate(json_string):
         print_error("schema validation failed for input '%s'" % json_string)
         print_error(traceback.format_exc())
 
-def rule_add(rule, filename, lineno, force_all_family_option, filename_path):
+def rule_add(rule, filename, lineno, force_all_family_option, filename_path, netns=""):
     '''
     Adds a rule
     '''
@@ -774,6 +822,9 @@  def rule_add(rule, filename, lineno, force_all_family_option, filename_path):
 
             # Add rule and check return code
             cmd = "add rule %s %s %s" % (table, chain, rule[0])
+            if netns:
+                cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
             ret = execute_cmd(cmd, filename, lineno, payload_log, debug="netlink")
 
             state = rule[1].rstrip()
@@ -870,6 +921,9 @@  def rule_add(rule, filename, lineno, force_all_family_option, filename_path):
 
                 # Add rule and check return code
                 cmd = "add rule %s %s %s" % (table, chain, rule_output.rstrip())
+                if netns:
+                    cmd = "ip netns exec " + "{} {}".format(netns,cmd)
+
                 ret = execute_cmd(cmd, filename, lineno, payload_log, debug="netlink")
 
                 if ret != 0:
@@ -1016,9 +1070,9 @@  def execute_cmd(cmd, filename, lineno, stdout_log=False, debug=False):
     :param debug: temporarily set these debug flags
     '''
     global log_file
-    print >> log_file, "command: %s" % cmd
+    print("command: {}".format(cmd),file=log_file)
     if debug_option:
-        print cmd
+        print(cmd)
 
     if debug:
         debug_old = nftables.get_debug()
@@ -1198,7 +1252,7 @@  def json_find_expected(json_log, rule):
     return json_buffer
 
 
-def run_test_file(filename, force_all_family_option, specific_file):
+def run_test_file(filename, force_all_family_option, specific_file,netns=""):
     '''
     Runs a test file
 
@@ -1207,12 +1261,14 @@  def run_test_file(filename, force_all_family_option, specific_file):
     filename_path = os.path.join(TESTS_PATH, filename)
     f = open(filename_path)
     tests = passed = total_unit_run = total_warning = total_error = 0
+    if netns:
+        execute_cmd("ip netns add " + netns, filename, 0)
 
     for lineno, line in enumerate(f):
         sys.stdout.flush()
 
         if signal_received == 1:
-            print "\nSignal received. Cleaning up and Exitting..."
+            print("\nSignal received. Cleaning up and Exitting...")
             cleanup_on_exit()
             sys.exit(0)
 
@@ -1319,13 +1375,15 @@  def run_test_file(filename, force_all_family_option, specific_file):
 
     if specific_file:
         if force_all_family_option:
-            print print_result_all(filename, tests, total_warning, total_error,
-                                   total_unit_run)
+            print(print_result_all(filename, tests, total_warning, total_error,
+                                   total_unit_run))
         else:
-            print print_result(filename, tests, total_warning, total_error)
+            print(print_result(filename, tests, total_warning, total_error))
     else:
         if tests == passed and tests > 0:
-            print filename + ": " + Colors.GREEN + "OK" + Colors.ENDC
+            print(filename + ": " + Colors.GREEN + "OK" + Colors.ENDC)
+        if netns:
+            execute_cmd("ip netns del " + netns, filename, 0)
 
     f.close()
     del table_list[:]
@@ -1336,7 +1394,7 @@  def run_test_file(filename, force_all_family_option, specific_file):
 
 
 def main():
-    parser = argparse.ArgumentParser(description='Run nft tests', version='1.0')
+    parser = argparse.ArgumentParser(description='Run nft tests')
 
     parser.add_argument('filenames', nargs='*', metavar='path/to/file.t',
                         help='Run only these tests')
@@ -1359,6 +1417,13 @@  def main():
                         dest='enable_schema',
                         help='verify json input/output against schema')
 
+    parser.add_argument('-N', '--netns', action='store_true',
+                        help='Test namespace path')
+
+    parser.add_argument('-v', '--version', action='version',
+                        version='1.0',
+                        help='Print the version information')
+
     args = parser.parse_args()
     global debug_option, need_fix_option, enable_json_option, enable_json_schema
     debug_option = args.debug
@@ -1372,15 +1437,15 @@  def main():
     signal.signal(signal.SIGTERM, signal_handler)
 
     if os.getuid() != 0:
-        print "You need to be root to run this, sorry"
+        print("You need to be root to run this, sorry")
         return
 
     # Change working directory to repository root
     os.chdir(TESTS_PATH + "/../..")
 
     if not os.path.exists('src/.libs/libnftables.so'):
-        print "The nftables library does not exist. " \
-              "You need to build the project."
+        print("The nftables library does not exist. "
+              "You need to build the project.")
         return
 
     if args.enable_schema and not args.enable_json:
@@ -1434,18 +1499,15 @@  def main():
             run_total += file_unit_run
 
     if test_files == 0:
-        print "No test files to run"
+        print("No test files to run")
     else:
         if not specific_file:
             if force_all_family_option:
-                print "%d test files, %d files passed, %d unit tests, " \
-                      "%d total executed, %d error, %d warning" \
-                      % (test_files, files_ok, tests, run_total, errors,
-                         warnings)
+                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
+                print("{} total executed, {} error, {} warning".format(run_total, errors, warnings))
             else:
-                print "%d test files, %d files passed, %d unit tests, " \
-                      "%d error, %d warning" \
-                      % (test_files, files_ok, tests, errors, warnings)
+                print("{} test files, {} files passed, {} unit tests, ".format(test_files,files_ok,tests))
+                print("{} error, {} warning".format(errors, warnings))
 
 
 if __name__ == '__main__':