Ignore:
File:
1 edited

Legend:

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

    r3b4571b rf3b9efc  
     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 spacific 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                settings.debug.flags,
     79                flags,
     80                target,
     81                redirects
     82        ])
     83        return sh(cmd)
     84
     85################################################################################
     86#               file handling
     87################################################################################
     88
     89# helper function to replace patterns in a file
     90def file_replace(fname, pat, s_after):
     91    # first, see if the pattern is even in the file.
     92    with open(fname) as f:
     93        if not any(re.search(pat, line) for line in f):
     94            return # pattern does not occur in file so we are done.
     95
     96    # pattern is in the file, so perform replace operation.
     97    with open(fname) as f:
     98        out_fname = fname + ".tmp"
     99        out = open(out_fname, "w")
     100        for line in f:
     101            out.write(re.sub(pat, s_after, line))
     102        out.close()
     103        os.rename(out_fname, fname)
     104
     105# helper function to check if a files contains only a specific string
     106def fileContainsOnly(file, text) :
     107        with open(file) as f:
     108                ff = f.read().strip()
     109                result = ff == text.strip()
     110
     111                return result;
     112
     113# check whether or not a file is executable
     114def fileIsExecutable(file) :
     115        try :
     116                fileinfo = os.stat(file)
     117                return bool(fileinfo.st_mode & stat.S_IXUSR)
     118        except Exception as inst:
     119                print(type(inst))    # the exception instance
     120                print(inst.args)     # arguments stored in .args
     121                print(inst)
     122                return False
     123
     124# transform path to canonical form
     125def canonicalPath(path):
     126        return os.path.join('.', os.path.normpath(path) )
     127
     128# compare path even if form is different
     129def pathCmp(lhs, rhs):
     130        return canonicalPath( lhs ) == canonicalPath( rhs )
     131
     132# walk all files in a path
     133def pathWalk( op ):
     134        def step(_, dirname, names):
     135                for name in names:
     136                        path = os.path.join(dirname, name)
     137
     138                        op( path )
     139
     140        # Start the walk
     141        os.path.walk('.', step, '')
     142
     143################################################################################
     144#               system
     145################################################################################
     146
     147# parses the Makefile to find the machine type (32-bit / 64-bit)
     148def getMachineType():
     149        sh('echo "void ?{}(int&a,int b){}int main(){return 0;}" > .dummy.c')
     150        ret, out = make('.dummy', silent = True)
     151
     152        if ret != 0:
     153                print("Failed to identify architecture:")
     154                print(out)
     155                print("Stopping")
     156                rm( (".dummy.c",".dummy") )
     157                sys.exit(1)
     158
     159        _, out = sh("file .dummy", print2stdout=False)
     160        rm( (".dummy.c",".dummy") )
     161
     162        if settings.dry_run :
     163                return 'x64'
     164
     165        return re.search(r"[^,]+,([^,]+),", out).group(1).strip()
     166
     167# count number of jobs to create
     168def jobCount( options, tests ):
     169        # check if the user already passed in a number of jobs for multi-threading
     170        make_flags = os.environ.get('MAKEFLAGS')
     171        make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None
     172        if make_jobs_fds :
     173                tokens = os.read(int(make_jobs_fds.group(2)), 1024)
     174                options.jobs = len(tokens)
     175                os.write(int(make_jobs_fds.group(3)), tokens)
     176        else :
     177                options.jobs = multiprocessing.cpu_count()
     178
     179        # make sure we have a valid number of jobs that corresponds to user input
     180        if options.jobs <= 0 :
     181                print('ERROR: Invalid number of jobs', file=sys.stderr)
     182                sys.exit(1)
     183
     184        return min( options.jobs, len(tests) ), True if make_flags else False
     185
     186# setup a proper processor pool with correct signal handling
     187def setupPool(jobs):
     188        original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
     189        pool = multiprocessing.Pool(jobs)
     190        signal.signal(signal.SIGINT, original_sigint_handler)
     191
     192        return pool
     193
     194# handle signals in scope
     195class SignalHandling():
     196        def __enter__(self):
     197                # enable signal handling
     198                signal.signal(signal.SIGINT, signal.SIG_DFL)
     199
     200        def __exit__(self, type, value, traceback):
     201                # disable signal handling
     202                signal.signal(signal.SIGINT, signal.SIG_IGN)
     203
     204################################################################################
     205#               misc
     206################################################################################
     207
     208# check if arguments is yes or no
     209def yes_no(string):
     210        if string == "yes" :
     211                return True
     212        if string == "no" :
     213                return False
     214        raise argparse.ArgumentTypeError(msg)
     215        return False
     216
     217
     218settings.set_machine_default( getMachineType )
Note: See TracChangeset for help on using the changeset viewer.