diff options
Diffstat (limited to 'tests/gem5/suite.py')
-rw-r--r-- | tests/gem5/suite.py | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/tests/gem5/suite.py b/tests/gem5/suite.py new file mode 100644 index 000000000..47cf421e1 --- /dev/null +++ b/tests/gem5/suite.py @@ -0,0 +1,163 @@ +# Copyright (c) 2017 Mark D. Hill and David A. Wood +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# 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: Sean Wilson + +import os +import copy +import subprocess + +from testlib.test import TestFunction +from testlib.suite import TestSuite +from testlib.helper import log_call +from testlib.config import constants, config +from fixture import TempdirFixture, Gem5Fixture, VariableFixture +import verifier + +def gem5_verify_config(name, + config, + config_args, + verifiers, + gem5_args=tuple(), + fixtures=[], + valid_isas=constants.supported_isas, + valid_variants=constants.supported_variants, + length=constants.supported_lengths[0]): + ''' + Helper class to generate common gem5 tests using verifiers. + + The generated TestSuite will run gem5 with the provided config and + config_args. After that it will run any provided verifiers to verify + details about the gem5 run. + + .. seealso:: For the verifiers see :mod:`testlib.gem5.verifier` + + :param name: Name of the test. + :param config: The config to give gem5. + :param config_args: A list of arguments to pass to the given config. + + :param verifiers: An iterable with Verifier instances which will be placed + into a suite that will be ran after a gem5 run. + + :param gem5_args: An iterable with arguments to give to gem5. (Arguments + that would normally go before the config path.) + + :param valid_isas: An iterable with the isas that this test can be ran + for. If None given, will run for all supported_isas. + + :param valid_variants: An iterable with the variant levels that + this test can be ran for. (E.g. opt, debug) + ''' + fixtures = list(fixtures) + testsuites = [] + for opt in valid_variants: + for isa in valid_isas: + + # Create a tempdir fixture to be shared throughout the test. + tempdir = TempdirFixture() + gem5_returncode = VariableFixture( + name=constants.gem5_returncode_fixture_name) + + # Common name of this generated testcase. + _name = '{given_name}-{isa}-{opt}'.format( + given_name=name, + isa=isa, + opt=opt) + + # Create the running of gem5 subtest. + # NOTE: We specifically create this test before our verifiers so + # this is listed first. + tests = [] + gem5_execution = TestFunction( + _create_test_run_gem5(config, config_args, gem5_args), + name=_name) + tests.append(gem5_execution) + + # Create copies of the verifier subtests for this isa and + # variant. + for verifier in verifiers: + tests.append(verifier.instantiate_test(_name)) + + # Add the isa and variant to tags list. + tags = [isa, opt, length] + + # Create the gem5 target for the specific architecture and + # variant. + _fixtures = copy.copy(fixtures) + _fixtures.append(Gem5Fixture(isa, opt)) + _fixtures.append(tempdir) + _fixtures.append(gem5_returncode) + + # Finally construct the self contained TestSuite out of our + # tests. + testsuites.append(TestSuite( + name=_name, + fixtures=_fixtures, + tags=tags, + tests=tests)) + return testsuites + +def _create_test_run_gem5(config, config_args, gem5_args): + def test_run_gem5(params): + ''' + Simple \'test\' which runs gem5 and saves the result into a tempdir. + + NOTE: Requires fixtures: tempdir, gem5 + ''' + fixtures = params.fixtures + + if gem5_args is None: + _gem5_args = tuple() + elif isinstance(gem5_args, str): + # If just a single str, place it in an iterable + _gem5_args = (gem5_args,) + else: + _gem5_args = gem5_args + + # FIXME/TODO: I don't like the idea of having to modify this test run + # or always collect results even if not using a verifier. There should + # be some configuration in here that only gathers certain results for + # certain verifiers. + # + # I.E. Only the returncode verifier will use the gem5_returncode + # fixture, but we always require it even if that verifier isn't being + # ran. + returncode = fixtures[constants.gem5_returncode_fixture_name] + tempdir = fixtures[constants.tempdir_fixture_name].path + gem5 = fixtures[constants.gem5_binary_fixture_name].path + command = [ + gem5, + '-d', # Set redirect dir to tempdir. + tempdir, + '-re',# TODO: Change to const. Redirect stdout and stderr + ] + command.extend(_gem5_args) + command.append(config) + # Config_args should set up the program args. + command.extend(config_args) + returncode.value = log_call(params.log, command) + + return test_run_gem5 |