In preparation of running the tests outside of a
container, add two flags to ftests.py: --container
and --no-container.  As the names imply, these flags
are used to specify whether the tests should be
containerized or not.

Note1: Some tests (cgrulesengd) will only work
       in a non-containerized environment.

Note2: Running the tests in a non-containerized
       environment could be destructive to a
       system as cgroup changes could be made that
       adversely affect the entire system.

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
 ftests/cgroup.py  | 49 +++++++++++++++++------------------
 ftests/config.py  | 20 ++++++++-------
 ftests/ftests.py  | 65 +++++++++++++++++++++++++++++------------------
 ftests/process.py | 17 ++++++-------
 4 files changed, 82 insertions(+), 69 deletions(-)

diff --git a/ftests/cgroup.py b/ftests/cgroup.py
index a2f978dd01ca..5906a199dd48 100644
--- a/ftests/cgroup.py
+++ b/ftests/cgroup.py
@@ -1,7 +1,7 @@
 #
 # Cgroup class for the libcgroup functional tests
 #
-# Copyright (c) 2019 Oracle and/or its affiliates.  All rights reserved.
+# Copyright (c) 2019-2021 Oracle and/or its affiliates.
 # Author: Tom Hromatka <tom.hroma...@oracle.com>
 #
 
@@ -79,21 +79,18 @@ class Cgroup(object):
         return True
 
     @staticmethod
-    def build_cmd_path(in_container, cmd):
-        if in_container:
-            return os.path.join(consts.LIBCG_MOUNT_POINT,
-                                'src/tools/{}'.format(cmd))
-        else:
-            return cmd
+    def build_cmd_path(cmd):
+        return os.path.join(consts.LIBCG_MOUNT_POINT,
+                            'src/tools/{}'.format(cmd))
 
     # TODO - add support for all of the cgcreate options
     @staticmethod
-    def create(config, controller_list, cgname, in_container=True):
+    def create(config, controller_list, cgname):
         if isinstance(controller_list, str):
             controller_list = [controller_list]
 
         cmd = list()
-        cmd.append(Cgroup.build_cmd_path(in_container, 'cgcreate'))
+        cmd.append(Cgroup.build_cmd_path('cgcreate'))
 
         controllers_and_path = '{}:{}'.format(
             ','.join(controller_list), cgname)
@@ -101,18 +98,18 @@ class Cgroup(object):
         cmd.append('-g')
         cmd.append(controllers_and_path)
 
-        if in_container:
+        if config.args.container:
             config.container.run(cmd)
         else:
             Run.run(cmd)
 
     @staticmethod
-    def delete(config, controller_list, cgname, in_container=True, 
recursive=False):
+    def delete(config, controller_list, cgname, recursive=False):
         if isinstance(controller_list, str):
             controller_list = [controller_list]
 
         cmd = list()
-        cmd.append(Cgroup.build_cmd_path(in_container, 'cgdelete'))
+        cmd.append(Cgroup.build_cmd_path('cgdelete'))
 
         if recursive:
             cmd.append('-r')
@@ -123,15 +120,15 @@ class Cgroup(object):
         cmd.append('-g')
         cmd.append(controllers_and_path)
 
-        if in_container:
+        if config.args.container:
             config.container.run(cmd)
         else:
             Run.run(cmd)
 
     @staticmethod
-    def set(config, cgname, setting, value, in_container=True):
+    def set(config, cgname, setting, value):
         cmd = list()
-        cmd.append(Cgroup.build_cmd_path(in_container, 'cgset'))
+        cmd.append(Cgroup.build_cmd_path('cgset'))
 
         if isinstance(setting, str) and isinstance(value, str):
             cmd.append('-r')
@@ -146,7 +143,7 @@ class Cgroup(object):
 
         cmd.append(cgname)
 
-        if in_container:
+        if config.args.container:
             config.container.run(cmd)
         else:
             Run.run(cmd)
@@ -169,10 +166,10 @@ class Cgroup(object):
     #     Read all of the settings from a cgroup at a specific path
     #         cgget -g memory:tomcgroup/tomcgroup
     def get(config, controller=None, cgname=None, setting=None,
-            in_container=True, print_headers=True, values_only=False,
+            print_headers=True, values_only=False,
             all_controllers=False):
         cmd = list()
-        cmd.append(Cgroup.build_cmd_path(in_container, 'cgget'))
+        cmd.append(Cgroup.build_cmd_path('cgget'))
 
         if not print_headers:
             cmd.append('-n')
@@ -218,7 +215,7 @@ class Cgroup(object):
                 for cg in cgname:
                     cmd.append(cg)
 
-        if in_container:
+        if config.args.container:
             ret = config.container.run(cmd)
         else:
             ret = Run.run(cmd)
