Add tox.ini and few checker scripts
[csit.git] / resources / libraries / python / autogen / Regenerator.py
index e7e0370..c822b16 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Cisco and/or its affiliates.
+# Copyright (c) 2019 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
 
 """Module defining utilities for test directory regeneration."""
 
 
 """Module defining utilities for test directory regeneration."""
 
+from __future__ import print_function
+
 from glob import glob
 from os import getcwd
 from glob import glob
 from os import getcwd
+import sys
 
 
-from .Testcase import Testcase
 from .DefaultTestcase import DefaultTestcase
 
 
 from .DefaultTestcase import DefaultTestcase
 
 
+# Copied from https://stackoverflow.com/a/14981125
+def eprint(*args, **kwargs):
+    """Print to stderr."""
+    print(*args, file=sys.stderr, **kwargs)
+
+
 class Regenerator(object):
     """Class containing file generating methods."""
 
 class Regenerator(object):
     """Class containing file generating methods."""
 
-    def __init__(self, testcase_class=DefaultTestcase):
+    def __init__(self, testcase_class=DefaultTestcase, quiet=True):
         """Initialize Testcase class to use.
 
         TODO: See the type doc for testcase_class?
         """Initialize Testcase class to use.
 
         TODO: See the type doc for testcase_class?
@@ -32,9 +40,12 @@ class Regenerator(object):
 
         :param testcase_class: Subclass of DefaultTestcase for generation.
             Default: DefaultTestcase
 
         :param testcase_class: Subclass of DefaultTestcase for generation.
             Default: DefaultTestcase
+        :param quiet: Reduce log prints (to stderr) when True (default).
         :type testcase_class: subclass of DefaultTestcase accepting suite_id
         :type testcase_class: subclass of DefaultTestcase accepting suite_id
+        :type quiet: boolean
         """
         self.testcase_class = testcase_class
         """
         self.testcase_class = testcase_class
+        self.quiet = quiet
 
     def regenerate_glob(self, pattern, protocol="ip4", tc_kwargs_list=None):
         """Regenerate files matching glob pattern based on arguments.
 
     def regenerate_glob(self, pattern, protocol="ip4", tc_kwargs_list=None):
         """Regenerate files matching glob pattern based on arguments.
@@ -44,6 +55,8 @@ class Regenerator(object):
         test cases, autonumbering them, taking arguments from list.
         If the list is None, use default list, which depends on ip6 usage.
 
         test cases, autonumbering them, taking arguments from list.
         If the list is None, use default list, which depends on ip6 usage.
 
+        Log-like prints are emited to sys.stderr.
+
         :param pattern: Glob pattern to select files. Example: *-ndrpdr.robot
         :param is_ip6: Flag determining minimal frame size. Default: False
         :param tc_kwargs_list: Arguments defining the testcases. Default: None
         :param pattern: Glob pattern to select files. Example: *-ndrpdr.robot
         :param is_ip6: Flag determining minimal frame size. Default: False
         :param tc_kwargs_list: Arguments defining the testcases. Default: None
@@ -63,24 +76,75 @@ class Regenerator(object):
         }
 
         def get_iface_and_suite_id(filename):
         }
 
         def get_iface_and_suite_id(filename):
+            """Get interface and suite ID.
+
+            :param filename: Suite file.
+            :type filename: str
+            :returns: Interface ID, Suite ID.
+            :rtype: tuple
+            """
             dash_split = filename.split("-", 1)
             if len(dash_split[0]) <= 4:
                 # It was something like "2n1l", we need one more split.
                 dash_split = dash_split[1].split("-", 1)
             return dash_split[0], dash_split[1].split(".", 1)[0]
 
             dash_split = filename.split("-", 1)
             if len(dash_split[0]) <= 4:
                 # It was something like "2n1l", we need one more split.
                 dash_split = dash_split[1].split("-", 1)
             return dash_split[0], dash_split[1].split(".", 1)[0]
 
