Changeset bacc36c


Ignore:
Timestamp:
Dec 4, 2017, 6:01:29 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
209383b
Parents:
0ad0c55
Message:

Major test cleanup by modularizing further into pybin

Location:
src/tests
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/tests/pybin/test_run.py

    r0ad0c55 rbacc36c  
    33from pybin.tools import *
    44
     5import pybin.settings
    56
    67# Test class that defines what a test is
     
    1415                return "{:25s} ({:5s} {:s})".format( self.name, self.arch if self.arch else "Any", self.target() )
    1516
    16         def prepare(self, dry_run):
    17                 sh("mkdir -p %s" % os.path.join(self.path, '.err'), dry_run)
    18                 sh("mkdir -p %s" % os.path.join(self.path, '.out'), dry_run)
    19                 sh("mkdir -p %s" % os.path.join(self.path, '.in' ), dry_run)
     17        def prepare(self):
     18                sh("mkdir -p %s" % os.path.join(self.path, '.err'))
     19                sh("mkdir -p %s" % os.path.join(self.path, '.out'))
     20                sh("mkdir -p %s" % os.path.join(self.path, '.in' ))
    2021
    21         def expect_file(self):
     22        def expect(self):
    2223                return ("%s/.expect/%s.txt" % (self.path, self.name))
    2324
    24         def error_file(self):
     25        def error_log(self):
    2526                return ("%s/.err/%s.log"    % (self.path, self.name))
    2627
    27         def output_file(self):
     28        def output_log(self):
    2829                return ("%s/.out/%s.log"    % (self.path, self.name))
    2930
    30         def input_file(self):
     31        def input(self):
    3132                return ("%s/.in/%s.txt"     % (self.path, self.name))
     33
     34        def target_output(self):
     35                return self.output_log() if not settings.generating else self.expect()
    3236
    3337        def target(self):
    3438                return os.path.join(self.path, self.name)
     39
     40        @classmethod
     41        def valid_name(cls, name):
     42                return not name.endswith( ('.c', '.cc', '.cpp', '.cfa') )
     43
     44        @classmethod
     45        def from_target(cls, target):
     46                test = Test()
     47                test.name = os.path.basename(target)
     48                test.path = os.path.dirname (target)
     49                test.arch = settings.arch.toString() if settings.arch.cross_compile else ''
     50                return test
     51
     52
     53class TestResult:
     54        SUCCESS = 0
     55        FAILURE = 1
     56        TIMEOUT = 124
     57
     58        @classmethod
     59        def toString( cls, retcode ):
     60                if settings.generating :
     61                        if   retcode == TestResult.SUCCESS:     return "Done"
     62                        elif retcode == TestResult.TIMEOUT:     return "TIMEOUT"
     63                        else :                                          return "ERROR code %d" % retcode
     64                else :
     65                        if   retcode == TestResult.SUCCESS:     return "PASSED"
     66                        elif retcode == TestResult.TIMEOUT:     return "TIMEOUT"
     67                        else :                                          return "FAILED with code %d" % retcode
  • src/tests/pybin/tools.py

    r0ad0c55 rbacc36c  
     1from __future__ import print_function
     2
    13import __main__
    24import argparse
     5import multiprocessing
    36import os
    47import re
     8import signal
    59import stat
    6 
     10import sys
     11
     12from pybin import settings
    713from subprocess import Popen, PIPE, STDOUT
    814
     15################################################################################
     16#               shell helpers
     17################################################################################
     18
    919# helper functions to run terminal commands
    10 def sh(cmd, dry_run = False, print2stdout = True):
    11         if dry_run :    # if this is a dry_run, only print the commands that would be ran
     20def sh(cmd, print2stdout = True, input = None):
     21        # add input redirection if needed
     22        if input and os.path.isfile(input):
     23                cmd += " < %s" % input
     24
     25        # if this is a dry_run, only print the commands that would be ran
     26        if settings.dry_run :
    1227                print("cmd: %s" % cmd)
    1328                return 0, None
    14         else :                  # otherwise create a pipe and run the desired command
     29
     30        # otherwise create a pipe and run the desired command
     31        else :
    1532                proc = Popen(cmd, stdout=None if print2stdout else PIPE, stderr=STDOUT, shell=True)
    1633                out, err = proc.communicate()
     
    1835
    1936# Remove 1 or more files silently
    20 def rm( files, dry_run = False ):
     37def rm( files ):
    2138        try:
    2239                for file in files:
    23                         sh("rm -f %s > /dev/null 2>&1" % file, dry_run)
     40                        sh("rm -f %s > /dev/null 2>&1" % file )
    2441        except TypeError:
    25                 sh("rm -f %s > /dev/null 2>&1" % files, dry_run)
     42                sh("rm -f %s > /dev/null 2>&1" % files )
    2643
    2744def chdir( dest = __main__.__file__ ):
     
    3047        os.chdir(dname)
    3148
    32 # helper function to replace patterns in a file
    33 def file_replace(fname, pat, s_after):
    34     # first, see if the pattern is even in the file.
    35     with open(fname) as f:
    36         if not any(re.search(pat, line) for line in f):
    37             return # pattern does not occur in file so we are done.
    38 
    39     # pattern is in the file, so perform replace operation.
    40     with open(fname) as f:
    41         out_fname = fname + ".tmp"
    42         out = open(out_fname, "w")
    43         for line in f:
    44             out.write(re.sub(pat, s_after, line))
    45         out.close()
    46         os.rename(out_fname, fname)
    47 
    48 # helper function to check if a files contains only a specific string
    49 def fileContainsOnly(file, text) :
    50         with open(file) as f:
    51                 ff = f.read().strip()
    52                 result = ff == text.strip()
    53 
    54                 return result;
    55 
    56 # check whether or not a file is executable
    57 def fileIsExecutable(file) :
    58         try :
    59                 fileinfo = os.stat(file)
    60                 return bool(fileinfo.st_mode & stat.S_IXUSR)
    61         except Exception as inst:
    62                 print(type(inst))    # the exception instance
    63                 print(inst.args)     # arguments stored in .args
    64                 print(inst)
    65                 return False
    66 
    67 # check if arguments is yes or no
    68 def yes_no(string):
    69         if string == "yes" :
    70                 return True
    71         if string == "no" :
    72                 return False
    73         raise argparse.ArgumentTypeError(msg)
    74         return False
    75 
    7649# diff two files
    77 def diff( lhs, rhs, dry_run ):
     50def diff( lhs, rhs ):
    7851        # diff the output of the files
    7952        diff_cmd = ("diff --ignore-all-space "
     
    9467
    9568        # fetch return code and error from the diff command
    96         return sh(diff_cmd % (lhs, rhs), dry_run, False)
     69        return sh(diff_cmd % (lhs, rhs), False)
     70
     71# call make
     72def make(target, flags = '', redirects = '', error_file = None, silent = False):
     73        test_param = """test="%s" """ % (error_file) if error_file else ''
     74        cmd = ' '.join([
     75                settings.make,
     76                '-s' if silent else '',
     77                test_param,
     78                flags,
     79                target,
     80                redirects
     81        ])
     82        return sh(cmd)
     83
     84################################################################################
     85#               file handling
     86################################################################################
     87
     88# helper function to replace patterns in a file
     89def file_replace(fname, pat, s_after):
     90    # first, see if the pattern is even in the file.
     91    with open(fname) as f:
     92        if not any(re.search(pat, line) for line in f):
     93            return # pattern does not occur in file so we are done.
     94
     95    # pattern is in the file, so perform replace operation.
     96    with open(fname) as f:
     97        out_fname = fname + ".tmp"
     98        out = open(out_fname, "w")
     99        for line in f:
     100            out.write(re.sub(pat, s_after, line))
     101        out.close()
     102        os.rename(out_fname, fname)
     103
     104# helper function to check if a files contains only a specific string
     105def fileContainsOnly(file, text) :
     106        with open(file) as f:
     107                ff = f.read().strip()
     108                result = ff == text.strip()
     109
     110                return result;
     111
     112# check whether or not a file is executable
     113def fileIsExecutable(file) :
     114        try :
     115                fileinfo = os.stat(file)
     116                return bool(fileinfo.st_mode & stat.S_IXUSR)
     117        except Exception as inst:
     118                print(type(inst))    # the exception instance
     119                print(inst.args)     # arguments stored in .args
     120                print(inst)
     121                return False
     122
     123# transform path to canonical form
     124def canonicalPath(path):
     125        return os.path.join('.', os.path.normpath(path) )
     126
     127# compare path even if form is different
     128def pathCmp(lhs, rhs):
     129        return canonicalPath( lhs ) == canonicalPath( rhs )
     130
     131# walk all files in a path
     132def pathWalk( op ):
     133        def step(_, dirname, names):
     134                for name in names:
     135                        path = os.path.join(dirname, name)
     136
     137                        op( path )
     138
     139        # Start the walk
     140        os.path.walk('.', step, '')
     141
     142################################################################################
     143#               system
     144################################################################################
    97145
    98146# parses the Makefile to find the machine type (32-bit / 64-bit)
     
    100148        return 'x64'
    101149        sh('echo "void ?{}(int&a,int b){}int main(){return 0;}" > .dummy.c')
    102         ret, out = sh("make .dummy -s", print2stdout=True)
     150        ret, out = make('.dummy', silent = True)
    103151
    104152        if ret != 0:
     
    114162        return out
    115163        return re.search("ELF\s([0-9]+)-bit", out).group(1)
     164
     165# count number of jobs to create
     166def jobCount( options, tests ):
     167        # check if the user already passed in a number of jobs for multi-threading
     168        make_flags = os.environ.get('MAKEFLAGS')
     169        make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None
     170        if make_jobs_fds :
     171                tokens = os.read(int(make_jobs_fds.group(2)), 1024)
     172                options.jobs = len(tokens)
     173                os.write(int(make_jobs_fds.group(3)), tokens)
     174        else :
     175                options.jobs = multiprocessing.cpu_count()
     176
     177        # make sure we have a valid number of jobs that corresponds to user input
     178        if options.jobs <= 0 :
     179                print('ERROR: Invalid number of jobs', file=sys.stderr)
     180                sys.exit(1)
     181
     182        return min( options.jobs, len(tests) ), True if make_flags else False
     183
     184# setup a proper processor pool with correct signal handling
     185def setupPool(jobs):
     186        original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
     187        pool = multiprocessing.Pool(jobs)
     188        signal.signal(signal.SIGINT, original_sigint_handler)
     189
     190        return pool
     191
     192# handle signals in scope
     193class SignalHandling():
     194        def __enter__(self):
     195                # enable signal handling
     196                signal.signal(signal.SIGINT, signal.SIG_DFL)
     197
     198        def __exit__(self, type, value, traceback):
     199                # disable signal handling
     200                signal.signal(signal.SIGINT, signal.SIG_IGN)
     201
     202################################################################################
     203#               misc
     204################################################################################
     205
     206# check if arguments is yes or no
     207def yes_no(string):
     208        if string == "yes" :
     209                return True
     210        if string == "no" :
     211                return False
     212        raise argparse.ArgumentTypeError(msg)
     213        return False
  • src/tests/test.py

    r0ad0c55 rbacc36c  
    22from __future__ import print_function
    33
    4 from functools import partial
    5 from multiprocessing import Pool
    6 from os import listdir, environ
    7 from os.path import isfile, join, splitext
    84from pybin.tools import *
    95from pybin.test_run import *
     6from pybin import settings
    107
    118import argparse
    12 import multiprocessing
    13 import os
     9import functools
    1410import re
    15 import signal
    1611import sys
    1712
     
    2318        expected = []
    2419
    25         def step(_, dirname, names):
    26                 for name in names:
    27                         path = os.path.join(dirname, name)
    28 
    29                         match = re.search("(\.[\w\/\-_]*)\/.expect\/([\w\-_]+)(\.[\w\-_]+)?\.txt", path)
    30                         if match :
    31                                 test = Test()
    32                                 test.name = match.group(2)
    33                                 test.path = match.group(1)
    34                                 test.arch = match.group(3)[1:] if match.group(3) else None
    35                                 expected.append(test)
    36 
    37         # Start the walk
    38         os.path.walk('.', step, '')
     20        def findTest(path):
     21                match = re.search("(\.[\w\/\-_]*)\/.expect\/([\w\-_]+)(\.[\w\-_]+)?\.txt", path)
     22                if match :
     23                        test = Test()
     24                        test.name = match.group(2)
     25                        test.path = match.group(1)
     26                        test.arch = match.group(3)[1:] if match.group(3) else None
     27                        expected.append(test)
     28
     29        pathWalk( findTest )
    3930
    4031        return expected
     
    4233# reads the directory ./.expect and indentifies the tests
    4334def listTests( includes, excludes ):
    44         includes = [os.path.normpath( os.path.join('.',i) ) for i in includes] if includes else None
    45         excludes = [os.path.normpath( os.path.join('.',i) ) for i in excludes] if excludes else None
     35        includes = [canonicalPath( i ) for i in includes] if includes else None
     36        excludes = [canonicalPath( i ) for i in excludes] if excludes else None
    4637
    4738        # tests directly in the .expect folder will always be processed
     
    5142        if includes:
    5243                test_list = [x for x in test_list if
    53                         os.path.normpath( x.path ).startswith( tuple(includes) )
     44                        x.path.startswith( tuple(includes) )
    5445                ]
    5546
     
    5748        if excludes:
    5849                test_list = [x for x in test_list if not
    59                         os.path.normpath( x.path ).startswith( tuple(excludes) )
     50                        x.path.startswith( tuple(excludes) )
    6051                ]
    6152
     
    7061        if options.regenerate_expected :
    7162                for testname in options.tests :
    72                         if testname.endswith( (".c", ".cc", ".cpp") ):
     63                        if Test.valid_name(testname):
     64                                found = [test for test in allTests if test.target() == testname]
     65                                tests.append( found[0] if len(found) == 1 else Test.from_target(testname) )
     66                        else :
    7367                                print('ERROR: "%s", tests are not allowed to end with a C/C++/CFA extension, ignoring it' % testname, file=sys.stderr)
    74                         else :
    75                                 found = [test for test in allTests if test.name == testname]
    76                                 tests.append( found[0] if len(found) == 1 else Test(testname, testname) )
    7768
    7869        else :
    7970                # otherwise we only need to validate that all tests are present in the complete list
    8071                for testname in options.tests:
    81                         test = [t for t in allTests if os.path.normpath( t.target() ) == os.path.normpath( testname )]
    82 
    83                         if len(test) != 0 :
     72                        test = [t for t in allTests if pathCmp( t.target(), testname )]
     73
     74                        if test :
    8475                                tests.append( test[0] )
    8576                        else :
     
    8778
    8879        # make sure we have at least some test to run
    89         if len(tests) == 0 :
     80        if tests :
    9081                print('ERROR: No valid test to run', file=sys.stderr)
    9182                sys.exit(1)
    9283
    9384        return tests
    94 
    95 class TestResult:
    96         SUCCESS = 0
    97         FAILURE = 1
    98         TIMEOUT = 124
    9985
    10086# parses the option
     
    10389        parser = argparse.ArgumentParser(description='Script which runs cforall tests')
    10490        parser.add_argument('--debug', help='Run all tests in debug or release', type=yes_no, default='no')
    105         parser.add_argument('--arch', help='Test for specific architecture', type=str, default=getMachineType())
     91        parser.add_argument('--arch', help='Test for specific architecture', type=str, default='')
    10692        parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true')
    10793        parser.add_argument('--list', help='List all test available', action='store_true')
     
    130116        return options
    131117
    132 def jobCount( options ):
    133         # check if the user already passed in a number of jobs for multi-threading
    134         make_flags = environ.get('MAKEFLAGS')
    135         make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None
    136         if make_jobs_fds :
    137                 tokens = os.read(int(make_jobs_fds.group(2)), 1024)
    138                 options.jobs = len(tokens)
    139                 os.write(int(make_jobs_fds.group(3)), tokens)
    140         else :
    141                 options.jobs = multiprocessing.cpu_count()
    142 
    143         # make sure we have a valid number of jobs that corresponds to user input
    144         if options.jobs <= 0 :
    145                 print('ERROR: Invalid number of jobs', file=sys.stderr)
    146                 sys.exit(1)
    147 
    148         return min( options.jobs, len(tests) ), True if make_flags else False
    149 
    150118################################################################################
    151119#               running test functions
    152120################################################################################
    153121# logic to run a single test and return the result (No handling of printing or other test framework logic)
    154 def run_single_test(test, generate, dry_run, debug):
     122def run_single_test(test, debug):
    155123
    156124        # find the output file based on the test name and options flag
    157         out_file = test.output_file() if not generate else test.expect_file()
    158         err_file = test.error_file()
    159         cmp_file = test.expect_file()
    160         in_file  = test.input_file()
     125        out_file = test.target_output()
     126        err_file = test.error_log()
     127        cmp_file = test.expect()
     128        in_file  = test.input()
    161129
    162130        # prepare the proper directories
    163         test.prepare( dry_run )
     131        test.prepare()
    164132
    165133        # remove any outputs from the previous tests to prevent side effects
    166         rm( (out_file, err_file, test.target()), dry_run )
     134        rm( (out_file, err_file, test.target()) )
    167135
    168136        options = "-debug" if debug else "-nodebug"
    169137
    170 
    171138        # build, skipping to next test on error
    172         make_ret, _ = sh("""%s  DEBUG_FLAGS="%s" %s test="%s" 2> %s 1> /dev/null""" % (make_cmd, options, test.target(), err_file, out_file), dry_run)
     139        make_ret, _ = make( test.target(),
     140                flags      = """DEBUG_FLAGS="%s" """ % options,
     141                redirects  = "2> %s 1> /dev/null" % out_file,
     142                error_file = err_file
     143        )
    173144
    174145        retcode = 0
     
    176147
    177148        # if the make command succeds continue otherwise skip to diff
    178         if make_ret == 0 or dry_run:
    179                 # fetch optional input
    180                 stdinput = "< %s" % in_file if isfile(in_file) else ""
    181 
    182                 if dry_run or fileIsExecutable(test.target()) :
     149        if make_ret == 0 or settings.dry_run:
     150                if settings.dry_run or fileIsExecutable(test.target()) :
    183151                        # run test
    184                         retcode, _ = sh("timeout 60 ./%s %s > %s 2>&1" % (test.target(), stdinput, out_file), dry_run)
     152                        retcode, _ = sh("timeout 60 %s > %s 2>&1" % (test.target(), out_file), input = in_file)
    185153                else :
    186154                        # simply cat the result into the output
    187                         sh("cat %s > %s" % (test.target(), out_file), dry_run)
     155                        sh("cat %s > %s" % (test.target(), out_file))
    188156        else:
    189                 sh("mv %s %s" % (err_file, out_file), dry_run)
     157                sh("mv %s %s" % (err_file, out_file))
    190158
    191159
    192160        if retcode == 0:
    193                 if generate :
     161                if settings.generating :
    194162                        # if we are ounly generating the output we still need to check that the test actually exists
    195                         if not dry_run and fileContainsOnly(out_file, "make: *** No rule to make target `%s'.  Stop." % test.target()) :
     163                        if not settings.dry_run and fileContainsOnly(out_file, "make: *** No rule to make target `%s'.  Stop." % test.target()) :
    196164                                retcode = 1;
    197165                                error = "\t\tNo make target for test %s!" % test.target()
     
    199167                else :
    200168                        # fetch return code and error from the diff command
    201                         retcode, error = diff(cmp_file, out_file, dry_run)
     169                        retcode, error = diff(cmp_file, out_file)
    202170
    203171        else:
     
    207175
    208176        # clean the executable
    209         sh("rm -f %s > /dev/null 2>&1" % test.target(), dry_run)
     177        sh("rm -f %s > /dev/null 2>&1" % test.target())
    210178
    211179        return retcode, error
    212180
    213181# run a single test and handle the errors, outputs, printing, exception handling, etc.
    214 def run_test_worker(t, generate, dry_run, debug) :
    215 
    216         signal.signal(signal.SIGINT, signal.SIG_DFL)
    217         # print formated name
    218         name_txt = "%20s  " % t.name
    219 
    220         retcode, error = run_single_test(t, generate, dry_run, debug)
    221 
    222         # update output based on current action
    223         if generate :
    224                 if   retcode == TestResult.SUCCESS:     result_txt = "Done"
    225                 elif retcode == TestResult.TIMEOUT:     result_txt = "TIMEOUT"
    226                 else :                                          result_txt = "ERROR code %d" % retcode
    227         else :
    228                 if   retcode == TestResult.SUCCESS:     result_txt = "PASSED"
    229                 elif retcode == TestResult.TIMEOUT:     result_txt = "TIMEOUT"
    230                 else :                                          result_txt = "FAILED with code %d" % retcode
    231 
    232         #print result with error if needed
    233         text = name_txt + result_txt
    234         out = sys.stdout
    235         if error :
    236                 text = text + "\n" + error
    237                 out = sys.stderr
    238 
    239         print(text, file = out)
    240         sys.stdout.flush()
    241         sys.stderr.flush()
    242         signal.signal(signal.SIGINT, signal.SIG_IGN)
     182def run_test_worker(t, debug) :
     183
     184        with SignalHandling():
     185                # print formated name
     186                name_txt = "%20s  " % t.name
     187
     188                retcode, error = run_single_test(t, debug)
     189
     190                # update output based on current action
     191                result_txt = TestResult.toString( retcode )
     192
     193                #print result with error if needed
     194                text = name_txt + result_txt
     195                out = sys.stdout
     196                if error :
     197                        text = text + "\n" + error
     198                        out = sys.stderr
     199
     200                print(text, file = out)
     201                sys.stdout.flush()
     202                sys.stderr.flush()
    243203
    244204        return retcode != TestResult.SUCCESS
    245205
    246206# run the given list of tests with the given parameters
    247 def run_tests(tests, generate, dry_run, jobs, debug) :
     207def run_tests(tests, jobs, debug) :
    248208        # clean the sandbox from previous commands
    249         sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)
    250 
    251         if generate :
    252                 print( "Regenerate tests for: " )
     209        make('clean', redirects = '> /dev/null 2>&1')
    253210
    254211        # create the executor for our jobs and handle the signal properly
    255         original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
    256         pool = Pool(jobs)
    257         signal.signal(signal.SIGINT, original_sigint_handler)
     212        pool = setupPool(jobs)
    258213
    259214        # for each test to run
    260215        try :
    261                 results = pool.map_async(partial(run_test_worker, generate=generate, dry_run=dry_run, debug=debug), tests, chunksize = 1 ).get(7200)
     216                results = pool.map_async(
     217                        functools.partial(run_test_worker, debug=debug),
     218                        tests,
     219                        chunksize = 1
     220                ).get(7200)
    262221        except KeyboardInterrupt:
    263222                pool.terminate()
     
    266225
    267226        # clean the workspace
    268         sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)
     227        make('clean', redirects = '> /dev/null 2>&1')
    269228
    270229        for failed in results:
     
    285244        options = getOptions()
    286245
     246        # init global settings
     247        settings.init( options )
     248
    287249        # fetch the liest of all valid tests
    288250        allTests = listTests( options.include, options.exclude )
     
    297259
    298260        # sort the test alphabetically for convenience
    299         tests.sort(key=lambda t: os.path.join(t.path, t.name))
     261        tests.sort(key=lambda t: t.target())
    300262
    301263        # users may want to simply list the tests
     
    305267
    306268        elif options.list :
    307                 print("Listing for %s:%s"% (options.arch, "debug" if options.debug else "no debug"))
     269                print("Listing for %s:%s"% (settings.arch.toString(), "debug" if options.debug else "no debug"))
    308270                print("\n".join(map(lambda t: "%s" % (t.toString()), tests)))
    309271
    310272        else :
    311                 options.jobs, forceJobs = jobCount( options )
    312 
    313                 print('Running (%s:%s) on %i cores' % (options.arch, "debug" if options.debug else "no debug", options.jobs))
    314                 make_cmd = "make" if forceJobs else ("make -j%i" % options.jobs)
     273                options.jobs, forceJobs = jobCount( options, tests )
     274                settings.updateMakeCmd(forceJobs, options.jobs)
     275
     276                print('%s (%s:%s) on %i cores' % (
     277                        'Regenerate tests' if settings.generating else 'Running',
     278                        settings.arch.toString(),
     279                        "debug" if options.debug else "no debug",
     280                        options.jobs
     281                ))
    315282
    316283                # otherwise run all tests and make sure to return the correct error code
    317                 sys.exit( run_tests(tests, options.regenerate_expected, options.dry_run, options.jobs, options.debug) )
     284                sys.exit( run_tests(tests, options.jobs, options.debug) )
Note: See TracChangeset for help on using the changeset viewer.