tests.py revision 13540
14479Sbinkertn@umich.edu#!/usr/bin/env python2.7
24479Sbinkertn@umich.edu#
34479Sbinkertn@umich.edu# Copyright (c) 2016-2017 ARM Limited
44479Sbinkertn@umich.edu# All rights reserved
54479Sbinkertn@umich.edu#
64479Sbinkertn@umich.edu# The license below extends only to copyright in the software and shall
74479Sbinkertn@umich.edu# not be construed as granting a license to any other intellectual
84479Sbinkertn@umich.edu# property including but not limited to intellectual property relating
94479Sbinkertn@umich.edu# to a hardware implementation of the functionality of the software
104479Sbinkertn@umich.edu# licensed hereunder.  You may use the software subject to the license
114479Sbinkertn@umich.edu# terms below provided that you ensure that this notice is replicated
124479Sbinkertn@umich.edu# unmodified and in its entirety in all distributions of the software,
134479Sbinkertn@umich.edu# modified or unmodified, in source code or in binary form.
144479Sbinkertn@umich.edu#
154479Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without
164479Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are
174479Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright
184479Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer;
194479Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright
204479Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the
214479Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution;
224479Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its
234479Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from
244479Sbinkertn@umich.edu# this software without specific prior written permission.
254479Sbinkertn@umich.edu#
264479Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
274479Sbinkertn@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
284479Sbinkertn@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
294479Sbinkertn@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
304479Sbinkertn@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
314479Sbinkertn@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
324479Sbinkertn@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
334479Sbinkertn@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
344479Sbinkertn@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
354479Sbinkertn@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
364479Sbinkertn@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
374479Sbinkertn@umich.edu#
384479Sbinkertn@umich.edu# Authors: Andreas Sandberg
394479Sbinkertn@umich.edu
404479Sbinkertn@umich.edufrom abc import ABCMeta, abstractmethod
414479Sbinkertn@umich.eduimport os
426498Snate@binkert.orgfrom collections import namedtuple
434479Sbinkertn@umich.edufrom units import *
444479Sbinkertn@umich.edufrom results import TestResult
454479Sbinkertn@umich.eduimport shutil
464479Sbinkertn@umich.edu
476498Snate@binkert.org_test_base = os.path.join(os.path.dirname(__file__), "..")
484479Sbinkertn@umich.edu
494479Sbinkertn@umich.eduClassicConfig = namedtuple("ClassicConfig", (
504479Sbinkertn@umich.edu    "category",
514479Sbinkertn@umich.edu    "mode",
524479Sbinkertn@umich.edu    "workload",
534479Sbinkertn@umich.edu    "isa",
544479Sbinkertn@umich.edu    "os",
554479Sbinkertn@umich.edu    "config",
564479Sbinkertn@umich.edu))
574479Sbinkertn@umich.edu
584479Sbinkertn@umich.edu# There are currently two "classes" of test
594479Sbinkertn@umich.edu# configurations. Architecture-specific ones and generic ones
604479Sbinkertn@umich.edu# (typically SE mode tests). In both cases, the configuration name
614479Sbinkertn@umich.edu# matches a file in tests/configs/ that will be picked up by the test
624479Sbinkertn@umich.edu# runner (run.py).
634479Sbinkertn@umich.edu#
644479Sbinkertn@umich.edu# Architecture specific configurations are listed in the arch_configs
654479Sbinkertn@umich.edu# dictionary. This is indexed by a (cpu architecture, gpu
664479Sbinkertn@umich.edu# architecture) tuple. GPU architecture is optional and may be None.
674479Sbinkertn@umich.edu#
684479Sbinkertn@umich.edu# Generic configurations are listed in the generic_configs tuple.
694479Sbinkertn@umich.edu#
704479Sbinkertn@umich.edu# When discovering available test cases, this script look uses the
716498Snate@binkert.org# test list as a list of /candidate/ configurations. A configuration
724479Sbinkertn@umich.edu# is only used if a test has a reference output for that
734479Sbinkertn@umich.edu# configuration. In addition to the base configurations from
744479Sbinkertn@umich.edu# arch_configs and generic_configs, a Ruby configuration may be
754479Sbinkertn@umich.edu# appended to the base name (this is probed /in addition/ to the
764479Sbinkertn@umich.edu# original name. See get_tests() for details.
774479Sbinkertn@umich.edu#
784479Sbinkertn@umich.eduarch_configs = {
794479Sbinkertn@umich.edu    ("alpha", None) : (
804479Sbinkertn@umich.edu        'tsunami-simple-atomic',
814479Sbinkertn@umich.edu        'tsunami-simple-timing',
824479Sbinkertn@umich.edu        'tsunami-simple-atomic-dual',
834479Sbinkertn@umich.edu        'tsunami-simple-timing-dual',
844479Sbinkertn@umich.edu        'twosys-tsunami-simple-atomic',
854479Sbinkertn@umich.edu        'tsunami-o3', 'tsunami-o3-dual',
864479Sbinkertn@umich.edu        'tsunami-minor', 'tsunami-minor-dual',
874479Sbinkertn@umich.edu        'tsunami-switcheroo-full',
884479Sbinkertn@umich.edu    ),
894479Sbinkertn@umich.edu
904479Sbinkertn@umich.edu    ("arm", None) : (
914479Sbinkertn@umich.edu        'simple-atomic-dummychecker',
924479Sbinkertn@umich.edu        'o3-timing-checker',
934479Sbinkertn@umich.edu        'realview-simple-atomic',
944479Sbinkertn@umich.edu        'realview-simple-atomic-dual',
954479Sbinkertn@umich.edu        'realview-simple-atomic-checkpoint',
964479Sbinkertn@umich.edu        'realview-simple-timing',
974479Sbinkertn@umich.edu        'realview-simple-timing-dual',
984479Sbinkertn@umich.edu        'realview-o3',
994479Sbinkertn@umich.edu        'realview-o3-checker',
1004479Sbinkertn@umich.edu        'realview-o3-dual',
1014479Sbinkertn@umich.edu        'realview-minor',
1024479Sbinkertn@umich.edu        'realview-minor-dual',
1034479Sbinkertn@umich.edu        'realview-switcheroo-atomic',
1044479Sbinkertn@umich.edu        'realview-switcheroo-timing',
1054479Sbinkertn@umich.edu        'realview-switcheroo-noncaching-timing',
1064479Sbinkertn@umich.edu        'realview-switcheroo-o3',
1074479Sbinkertn@umich.edu        'realview-switcheroo-full',
1084479Sbinkertn@umich.edu        'realview64-simple-atomic',
1094479Sbinkertn@umich.edu        'realview64-simple-atomic-checkpoint',
1104479Sbinkertn@umich.edu        'realview64-simple-atomic-dual',
1114479Sbinkertn@umich.edu        'realview64-simple-timing',
1124479Sbinkertn@umich.edu        'realview64-simple-timing-dual',
1134479Sbinkertn@umich.edu        'realview64-o3',
1144479Sbinkertn@umich.edu        'realview64-o3-checker',
1154479Sbinkertn@umich.edu        'realview64-o3-dual',
1164479Sbinkertn@umich.edu        'realview64-minor',
1174479Sbinkertn@umich.edu        'realview64-minor-dual',
1184479Sbinkertn@umich.edu        'realview64-switcheroo-atomic',
1194479Sbinkertn@umich.edu        'realview64-switcheroo-timing',
1204479Sbinkertn@umich.edu        'realview64-switcheroo-o3',
1214479Sbinkertn@umich.edu        'realview64-switcheroo-full',
1224479Sbinkertn@umich.edu    ),
1234479Sbinkertn@umich.edu
1246498Snate@binkert.org    ("sparc", None) : (
1254479Sbinkertn@umich.edu        't1000-simple-atomic',
1264479Sbinkertn@umich.edu        't1000-simple-x86',
1274479Sbinkertn@umich.edu    ),
1284479Sbinkertn@umich.edu
1294479Sbinkertn@umich.edu    ("timing", None) : (
1304479Sbinkertn@umich.edu        'pc-simple-atomic',
1314479Sbinkertn@umich.edu        'pc-simple-timing',
1324479Sbinkertn@umich.edu        'pc-o3-timing',
1334479Sbinkertn@umich.edu        'pc-switcheroo-full',
1344479Sbinkertn@umich.edu    ),
1354479Sbinkertn@umich.edu
1364479Sbinkertn@umich.edu    ("x86", "hsail") : (
1374479Sbinkertn@umich.edu        'gpu',
1384479Sbinkertn@umich.edu    ),
1394479Sbinkertn@umich.edu}
1404479Sbinkertn@umich.edu
1414479Sbinkertn@umich.edugeneric_configs = (
1424479Sbinkertn@umich.edu    'simple-atomic',
1434479Sbinkertn@umich.edu    'simple-atomic-mp',
1444479Sbinkertn@umich.edu    'simple-timing',
1454479Sbinkertn@umich.edu    'simple-timing-mp',
1464479Sbinkertn@umich.edu
1474479Sbinkertn@umich.edu    'minor-timing',
1484479Sbinkertn@umich.edu    'minor-timing-mp',
1494479Sbinkertn@umich.edu
1504479Sbinkertn@umich.edu    'o3-timing',
1514479Sbinkertn@umich.edu    'o3-timing-mt',
1524479Sbinkertn@umich.edu    'o3-timing-mp',
1534479Sbinkertn@umich.edu
1544479Sbinkertn@umich.edu    'rubytest',
1554479Sbinkertn@umich.edu    'memcheck',
1564479Sbinkertn@umich.edu    'memtest',
1574479Sbinkertn@umich.edu    'memtest-filter',
1584479Sbinkertn@umich.edu    'tgen-simple-mem',
1594479Sbinkertn@umich.edu    'tgen-dram-ctrl',
1604479Sbinkertn@umich.edu    'dram-lowp',
1614479Sbinkertn@umich.edu
1624479Sbinkertn@umich.edu    'learning-gem5-p1-simple',
1634479Sbinkertn@umich.edu    'learning-gem5-p1-two-level',
1644479Sbinkertn@umich.edu)
1654479Sbinkertn@umich.edu
1664479Sbinkertn@umich.edudefault_ruby_protocol = {
1674479Sbinkertn@umich.edu    "arm" : "MOESI_CMP_directory",
1684479Sbinkertn@umich.edu}
1694479Sbinkertn@umich.edu
1704479Sbinkertn@umich.edudef get_default_protocol(arch):
1714479Sbinkertn@umich.edu    return default_ruby_protocol.get(arch, 'MI_example')
1724479Sbinkertn@umich.edu
1734479Sbinkertn@umich.eduall_categories = ("quick", "long")
1744479Sbinkertn@umich.eduall_modes = ("fs", "se")
1754479Sbinkertn@umich.edu
1764479Sbinkertn@umich.educlass Test(object):
1774479Sbinkertn@umich.edu    """Test case base class.
1784479Sbinkertn@umich.edu
1794479Sbinkertn@umich.edu    Test cases consists of one or more test units that are run in two
1804479Sbinkertn@umich.edu    phases. A run phase (units produced by run_units() and a verify
1814479Sbinkertn@umich.edu    phase (units from verify_units()). The verify phase is skipped if
1824479Sbinkertn@umich.edu    the run phase fails.
1834479Sbinkertn@umich.edu
1844479Sbinkertn@umich.edu    """
1854479Sbinkertn@umich.edu
1864479Sbinkertn@umich.edu    __metaclass__ = ABCMeta
1874479Sbinkertn@umich.edu
1884479Sbinkertn@umich.edu    def __init__(self, name):
1894479Sbinkertn@umich.edu        self.test_name = name
1904479Sbinkertn@umich.edu
1916498Snate@binkert.org    @abstractmethod
1924479Sbinkertn@umich.edu    def ref_files(self):
1934479Sbinkertn@umich.edu        """Get a list of reference files used by this test case"""
1944479Sbinkertn@umich.edu        pass
1954479Sbinkertn@umich.edu
1964479Sbinkertn@umich.edu    @abstractmethod
1974479Sbinkertn@umich.edu    def run_units(self):
1984479Sbinkertn@umich.edu        """Units (typically RunGem5 instances) that describe the run phase of
1994479Sbinkertn@umich.edu        this test.
2004479Sbinkertn@umich.edu
2014479Sbinkertn@umich.edu        """
2024479Sbinkertn@umich.edu        pass
2034479Sbinkertn@umich.edu
2044479Sbinkertn@umich.edu    @abstractmethod
2054479Sbinkertn@umich.edu    def verify_units(self):
2064479Sbinkertn@umich.edu        """Verify the output from the run phase (see run_units())."""
2074479Sbinkertn@umich.edu        pass
2084479Sbinkertn@umich.edu
2094479Sbinkertn@umich.edu    @abstractmethod
2104479Sbinkertn@umich.edu    def update_ref(self):
2114479Sbinkertn@umich.edu        """Update reference files with files from a test run"""
2124479Sbinkertn@umich.edu        pass
2134479Sbinkertn@umich.edu
2144479Sbinkertn@umich.edu    def run(self):
2154479Sbinkertn@umich.edu        """Run this test case and return a list of results"""
2164479Sbinkertn@umich.edu
2174479Sbinkertn@umich.edu        run_results = [ u.run() for u in self.run_units() ]
2184479Sbinkertn@umich.edu        run_ok = all([not r.skipped() and r for r in run_results ])
2194479Sbinkertn@umich.edu
2204479Sbinkertn@umich.edu        verify_results = [
2214479Sbinkertn@umich.edu            u.run() if run_ok else u.skip()
2224479Sbinkertn@umich.edu            for u in self.verify_units()
2234479Sbinkertn@umich.edu        ]
2244479Sbinkertn@umich.edu
2254479Sbinkertn@umich.edu        return TestResult(self.test_name,
2264479Sbinkertn@umich.edu                          run_results=run_results,
2274479Sbinkertn@umich.edu                          verify_results=verify_results)
2284479Sbinkertn@umich.edu
2294479Sbinkertn@umich.edu    def __str__(self):
2304479Sbinkertn@umich.edu        return self.test_name
2314479Sbinkertn@umich.edu
2324479Sbinkertn@umich.educlass ClassicTest(Test):
2334479Sbinkertn@umich.edu    # The diff ignore list contains all files that shouldn't be diffed
2344479Sbinkertn@umich.edu    # using DiffOutFile. These files typically use special-purpose
2354479Sbinkertn@umich.edu    # diff tools (e.g., DiffStatFile).
2364479Sbinkertn@umich.edu    diff_ignore_files = FileIgnoreList(
2374479Sbinkertn@umich.edu        names=(
2384479Sbinkertn@umich.edu            # Stat files use a special stat differ
2394479Sbinkertn@umich.edu            "stats.txt",
2404479Sbinkertn@umich.edu        ), rex=(
2414479Sbinkertn@umich.edu        ))
2424479Sbinkertn@umich.edu
2434479Sbinkertn@umich.edu    # These files should never be included in the list of
2444479Sbinkertn@umich.edu    # reference files. This list should include temporary files
2454479Sbinkertn@umich.edu    # and other files that we don't care about.
2464479Sbinkertn@umich.edu    ref_ignore_files = FileIgnoreList(
2474479Sbinkertn@umich.edu        names=(
2484479Sbinkertn@umich.edu            "EMPTY",
2494479Sbinkertn@umich.edu        ), rex=(
2504479Sbinkertn@umich.edu            # Mercurial sometimes leaves backups when applying MQ patches
2514479Sbinkertn@umich.edu            r"\.orig$",
2524479Sbinkertn@umich.edu            r"\.rej$",
2534479Sbinkertn@umich.edu        ))
2544479Sbinkertn@umich.edu
2554479Sbinkertn@umich.edu    def __init__(self, gem5, output_dir, config_tuple,
2564479Sbinkertn@umich.edu                 timeout=None,
2574479Sbinkertn@umich.edu                 skip=False, skip_diff_out=False, skip_diff_stat=False):
2584479Sbinkertn@umich.edu
2594479Sbinkertn@umich.edu        super(ClassicTest, self).__init__("/".join(config_tuple))
2604479Sbinkertn@umich.edu
2614479Sbinkertn@umich.edu        ct = config_tuple
2624479Sbinkertn@umich.edu
2634479Sbinkertn@umich.edu        self.gem5 = os.path.abspath(gem5)
2644479Sbinkertn@umich.edu        self.script = os.path.join(_test_base, "run.py")
2654479Sbinkertn@umich.edu        self.config_tuple = ct
2664479Sbinkertn@umich.edu        self.timeout = timeout
2674479Sbinkertn@umich.edu
2684479Sbinkertn@umich.edu        self.output_dir = output_dir
2694479Sbinkertn@umich.edu        self.ref_dir = os.path.join(_test_base,
2704479Sbinkertn@umich.edu                                    ct.category, ct.mode, ct.workload,
2714479Sbinkertn@umich.edu                                    "ref", ct.isa, ct.os, ct.config)
2724479Sbinkertn@umich.edu        self.skip_run = skip
2734479Sbinkertn@umich.edu        self.skip_diff_out = skip or skip_diff_out
2744479Sbinkertn@umich.edu        self.skip_diff_stat = skip or skip_diff_stat
2754479Sbinkertn@umich.edu
2764479Sbinkertn@umich.edu    def ref_files(self):
2774479Sbinkertn@umich.edu        ref_dir = os.path.abspath(self.ref_dir)
2784479Sbinkertn@umich.edu        for root, dirs, files in os.walk(ref_dir, topdown=False):
2794479Sbinkertn@umich.edu            for f in files:
2804479Sbinkertn@umich.edu                fpath = os.path.join(root[len(ref_dir) + 1:], f)
2814479Sbinkertn@umich.edu                if fpath not in ClassicTest.ref_ignore_files:
2824479Sbinkertn@umich.edu                    yield fpath
2834479Sbinkertn@umich.edu
2844479Sbinkertn@umich.edu    def run_units(self):
2854479Sbinkertn@umich.edu        args = [
2864479Sbinkertn@umich.edu            self.script,
2874479Sbinkertn@umich.edu            "/".join(self.config_tuple),
2884479Sbinkertn@umich.edu        ]
2894479Sbinkertn@umich.edu
2904479Sbinkertn@umich.edu        return [
2914479Sbinkertn@umich.edu            RunGem5(self.gem5, args,
2924479Sbinkertn@umich.edu                    ref_dir=self.ref_dir, test_dir=self.output_dir,
2934479Sbinkertn@umich.edu                    skip=self.skip_run),
2944479Sbinkertn@umich.edu        ]
2954479Sbinkertn@umich.edu
2964479Sbinkertn@umich.edu    def verify_units(self):
2974479Sbinkertn@umich.edu        ref_files = set(self.ref_files())
2984479Sbinkertn@umich.edu        units = []
2994479Sbinkertn@umich.edu        if "stats.txt" in ref_files:
3004479Sbinkertn@umich.edu            units.append(
3014479Sbinkertn@umich.edu                DiffStatFile(ref_dir=self.ref_dir, test_dir=self.output_dir,
3024479Sbinkertn@umich.edu                             skip=self.skip_diff_stat))
3034479Sbinkertn@umich.edu        units += [
3044479Sbinkertn@umich.edu            DiffOutFile(f,
3054479Sbinkertn@umich.edu                        ref_dir=self.ref_dir, test_dir=self.output_dir,
3064479Sbinkertn@umich.edu                        skip=self.skip_diff_out)
3074479Sbinkertn@umich.edu            for f in ref_files if f not in ClassicTest.diff_ignore_files
3084479Sbinkertn@umich.edu        ]
3094479Sbinkertn@umich.edu
3104479Sbinkertn@umich.edu        return units
3114479Sbinkertn@umich.edu
3124479Sbinkertn@umich.edu    def update_ref(self):
3134479Sbinkertn@umich.edu        for fname in self.ref_files():
3144479Sbinkertn@umich.edu            shutil.copy(
3154479Sbinkertn@umich.edu                os.path.join(self.output_dir, fname),
3164479Sbinkertn@umich.edu                os.path.join(self.ref_dir, fname))
3174479Sbinkertn@umich.edu
3184479Sbinkertn@umich.edudef parse_test_filter(test_filter):
3194479Sbinkertn@umich.edu    wildcards = ("", "*")
3204479Sbinkertn@umich.edu
3214479Sbinkertn@umich.edu    _filter = list(test_filter.split("/"))
3224479Sbinkertn@umich.edu    if len(_filter) > 3:
3234479Sbinkertn@umich.edu        raise RuntimeError("Illegal test filter string")
3244479Sbinkertn@umich.edu    _filter += [ "", ] * (3 - len(_filter))
3254479Sbinkertn@umich.edu
3264479Sbinkertn@umich.edu    isa, cat, mode = _filter
3274479Sbinkertn@umich.edu
3284479Sbinkertn@umich.edu    if isa in wildcards:
3294479Sbinkertn@umich.edu        raise RuntimeError("No ISA specified")
3304479Sbinkertn@umich.edu
3314479Sbinkertn@umich.edu    cat = all_categories if cat in wildcards else (cat, )
3324479Sbinkertn@umich.edu    mode = all_modes if mode in wildcards else (mode, )
3334479Sbinkertn@umich.edu
3344479Sbinkertn@umich.edu    return isa, cat, mode
3354479Sbinkertn@umich.edu
3364479Sbinkertn@umich.edudef get_tests(isa,
3374479Sbinkertn@umich.edu              categories=all_categories, modes=all_modes,
3384479Sbinkertn@umich.edu              ruby_protocol=None, gpu_isa=None):
3394479Sbinkertn@umich.edu
3404479Sbinkertn@umich.edu    # Generate a list of candidate configs
3414479Sbinkertn@umich.edu    configs = list(arch_configs.get((isa, gpu_isa), []))
3424479Sbinkertn@umich.edu
3434479Sbinkertn@umich.edu    if (isa, gpu_isa) == ("x86", "hsail"):
3444479Sbinkertn@umich.edu        if ruby_protocol == "GPU_RfO":
3454479Sbinkertn@umich.edu            configs += ['gpu-randomtest']
3464479Sbinkertn@umich.edu    else:
3474479Sbinkertn@umich.edu        configs += generic_configs
3484479Sbinkertn@umich.edu
3494479Sbinkertn@umich.edu    if ruby_protocol == get_default_protocol(isa):
3504479Sbinkertn@umich.edu        if ruby_protocol == 'MI_example':
3514479Sbinkertn@umich.edu            configs += [ "%s-ruby" % (c, ) for c in configs ]
3524479Sbinkertn@umich.edu        else:
3534479Sbinkertn@umich.edu            configs += [ "%s-ruby-%s" % (c, ruby_protocol) for c in configs ]
3544479Sbinkertn@umich.edu    elif ruby_protocol is not None:
3554479Sbinkertn@umich.edu        # Override generic ISA configs when using Ruby (excluding
3564479Sbinkertn@umich.edu        # MI_example which is included in all ISAs by default). This
3574479Sbinkertn@umich.edu        # reduces the number of generic tests we re-run for when
3584479Sbinkertn@umich.edu        # compiling Ruby targets.
3594479Sbinkertn@umich.edu        configs = [ "%s-ruby-%s" % (c, ruby_protocol) for c in configs ]
3604479Sbinkertn@umich.edu
3614479Sbinkertn@umich.edu    # /(quick|long)/(fs|se)/workload/ref/arch/guest/config/
3624479Sbinkertn@umich.edu    for conf_script in configs:
3634479Sbinkertn@umich.edu        for cat in categories:
3644479Sbinkertn@umich.edu            for mode in modes:
3654479Sbinkertn@umich.edu                mode_dir = os.path.join(_test_base, cat, mode)
3664479Sbinkertn@umich.edu                if not os.path.exists(mode_dir):
3674479Sbinkertn@umich.edu                    continue
3684479Sbinkertn@umich.edu
3694479Sbinkertn@umich.edu                for workload in os.listdir(mode_dir):
3704479Sbinkertn@umich.edu                    isa_dir = os.path.join(mode_dir, workload, "ref", isa)
3714479Sbinkertn@umich.edu                    if not os.path.isdir(isa_dir):
3724479Sbinkertn@umich.edu                        continue
3734479Sbinkertn@umich.edu
3744479Sbinkertn@umich.edu                    for _os in os.listdir(isa_dir):
3754479Sbinkertn@umich.edu                        test_dir = os.path.join(isa_dir, _os, conf_script)
3764479Sbinkertn@umich.edu                        if not os.path.exists(test_dir) or \
3774479Sbinkertn@umich.edu                           os.path.exists(os.path.join(test_dir, "skip")):
3784479Sbinkertn@umich.edu                            continue
3794479Sbinkertn@umich.edu
3804479Sbinkertn@umich.edu                        yield ClassicConfig(cat, mode, workload, isa, _os,
3814479Sbinkertn@umich.edu                                            conf_script)
3824479Sbinkertn@umich.edu