Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: gtest-parallel

Issue 2671333002: Roll latest version of gtest-parallel. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « README.webrtc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python2 1 #!/usr/bin/env python2
2 # Copyright 2013 Google Inc. All rights reserved. 2 # Copyright 2013 Google Inc. All rights reserved.
3 # 3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License. 5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at 6 # You may obtain a copy of the License at
7 # 7 #
8 # http://www.apache.org/licenses/LICENSE-2.0 8 # http://www.apache.org/licenses/LICENSE-2.0
9 # 9 #
10 # Unless required by applicable law or agreed to in writing, software 10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, 11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and 13 # See the License for the specific language governing permissions and
14 # limitations under the License. 14 # limitations under the License.
15 import cPickle 15 import cPickle
16 import errno 16 import errno
17 import gzip 17 import gzip
18 import json 18 import json
19 import multiprocessing 19 import multiprocessing
20 import optparse 20 import optparse
21 import os 21 import os
22 import re
22 import signal 23 import signal
23 import subprocess 24 import subprocess
24 import sys 25 import sys
25 import tempfile 26 import tempfile
26 import thread 27 import thread
27 import threading 28 import threading
28 import time 29 import time
29 import zlib 30 import zlib
30 31
31 # An object that catches SIGINT sent to the Python process and notices 32 # An object that catches SIGINT sent to the Python process and notices
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 # run if it was successful, or None if the test is new or the most 387 # run if it was successful, or None if the test is new or the most
387 # recent run failed. 388 # recent run failed.
388 tests = [x for x in tests if x[0] is None] 389 tests = [x for x in tests if x[0] is None]
389 390
390 # Sort tests by falling runtime (with None, which is what we get for 391 # Sort tests by falling runtime (with None, which is what we get for
391 # new and failing tests, being considered larger than any real 392 # new and failing tests, being considered larger than any real
392 # runtime). 393 # runtime).
393 tests.sort(reverse=True, key=lambda x: ((1 if x[0] is None else 0), x)) 394 tests.sort(reverse=True, key=lambda x: ((1 if x[0] is None else 0), x))
394 395
395 # Repeat tests (-r flag). 396 # Repeat tests (-r flag).
396 tests *= options.repeat 397 tests = [(test, i + 1) for test in tests for i in range(options.repeat)]
397 test_lock = threading.Lock() 398 test_lock = threading.Lock()
398 job_id = 0 399 job_id = 0
399 logger.log(str(-1) + ': TESTCNT ' + ' ' + str(len(tests))) 400 logger.log(str(-1) + ': TESTCNT ' + ' ' + str(len(tests)))
400 401
401 exit_code = 0 402 exit_code = 0
402 403
403 # Create directory for test log output. 404 # Create directory for test log output.
404 try: 405 try:
405 os.makedirs(options.output_dir) 406 os.makedirs(options.output_dir)
406 except OSError as e: 407 except OSError as e:
407 # Ignore errors if this directory already exists. 408 # Ignore errors if this directory already exists.
408 if e.errno != errno.EEXIST or not os.path.isdir(options.output_dir): 409 if e.errno != errno.EEXIST or not os.path.isdir(options.output_dir):
409 raise e 410 raise e
410 # Remove files from old test runs. 411 # Remove files from old test runs.
411 for logfile in os.listdir(options.output_dir): 412 for logfile in os.listdir(options.output_dir):
412 os.remove(os.path.join(options.output_dir, logfile)) 413 os.remove(os.path.join(options.output_dir, logfile))
413 414
414 # Run the specified job. Return the elapsed time in milliseconds if 415 # Run the specified job. Return the elapsed time in milliseconds if
415 # the job succeeds, or None if the job fails. (This ensures that 416 # the job succeeds, or None if the job fails. (This ensures that
416 # failing tests will run first the next time.) 417 # failing tests will run first the next time.)
417 def run_job((command, job_id, test)): 418 def run_job((command, job_id, test, test_index)):
418 begin = time.time() 419 begin = time.time()
419 420
420 with tempfile.NamedTemporaryFile(dir=options.output_dir, delete=False) as log: 421 test_name = re.sub('[^A-Za-z0-9]', '_', test) + '-' + str(test_index) + '.log'
422 with open(os.path.join(options.output_dir, test_name), 'w') as log:
421 sub = subprocess.Popen(command + ['--gtest_filter=' + test] + 423 sub = subprocess.Popen(command + ['--gtest_filter=' + test] +
422 ['--gtest_color=' + options.gtest_color], 424 ['--gtest_color=' + options.gtest_color],
423 stdout=log.file, 425 stdout=log, stderr=log)
424 stderr=log.file)
425 try: 426 try:
426 code = sigint_handler.wait(sub) 427 code = sigint_handler.wait(sub)
427 except sigint_handler.ProcessWasInterrupted: 428 except sigint_handler.ProcessWasInterrupted:
428 thread.exit() 429 thread.exit()
429 runtime_ms = int(1000 * (time.time() - begin)) 430 runtime_ms = int(1000 * (time.time() - begin))
430 logger.logfile(job_id, log.name) 431 logger.logfile(job_id, log.name)
431 432
432 test_results.log(test, { 433 test_results.log(test, {
433 "expected": "PASS", 434 "expected": "PASS",
434 "actual": "PASS" if code == 0 else "FAIL", 435 "actual": "PASS" if code == 0 else "FAIL",
435 "time": runtime_ms, 436 "time": runtime_ms,
436 }) 437 })
437 logger.log("%s: EXIT %s %d" % (job_id, code, runtime_ms)) 438 logger.log("%s: EXIT %s %d" % (job_id, code, runtime_ms))
438 if code == 0: 439 if code == 0:
439 return runtime_ms 440 return runtime_ms
440 global exit_code 441 global exit_code
441 exit_code = code 442 exit_code = code
442 return None 443 return None
443 444
444 def worker(): 445 def worker():
445 global job_id 446 global job_id
446 while True: 447 while True:
447 job = None 448 job = None
448 test_lock.acquire() 449 test_lock.acquire()
449 if job_id < len(tests): 450 if job_id < len(tests):
450 (_, test_binary, test, command) = tests[job_id] 451 ((_, test_binary, test, command), test_index) = tests[job_id]
451 logger.log(str(job_id) + ': TEST ' + test_binary + ' ' + test) 452 logger.log(str(job_id) + ': TEST ' + test_binary + ' ' + test)
452 job = (command, job_id, test) 453 job = (command, job_id, test, test_index)
453 job_id += 1 454 job_id += 1
454 test_lock.release() 455 test_lock.release()
455 if job is None: 456 if job is None:
456 return 457 return
457 times.record_test_time(test_binary, test, run_job(job)) 458 times.record_test_time(test_binary, test, run_job(job))
458 459
459 def start_daemon(func): 460 def start_daemon(func):
460 t = threading.Thread(target=func) 461 t = threading.Thread(target=func)
461 t.daemon = True 462 t.daemon = True
462 t.start() 463 t.start()
463 return t 464 return t
464 465
465 workers = [start_daemon(worker) for i in range(options.workers)] 466 workers = [start_daemon(worker) for i in range(options.workers)]
466 467
467 [t.join() for t in workers] 468 [t.join() for t in workers]
468 logger.end() 469 logger.end()
469 times.write_to_file(save_file) 470 times.write_to_file(save_file)
470 if options.print_test_times: 471 if options.print_test_times:
471 ts = sorted((times.get_test_time(test_binary, test), test_binary, test) 472 ts = sorted((times.get_test_time(test_binary, test), test_binary, test)
472 for (_, test_binary, test, _) in tests 473 for (_, test_binary, test, _) in tests
473 if times.get_test_time(test_binary, test) is not None) 474 if times.get_test_time(test_binary, test) is not None)
474 for (time_ms, test_binary, test) in ts: 475 for (time_ms, test_binary, test) in ts:
475 print "%8s %s" % ("%dms" % time_ms, test) 476 print "%8s %s" % ("%dms" % time_ms, test)
476 477
477 test_results.dump_to_file_and_close() 478 test_results.dump_to_file_and_close()
478 sys.exit(-signal.SIGINT if sigint_handler.got_sigint() else exit_code) 479 sys.exit(-signal.SIGINT if sigint_handler.got_sigint() else exit_code)
OLDNEW
« no previous file with comments | « README.webrtc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698