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

Side by Side Diff: recipe_engine/test.py

Issue 2797023002: Always identify test names that lead to failures (Closed)
Patch Set: proto Created 3 years, 8 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 | « no previous file | recipe_engine/test_result.proto » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2017 The LUCI Authors. All rights reserved. 1 # Copyright 2017 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0 2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file. 3 # that can be found in the LICENSE file.
4 4
5 from __future__ import print_function 5 from __future__ import print_function
6 6
7 import argparse 7 import argparse
8 import bdb 8 import bdb
9 import cStringIO 9 import cStringIO
10 import contextlib 10 import contextlib
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 536
537 537
538 def worker(f): 538 def worker(f):
539 """Wrapper for a multiprocessing worker function. 539 """Wrapper for a multiprocessing worker function.
540 540
541 This addresses known issues with multiprocessing workers: 541 This addresses known issues with multiprocessing workers:
542 542
543 - they can hang on uncaught exceptions 543 - they can hang on uncaught exceptions
544 - we need explicit kill switch to clearly terminate parent""" 544 - we need explicit kill switch to clearly terminate parent"""
545 @functools.wraps(f) 545 @functools.wraps(f)
546 def wrapper(*args, **kwargs): 546 def wrapper(test, *args, **kwargs):
547 try: 547 try:
548 if _KILL_SWITCH.is_set(): 548 if _KILL_SWITCH.is_set():
549 return (False, 'kill switch') 549 return (False, test, 'kill switch')
550 return (True, f(*args, **kwargs)) 550 return (True, test, f(test, *args, **kwargs))
551 except Exception: 551 except Exception:
552 return (False, traceback.format_exc()) 552 return (False, test, traceback.format_exc())
553 return wrapper 553 return wrapper
554 554
555 555
556 @worker 556 @worker
557 def run_worker(test, debug=False, train=False): 557 def run_worker(test, debug=False, train=False):
558 """Worker for 'run' command (note decorator above).""" 558 """Worker for 'run' command (note decorator above)."""
559 return run_test(test, debug=debug, train=train) 559 return run_test(test, debug=debug, train=train)
560 560
561 561
562 def scan_for_expectations(root, inside_expectations=False): 562 def scan_for_expectations(root, inside_expectations=False):
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 results.append(run_worker(t, debug=debug, train=train)) 610 results.append(run_worker(t, debug=debug, train=train))
611 else: 611 else:
612 with kill_switch(): 612 with kill_switch():
613 pool = multiprocessing.Pool(jobs) 613 pool = multiprocessing.Pool(jobs)
614 results = pool.map(functools.partial(run_worker, train=train), tests) 614 results = pool.map(functools.partial(run_worker, train=train), tests)
615 615
616 print() 616 print()
617 617
618 used_expectations = set() 618 used_expectations = set()
619 619
620 for success, details in results: 620 for success, test_description, details in results:
621 if success: 621 if success:
622 assert isinstance(details, TestResult) 622 assert isinstance(details, TestResult)
623 if details.failures: 623 if details.failures:
624 rc = 1 624 rc = 1
625 key = details.test_description.full_name 625 key = details.test_description.full_name
626 print('%s failed:' % key) 626 print('%s failed:' % key)
627 for failure in details.failures: 627 for failure in details.failures:
628 results_proto.test_failures[key].failures.extend([failure.as_proto()]) 628 results_proto.test_failures[key].failures.extend([failure.as_proto()])
629 print(failure.format()) 629 print(failure.format())
630 coverage_data.update(details.coverage_data) 630 coverage_data.update(details.coverage_data)
631 if details.generates_expectation: 631 if details.generates_expectation:
632 used_expectations.add(details.test_description.expectation_path) 632 used_expectations.add(details.test_description.expectation_path)
633 used_expectations.add( 633 used_expectations.add(
634 os.path.dirname(details.test_description.expectation_path)) 634 os.path.dirname(details.test_description.expectation_path))
635 else: 635 else:
636 rc = 1 636 rc = 1
637 results_proto.valid = False 637 results_proto.valid = False
638 print('Internal failure:') 638 failure_proto = test_result_pb2.TestResult.TestFailure()
639 failure_proto.internal_failure.MergeFrom(
640 test_result_pb2.TestResult.InternalFailure())
641 results_proto.test_failures[test_description.full_name].failures.extend([
642 failure_proto])
643 print('%s failed:' % test_description.full_name)
639 print(details) 644 print(details)
640 645
641 if test_filter: 646 if test_filter:
642 print('NOTE: not checking coverage, because a filter is enabled') 647 print('NOTE: not checking coverage, because a filter is enabled')
643 else: 648 else:
644 try: 649 try:
645 # TODO(phajdan.jr): Add API to coverage to load data from memory. 650 # TODO(phajdan.jr): Add API to coverage to load data from memory.
646 with tempfile.NamedTemporaryFile(delete=False) as coverage_file: 651 with tempfile.NamedTemporaryFile(delete=False) as coverage_file:
647 coverage_data.write_file(coverage_file.name) 652 coverage_data.write_file(coverage_file.name)
648 653
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 Returns: 883 Returns:
879 Exit code 884 Exit code
880 """ 885 """
881 global _UNIVERSE_VIEW 886 global _UNIVERSE_VIEW
882 _UNIVERSE_VIEW = universe_view 887 _UNIVERSE_VIEW = universe_view
883 global _ENGINE_FLAGS 888 global _ENGINE_FLAGS
884 _ENGINE_FLAGS = engine_flags 889 _ENGINE_FLAGS = engine_flags
885 890
886 args = parse_args(raw_args) 891 args = parse_args(raw_args)
887 return args.func(args) 892 return args.func(args)
OLDNEW
« no previous file with comments | « no previous file | recipe_engine/test_result.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698