SConscript revision 12305
15148SN/A# -*- mode:python -*-
25148SN/A#
35148SN/A# Copyright (c) 2016 ARM Limited
410036SAli.Saidi@ARM.com# All rights reserved
58835SAli.Saidi@ARM.com#
610036SAli.Saidi@ARM.com# The license below extends only to copyright in the software and shall
77873SN/A# not be construed as granting a license to any other intellectual
87873SN/A# property including but not limited to intellectual property relating
97873SN/A# to a hardware implementation of the functionality of the software
105148SN/A# licensed hereunder.  You may use the software subject to the license
115148SN/A# terms below provided that you ensure that this notice is replicated
125148SN/A# unmodified and in its entirety in all distributions of the software,
139885Sstever@gmail.com# modified or unmodified, in source code or in binary form.
148835SAli.Saidi@ARM.com#
159885Sstever@gmail.com# Copyright (c) 2004-2006 The Regents of The University of Michigan
169885Sstever@gmail.com# All rights reserved.
1710036SAli.Saidi@ARM.com#
188835SAli.Saidi@ARM.com# Redistribution and use in source and binary forms, with or without
198835SAli.Saidi@ARM.com# modification, are permitted provided that the following conditions are
208835SAli.Saidi@ARM.com# met: redistributions of source code must retain the above copyright
215148SN/A# notice, this list of conditions and the following disclaimer;
229481Snilay@cs.wisc.edu# redistributions in binary form must reproduce the above copyright
238673SN/A# notice, this list of conditions and the following disclaimer in the
248721SN/A# documentation and/or other materials provided with the distribution;
258835SAli.Saidi@ARM.com# neither the name of the copyright holders nor the names of its
268835SAli.Saidi@ARM.com# contributors may be used to endorse or promote products derived from
277935SN/A# this software without specific prior written permission.
287935SN/A#
297935SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
307935SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
317935SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
327935SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
337935SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
348983Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
355148SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
369885Sstever@gmail.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
379885Sstever@gmail.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
389885Sstever@gmail.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3910036SAli.Saidi@ARM.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
409885Sstever@gmail.com#
419885Sstever@gmail.com# Authors: Steve Reinhardt
425148SN/A#          Kevin Lim
435148SN/A#          Andreas Sandberg
449885Sstever@gmail.com
455876SN/Afrom SCons.Script.SConscript import SConsEnvironment
469885Sstever@gmail.comimport os
475148SN/Aimport pickle
485876SN/Aimport sys
498835SAli.Saidi@ARM.com
505876SN/Asys.path.insert(0, Dir(".").srcnode().abspath)
515148SN/Aimport testing.tests as tests
5210036SAli.Saidi@ARM.comimport testing.results as results
538983Snate@binkert.orgfrom gem5_scons.util import get_termcap
545148SN/A
555148SN/AImport('env')
568835SAli.Saidi@ARM.com
579481Snilay@cs.wisc.edu# get the termcap from the environment
585148SN/Atermcap = get_termcap()
595148SN/A
605148SN/A# Dict that accumulates lists of tests by category (quick, medium, long)
615148SN/Aenv.Tests = {}
625148SN/Agpu_isa = env['TARGET_GPU_ISA'] if env['BUILD_GPU'] else None
635540SN/Afor cat in tests.all_categories:
648835SAli.Saidi@ARM.com    env.Tests[cat] = tuple(
655148SN/A        tests.get_tests(env["TARGET_ISA"],
669885Sstever@gmail.com                        categories=(cat, ),
679885Sstever@gmail.com                        ruby_protocol=env["PROTOCOL"],
689885Sstever@gmail.com                        gpu_isa=gpu_isa))
699885Sstever@gmail.com
705509SN/Adef color_message(color, msg):
715509SN/A    return color + msg + termcap.Normal
729481Snilay@cs.wisc.edu
735148SN/Adef run_test(target, source, env):
745148SN/A    """Run a test and produce results as a pickle file.
755148SN/A
765148SN/A    Targets are as follows:
778983Snate@binkert.org    target[0] : Pickle file
788983Snate@binkert.org
795148SN/A    Sources are:
809885Sstever@gmail.com    source[0] : gem5 binary
819885Sstever@gmail.com    source[1] : tests/run.py script
829885Sstever@gmail.com    source[2:] : reference files
839885Sstever@gmail.com
8410036SAli.Saidi@ARM.com    """
859885Sstever@gmail.com    tgt_dir = os.path.dirname(str(target[0]))
865148SN/A    config = tests.ClassicConfig(*tgt_dir.split('/')[-6:])
876024SN/A    test = tests.ClassicTest(source[0].abspath, tgt_dir, config,
888835SAli.Saidi@ARM.com                             timeout=5*60*60,
8910036SAli.Saidi@ARM.com                             skip_diff_out=True)
905148SN/A
918835SAli.Saidi@ARM.com    for ref in test.ref_files():
928835SAli.Saidi@ARM.com        out_file = os.path.join(tgt_dir, ref)
938835SAli.Saidi@ARM.com        if os.path.exists(out_file):
948835SAli.Saidi@ARM.com            env.Execute(Delete(out_file))
959885Sstever@gmail.com
9610036SAli.Saidi@ARM.com    with open(target[0].abspath, "wb") as fout:
979885Sstever@gmail.com        formatter = results.Pickle(fout=fout)
988835SAli.Saidi@ARM.com        formatter.dump_suites([ test.run() ])
998983Snate@binkert.org
1008835SAli.Saidi@ARM.com    return 0
1018835SAli.Saidi@ARM.com
1028835SAli.Saidi@ARM.comdef run_test_string(target, source, env):
1039885Sstever@gmail.com    return env.subst("Running test in ${TARGETS[0].dir}.",
10410036SAli.Saidi@ARM.com                     target=target, source=source)
1058835SAli.Saidi@ARM.com
1068835SAli.Saidi@ARM.comtestAction = env.Action(run_test, run_test_string)
1079213Snilay@cs.wisc.edu
1088835SAli.Saidi@ARM.comdef print_test(target, source, env):
1098983Snate@binkert.org    """Run a test and produce results as a pickle file.
1108983Snate@binkert.org
1118983Snate@binkert.org    Targets are as follows:
1125148SN/A    target[*] : Dummy targets
1139481Snilay@cs.wisc.edu
1149481Snilay@cs.wisc.edu    Sources are:
11510036SAli.Saidi@ARM.com    source[0] : Pickle file
1169481Snilay@cs.wisc.edu
1175148SN/A    """
1186024SN/A    with open(source[0].abspath, "rb") as fin:
1198835SAli.Saidi@ARM.com        result = pickle.load(fin)
12010036SAli.Saidi@ARM.com
1215148SN/A    assert len(result) == 1
1228835SAli.Saidi@ARM.com    result = result[0]
1238835SAli.Saidi@ARM.com
1248835SAli.Saidi@ARM.com    formatter = None
1258835SAli.Saidi@ARM.com    if result.skipped():
1269885Sstever@gmail.com        status = color_message(termcap.Cyan, "skipped.")
12710036SAli.Saidi@ARM.com    elif result.changed():
1289885Sstever@gmail.com        status = color_message(termcap.Yellow, "CHANGED!")
1298835SAli.Saidi@ARM.com        formatter = results.Text()
1308983Snate@binkert.org    elif result:
1315148SN/A        status = color_message(termcap.Green, "passed.")
1325148SN/A    else:
1335148SN/A        status = color_message(termcap.Red, "FAILED!")
13410036SAli.Saidi@ARM.com        formatter = results.Text()
1355148SN/A
1365148SN/A    if formatter:
1375148SN/A        formatter.dump_suites([result])
1385148SN/A
1395148SN/A    print "***** %s: %s" % (source[0].dir, status)
1405148SN/A    return 0
1415148SN/A
1425516SN/AprintAction = env.Action(print_test, strfunction=None)
1435148SN/A
14410036SAli.Saidi@ARM.comdef update_test(target, source, env):
14510036SAli.Saidi@ARM.com    """Update test reference data
1465148SN/A
1475148SN/A    Targets are as follows:
1485176SN/A    target[0] : Dummy file
1495148SN/A
1505148SN/A    Sources are:
1515148SN/A    source[0] : Pickle file
1525410SN/A    """
1535148SN/A
1545148SN/A    src_dir = os.path.dirname(str(source[0]))
1555148SN/A    config = tests.ClassicConfig(*src_dir.split('/')[-6:])
1569885Sstever@gmail.com    test = tests.ClassicTest(source[0].abspath, src_dir, config)
1579885Sstever@gmail.com    ref_dir = test.ref_dir
1589885Sstever@gmail.com
15910036SAli.Saidi@ARM.com    with open(source[0].abspath, "rb") as fin:
1609885Sstever@gmail.com        result = pickle.load(fin)
1619885Sstever@gmail.com
1625148SN/A    assert len(result) == 1
1639039Sgblack@eecs.umich.edu    result = result[0]
1649885Sstever@gmail.com
16510036SAli.Saidi@ARM.com    if result.skipped():
1665410SN/A        print "*** %s: %s: Test skipped, not updating." % (
1679583Snilay@cs.wisc.edu            source[0].dir, color_message(termcap.Yellow, "WARNING"), )
1687524SN/A        return 0
1699150SAli.Saidi@ARM.com    elif result:
1709150SAli.Saidi@ARM.com        print "*** %s: %s: Test successful, not updating." % (
1718983Snate@binkert.org            source[0].dir, color_message(termcap.Green, "skipped"), )
1725148SN/A        return 0
1735148SN/A    elif result.failed_run():
1748983Snate@binkert.org        print "*** %s: %s: Test failed, not updating." % (
1759373Snilay@cs.wisc.edu            source[0].dir, color_message(termcap.Red, "ERROR"), )
1769885Sstever@gmail.com        return 1
1779885Sstever@gmail.com
17810036SAli.Saidi@ARM.com    print "** Updating %s" % (test, )
1798983Snate@binkert.org    test.update_ref()
1805540SN/A
1815410SN/A    return 0
1825509SN/A
1835148SN/Adef update_test_string(target, source, env):
1848983Snate@binkert.org    return env.subst("Updating ${SOURCES[0].dir}",
1855148SN/A                     target=target, source=source)
1869885Sstever@gmail.com
1879885Sstever@gmail.comupdateAction = env.Action(update_test, update_test_string)
18810036SAli.Saidi@ARM.com
1899885Sstever@gmail.comdef test_builder(test_tuple):
1909885Sstever@gmail.com    """Define a test."""
191
192    out_dir = "/".join(test_tuple)
193    binary = env.M5Binary.abspath
194    test = tests.ClassicTest(binary, out_dir, test_tuple)
195
196    def tgt(name):
197        return os.path.join(out_dir, name)
198
199    def ref(name):
200        return os.path.join(test.ref_dir, name)
201
202    pickle_file = tgt("status.pickle")
203    targets = [
204        pickle_file,
205    ]
206
207    sources = [
208        env.M5Binary,
209        "run.py",
210    ] + [ ref(f) for f in test.ref_files() ]
211
212    env.Command(targets, sources, testAction)
213
214    # phony target to echo status
215    if GetOption('update_ref'):
216        p = env.Command(tgt("_update"), [pickle_file], updateAction)
217    else:
218        p = env.Command(tgt("_print"), [pickle_file], printAction)
219
220    env.AlwaysBuild(p)
221
222def list_tests(target, source, env):
223    """Create a list of tests
224
225    Targets are as follows:
226    target[0] : List file (e.g., tests/opt/all.list,  tests/opt/quick.list)
227
228    Sources are: -
229
230    """
231
232    tgt_name = os.path.basename(str(target[0]))
233    base, ext = os.path.splitext(tgt_name)
234    categories = tests.all_categories if base == "all" else (base, )
235
236    with open(target[0].abspath, "w") as fout:
237        for cat in categories:
238            for test in env.Tests[cat]:
239                print >> fout,"/".join(test)
240
241    return 0
242
243testListAction = env.Action(list_tests, strfunction=None)
244
245env.Command("all.list", tuple(), testListAction)
246for cat, test_list in env.Tests.items():
247    env.Command("%s.list" % cat, tuple(), testListAction)
248    for test in test_list:
249        test_builder(test)
250