Changes in tests/pybin/tools.py [0f5da65:dcfedca]
- File:
-
- 1 edited
-
tests/pybin/tools.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
tests/pybin/tools.py
r0f5da65 rdcfedca 23 23 24 24 # 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): 26 try: 27 cmd = list(cmd) 28 29 if input_file and input_text: 30 return 401, "Cannot use both text and file inputs" 31 32 # if this is a dry_run, only print the commands that would be ran 33 if settings.dry_run and not ignore_dry_run: 34 cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd)) 35 if output_file and not isinstance(output_file, int): 36 cmd += " > " 37 cmd += output_file 38 39 if error and not isinstance(error, int): 40 cmd += " 2> " 41 cmd += error 42 43 if input_file and not isinstance(input_file, int) and os.path.isfile(input_file): 44 cmd += " < " 45 cmd += input_file 46 47 print(cmd) 48 return 0, None 49 50 with contextlib.ExitStack() as onexit: 51 # add input redirection if needed 52 input_file = openfd(input_file, 'r', onexit, True) 53 54 # add output redirection if needed 55 output_file = openfd(output_file, 'w', onexit, False) 56 57 # add error redirection if needed 58 error = openfd(error, 'w', onexit, False) 59 60 # run the desired command 61 # use with statement to make sure proc is cleaned 62 # don't use subprocess.run because we want to send SIGABRT on exit 63 with subprocess.Popen( 25 def sh(*cmd, timeout = False, output = None, input = None, error = subprocess.STDOUT): 26 cmd = list(cmd) 27 28 # if this is a dry_run, only print the commands that would be ran 29 if settings.dry_run : 30 cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd)) 31 if output and not isinstance(output, int): 32 cmd += " > " 33 cmd += output 34 35 if error and not isinstance(error, int): 36 cmd += " 2> " 37 cmd += error 38 39 if input and not isinstance(input, int) and os.path.isfile(input): 40 cmd += " < " 41 cmd += input 42 43 print(cmd) 44 return 0, None 45 46 with contextlib.ExitStack() as onexit: 47 # add input redirection if needed 48 input = openfd(input, 'r', onexit, True) 49 50 # add output redirection if needed 51 output = openfd(output, 'w', onexit, False) 52 53 # add error redirection if needed 54 error = openfd(error, 'w', onexit, False) 55 56 # run the desired command 57 try: 58 proc = subprocess.run( 64 59 cmd, 65 **({'input' : bytes(input_text, encoding='utf-8')} if input_text else {'stdin' : input_file}), 66 stdout = output_file, 67 stderr = error 68 ) as proc: 69 70 try: 71 out, _ = proc.communicate( 72 timeout = settings.timeout.single if timeout else None 73 ) 74 75 return proc.returncode, out.decode("utf-8") if out else None 76 except subprocess.TimeoutExpired: 77 proc.send_signal(signal.SIGABRT) 78 proc.communicate() 79 return 124, str(None) 80 81 except Exception as ex: 82 print ("Unexpected error: %s" % ex) 83 raise 60 stdin =input, 61 stdout=output, 62 stderr=error, 63 timeout=settings.timeout.single if timeout else None 64 ) 65 return proc.returncode, proc.stdout.decode("utf-8") if proc.stdout else None 66 except subprocess.TimeoutExpired: 67 return 124, str(None) 84 68 85 69 def is_ascii(fname): … … 91 75 return False 92 76 93 code, out = sh("file %s" % fname, output _file=subprocess.PIPE)77 code, out = sh("file %s" % fname, output=subprocess.PIPE) 94 78 if code != 0: 95 79 return False … … 123 107 if isinstance(files, str ): files = [ files ] 124 108 for file in files: 125 sh( 'rm', '-f', file, output _file=subprocess.DEVNULL, error=subprocess.DEVNULL )109 sh( 'rm', '-f', file, output=subprocess.DEVNULL, error=subprocess.DEVNULL ) 126 110 127 111 # Create 1 or more directory … … 131 115 p = os.path.normpath( file ) 132 116 d = os.path.dirname ( p ) 133 sh( 'mkdir', '-p', d, output _file=subprocess.DEVNULL, error=subprocess.DEVNULL )117 sh( 'mkdir', '-p', d, output=subprocess.DEVNULL, error=subprocess.DEVNULL ) 134 118 135 119 … … 154 138 lhs, 155 139 rhs, 156 output _file=subprocess.PIPE140 output=subprocess.PIPE 157 141 ) 158 142 159 143 # call make 160 def make(target, *, flags = '', output _file= None, error = None, error_file = None, silent = False):144 def make(target, *, flags = '', output = None, error = None, error_file = None, silent = False): 161 145 test_param = """test="%s" """ % (error_file) if error_file else None 162 146 cmd = [ … … 167 151 settings.debug.flags, 168 152 settings.install.flags, 169 settings.distcc if settings.distribute else None,170 153 flags, 171 154 target 172 155 ] 173 156 cmd = [s for s in cmd if s] 174 return sh(*cmd, output _file=output_file, error=error)157 return sh(*cmd, output=output, error=error) 175 158 176 159 def which(program): 177 fpath, fname = os.path.split(program) 178 if fpath: 179 if is_exe(program): 180 return program 181 else: 182 for path in os.environ["PATH"].split(os.pathsep): 183 exe_file = os.path.join(path, program) 184 if is_exe(exe_file): 185 return exe_file 186 return None 160 fpath, fname = os.path.split(program) 161 if fpath: 162 if is_exe(program): 163 return program 164 else: 165 for path in os.environ["PATH"].split(os.pathsep): 166 exe_file = os.path.join(path, program) 167 if is_exe(exe_file): 168 return exe_file 169 170 return None 187 171 188 172 @contextlib.contextmanager … … 217 201 # cat one file into the other 218 202 def cat(source, dest): 219 ret, _ = sh("cat", source, output _file=dest)203 ret, _ = sh("cat", source, output=dest) 220 204 return ret 221 205 … … 272 256 os.write(int(make_jobs_fds.group(3)), tokens) 273 257 else : 274 if settings.distribute: 275 ret, jstr = sh("distcc", "-j", output_file=subprocess.PIPE, ignore_dry_run=True) 276 if ret == 0: 277 options.jobs = int(jstr.strip()) 278 else : 279 options.jobs = multiprocessing.cpu_count() 280 else: 281 options.jobs = multiprocessing.cpu_count() 258 options.jobs = multiprocessing.cpu_count() 282 259 else : 283 260 force = True … … 297 274 ################################################################################ 298 275 299 # get hash for given configuration300 def config_hash():301 path = os.path.normpath(os.path.join(302 settings.SRCDIR,303 ))304 305 distcc_hash = os.path.join(settings.SRCDIR, '../tools/build/distcc_hash')306 config = "%s-%s" % (settings.arch.target, settings.debug.path)307 _, out = sh(distcc_hash, config, output_file=subprocess.PIPE, ignore_dry_run=True)308 return out.strip()309 310 # get pretty string for time of day311 276 def pretty_now(): 312 277 ts = time.time() … … 343 308 return 1, "ERR No core dump" 344 309 345 return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output _file=subprocess.PIPE)310 return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output=subprocess.PIPE) 346 311 347 312 def core_archive(dst, name, exe): 348 # Get the core dump313 # Get the files to copy 349 314 core = os.path.join(os.getcwd(), "core" ) 350 315 351 # update the path for this test352 dst = os.path.join(dst, name)316 # Uncomment if we want timestamps on coredumps 317 # dst = os.path.join(dst, "%s_%s" % (name, pretty_now())) 353 318 354 319 # make a directory for this test 355 # mkdir makes the parent directory only so add a dummy 356 mkdir(os.path.join(dst, name )) 320 mkdir(os.path.join(dst, "dir")) 357 321 358 322 # moves the files … … 364 328 365 329 class Timed: 366 def __enter__(self):367 self.start = time.time()368 return self369 370 def __exit__(self, *args):371 self.end = time.time()372 self.duration = self.end - self.start330 def __enter__(self): 331 self.start = time.time() 332 return self 333 334 def __exit__(self, *args): 335 self.end = time.time() 336 self.duration = self.end - self.start 373 337 374 338 def timed(src, timeout): 375 339 expire = time.time() + timeout 376 340 i = iter(src) 377 with contextlib.suppress(StopIteration): 378 while True: 379 yield i.next(max(expire - time.time(), 0)) 341 while True: 342 yield i.next(max(expire - time.time(), 0))
Note:
See TracChangeset
for help on using the changeset viewer.