-        def add_testcase(testcase, iface, file_out, num, **kwargs):
+        def add_testcase(testcase, iface, suite_id, file_out, num, **kwargs):
+            """Add testcase to file.
+
+            :param testcase: Testcase class.
+            :param iface: Interface.
+            :param suite_id: Suite ID.
+            :param file_out: File to write testcases to.
+            :param num: Testcase number.
+            :param kwargs: Key-value pairs used to construct testcase.
+            :type testcase: Testcase
+            :type iface: str
+            :type suite_id: str
+            :type file_out: file
+            :type num: int
+            :type kwargs: dict
+            :returns: Next testcase number.
+            :rtype: int
+            """
             # TODO: Is there a better way to disable some combinations?
             # TODO: Is there a better way to disable some combinations?
-            if kwargs["framesize"] != 9000 or "vic1227" not in iface:
+            if kwargs["framesize"] == 9000 and "vic1227" in iface:
+                # Not supported in HW.
+                pass
+            elif kwargs["framesize"] == 9000 and "avf" in suite_id:
+                # Not supported by AVF driver.
+                # https://git.fd.io/vpp/tree/src/plugins/avf/README.md
+                pass
+            elif ("soak" in suite_id and
+                  (kwargs["phy_cores"] != 1
+                   or kwargs["framesize"] in (1518, 9000, "IMIX_v4_1"))):
+                # Soak test take too long, do not risk other than tc01.
+                pass
+            else:
                 file_out.write(testcase.generate(num=num, **kwargs))
             return num + 1
 
                 file_out.write(testcase.generate(num=num, **kwargs))
             return num + 1
 
-        def add_testcases(testcase, iface, file_out, tc_kwargs_list):
+        def add_testcases(testcase, iface, suite_id, file_out, tc_kwargs_list):
+            """Add testcases to file.
+
+            :param testcase: Testcase class.
+            :param iface: Interface.
+            :param suite_id: Suite ID.
+            :param file_out: File to write testcases to.
+            :param tc_kwargs_list: Key-value pairs used to construct testcases.
+            :type testcase: Testcase
+            :type iface: str
+            :type suite_id: str
+            :type file_out: file
+            :type tc_kwargs_list: dict
+            """
             num = 1
             for tc_kwargs in tc_kwargs_list:
             num = 1
             for tc_kwargs in tc_kwargs_list:
-                num = add_testcase(testcase, iface, file_out, num, **tc_kwargs)
+                num = add_testcase(testcase, iface, suite_id, file_out, num,
+                                   **tc_kwargs)
 
 
-        print "Regenerator starts at {cwd}".format(cwd=getcwd())
+        if not self.quiet:
+            eprint("Regenerator starts at {cwd}".format(cwd=getcwd()))
         min_framesize = protocol_to_min_framesize[protocol]
         kwargs_list = tc_kwargs_list if tc_kwargs_list else [
             {"framesize": min_framesize, "phy_cores": 1},
         min_framesize = protocol_to_min_framesize[protocol]
         kwargs_list = tc_kwargs_list if tc_kwargs_list else [
             {"framesize": min_framesize, "phy_cores": 1},
@@ -97,7 +161,8 @@ class Regenerator(object):
             {"framesize": "IMIX_v4_1", "phy_cores": 4}
         ]
         for filename in glob(pattern):
             {"framesize": "IMIX_v4_1", "phy_cores": 4}
         ]
         for filename in glob(pattern):
-            print "Regenerating filename:", filename
+            if not self.quiet:
+                eprint("Regenerating filename:", filename)
             with open(filename, "r") as file_in:
                 text = file_in.read()
                 text_prolog = "".join(text.partition("*** Test Cases ***")[:-1])
             with open(filename, "r") as file_in:
                 text = file_in.read()
                 text_prolog = "".join(text.partition("*** Test Cases ***")[:-1])
@@ -105,6 +170,7 @@ class Regenerator(object):
             testcase = self.testcase_class(suite_id)
             with open(filename, "w") as file_out:
                 file_out.write(text_prolog)
             testcase = self.testcase_class(suite_id)
             with open(filename, "w") as file_out:
                 file_out.write(text_prolog)
-                add_testcases(testcase, iface, file_out, kwargs_list)
-        print "Regenerator ends."
-        print  # To make autogen check output more readable.
+                add_testcases(testcase, iface, suite_id, file_out, kwargs_list)
+        if not self.quiet:
+            eprint("Regenerator ends.")
+        eprint()  # To make autogen check output more readable.