Changes in tests/pybin/tools.py [f806b61:0c13238]
- File:
-
- 1 edited
-
tests/pybin/tools.py (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
tests/pybin/tools.py
rf806b61 r0c13238 1 from __future__ import print_function 2 1 3 import __main__ 2 4 import argparse 3 import contextlib4 5 import fileinput 5 6 import multiprocessing … … 9 10 import signal 10 11 import stat 11 import subprocess12 12 import sys 13 import tempfile14 13 import time 15 import types16 14 17 15 from pybin import settings 16 from subprocess import Popen, PIPE, STDOUT 18 17 19 18 ################################################################################ … … 22 21 23 22 # helper functions to run terminal commands 24 def sh(*cmd, timeout = False, output = None, input = None, error = subprocess.STDOUT): 25 cmd = list(cmd) 23 def sh(cmd, print2stdout = True, input = None): 24 # add input redirection if needed 25 if input and os.path.isfile(input): 26 cmd += " < %s" % input 26 27 27 28 # if this is a dry_run, only print the commands that would be ran 28 29 if settings.dry_run : 29 cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd)) 30 if output and not isinstance(output, int): 31 cmd += " > " 32 cmd += output 33 34 if error and not isinstance(error, int): 35 cmd += " 2> " 36 cmd += error 37 38 if input and not isinstance(input, int) and os.path.isfile(input): 39 cmd += " < " 40 cmd += input 41 42 print(cmd) 30 print("cmd: %s" % cmd) 43 31 return 0, None 44 32 45 with contextlib.ExitStack() as onexit: 46 # add input redirection if needed 47 input = openfd(input, 'r', onexit, True) 48 49 # add output redirection if needed 50 output = openfd(output, 'w', onexit, False) 51 52 # add error redirection if needed 53 error = openfd(error, 'w', onexit, False) 54 55 # run the desired command 56 try: 57 proc = subprocess.run( 58 cmd, 59 stdin =input, 60 stdout=output, 61 stderr=error, 62 timeout=settings.timeout.single if timeout else None 63 ) 64 return proc.returncode, proc.stdout.decode("utf-8") if proc.stdout else None 65 except subprocess.TimeoutExpired: 66 return 124, str(None) 33 # otherwise create a pipe and run the desired command 34 else : 35 proc = Popen(cmd, stdout=None if print2stdout else PIPE, stderr=STDOUT, shell=True) 36 out, err = proc.communicate() 37 return proc.returncode, out 67 38 68 39 def is_ascii(fname): … … 74 45 return False 75 46 76 code, out = sh("file %s" % fname, output=subprocess.PIPE)47 code, out = sh("file %s" % fname, print2stdout = False) 77 48 if code != 0: 78 49 return False … … 84 55 85 56 return match.group(1).startswith("ASCII text") 86 87 def is_exe(fname):88 return os.path.isfile(fname) and os.access(fname, os.X_OK)89 90 def openfd(file, mode, exitstack, checkfile):91 if not file:92 return file93 94 if isinstance(file, int):95 return file96 97 if checkfile and not os.path.isfile(file):98 return None99 100 file = open(file, mode)101 exitstack.push(file)102 return file103 57 104 58 # Remove 1 or more files silently 105 59 def rm( files ): 106 if isinstance(files, str ): files = [ files ] 107 for file in files: 108 sh( 'rm', '-f', file, output=subprocess.DEVNULL, error=subprocess.DEVNULL ) 60 if isinstance( files, basestring ): 61 sh("rm -f %s > /dev/null 2>&1" % files ) 62 else: 63 for file in files: 64 sh("rm -f %s > /dev/null 2>&1" % file ) 109 65 110 66 # Create 1 or more directory 111 67 def mkdir( files ): 112 if isinstance( files, str ): files = [ files ]113 for file in files:114 p = os.path.normpath( file )115 d = os.path.dirname ( p )116 sh( 'mkdir', '-p', d, output=subprocess.DEVNULL, error=subprocess.DEVNULL)68 if isinstance( files, basestring ): 69 sh("mkdir -p %s" % os.path.dirname(files) ) 70 else: 71 for file in files: 72 sh("mkdir -p %s" % os.path.dirname(file) ) 117 73 118 74 … … 124 80 # diff two files 125 81 def diff( lhs, rhs ): 82 # diff the output of the files 83 diff_cmd = ("diff --text " 84 # "--ignore-all-space " 85 # "--ignore-blank-lines " 86 "--old-group-format='\t\tmissing lines :\n" 87 "%%<' \\\n" 88 "--new-group-format='\t\tnew lines :\n" 89 "%%>' \\\n" 90 "--unchanged-group-format='%%=' \\" 91 "--changed-group-format='\t\texpected :\n" 92 "%%<" 93 "\t\tgot :\n" 94 "%%>\n' \\\n" 95 "--new-line-format='\t\t%%dn\t%%L' \\\n" 96 "--old-line-format='\t\t%%dn\t%%L' \\\n" 97 "--unchanged-line-format='' \\\n" 98 "%s %s") 99 126 100 # fetch return code and error from the diff command 127 return sh( 128 '''diff''', 129 '''--text''', 130 '''--old-group-format=\t\tmissing lines :\n%<''', 131 '''--new-line-format=\t\t%dn\t%L''', 132 '''--new-group-format=\t\tnew lines : \n%>''', 133 '''--old-line-format=\t\t%dn\t%L''', 134 '''--unchanged-group-format=%=''', 135 '''--changed-group-format=\t\texpected :\n%<\t\tgot :\n%>''', 136 '''--unchanged-line-format=''', 137 lhs, 138 rhs, 139 output=subprocess.PIPE 140 ) 101 return sh(diff_cmd % (lhs, rhs), False) 141 102 142 103 # call make 143 def make(target, *, flags = '', output = None, error = None, error_file = None, silent = False):144 test_param = """test="%s" """ % (error_file) if error_file else None145 cmd = [146 *settings.make,147 '-s' if silent else None,104 def make(target, flags = '', redirects = '', error_file = None, silent = False): 105 test_param = """test="%s" """ % (error_file) if error_file else '' 106 cmd = ' '.join([ 107 settings.make, 108 '-s' if silent else '', 148 109 test_param, 149 110 settings.arch.flags, … … 151 112 settings.install.flags, 152 113 flags, 153 target 154 ]155 cmd = [s for s in cmd if s]156 return sh( *cmd, output=output, error=error)114 target, 115 redirects 116 ]) 117 return sh(cmd) 157 118 158 119 def which(program): 120 import os 121 def is_exe(fpath): 122 return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 123 159 124 fpath, fname = os.path.split(program) 160 125 if fpath: … … 169 134 return None 170 135 171 @contextlib.contextmanager 172 def tempdir(): 173 cwd = os.getcwd() 174 with tempfile.TemporaryDirectory() as temp: 175 os.chdir(temp) 176 try: 177 yield temp 178 finally: 179 os.chdir(cwd) 136 def run(exe, output, input): 137 ret, _ = sh("timeout %d %s > %s 2>&1" % (settings.timeout.single, exe, output), input = input) 138 return ret 180 139 181 140 ################################################################################ … … 184 143 # move a file 185 144 def mv(source, dest): 186 ret, _ = sh("mv ", source, dest)145 ret, _ = sh("mv %s %s" % (source, dest)) 187 146 return ret 188 147 189 148 # cat one file into the other 190 149 def cat(source, dest): 191 ret, _ = sh("cat ", source, output=dest)150 ret, _ = sh("cat %s > %s" % (source, dest)) 192 151 return ret 193 152 … … 204 163 205 164 # helper function to check if a files contains only a specific string 206 def file _contains_only(file, text) :165 def fileContainsOnly(file, text) : 207 166 with open(file) as f: 208 167 ff = f.read().strip() 209 168 result = ff == text.strip() 210 169 211 return result 170 return result; 171 172 # check whether or not a file is executable 173 def fileIsExecutable(file) : 174 try : 175 fileinfo = os.stat(file) 176 return bool(fileinfo.st_mode & stat.S_IXUSR) 177 except Exception as inst: 178 print(type(inst)) # the exception instance 179 print(inst.args) # arguments stored in .args 180 print(inst) 181 return False 212 182 213 183 # transform path to canonical form 214 def canonical _path(path):184 def canonicalPath(path): 215 185 abspath = os.path.abspath(__main__.__file__) 216 186 dname = os.path.dirname(abspath) … … 218 188 219 189 # compare path even if form is different 220 def path _cmp(lhs, rhs):221 return canonical _path( lhs ) == canonical_path( rhs )190 def pathCmp(lhs, rhs): 191 return canonicalPath( lhs ) == canonicalPath( rhs ) 222 192 223 193 # walk all files in a path 224 def path_walk( op ): 225 dname = settings.SRCDIR 226 for dirname, _, names in os.walk(dname): 194 def pathWalk( op ): 195 def step(_, dirname, names): 227 196 for name in names: 228 197 path = os.path.join(dirname, name) 229 198 op( path ) 230 199 200 # Start the walk 201 dname = settings.SRCDIR 202 os.path.walk(dname, step, '') 203 231 204 ################################################################################ 232 205 # system 233 206 ################################################################################ 234 207 # count number of jobs to create 235 def job _count( options, tests ):208 def jobCount( options, tests ): 236 209 # check if the user already passed in a number of jobs for multi-threading 237 210 if not options.jobs: … … 255 228 return min( options.jobs, len(tests) ), force 256 229 230 # setup a proper processor pool with correct signal handling 231 def setupPool(jobs): 232 original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) 233 pool = multiprocessing.Pool(jobs) 234 signal.signal(signal.SIGINT, original_sigint_handler) 235 236 return pool 237 238 # handle signals in scope 239 class SignalHandling(): 240 def __enter__(self): 241 # enable signal handling 242 signal.signal(signal.SIGINT, signal.SIG_DFL) 243 244 def __exit__(self, type, value, traceback): 245 # disable signal handling 246 signal.signal(signal.SIGINT, signal.SIG_IGN) 247 248 257 249 # enable core dumps for all the test children 258 250 resource.setrlimit(resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY)) … … 269 261 return False 270 262 raise argparse.ArgumentTypeError(msg) 263 return False 271 264 272 265 def fancy_print(text): 273 266 column = which('column') 274 267 if column: 275 subprocess.run(column, input=bytes(text + "\n", "UTF-8")) 268 cmd = "%s 2> /dev/null" % column 269 proc = Popen(cmd, stdin=PIPE, stderr=None, shell=True) 270 proc.communicate(input=text + "\n") 276 271 else: 277 272 print(text) 278 273 279 274 280 def core_info(path): 281 if not os.path.isfile(path): 282 return 1, "ERR Executable path is wrong" 283 275 def coreInfo(path): 284 276 cmd = os.path.join(settings.SRCDIR, "pybin/print-core.gdb") 285 277 if not os.path.isfile(cmd): 286 278 return 1, "ERR Printing format for core dumps not found" 287 279 288 core = os.path.join(os.getcwd(), "core" ) 280 dname = os.path.dirname(path) 281 core = os.path.join(dname, "core" ) 282 if not os.path.isfile(path): 283 return 1, "ERR Executable path is wrong" 289 284 290 285 if not os.path.isfile(core): 291 286 return 1, "ERR No core dump" 292 287 293 return sh( 'gdb', '-n', path, core, '-batch', '-x', cmd, output=subprocess.PIPE)288 return sh("gdb -n %s %s -batch -x %s" % (path, core, cmd), print2stdout=False) 294 289 295 290 class Timed:
Note:
See TracChangeset
for help on using the changeset viewer.