tests: arch-power: Add 64-bit hello binaries
[gem5.git] / tests / run.py
index e4474ac5cd5ff08eb4c69d124596c2ad6f5cfbae..c3360acbd446041cf73f4ebc1de322688df8bb77 100644 (file)
@@ -35,8 +35,6 @@
 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Steve Reinhardt
 
 import os
 import sys
@@ -44,6 +42,8 @@ import re
 import string
 
 from os.path import join as joinpath
+import os.path
+import os
 
 import m5
 
@@ -55,7 +55,7 @@ def skip_test(reason=""):
     """
 
     if reason:
-        print "Skipping test: %s" % reason
+        print("Skipping test: %s" % reason)
     sys.exit(2)
 
 def has_sim_object(name):
@@ -93,6 +93,56 @@ def require_sim_object(name, fatal=False):
         else:
             skip_test(msg)
 
+
+def require_file(path, fatal=False, mode=os.F_OK):
+    """Test if a file exists and abort/skip test if not.
+
+    Arguments:
+      path -- File to test for.
+
+    Keyword arguments:
+      fatal -- Set to True to indicate that the test should fail
+               instead of being skipped.
+      modes -- Mode to test for, default to existence. See the
+               Python documentation for os.access().
+    """
+
+    if os.access(path, mode):
+        return
+    else:
+        msg = "Test requires '%s'" % path
+        if not os.path.exists(path):
+            msg += " which does not exist."
+        else:
+            msg += " which has incorrect permissions."
+
+        if fatal:
+            m5.fatal(msg)
+        else:
+            skip_test(msg)
+
+def require_kvm(kvm_dev="/dev/kvm", fatal=False):
+    """Test if KVM is available.
+
+    Keyword arguments:
+      kvm_dev -- Device to test (normally /dev/kvm)
+      fatal -- Set to True to indicate that the test should fail
+               instead of being skipped.
+    """
+
+    require_sim_object("BaseKvmCPU", fatal=fatal)
+    require_file(kvm_dev, fatal=fatal, mode=os.R_OK | os.W_OK)
+
+def run_test(root):
+    """Default run_test implementations. Scripts can override it."""
+
+    # instantiate configuration
+    m5.instantiate()
+
+    # simulate until program terminates
+    exit_event = m5.simulate(maxtick)
+    print('Exiting @ tick', m5.curTick(), 'because', exit_event.getCause())
+
 # Since we're in batch mode, dont allow tcp socket connections
 m5.disableAllListeners()
 
@@ -119,13 +169,45 @@ def inputpath(app, file=None):
         file = app
     return joinpath(test_progs, app, 'input', file)
 
+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
 # for ruby configurations, remove the protocol name from the test filename
 if re.search('-ruby', test_filename):
     test_filename = test_filename.split('-ruby')[0]+'-ruby'
-execfile(joinpath(tests_root, 'configs', test_filename + '.py'))
+exec(compile( \
+    open(joinpath(tests_root, 'configs', test_filename + '.py')).read(), \
+    joinpath(tests_root, 'configs', test_filename + '.py'), 'exec'))
 
 # set default maxtick... script can override
 # -1 means run forever
@@ -133,15 +215,19 @@ maxtick = m5.MaxTick
 
 # tweak configuration for specific test
 sys.path.append(joinpath(tests_root, category, mode, name))
-execfile(joinpath(tests_root, category, mode, name, 'test.py'))
+exec(compile( \
+    open(joinpath(tests_root, category, mode, name, 'test.py')).read(), \
+    joinpath(tests_root, category, mode, name, 'test.py'), 'exec'))
 
 # Initialize all CPUs in a system
 def initCPUs(sys):
     def initCPU(cpu):
         # We might actually have a MemTest object or something similar
         # here that just pretends to be a CPU.
-        if isinstance(cpu, BaseCPU):
+        try:
             cpu.createThreads()
+        except:
+            pass
 
     # The CPU attribute doesn't exist in some cases, e.g. the Ruby
     # testers.
@@ -160,10 +246,4 @@ for sysattr in [ "system", "testsys", "drivesys" ]:
     if hasattr(root, sysattr):
         initCPUs(getattr(root, sysattr))
 
-# instantiate configuration
-m5.instantiate()
-
-# simulate until program terminates
-exit_event = m5.simulate(maxtick)
-
-print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
+run_test(root)