Ticket #4699: trac_4699_new_bin.patch

File trac_4699_new_bin.patch, 14.6 KB (added by gfurnish, 13 years ago)

apply instead of other patches

  • sage-ptest

    # HG changeset patch
    # User Gary Furnish <gfurnish@gfurnish.net>
    # Date 1229000980 28800
    # Node ID b7526872436f885c8878f52981ecd639c7b00639
    # Parent  be25cc5531c2350fa15158cc88c1f6bd21420665
    4699
    
    diff -r be25cc5531c2 -r b7526872436f sage-ptest
    a b  
    2626print 'TeX files: ' + str(checktex)
    2727
    2828abort = False
     29
     30def run(x):
     31    global abort
     32    try:
     33        while True:
     34            filemutex.acquire()
     35            if len(files)!=0 and abort==False:
     36                F = files.pop()
     37                filemutex.release()
     38                base, ext = os.path.splitext(F)
     39                if use_sage_only or ext == '.sage':
     40                    e = test(F, 'doctest_tex ' + opts)
     41                elif ext in ['.py', '.pyx', '.tex', '.pxi']:
     42                    e = test(F, 'doctest '+opts)
     43                else:
     44                    continue # prefer silence to: raise TypeError, "Unknown File %s" % F
     45                if e==-2:
     46                    raise KeyboardInterrupt
     47            else:
     48               filemutex.release()
     49               return
     50    except KeyboardInterrupt:
     51        abort = True
     52        return
     53
     54def abspath(x):
     55    """
     56    This function returns the absolute path (adjusted for NFS)
     57    """
     58    return strip_automount_prefix(os.path.abspath(x))
     59
     60def strip_automount_prefix(filename):
     61    """
     62    Strip prefixes added on automounted filesystems in some cases,
     63    which make the absolute path appear hidden.
     64
     65    AUTHOR:
     66        -- Kate Minola
     67    """
     68    sep = os.path.sep
     69    str = filename.split(sep,2)
     70    if len(str) < 2:
     71        new = sep
     72    else:
     73        new = sep + str[1]
     74    if os.path.exists(new):
     75        inode1 = os.stat(filename)[1]
     76        inode2 = os.stat(new)[1]
     77        if inode1 == inode2:
     78            filename = new
     79    return filename
     80
     81def abs(f):
     82    """
     83    Return the test command for the file
     84    """
     85    return "sage -t %s %s"%(opts, abspath(f)[len(SAGE_ROOT)+1:])
     86
     87def abs_sage_path(f):
     88    """
     89    Return the absolute path, relative to the sage root directory
     90    """
     91    return abspath(f)[len(SAGE_ROOT)+1:]
     92
     93def skip(F):
     94    """
     95    Returns true if the file should not be tested
     96    """
     97    if not os.path.exists(F):
     98        return True
     99    G = abspath(F)
     100    i = G.rfind('/')
     101    if os.path.exists('%s/nodoctest.py'%G[:i]):
     102        printmutex.acquire()
     103        print "%s (skipping) -- nodoctest.py file in directory"%abs(F)
     104        printmutex.release()
     105        return True
     106    filenm = os.path.split(F)[1]
     107    if filenm == "all.py" or filenm == "__init__.py" \
     108          or filenm[0] == '.' or '/.' in G.lstrip('/.') or \
     109          'nodoctest' in open(G).read():
     110        return True
     111    if not (os.path.splitext(F)[1] in ['.py', '.pyx', '.tex', '.pxi', '.sage']):
     112        return True
     113    return False
     114
     115def test_file(F):
     116    """
     117    This is the function that actually tests a file
     118    """
     119    t = time.time()
     120    outfile = tempfile.NamedTemporaryFile()
     121    base, ext = os.path.splitext(F)
     122    if use_sage_only or ext == '.sage':
     123        cmd =  'doctest_tex ' + opts
     124    elif ext in ['.py', '.pyx', '.tex', '.pxi']:
     125        cmd = 'doctest '+opts
     126    filestr = os.path.split(F)[1]
     127    for i in range(0,numiteration):
     128        os.chdir(os.path.dirname(F))
     129        s = 'bash -c "%s/local/bin/sage-%s %s > %s" ' %(SAGE_ROOT, cmd, filestr, outfile.name)
     130        try:
     131            ret = os.system(s)
     132            if ret>=256:
     133                ret=ret/256
     134            ret = -ret
     135        except:
     136            ol = outfile.read()
     137            return (-5, 0, ol)
     138        ol = outfile.read()
     139        if ret != 0:
     140            break
     141    finished_time = time.time() - t
     142    return (F, ret, finished_time, ol)
     143
     144def process_result(result):
     145    """
     146    This file takes a tuple in the form
     147    (F, ret, finished_time, ol)
     148    and processes it to display/log the appropriate output.
     149    """
     150    global failed
     151    F = result[0]
     152    ret = result[1]
     153    finished_time = result[2]
     154    ol = result[3]
     155    if ret != 0:
     156        if ret == -4:
     157            numfail = ol.count('Expected:') + ol.count('Expected nothing') + ol.count('Exception raised:')
     158            failed.append(abs(F)+(" # %s doctests failed" % numfail))
     159            ret = numfail
     160        elif ret == -3:
     161            failed.append(abs(F)+" # Segfault")
     162        elif ret == -2:
     163            failed.append(abs(F)+" # KeyboardInterrupt")
     164        elif ret == -1:
     165            failed.append(abs(F)+" # File not found")
     166        else:
     167            failed.append(abs(F))
     168    print abs(F)
     169    if ol!="" and (not ol.isspace()):
     170        if (ol[len(ol)-1]=="\n"):
     171            ol=ol[0:len(ol)-1]
     172        print ol
     173    time_dict[abs_sage_path(F)] = finished_time
     174    print "\t [%.1f s]"%(finished_time)
     175
     176def infiles_cmp(a,b):
     177    """
     178    This compare function is used to sort the list of filenames by the time they take to run
     179    """
     180    if time_dict.has_key(abs_sage_path(a)):
     181        if time_dict.has_key(abs_sage_path(b)):
     182            return cmp(time_dict[abs_sage_path(a)],time_dict[abs_sage_path(b)])
     183        else:
     184            return 1
     185    else:
     186        return -1
     187
     188def populatefilelist(filelist):
     189    """
     190    This populates the file list by expanding directories into lists of files
     191    """
     192    global CUR
     193    filemutex.acquire()
     194    for FF in filelist:
     195        if os.path.isfile(FF):
     196            if skip(FF):
     197                continue
     198            if not os.path.isabs(FF):
     199                cwd = os.getcwd()
     200                files.append(cwd + '/' +  FF)
     201            else:
     202                files.append(FF)
     203            continue
     204        curdir = os.getcwd()
     205        walkdir = os.path.join(CUR,FF)
     206        for root, dirs, lfiles in os.walk(walkdir):
     207            for F in lfiles:
     208                base, ext = os.path.splitext(F)
     209                if use_sage_only and ext == '.sage':
     210                    continue
     211                elif not (ext in ['.py', '.pyx', '.tex', '.pxi']):
     212                    continue
     213                elif '__nodoctest__' in files:
     214                    continue
     215                appendstr = os.path.join(root,F)
     216                if skip(appendstr):
     217                    continue
     218                files.append(appendstr)
     219            for D in dirs:
     220                if '#' in D or '/notes' in D:
     221                    dirs.remove(D)
     222    if checktex:
     223        files.insert(0,SAGE_ROOT+"/devel/doc/tut/tut.tex")
     224        files.insert(0,SAGE_ROOT+"/devel/doc/prog/prog.tex")
     225        files.insert(0,SAGE_ROOT+"/devel/doc/const/const.tex")
     226    filemutex.release()
     227    return 0
     228
     229
     230
     231
     232
     233
     234
     235
     236
    29237
    30238for gr in range(0,numglobaliteration):
    31239
     
    72280        else:
    73281            print "No cached timings exist; will create upon successful finish."
    74282    done = False
    75     threadlist = list()
    76283
    77284    numthreads = int(argv[1])
    78285
    79     class tester(threading.Thread):
    80         def __init__(self):
    81             threading.Thread.__init__(self)
    82         def run(x):
    83             global abort
    84             try:
    85                 while True:
    86                     filemutex.acquire()
    87                     if len(files)!=0 and abort==False:
    88                         F = files.pop()
    89                         filemutex.release()
    90                         base, ext = os.path.splitext(F)
    91                         if use_sage_only or ext == '.sage':
    92                             e = test(F, 'doctest_tex ' + opts)
    93                         elif ext in ['.py', '.pyx', '.tex', '.pxi']:
    94                             e = test(F, 'doctest '+opts)
    95                         else:
    96                             continue # prefer silence to: raise TypeError, "Unknown File %s" % F
    97                         if e==-2:
    98                             raise KeyboardInterrupt
    99                     else:
    100                        filemutex.release()
    101                        return
    102             except KeyboardInterrupt:
    103                 abort = True
    104                 return
    105 
    106 
    107     def launchthreads(x):
    108         for i in range(0,x):
    109             curtester = tester()
    110             threadlist.append(curtester)
    111             curtester.start()
    112 
    113     def abspath(x):
    114     #     return os.path.abspath(x)
    115         return strip_automount_prefix(os.path.abspath(x))
    116 
    117     def strip_automount_prefix(filename):
    118         """
    119         Strip prefixes added on automounted filesystems in some cases,
    120         which make the absolute path appear hidden.
    121        
    122         AUTHOR:
    123             -- Kate Minola
    124         """
    125         sep = os.path.sep
    126         str = filename.split(sep,2)
    127         if len(str) < 2:
    128             new = sep
    129         else:
    130             new = sep + str[1]
    131         if os.path.exists(new):
    132             inode1 = os.stat(filename)[1]
    133             inode2 = os.stat(new)[1]
    134             if inode1 == inode2:
    135                 filename = new
    136         return filename
    137 
    138286    CUR = abspath(os.getcwd())
    139 
    140 
    141     def abs(f):
    142         return "sage -t %s %s"%(opts, abspath(f)[len(SAGE_ROOT)+1:])
    143 
    144     def abs_sage_path(f):
    145         return abspath(f)[len(SAGE_ROOT)+1:]
    146 
    147     def skip(F):
    148         if not os.path.exists(F):
    149             return True
    150         G = abspath(F)
    151         i = G.rfind('/')
    152         if os.path.exists('%s/nodoctest.py'%G[:i]):
    153             printmutex.acquire()
    154             print "%s (skipping) -- nodoctest.py file in directory"%abs(F)
    155             printmutex.release()
    156             return True
    157         filenm = os.path.split(F)[1]
    158         if filenm == "all.py" or filenm == "__init__.py" \
    159               or filenm[0] == '.' or '/.' in G.lstrip('/.') or \
    160               'nodoctest' in open(G).read():
    161             return True
    162 
    163         return False
    164287
    165288    failed = []
    166289
     
    169292    if not os.path.exists(TMP):
    170293        os.makedirs(TMP)
    171294
    172     def test(F, cmd):
    173         t = time.time()
    174         if not skip(F):
    175             outfile = tempfile.NamedTemporaryFile()
    176             filestr = "./" + abspath(F)[len(CUR)+1:]
    177     #        filestr = F
    178             filestr = os.path.split(F)[1]
    179             for i in range(0,numiteration):
    180                 os.chdir(os.path.dirname(F))
    181                 s = 'bash -c "%s/local/bin/sage-%s %s > %s" ' %(SAGE_ROOT, cmd, filestr, outfile.name)
    182                 try:
    183                     ret = os.system(s)
    184                     if ret>=256:
    185                         ret=ret/256
    186                     ret = -ret
    187                 except:
    188                     printmutex.acquire()
    189                     failed.append(abs(F))
    190                     printmutex.release()
    191                     break
    192                 ol = outfile.read()
    193                 if ret != 0:
    194                     printmutex.acquire()
    195                     if ret == -4:
    196                         numfail = ol.count('Expected:') + ol.count('Expected nothing') + ol.count('Exception raised:')
    197                         failed.append(abs(F)+(" # %s doctests failed" % numfail))
    198                         ret = numfail
    199                     elif ret == -3:
    200                         failed.append(abs(F)+" # Segfault")
    201                     elif ret == -2:
    202                         failed.append(abs(F)+" # KeyboardInterrupt")
    203                     elif ret == -1:
    204                         failed.append(abs(F)+" # File not found")
    205                     else:
    206                         failed.append(abs(F))
    207                     printmutex.release()
    208                     break
    209         else:
    210             return 0
    211         finished_time = time.time() - t
    212         printmutex.acquire()
    213         print abs(F)
    214         if ol!="" and (not ol.isspace()):
    215             print ol
    216         time_dict[abs_sage_path(F)] = finished_time
    217         print "\t [%.1f s]"%(finished_time)
    218         printmutex.release()
    219         return ret
    220295
    221 
    222     def infiles_cmp(a,b):
    223         #This compare function is used to sort the list of filenames by the time they take to run
    224         if time_dict.has_key(abs_sage_path(a)):
    225             if time_dict.has_key(abs_sage_path(b)):
    226                 return cmp(time_dict[abs_sage_path(a)],time_dict[abs_sage_path(b)])
    227             else:
    228                 return 1
    229         else:
    230             return -1
    231 
    232     def populatefilelist(filelist):
    233         global CUR
    234         filemutex.acquire()
    235         for FF in filelist:
    236             if os.path.isfile(FF):
    237                 if not os.path.isabs(FF):
    238                     cwd = os.getcwd()
    239                     files.append(cwd + '/' +  FF)
    240                 else:
    241                     files.append(FF)
    242                 continue
    243             curdir = os.getcwd()
    244             walkdir = os.path.join(CUR,FF)
    245             for root, dirs, lfiles in os.walk(walkdir):
    246                 for F in lfiles:
    247                     base, ext = os.path.splitext(F)
    248                     if use_sage_only and ext == '.sage':
    249                         continue
    250                     elif not (ext in ['.py', '.pyx', '.tex', '.pxi']):
    251                         continue
    252                     elif '__nodoctest__' in files:
    253                         continue
    254                     appendstr = os.path.join(root,F)
    255                     files.append(appendstr)
    256                 for D in dirs:
    257                     if '#' in D or '/notes' in D:
    258                         dirs.remove(D)
    259         if checktex:
    260             files.insert(0,SAGE_ROOT+"/devel/doc/tut/tut.tex")
    261             files.insert(0,SAGE_ROOT+"/devel/doc/prog/prog.tex")
    262             files.insert(0,SAGE_ROOT+"/devel/doc/const/const.tex")
    263         filemutex.release()
    264         return 0
    265296    populatefilelist(infiles)
    266297    #Sort the files by test time
    267298    files.sort(infiles_cmp)
    268     launchthreads(numthreads)
    269 
    270 
    271      
     299    files.reverse()
     300    interrupt = False
     301    try:
     302        from processing import Pool
     303        p = Pool(numthreads)
     304        for r in p.imap_unordered(test_file, files):
     305            #The format is  (F, ret, finished_time, ol)
     306            process_result(r)
     307    except KeyboardInterrupt:
     308        interrupt = True
     309        pass
    272310    print " "
    273311    print "-"*int(70)
    274312
    275     for t in threadlist:
    276         t.join()
    277313    os.chdir(CUR)
    278314   
    279315    if len(failed) == 0:
    280         print "All tests passed!"
     316        if interrupt == False:
     317            print "All tests passed!"
     318        else:
     319            print "Keyboard Interrupt: All tests that ran passed."
    281320        #Only update timings if we are doing something standard
    282321        if opts=="-long" or len(opts)==0:
    283322            with open(time_file_name,"w") as time_file:
    284323                pickle.dump(time_dict, time_file)
    285324                print "Timings have been updated."
    286325    else:
     326        if interrupt:
     327            print "Keyboard Interrupt, not all tests ran"
    287328        print "\nThe following tests failed:\n"
    288329        for i in range(len(failed)):
    289330               print "\t", failed[i]