Changeset d672350 for tests


Ignore:
Timestamp:
Mar 21, 2022, 1:44:06 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
a76202d
Parents:
ef3c383 (diff), dbe2533 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
tests
Files:
41 added
17 edited
1 moved

Legend:

Unmodified
Added
Removed
  • tests/.expect/declarationSpecifier.arm64.txt

    ref3c383 rd672350  
    11321132char **_X13cfa_args_argvPPc_1;
    11331133char **_X13cfa_args_envpPPc_1;
    1134 signed int _X17cfa_main_returnedi_1 = ((signed int )0);
     1134__attribute__ ((weak)) extern signed int _X17cfa_main_returnedi_1;
    11351135signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
    11361136    __attribute__ ((unused)) signed int _X12_retval_maini_1;
     
    11491149    signed int _tmp_cp_ret6;
    11501150    signed int _X3reti_2 = (((void)(_tmp_cp_ret6=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret6);
    1151     {
    1152         ((void)(_X17cfa_main_returnedi_1=((signed int )1)));
     1151    if ( ((&_X17cfa_main_returnedi_1)!=((signed int *)0)) ) {
     1152        {
     1153            ((void)(_X17cfa_main_returnedi_1=((signed int )1)));
     1154        }
     1155
    11531156    }
    11541157
  • tests/.expect/gccExtensions.arm64.txt

    ref3c383 rd672350  
    324324char **_X13cfa_args_argvPPc_1;
    325325char **_X13cfa_args_envpPPc_1;
    326 signed int _X17cfa_main_returnedi_1 = ((signed int )0);
     326__attribute__ ((weak)) extern signed int _X17cfa_main_returnedi_1;
    327327signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
    328328    __attribute__ ((unused)) signed int _X12_retval_maini_1;
     
    341341    signed int _tmp_cp_ret6;
    342342    signed int _X3reti_2 = (((void)(_tmp_cp_ret6=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret6);
    343     {
    344         ((void)(_X17cfa_main_returnedi_1=((signed int )1)));
     343    if ( ((&_X17cfa_main_returnedi_1)!=((signed int *)0)) ) {
     344        {
     345            ((void)(_X17cfa_main_returnedi_1=((signed int )1)));
     346        }
     347
    345348    }
    346349
  • tests/.expect/random.arm64.txt

    ref3c383 rd672350  
    11õ
    22=
    3 V
     3K
    44-911259971
    556
    6 -4
     611
    771232105397
    880
    9 18
     911
    1010-914096085
    11111
    12 15
     1220
    13132077092859
    14141
    15 11
     1512
    16160.677254
    17170.678106775246139
  • tests/Makefile.am

    ref3c383 rd672350  
    6666PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
    6767
    68 .PHONY: list .validate
    69 .INTERMEDIATE: .validate .validate.cfa
     68.PHONY: list .validate .test_makeflags
     69.INTERMEDIATE: .validate .validate.cfa .test_makeflags
    7070EXTRA_PROGRAMS = avl_test linkonce .dummy_hack # build but do not install
    7171EXTRA_DIST = test.py \
     
    123123        @+${TEST_PY} --list ${concurrent}
    124124
     125.test_makeflags:
     126        @echo "${MAKEFLAGS}"
     127
    125128.validate: .validate.cfa
    126129        $(CFACOMPILE) .validate.cfa -fsyntax-only -Wall -Wextra -Werror
  • tests/collections/.expect/string-api-coverage.txt

    ref3c383 rd672350  
    11hello hello hello
     2
     3hello
    24true false
    35true false
  • tests/collections/.expect/string-gc.txt

    ref3c383 rd672350  
    3838x from 5 to 15
    3939y from 5 to 15
     40======================== fillNoCompact
     41about to expand, a = aaa
     42expanded, a = aaa
     43about to expand, a = aaa
     44expanded, a = aaa
     45about to expand, a = aaa
     46expanded, a = aaa
     47about to expand, a = aaa
     48expanded, a = aaa
     49about to expand, a = aaa
     50expanded, a = aaa
  • tests/collections/.expect/vector-err-pass-perm-it-byval.txt

    ref3c383 rd672350  
    1 error: Unique best alternative includes deleted identifier in Generated Cast of:
     1collections/vector-demo.cfa:95:1 error: Unique best alternative includes deleted identifier in Generated Cast of:
    22  Application of
    33    Deleted Expression
  • tests/collections/string-api-coverage.cfa

    ref3c383 rd672350  
    11#include <containers/string.hfa>
     2#include <string_sharectx.hfa>
    23
    34void assertWellFormedHandleList( int maxLen ) { // with(HeapArea)
     
    2526
    2627int main () {
     28
     29    #ifdef STRING_SHARING_OFF
     30    string_sharectx c = { NO_SHARING };
     31    #endif
     32
    2733    string s = "hello";
    2834    string s2 = "hello";
     
    3137
    3238    // IO operator, x2
    33     sout | s | s | s;
     39    sout | s | s | s;  // hello hello hello
     40
     41    // empty ctor then assign
     42    string sxx;
     43    sout | sxx;  // (blank line)
     44    sxx = s;
     45    sout | sxx;  // hello
    3446
    3547    // Comparisons
  • tests/collections/string-gc.cfa

    ref3c383 rd672350  
    22
    33size_t bytesRemaining() {
    4     return DEBUG_string_bytes_avail_until_gc( DEBUG_string_heap );
     4    return DEBUG_string_bytes_avail_until_gc( DEBUG_string_heap() );
    55}
    66
    77size_t heapOffsetStart( string_res & s ) {
    8     const char * startByte = DEBUG_string_heap_start( DEBUG_string_heap );
     8    const char * startByte = DEBUG_string_heap_start( DEBUG_string_heap() );
    99    assert( s.Handle.s >= startByte );
    1010    return s.Handle.s - startByte;
     
    120120}
    121121
     122void fillNoCompact() {
     123    // show that allocating in a heap filled with mostly live strings (no collectable garbage) causes heap growth
     124
     125    sout | "======================== fillNoCompact";
     126
     127    size_t lastTimeBytesAvail = bytesRemaining();
     128    assert( lastTimeBytesAvail >= 200 ); // starting this test with nontrivial room
     129
     130    // mostly fill the pad
     131    string_res a = "aaa";  // will have to be moved
     132    string_res z = "zzz";
     133    for (i; 5) {
     134        while ( bytesRemaining() > 10 ) {
     135            z += ".";
     136        }
     137        sout | "about to expand, a = " | a;
     138        while ( bytesRemaining() <= 10 ) {
     139            z += ".";
     140        }
     141        sout | "expanded, a = " | a;
     142
     143        // each growth gives more usable space than the last
     144        assert( bytesRemaining() > lastTimeBytesAvail );
     145        lastTimeBytesAvail = bytesRemaining();
     146    }
     147}
     148
    122149int main() {
    123150    basicFillCompact();
    124151    fillCompact_withSharedEdits();
     152    fillNoCompact();
    125153}
  • tests/collections/string-overwrite.cfa

    ref3c383 rd672350  
    11#include <containers/string.hfa>
     2#include <string_sharectx.hfa>
    23
    34/*
     
    1112WE = witness end
    1213
    13 The dest does:
     14The test does:
    1415  starts with the entire string being, initially, the alphabet; prints this entire alphabet
    1516  sets up modifier and witness as ranges within it, and prints a visualization of those ranges
     
    2425This API's convention has Start positions being inclusive and end positions being exclusive.
    2526
     27                                v Case number in output
    2628With 1 equivalence class:
    2729MS = ME = WS = WE               1
     
    118120    struct { int ms; int me; int ws; int we; char *replaceWith; char *label; } cases[] = {
    119121        { 12, 14, 10, 20, "xxxxx", "warmup" },
    120 //        { 12, 14, 12, 14, "xxxxx", ""       },  // the bug that got me into this test (should be a dup with case 6)
    121122        { 10, 10, 10, 10, "=====", "1"      },
    122123        { 10, 10, 10, 10, "=="   , ""       },
     
    223224        { 12, 14, 10, 16, "="    , ""       },
    224225        { 12, 14, 10, 16, ""     , ""       },
    225 /*
    226         { , , , , "=====", "NN"     },
    227         {  "=="   , ""       },
    228         {  "="    , ""       },
    229         {  ""     , ""       },
    230 */
    231226    };
    232227    for ( i; sizeof(cases)/sizeof(cases[0]) ) {
     
    238233
    239234
    240 // void f( string & s, string & toEdit ) {
    241 
    242 //     sout | s | "|" | toEdit | "|";
    243 
    244 //     s(14, 16) = "-";
    245 //     sout | s | "|" | toEdit | "|";
    246 // }
    247 
    248235int main() {
     236
     237    #ifdef STRING_SHARING_OFF
     238    string_sharectx c = { NO_SHARING };
     239    #endif
     240
     241
    249242    //          0         1         2
    250243    //          01234567890123456789012345
  • tests/concurrent/mutexstmt/.expect/locks.txt

    ref3c383 rd672350  
    33Start Test: multi lock deadlock/mutual exclusion
    44End Test: multi lock deadlock/mutual exclusion
    5 Start Test: single scoped lock mutual exclusion
    6 End Test: single scoped lock mutual exclusion
    7 Start Test: multi scoped lock deadlock/mutual exclusion
    8 End Test: multi scoped lock deadlock/mutual exclusion
     5Start Test: multi polymorphic lock deadlock/mutual exclusion
     6End Test: multi polymorphic lock deadlock/mutual exclusion
  • tests/concurrent/mutexstmt/locks.cfa

    ref3c383 rd672350  
    33
    44const unsigned int num_times = 10000;
     5
     6Duration default_preemption() { return 0; }
    57
    68single_acquisition_lock m1, m2, m3, m4, m5;
     
    2224}
    2325
     26void refTest( single_acquisition_lock & m ) {
     27        mutex ( m ) {
     28                assert(!insideFlag);
     29                insideFlag = true;
     30                assert(insideFlag);
     31                insideFlag = false;
     32        }
     33}
     34
    2435thread T_Multi {};
    2536
    2637void main( T_Multi & this ) {
    2738        for (unsigned int i = 0; i < num_times; i++) {
     39                refTest( m1 );
    2840                mutex ( m1 ) {
    2941                        assert(!insideFlag);
     
    5971}
    6072
    61 thread T_Mutex_Scoped {};
     73single_acquisition_lock l1;
     74linear_backoff_then_block_lock l2;
     75owner_lock l3;
    6276
    63 void main( T_Mutex_Scoped & this ) {
     77monitor monitor_t {};
     78
     79monitor_t l4;
     80
     81thread T_Multi_Poly {};
     82
     83void main( T_Multi_Poly & this ) {
    6484        for (unsigned int i = 0; i < num_times; i++) {
    65                 {
    66                         scoped_lock(single_acquisition_lock) s{m1};
    67                         count++;
    68                 }
    69                 {
    70                         scoped_lock(single_acquisition_lock) s{m1};
     85                refTest( l1 );
     86                mutex ( l1, l4 ) {
    7187                        assert(!insideFlag);
    7288                        insideFlag = true;
     
    7490                        insideFlag = false;
    7591                }
    76         }
    77 }
    78 
    79 thread T_Multi_Scoped {};
    80 
    81 void main( T_Multi_Scoped & this ) {
    82         for (unsigned int i = 0; i < num_times; i++) {
    83                 {
    84                         scoped_lock(single_acquisition_lock) s{m1};
     92                mutex ( l1, l2, l3 ) {
    8593                        assert(!insideFlag);
    8694                        insideFlag = true;
     
    8896                        insideFlag = false;
    8997                }
    90                 {
    91                         scoped_lock(single_acquisition_lock) s1{m1};
    92                         scoped_lock(single_acquisition_lock) s2{m2};
    93                         scoped_lock(single_acquisition_lock) s3{m3};
    94                         scoped_lock(single_acquisition_lock) s4{m4};
    95                         scoped_lock(single_acquisition_lock) s5{m5};
     98                mutex ( l3, l1, l4 ) {
    9699                        assert(!insideFlag);
    97100                        insideFlag = true;
     
    99102                        insideFlag = false;
    100103                }
    101                 {
    102                         scoped_lock(single_acquisition_lock) s1{m1};
    103                         scoped_lock(single_acquisition_lock) s3{m3};
    104                         assert(!insideFlag);
    105                         insideFlag = true;
    106                         assert(insideFlag);
    107                         insideFlag = false;
    108                 }
    109                 {
    110                         scoped_lock(single_acquisition_lock) s1{m1};
    111                         scoped_lock(single_acquisition_lock) s2{m2};
    112                         scoped_lock(single_acquisition_lock) s4{m4};
    113                         assert(!insideFlag);
    114                         insideFlag = true;
    115                         assert(insideFlag);
    116                         insideFlag = false;
    117                 }
    118                 {
    119                         scoped_lock(single_acquisition_lock) s1{m1};
    120                         scoped_lock(single_acquisition_lock) s3{m3};
    121                         scoped_lock(single_acquisition_lock) s4{m4};
    122                         scoped_lock(single_acquisition_lock) s5{m5};
     104                mutex ( l1, l2, l4 ) {
    123105                        assert(!insideFlag);
    124106                        insideFlag = true;
     
    131113int num_tasks = 10;
    132114int main() {
    133         processor p[10];
     115        processor p[num_tasks - 1];
    134116
    135117        printf("Start Test: single lock mutual exclusion\n");
    136118        {
    137                 T_Mutex t[10];
     119                T_Mutex t[num_tasks];
    138120        }
    139121        assert(count == num_tasks * num_times);
     
    141123        printf("Start Test: multi lock deadlock/mutual exclusion\n");
    142124        {
    143                 T_Multi t[10];
     125                T_Multi t[num_tasks];
    144126        }
    145127        printf("End Test: multi lock deadlock/mutual exclusion\n");
    146        
    147         count = 0;
    148         printf("Start Test: single scoped lock mutual exclusion\n");
     128        printf("Start Test: multi polymorphic lock deadlock/mutual exclusion\n");
    149129        {
    150                 T_Mutex_Scoped t[10];
     130                T_Multi_Poly t[num_tasks];
    151131        }
    152         assert(count == num_tasks * num_times);
    153         printf("End Test: single scoped lock mutual exclusion\n");
    154         printf("Start Test: multi scoped lock deadlock/mutual exclusion\n");
    155         {
    156                 T_Multi_Scoped t[10];
    157         }
    158         printf("End Test: multi scoped lock deadlock/mutual exclusion\n");     
     132        printf("End Test: multi polymorphic lock deadlock/mutual exclusion\n");
    159133}
  • tests/io/many_read.cfa

    ref3c383 rd672350  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // many_read.cfa -- Make sure that multiple concurrent reads to mess up.
     7// many_read.cfa -- Make sure that multiple concurrent reads don't mess up.
    88//
    99// Author           : Thierry Delisle
  • tests/meta/dumpable.cfa

    ref3c383 rd672350  
    7272        }
    7373
    74         if((buf.f_bsize * buf.f_bavail) < 536870912) {
    75                 serr | "Available diskspace is less than ~500Mb: " | (buf.f_bsize * buf.f_bavail);
     74        uint64_t avail = buf.f_bavail;
     75        avail *= buf.f_bsize;
     76        if(avail < 536870912_l64u) {
     77                serr | "Available diskspace is less than ~500Mb: " | avail;
    7678        }
    7779
  • tests/pybin/settings.py

    ref3c383 rd672350  
    155155        global generating
    156156        global make
     157        global make_jobfds
    157158        global output_width
    158159        global timeout
     
    168169        generating   = options.regenerate_expected
    169170        make         = ['make']
     171        make_jobfds  = []
    170172        output_width = 24
    171173        timeout      = Timeouts(options.timeout, options.global_timeout)
     
    177179                os.putenv('DISTCC_LOG', os.path.join(BUILDDIR, 'distcc_error.log'))
    178180
    179 def update_make_cmd(force, jobs):
     181def update_make_cmd(flags):
    180182        global make
    181 
    182         make = ['make'] if not force else ['make', "-j%i" % jobs]
     183        make = ['make', *flags]
     184
     185def update_make_fds(r, w):
     186        global make_jobfds
     187        make_jobfds = (r, w)
    183188
    184189def validate():
     
    187192        global distcc
    188193        distcc       = "DISTCC_CFA_PATH=~/.cfadistcc/%s/cfa" % tools.config_hash()
    189         errf = os.path.join(BUILDDIR, ".validate.err")
    190         make_ret, out = tools.make( ".validate", error_file = errf, output_file=subprocess.DEVNULL, error=subprocess.DEVNULL )
     194        make_ret, out, err = tools.make( ".validate", output_file=subprocess.PIPE, error=subprocess.PIPE )
    191195        if make_ret != 0:
    192                 with open (errf, "r") as myfile:
    193                         error=myfile.read()
    194196                print("ERROR: Invalid configuration %s:%s" % (arch.string, debug.string), file=sys.stderr)
    195                 print("       verify returned : \n%s" % error, file=sys.stderr)
    196                 tools.rm(errf)
     197                print("       verify returned : \n%s" % err, file=sys.stderr)
    197198                sys.exit(1)
    198 
    199         tools.rm(errf)
    200199
    201200def prep_output(tests):
  • tests/pybin/tools.py

    ref3c383 rd672350  
    2323
    2424# helper functions to run terminal commands
    25 def sh(*cmd, timeout = False, output_file = None, input_file = None, input_text = None, error = subprocess.STDOUT, ignore_dry_run = False):
     25def sh(*cmd, timeout = False, output_file = None, input_file = None, input_text = None, error = subprocess.STDOUT, ignore_dry_run = False, pass_fds = []):
    2626        try:
    2727                cmd = list(cmd)
     
    6565                                **({'input' : bytes(input_text, encoding='utf-8')} if input_text else {'stdin' : input_file}),
    6666                                stdout  = output_file,
    67                                 stderr  = error
     67                                stderr  = error,
     68                                pass_fds = pass_fds
    6869                        ) as proc:
    6970
    7071                                try:
    71                                         out, _ = proc.communicate(
     72                                        out, errout = proc.communicate(
    7273                                                timeout = settings.timeout.single if timeout else None
    7374                                        )
    7475
    75                                         return proc.returncode, out.decode("latin-1") if out else None
     76                                        return proc.returncode, out.decode("latin-1") if out else None, errout.decode("latin-1") if errout else None
    7677                                except subprocess.TimeoutExpired:
    7778                                        if settings.timeout2gdb:
    7879                                                print("Process {} timeout".format(proc.pid))
    7980                                                proc.communicate()
    80                                                 return 124, str(None)
     81                                                return 124, str(None), "Subprocess Timeout 2 gdb"
    8182                                        else:
    8283                                                proc.send_signal(signal.SIGABRT)
    8384                                                proc.communicate()
    84                                                 return 124, str(None)
     85                                                return 124, str(None), "Subprocess Timeout 2 gdb"
    8586
    8687        except Exception as ex:
     
    105106                return (False, "No file")
    106107
    107         code, out = sh("file", fname, output_file=subprocess.PIPE)
     108        code, out, err = sh("file", fname, output_file=subprocess.PIPE)
    108109        if code != 0:
    109                 return (False, "'file EXPECT' failed with code {}".format(code))
     110                return (False, "'file EXPECT' failed with code {} '{}'".format(code, err))
    110111
    111112        match = re.search(".*: (.*)", out)
     
    190191        ]
    191192        cmd = [s for s in cmd if s]
    192         return sh(*cmd, output_file=output_file, error=error)
     193        return sh(*cmd, output_file=output_file, error=error, pass_fds=settings.make_jobfds)
    193194
    194195def make_recon(target):
     
    241242# move a file
    242243def mv(source, dest):
    243         ret, _ = sh("mv", source, dest)
     244        ret, _, _ = sh("mv", source, dest)
    244245        return ret
    245246
    246247# cat one file into the other
    247248def cat(source, dest):
    248         ret, _ = sh("cat", source, output_file=dest)
     249        ret, _, _ = sh("cat", source, output_file=dest)
    249250        return ret
    250251
     
    289290#               system
    290291################################################################################
     292def jobserver_version():
     293        make_ret, out, err = sh('make', '.test_makeflags', '-j2', output_file=subprocess.PIPE, error=subprocess.PIPE)
     294        if make_ret != 0:
     295                print("ERROR: cannot find Makefile jobserver version", file=sys.stderr)
     296                print("       test returned : {} '{}'".format(make_ret, err), file=sys.stderr)
     297                sys.exit(1)
     298
     299        re_jobs = re.search("--jobserver-(auth|fds)", out)
     300        if not re_jobs:
     301                print("ERROR: cannot find Makefile jobserver version", file=sys.stderr)
     302                print("       MAKEFLAGS are : '{}'".format(out), file=sys.stderr)
     303                sys.exit(1)
     304
     305        return "--jobserver-{}".format(re_jobs.group(1))
     306
     307def prep_recursive_make(N):
     308        if N < 2:
     309                return []
     310
     311        # create the pipe
     312        (r, w) = os.pipe()
     313
     314        # feel it with N-1 tokens, (Why N-1 and not N, I don't know it's in the manpage for make)
     315        os.write(w, b'+' * (N - 1));
     316
     317        # prep the flags for make
     318        make_flags = ["-j{}".format(N), "--jobserver-auth={},{}".format(r, w)]
     319
     320        # tell make about the pipes
     321        os.environ["MAKEFLAGS"] = os.environ["MFLAGS"] = " ".join(make_flags)
     322
     323        # make sure pass the pipes to our children
     324        settings.update_make_fds(r, w)
     325
     326        return make_flags
     327
     328def prep_unlimited_recursive_make():
     329        # prep the flags for make
     330        make_flags = ["-j"]
     331
     332        # tell make about the pipes
     333        os.environ["MAKEFLAGS"] = os.environ["MFLAGS"] = "-j"
     334
     335        return make_flags
     336
     337
     338def eval_hardware():
     339        # we can create as many things as we want
     340        # how much hardware do we have?
     341        if settings.distribute:
     342                # remote hardware is allowed
     343                # how much do we have?
     344                ret, jstr, _ = sh("distcc", "-j", output_file=subprocess.PIPE, ignore_dry_run=True)
     345                return int(jstr.strip()) if ret == 0 else multiprocessing.cpu_count()
     346        else:
     347                # remote isn't allowed, use local cpus
     348                return multiprocessing.cpu_count()
     349
    291350# count number of jobs to create
    292 def job_count( options, tests ):
     351def job_count( options ):
    293352        # check if the user already passed in a number of jobs for multi-threading
    294         if not options.jobs:
    295                 make_flags = os.environ.get('MAKEFLAGS')
    296                 force = bool(make_flags)
    297                 make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None
    298                 if make_jobs_fds :
    299                         tokens = os.read(int(make_jobs_fds.group(2)), 1024)
    300                         options.jobs = len(tokens)
    301                         os.write(int(make_jobs_fds.group(3)), tokens)
    302                 else :
    303                         if settings.distribute:
    304                                 ret, jstr = sh("distcc", "-j", output_file=subprocess.PIPE, ignore_dry_run=True)
    305                                 if ret == 0:
    306                                         options.jobs = int(jstr.strip())
    307                                 else :
    308                                         options.jobs = multiprocessing.cpu_count()
    309                         else:
    310                                 options.jobs = multiprocessing.cpu_count()
     353        make_env = os.environ.get('MAKEFLAGS')
     354        make_flags = make_env.split() if make_env else None
     355        jobstr = jobserver_version()
     356
     357        if options.jobs and make_flags:
     358                print('WARNING: -j options should not be specified when called form Make', file=sys.stderr)
     359
     360        # Top level make is calling the shots, just follow
     361        if make_flags:
     362                # do we have -j and --jobserver-...
     363                jobopt = None
     364                exists_fds = None
     365                for f in make_flags:
     366                        jobopt = f if f.startswith("-j") else jobopt
     367                        exists_fds = f if f.startswith(jobstr) else exists_fds
     368
     369                # do we have limited parallelism?
     370                if exists_fds :
     371                        try:
     372                                rfd, wfd = tuple(exists_fds.split('=')[1].split(','))
     373                        except:
     374                                print("ERROR: jobserver has unrecoginzable format, was '{}'".format(exists_fds), file=sys.stderr)
     375                                sys.exit(1)
     376
     377                        # read the token pipe to count number of available tokens and restore the pipe
     378                        # this assumes the test suite script isn't invoked in parellel with something else
     379                        tokens = os.read(int(rfd), 65536)
     380                        os.write(int(wfd), tokens)
     381
     382                        # the number of tokens is off by one for obscure but well documented reason
     383                        # see man make for more details
     384                        options.jobs = len(tokens) + 1
     385
     386                # do we have unlimited parallelism?
     387                elif jobopt and jobopt != "-j1":
     388                        # check that this actually make sense
     389                        if jobopt != "-j":
     390                                print("ERROR: -j option passed by make but no {}, was '{}'".format(jobstr, jobopt), file=sys.stderr)
     391                                sys.exit(1)
     392
     393                        options.jobs = eval_hardware()
     394                        flags = prep_unlimited_recursive_make()
     395
     396
     397                # then no parallelism
     398                else:
     399                        options.jobs = 1
     400
     401                # keep all flags make passed along, except the weird 'w' which is about subdirectories
     402                flags = [f for f in make_flags if f != 'w']
     403
     404        # Arguments are calling the shots, fake the top level make
     405        elif options.jobs :
     406
     407                # make sure we have a valid number of jobs that corresponds to user input
     408                if options.jobs < 0 :
     409                        print('ERROR: Invalid number of jobs', file=sys.stderr)
     410                        sys.exit(1)
     411
     412                flags = prep_recursive_make(options.jobs)
     413
     414        # Arguments are calling the shots, fake the top level make, but 0 is a special case
     415        elif options.jobs == 0:
     416                options.jobs = eval_hardware()
     417                flags = prep_unlimited_recursive_make()
     418
     419        # No one says to run in parallel, then don't
    311420        else :
    312                 force = True
    313 
    314         # make sure we have a valid number of jobs that corresponds to user input
    315         if options.jobs <= 0 :
    316                 print('ERROR: Invalid number of jobs', file=sys.stderr)
    317                 sys.exit(1)
    318 
    319         return min( options.jobs, len(tests) ), force
     421                options.jobs = 1
     422                flags = []
     423
     424        # Make sure we call make as expected
     425        settings.update_make_cmd( flags )
     426
     427        # return the job count
     428        return options.jobs
    320429
    321430# enable core dumps for all the test children
     
    334443        distcc_hash = os.path.join(settings.SRCDIR, '../tools/build/distcc_hash')
    335444        config = "%s-%s" % (settings.arch.target, settings.debug.path)
    336         _, out = sh(distcc_hash, config, output_file=subprocess.PIPE, ignore_dry_run=True)
     445        _, out, _ = sh(distcc_hash, config, output_file=subprocess.PIPE, ignore_dry_run=True)
    337446        return out.strip()
    338447
     
    374483
    375484        if not os.path.isfile(core):
    376                 return 1, "ERR No core dump (limit soft: {} hard: {})".format(*resource.getrlimit(resource.RLIMIT_CORE))
     485                return 1, "ERR No core dump, expected '{}' (limit soft: {} hard: {})".format(core, *resource.getrlimit(resource.RLIMIT_CORE))
    377486
    378487        try:
    379                 return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output_file=subprocess.PIPE)
     488                ret, out, err = sh('gdb', '-n', path, core, '-batch', '-x', cmd, output_file=subprocess.PIPE)
     489                if ret == 0:
     490                        return 0, out
     491                else:
     492                        return 1, err
    380493        except:
    381494                return 1, "ERR Could not read core with gdb"
  • tests/test.py

    ref3c383 rd672350  
    140140        parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true')
    141141        parser.add_argument('--archive-errors', help='If called with a valid path, on test crashes the test script will copy the core dump and the executable to the specified path.', type=str, default='')
    142         parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int)
     142        parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously, 0 (default) for unlimited', nargs='?', const=0, type=int)
    143143        parser.add_argument('--list-comp', help='List all valide arguments', action='store_true')
    144144        parser.add_argument('--list-dist', help='List all tests for distribution', action='store_true')
     
    195195        # build, skipping to next test on error
    196196        with Timed() as comp_dur:
    197                 make_ret, _ = make( test.target(), output_file=subprocess.DEVNULL, error=out_file, error_file = err_file )
     197                make_ret, _, _ = make( test.target(), output_file=subprocess.DEVNULL, error=out_file, error_file = err_file )
    198198
    199199        # ----------
     
    208208                                if settings.dry_run or is_exe(exe_file):
    209209                                        # run test
    210                                         retcode, _ = sh(exe_file, output_file=out_file, input_file=in_file, timeout=True)
     210                                        retcode, _, _ = sh(exe_file, output_file=out_file, input_file=in_file, timeout=True)
    211211                                else :
    212212                                        # simply cat the result into the output
     
    226226                        else :
    227227                                # fetch return code and error from the diff command
    228                                 retcode, error = diff(cmp_file, out_file)
     228                                retcode, error, _ = diff(cmp_file, out_file)
    229229
    230230                else:
     
    366366                        print(os.path.relpath(t.expect(), settings.SRCDIR), end=' ')
    367367                        print(os.path.relpath(t.input() , settings.SRCDIR), end=' ')
    368                         code, out = make_recon(t.target())
     368                        code, out, err = make_recon(t.target())
    369369
    370370                        if code != 0:
    371                                 print('ERROR: recond failed for test {}'.format(t.target()), file=sys.stderr)
     371                                print('ERROR: recond failed for test {}: {} \'{}\''.format(t.target(), code, err), file=sys.stderr)
    372372                                sys.exit(1)
    373373
     
    417417                        if is_empty(t.expect()):
    418418                                print('WARNING: test "{}" has empty .expect file'.format(t.target()), file=sys.stderr)
     419
     420        options.jobs = job_count( options )
    419421
    420422        # for each build configurations, run the test
     
    430432                        local_tests = settings.ast.filter( tests )
    431433                        local_tests = settings.arch.filter( local_tests )
    432                         options.jobs, forceJobs = job_count( options, local_tests )
    433                         settings.update_make_cmd(forceJobs, options.jobs)
    434434
    435435                        # check the build configuration works
    436436                        settings.validate()
     437                        jobs = min(options.jobs, len(local_tests))
    437438
    438439                        # print configuration
     
    440441                                'Regenerating' if settings.generating else 'Running',
    441442                                len(local_tests),
    442                                 options.jobs,
     443                                jobs,
    443444                                settings.ast.string,
    444445                                settings.arch.string,
     
    450451
    451452                        # otherwise run all tests and make sure to return the correct error code
    452                         failed = run_tests(local_tests, options.jobs)
     453                        failed = run_tests(local_tests, jobs)
    453454                        if failed:
    454455                                if not settings.continue_:
Note: See TracChangeset for help on using the changeset viewer.