112882Sspwilson2@wisc.edu# Copyright (c) 2017 Mark D. Hill and David A. Wood
212882Sspwilson2@wisc.edu# All rights reserved.
312882Sspwilson2@wisc.edu#
412882Sspwilson2@wisc.edu# Redistribution and use in source and binary forms, with or without
512882Sspwilson2@wisc.edu# modification, are permitted provided that the following conditions are
612882Sspwilson2@wisc.edu# met: redistributions of source code must retain the above copyright
712882Sspwilson2@wisc.edu# notice, this list of conditions and the following disclaimer;
812882Sspwilson2@wisc.edu# redistributions in binary form must reproduce the above copyright
912882Sspwilson2@wisc.edu# notice, this list of conditions and the following disclaimer in the
1012882Sspwilson2@wisc.edu# documentation and/or other materials provided with the distribution;
1112882Sspwilson2@wisc.edu# neither the name of the copyright holders nor the names of its
1212882Sspwilson2@wisc.edu# contributors may be used to endorse or promote products derived from
1312882Sspwilson2@wisc.edu# this software without specific prior written permission.
1412882Sspwilson2@wisc.edu#
1512882Sspwilson2@wisc.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1612882Sspwilson2@wisc.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1712882Sspwilson2@wisc.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812882Sspwilson2@wisc.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1912882Sspwilson2@wisc.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2012882Sspwilson2@wisc.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2112882Sspwilson2@wisc.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2212882Sspwilson2@wisc.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2312882Sspwilson2@wisc.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2412882Sspwilson2@wisc.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2512882Sspwilson2@wisc.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2612882Sspwilson2@wisc.edu#
2712882Sspwilson2@wisc.edu# Authors: Sean Wilson
2812882Sspwilson2@wisc.edu
2912882Sspwilson2@wisc.eduimport os
3012882Sspwilson2@wisc.eduimport copy
3112882Sspwilson2@wisc.eduimport subprocess
3212882Sspwilson2@wisc.edu
3312882Sspwilson2@wisc.edufrom testlib.test import TestFunction
3412882Sspwilson2@wisc.edufrom testlib.suite import TestSuite
3512882Sspwilson2@wisc.edufrom testlib.helper import log_call
3612882Sspwilson2@wisc.edufrom testlib.config import constants, config
3712882Sspwilson2@wisc.edufrom fixture import TempdirFixture, Gem5Fixture, VariableFixture
3812882Sspwilson2@wisc.eduimport verifier
3912882Sspwilson2@wisc.edu
4012882Sspwilson2@wisc.edudef gem5_verify_config(name,
4112882Sspwilson2@wisc.edu                       config,
4212882Sspwilson2@wisc.edu                       config_args,
4312882Sspwilson2@wisc.edu                       verifiers,
4412882Sspwilson2@wisc.edu                       gem5_args=tuple(),
4512882Sspwilson2@wisc.edu                       fixtures=[],
4612882Sspwilson2@wisc.edu                       valid_isas=constants.supported_isas,
4712882Sspwilson2@wisc.edu                       valid_variants=constants.supported_variants,
4813851Sjason@lowepower.com                       length=constants.supported_lengths[0],
4913851Sjason@lowepower.com                       protocol=None):
5012882Sspwilson2@wisc.edu    '''
5112882Sspwilson2@wisc.edu    Helper class to generate common gem5 tests using verifiers.
5212882Sspwilson2@wisc.edu
5312882Sspwilson2@wisc.edu    The generated TestSuite will run gem5 with the provided config and
5412882Sspwilson2@wisc.edu    config_args. After that it will run any provided verifiers to verify
5512882Sspwilson2@wisc.edu    details about the gem5 run.
5612882Sspwilson2@wisc.edu
5712882Sspwilson2@wisc.edu    .. seealso::  For the verifiers see :mod:`testlib.gem5.verifier`
5812882Sspwilson2@wisc.edu
5912882Sspwilson2@wisc.edu    :param name: Name of the test.
6012882Sspwilson2@wisc.edu    :param config: The config to give gem5.
6112882Sspwilson2@wisc.edu    :param config_args: A list of arguments to pass to the given config.
6212882Sspwilson2@wisc.edu
6312882Sspwilson2@wisc.edu    :param verifiers: An iterable with Verifier instances which will be placed
6412882Sspwilson2@wisc.edu        into a suite that will be ran after a gem5 run.
6512882Sspwilson2@wisc.edu
6612882Sspwilson2@wisc.edu    :param gem5_args: An iterable with arguments to give to gem5. (Arguments
6712882Sspwilson2@wisc.edu        that would normally go before the config path.)
6812882Sspwilson2@wisc.edu
6912882Sspwilson2@wisc.edu    :param valid_isas: An iterable with the isas that this test can be ran
7012882Sspwilson2@wisc.edu        for. If None given, will run for all supported_isas.
7112882Sspwilson2@wisc.edu
7212882Sspwilson2@wisc.edu    :param valid_variants: An iterable with the variant levels that
7312882Sspwilson2@wisc.edu        this test can be ran for. (E.g. opt, debug)
7412882Sspwilson2@wisc.edu    '''
7512882Sspwilson2@wisc.edu    fixtures = list(fixtures)
7612882Sspwilson2@wisc.edu    testsuites = []
7712882Sspwilson2@wisc.edu    for opt in valid_variants:
7812882Sspwilson2@wisc.edu        for isa in valid_isas:
7912882Sspwilson2@wisc.edu
8012882Sspwilson2@wisc.edu            # Create a tempdir fixture to be shared throughout the test.
8112882Sspwilson2@wisc.edu            tempdir = TempdirFixture()
8212882Sspwilson2@wisc.edu            gem5_returncode = VariableFixture(
8312882Sspwilson2@wisc.edu                    name=constants.gem5_returncode_fixture_name)
8412882Sspwilson2@wisc.edu
8512882Sspwilson2@wisc.edu            # Common name of this generated testcase.
8612882Sspwilson2@wisc.edu            _name = '{given_name}-{isa}-{opt}'.format(
8712882Sspwilson2@wisc.edu                    given_name=name,
8812882Sspwilson2@wisc.edu                    isa=isa,
8912882Sspwilson2@wisc.edu                    opt=opt)
9013851Sjason@lowepower.com            if protocol:
9113851Sjason@lowepower.com                _name += '-'+protocol
9212882Sspwilson2@wisc.edu
9312882Sspwilson2@wisc.edu            # Create the running of gem5 subtest.
9412882Sspwilson2@wisc.edu            # NOTE: We specifically create this test before our verifiers so
9512882Sspwilson2@wisc.edu            # this is listed first.
9612882Sspwilson2@wisc.edu            tests = []
9712882Sspwilson2@wisc.edu            gem5_execution = TestFunction(
9812882Sspwilson2@wisc.edu                    _create_test_run_gem5(config, config_args, gem5_args),
9912882Sspwilson2@wisc.edu                    name=_name)
10012882Sspwilson2@wisc.edu            tests.append(gem5_execution)
10112882Sspwilson2@wisc.edu
10212882Sspwilson2@wisc.edu            # Create copies of the verifier subtests for this isa and
10312882Sspwilson2@wisc.edu            # variant.
10412882Sspwilson2@wisc.edu            for verifier in verifiers:
10512882Sspwilson2@wisc.edu                tests.append(verifier.instantiate_test(_name))
10612882Sspwilson2@wisc.edu
10712882Sspwilson2@wisc.edu            # Add the isa and variant to tags list.
10812882Sspwilson2@wisc.edu            tags = [isa, opt, length]
10912882Sspwilson2@wisc.edu
11012882Sspwilson2@wisc.edu            # Create the gem5 target for the specific architecture and
11112882Sspwilson2@wisc.edu            # variant.
11212882Sspwilson2@wisc.edu            _fixtures = copy.copy(fixtures)
11313851Sjason@lowepower.com            _fixtures.append(Gem5Fixture(isa, opt, protocol))
11412882Sspwilson2@wisc.edu            _fixtures.append(tempdir)
11512882Sspwilson2@wisc.edu            _fixtures.append(gem5_returncode)
11612882Sspwilson2@wisc.edu
11712882Sspwilson2@wisc.edu            # Finally construct the self contained TestSuite out of our
11812882Sspwilson2@wisc.edu            # tests.
11912882Sspwilson2@wisc.edu            testsuites.append(TestSuite(
12012882Sspwilson2@wisc.edu                name=_name,
12112882Sspwilson2@wisc.edu                fixtures=_fixtures,
12212882Sspwilson2@wisc.edu                tags=tags,
12312882Sspwilson2@wisc.edu                tests=tests))
12412882Sspwilson2@wisc.edu    return testsuites
12512882Sspwilson2@wisc.edu
12612882Sspwilson2@wisc.edudef _create_test_run_gem5(config, config_args, gem5_args):
12712882Sspwilson2@wisc.edu    def test_run_gem5(params):
12812882Sspwilson2@wisc.edu        '''
12912882Sspwilson2@wisc.edu        Simple \'test\' which runs gem5 and saves the result into a tempdir.
13012882Sspwilson2@wisc.edu
13112882Sspwilson2@wisc.edu        NOTE: Requires fixtures: tempdir, gem5
13212882Sspwilson2@wisc.edu        '''
13312882Sspwilson2@wisc.edu        fixtures = params.fixtures
13412882Sspwilson2@wisc.edu
13512882Sspwilson2@wisc.edu        if gem5_args is None:
13612882Sspwilson2@wisc.edu            _gem5_args = tuple()
13712882Sspwilson2@wisc.edu        elif isinstance(gem5_args, str):
13812882Sspwilson2@wisc.edu            # If just a single str, place it in an iterable
13912882Sspwilson2@wisc.edu            _gem5_args = (gem5_args,)
14012882Sspwilson2@wisc.edu        else:
14112882Sspwilson2@wisc.edu            _gem5_args = gem5_args
14212882Sspwilson2@wisc.edu
14312882Sspwilson2@wisc.edu        # FIXME/TODO: I don't like the idea of having to modify this test run
14412882Sspwilson2@wisc.edu        # or always collect results even if not using a verifier. There should
14512882Sspwilson2@wisc.edu        # be some configuration in here that only gathers certain results for
14612882Sspwilson2@wisc.edu        # certain verifiers.
14712882Sspwilson2@wisc.edu        #
14812882Sspwilson2@wisc.edu        # I.E. Only the returncode verifier will use the gem5_returncode
14912882Sspwilson2@wisc.edu        # fixture, but we always require it even if that verifier isn't being
15012882Sspwilson2@wisc.edu        # ran.
15112882Sspwilson2@wisc.edu        returncode = fixtures[constants.gem5_returncode_fixture_name]
15212882Sspwilson2@wisc.edu        tempdir = fixtures[constants.tempdir_fixture_name].path
15312882Sspwilson2@wisc.edu        gem5 = fixtures[constants.gem5_binary_fixture_name].path
15412882Sspwilson2@wisc.edu        command = [
15512882Sspwilson2@wisc.edu            gem5,
15612882Sspwilson2@wisc.edu            '-d',  # Set redirect dir to tempdir.
15712882Sspwilson2@wisc.edu            tempdir,
15812882Sspwilson2@wisc.edu            '-re',# TODO: Change to const. Redirect stdout and stderr
15912882Sspwilson2@wisc.edu        ]
16012882Sspwilson2@wisc.edu        command.extend(_gem5_args)
16112882Sspwilson2@wisc.edu        command.append(config)
16212882Sspwilson2@wisc.edu        # Config_args should set up the program args.
16312882Sspwilson2@wisc.edu        command.extend(config_args)
16412882Sspwilson2@wisc.edu        returncode.value = log_call(params.log, command)
16512882Sspwilson2@wisc.edu
16612882Sspwilson2@wisc.edu    return test_run_gem5
167