@@ -227,9 +224,9 @@ class Cgroup(object):
 
     @staticmethod
     def classify(config, controller, cgname, pid_list, sticky=False,
-                 cancel_sticky=False, in_container=True):
+                 cancel_sticky=False):
         cmd = list()
-        cmd.append(Cgroup.build_cmd_path(in_container, 'cgclassify'))
+        cmd.append(Cgroup.build_cmd_path('cgclassify'))
         cmd.append('-g')
         cmd.append('{}:{}'.format(controller, cgname))
 
@@ -241,7 +238,7 @@ class Cgroup(object):
             for pid in pid_list:
                 cmd.append(pid)
 
-        if in_container:
+        if config.args.container:
             config.container.run(cmd)
         else:
             Run.run(cmd)
@@ -321,19 +318,19 @@ class Cgroup(object):
         return cgdict
 
     @staticmethod
-    def snapshot(config, controller=None, in_container=True):
+    def snapshot(config, controller=None):
         cmd = list()
-        cmd.append(Cgroup.build_cmd_path(in_container, 'cgsnapshot'))
+        cmd.append(Cgroup.build_cmd_path('cgsnapshot'))
         if controller is not None:
             cmd.append(controller)
 
-        if in_container:
+        if config.args.container:
             # if we're running in a container, it's unlikely that libcgroup
             # was installed and thus /etc/cgsnapshot_blacklist.conf likely
             # doesn't exist.  Let's make it
             config.container.run(['sudo', 'touch', 
'/etc/cgsnapshot_blacklist.conf'])
 
-        if in_container:
+        if config.args.container:
             res = config.container.run(cmd)
         else:
             res = Run.run(cmd)
diff --git a/ftests/config.py b/ftests/config.py
index 5cdc21d36eb8..10664609113f 100644
--- a/ftests/config.py
+++ b/ftests/config.py
@@ -1,7 +1,7 @@
 #
 # Config class for the libcgroup functional tests
 #
-# Copyright (c) 2019 Oracle and/or its affiliates.  All rights reserved.
+# Copyright (c) 2019-2021 Oracle and/or its affiliates.
 # Author: Tom Hromatka <tom.hroma...@oracle.com>
 #
 
@@ -27,13 +27,14 @@ class Config(object):
     def __init__(self, args, container=None):
         self.args = args
 
-        if container:
-            self.container = container
-        else:
-            # Use the default container settings
-            self.container = Container(name=consts.DEFAULT_CONTAINER_NAME,
-                stop_timeout=args.timeout, arch=None,
-                distro=args.distro, release=args.release)
+        if self.args.container:
+            if container:
+                self.container = container
+            else:
+                # Use the default container settings
+                self.container = Container(name=consts.DEFAULT_CONTAINER_NAME,
+                    stop_timeout=args.timeout, arch=None,
+                    distro=args.distro, release=args.release)
 
         self.ftest_dir = os.path.dirname(os.path.abspath(__file__))
         self.libcg_dir = os.path.dirname(self.ftest_dir)
@@ -44,7 +45,8 @@ class Config(object):
 
     def __str__(self):
         out_str = "Configuration"
-        out_str += "\n\tcontainer = {}".format(self.container)
+        if self.args.container:
+            out_str += "\n\tcontainer = {}".format(self.container)
 
         return out_str
 
diff --git a/ftests/ftests.py b/ftests/ftests.py
index 5971789097c0..6b3c96f897fb 100755
--- a/ftests/ftests.py
+++ b/ftests/ftests.py
@@ -2,7 +2,7 @@
 #
 # Main entry point for the libcgroup functional tests
 #
-# Copyright (c) 2019 Oracle and/or its affiliates.  All rights reserved.
+# Copyright (c) 2019-2021 Oracle and/or its affiliates.
 # Author: Tom Hromatka <tom.hroma...@oracle.com>
 #
 
@@ -68,6 +68,18 @@ def parse_args():
     parser.add_argument('-s', '--suite',
                         help='Test suite to run, e.g. cpuset', required=False,
                         default=consts.TESTS_RUN_ALL_SUITES, type=str)
+
+    container_parser = parser.add_mutually_exclusive_group(required=False)
+    container_parser.add_argument('--container', action='store_true',
+                        help='Run the tests in a container. '
+                        'Note that some tests cannot be run in a container.',
+                        dest='container')
+    container_parser.add_argument('--no-container', action='store_false',
+                        help='Do not run the tests in a container. '
+                        'Note that some tests are destructive and will modify 
your cgroup hierarchy.',
+                        dest='container')
+    parser.set_defaults(container=True)
+
     parser.add_argument('-v', '--verbose',
                         help='Print all information about this test run',
                         default=True, required=False, action="store_false")
@@ -139,23 +151,25 @@ def setup(config, do_teardown=True, record_time=False):
             # log but ignore all exceptions
             Log.log_debug(e)
 
