tests: Add a helper to run external scripts
authorAndreas Sandberg <andreas.sandberg@arm.com>
Mon, 28 Jan 2019 16:50:35 +0000 (16:50 +0000)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Thu, 31 Jan 2019 17:31:54 +0000 (17:31 +0000)
Some tests are really just a wrapper around a test script in
configs/. Add a helper method to wrap these scripts to make sure they
are executed in a consistent environment. This wrapper sets up a
global environment that is identical to that created by main() when it
executes the script. Unlike the old wrappers, it updates the module
search path to make relative imports work correctly in Python 3.

Change-Id: Ie9f81ec4e2689aa8cf5ecb9fc8025d3534b5c9ca
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/15976
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>

tests/configs/dram-lowp.py
tests/configs/learning-gem5-p1-simple.py
tests/configs/learning-gem5-p1-two-level.py
tests/configs/memcheck.py
tests/run.py

index 20c774ea9cd555a32620022cb1322e0667de287e..418514d630a16df948c8fba2d9826bde71d882c4 100644 (file)
@@ -50,19 +50,13 @@ import m5
 def run_test(root):
         # Called from tests/run.py
 
-        # Set the working directory in case we are executing from
-        # outside gem5's source tree
-        import os
-        os.chdir(os.path.join(os.path.dirname(__file__), "../"))
-
-        # The path to this script is the only parameter. Delete it so
-        # we can execute the script that we want to execute.
         import sys
-        del sys.argv[1:]
-
-        # Add a specific page policy and specify the number of ranks
-        sys.argv.append('-p%s' % page_policy)
-        sys.argv.append('-r 2')
+        argv = [
+                sys.argv[0],
+                # Add a specific page policy and specify the number of ranks
+                '-p%s' % page_policy,
+                '-r 2',
+        ]
 
         # Execute the script we are wrapping
-        execfile(srcpath('configs/dram/low_power_sweep.py'), globals())
+        run_config('configs/dram/low_power_sweep.py', argv=argv)
index 9ad70854ed5135ca54494cf3782cdbad90773c4d..aba538a7ea392e74f4fc47fc4194029ee14c9271 100644 (file)
 root = None
 
 def run_test(root):
-        # Called from tests/run.py
-
-        # Set the working directory in case we are executing from
-        # outside gem5's source tree
-        import os
-        os.chdir(os.path.join(os.path.dirname(__file__), "../"))
-
-        # Execute the script we are wrapping
-        execfile(srcpath('configs/learning_gem5/part1/simple.py'))
+        run_config('configs/learning_gem5/part1/simple.py')
index c0a1e466240f9395f3bbd8f7f36831c7e08349cf..0c355e8384c0938d0f3912650cb501bb3cff0e42 100644 (file)
 # For some reason, this is implicitly needed by run.py
 root = None
 
-import m5
-
 def run_test(root):
-        # Called from tests/run.py
-
-
-        # Set the working directory in case we are executing from
-        # outside gem5's source tree
-        import os
-        os.chdir(os.path.join(os.path.dirname(__file__), "../"))
-
-        # Add paths that we need
-        m5.util.addToPath('../configs/learning_gem5/part1')
-        m5.util.addToPath('../configs/')
-
-        # The path to this script is the only parameter. Delete it so we can
-        # execute the script that we want to execute.
-        import sys
-        del sys.argv[1:]
-        # Note: at this point, we could add options we want to test.
-        # For instance, sys.argv.append('--l2_size=512kB')
-
-        # Execute the script we are wrapping
-        execfile(srcpath('configs/learning_gem5/part1/two_level.py'))
+        run_config('configs/learning_gem5/part1/two_level.py')
index 97f8d1369768158b5281a41ff5aa976b85be7ee7..ec20431db677cfc7ecc6eb26a051b987c40ded22 100644 (file)
@@ -54,18 +54,11 @@ root = None
 def run_test(root):
         # Called from tests/run.py
 
-        # Set the working directory in case we are executing from
-        # outside gem5's source tree
-        import os
-        os.chdir(os.path.join(os.path.dirname(__file__), "../"))
-
-        # The path to this script is the only parameter. Delete it so
-        # we can execute the script that we want to execute.
         import sys
-        del sys.argv[1:]
-
-        # Add a specific max tick
-        sys.argv.append('-m %d' % maxtick)
+        argv = [
+                sys.argv[0],
+                '-m %d' % maxtick,
+        ]
 
         # Execute the script we are wrapping
-        execfile(srcpath('configs/example/memcheck.py'), globals())
+        run_config('configs/example/memcheck.py', argv=argv)
index 845a3eb62dd73daf33b26ecac4573d7ba0f95856..93ea82edd2c040decb4fe4cc0f2bcb0cebcb4ea2 100644 (file)
@@ -177,6 +177,32 @@ def srcpath(path):
     """Path to file in gem5's source tree"""
     return joinpath(os.path.dirname(__file__), "..", path)
 
+def run_config(config, argv=None):
+    """Execute a configuration script that is external to the test system"""
+
+    src_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
+    abs_path = joinpath(src_root, config)
+
+    code = compile(open(abs_path, 'r').read(), abs_path, 'exec')
+    scope = {
+        '__file__' : config,
+        '__name__' : '__m5_main__',
+    }
+
+    # Set the working directory in case we are executing from
+    # outside gem5's source tree
+    os.chdir(src_root)
+
+    # gem5 normally adds the script's directory to the path to make
+    # script-relative imports work.
+    sys.path = [ os.path.dirname(abs_path), ] + sys.path
+
+    if argv is None:
+        sys.argv = [ config, ]
+    else:
+        sys.argv = argv
+    exec(code, scope)
+
 # build configuration
 sys.path.append(joinpath(tests_root, 'configs'))
 test_filename = config