-    # this command initializes the lxd storage, networking, etc.
-    Run.run(['sudo', 'lxd', 'init', '--auto'])
-    update_host_subuid()
-    update_host_subgid()
+    if config.args.container:
+        # this command initializes the lxd storage, networking, etc.
+        Run.run(['sudo', 'lxd', 'init', '--auto'])
+        update_host_subuid()
+        update_host_subgid()
 
-    config.container.create()
-    config.container.config()
-    config.container.start()
+        config.container.create()
+        config.container.config()
+        config.container.start()
 
-    # LXC on Ubuntu 20.04 put sed in a different spot.  Add a symlink
-    config.container.run(['ln', '-s', '/bin/sed', '/usr/bin/sed'])
+        # LXC on Ubuntu 20.04 put sed in a different spot.  Add a symlink
+        config.container.run(['ln', '-s', '/bin/sed', '/usr/bin/sed'])
+
+        # add the libcgroup library to the container's ld
+        echo_cmd = ['bash', '-c', 'echo {} >> 
/etc/ld.so.conf.d/libcgroup.conf'.format(
+                   os.path.join(consts.LIBCG_MOUNT_POINT, 'src/.libs'))]
+        config.container.run(echo_cmd)
+        config.container.run('ldconfig')
 
-    # add the libcgroup library to the container's ld
-    echo_cmd = ['bash', '-c', 'echo {} >> 
/etc/ld.so.conf.d/libcgroup.conf'.format(
-               os.path.join(consts.LIBCG_MOUNT_POINT, 'src/.libs'))]
-    config.container.run(echo_cmd)
-    config.container.run('ldconfig')
     if record_time:
         setup_time = time.time() - start_time
 
@@ -277,16 +291,17 @@ def teardown(config, record_time=False):
 
     Process.join_children()
 
-    try:
-        config.container.stop()
-    except Exception as e:
-        # log but ignore all exceptions
-        Log.log_debug(e)
-    try:
-        config.container.delete()
-    except Exception as e:
-        # log but ignore all exceptions
-        Log.log_debug(e)
+    if config.args.container:
+        try:
+            config.container.stop()
+        except Exception as e:
+            # log but ignore all exceptions
+            Log.log_debug(e)
+        try:
+            config.container.delete()
+        except Exception as e:
+            # log but ignore all exceptions
+            Log.log_debug(e)
 
     if record_time:
         teardown_time = time.time() - start_time
diff --git a/ftests/process.py b/ftests/process.py
index 82a40d2c8013..8996ce32382c 100644
--- a/ftests/process.py
+++ b/ftests/process.py
@@ -1,7 +1,7 @@
 #
 # Cgroup class for the libcgroup functional tests
 #
-# Copyright (c) 2020 Oracle and/or its affiliates.
+# Copyright (c) 2020-2021 Oracle and/or its affiliates.
 # Author: Tom Hromatka <tom.hroma...@oracle.com>
 #
 
@@ -28,16 +28,16 @@ children = list()
 
 class Process(object):
     @staticmethod
-    def __infinite_loop(config, sleep_time=1, in_container=True):
+    def __infinite_loop(config, sleep_time=1):
         cmd = ['nohup', 'perl', '-e', 
'\'while(1){{sleep({})}};\''.format(sleep_time), '&']
 
-        if in_container:
+        if config.args.container:
             config.container.run(cmd, shell_bool=True)
         else:
             Run.run(cmd, shell_bool=True)
 
     @staticmethod
-    def create_process(config, in_container=True):
+    def create_process(config):
         # To allow for multiple processes to be created, each new process
         # sleeps for a different amount of time.  This lets us uniquely find
         # each process later in this function
@@ -53,7 +53,7 @@ class Process(object):
 
         # get the PID of the newly spawned infinite loop
         cmd = 'ps x | grep perl | grep "sleep({})" | awk \'{{print 
$1}}\''.format(sleep_time)
-        if in_container:
+        if config.args.container:
             pid = config.container.run(cmd, shell_bool=True)
         else:
             pid = Run.run(cmd, shell_bool=True)
@@ -66,10 +66,9 @@ class Process(object):
 
     # Create a simple process in the requested cgroup
     @staticmethod
-    def create_process_in_cgroup(config, controller, cgname, 
in_container=True):
-        child_pid = Process.create_process(config, in_container=in_container)
-        Cgroup.classify(config, controller, cgname, child_pid,
-                        in_container=in_container)
+    def create_process_in_cgroup(config, controller, cgname):
+        child_pid = Process.create_process(config)
+        Cgroup.classify(config, controller, cgname, child_pid)
 
     # The caller will block until all children are stopped.
     @staticmethod
-- 
2.26.2



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to