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

Side by Side Diff: typ/runner.py

Issue 2363773008: Add better logging when failing to load a test. (Closed)
Patch Set: patch for review Created 4 years, 3 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
OLDNEW
1 # Copyright 2014 Google Inc. All rights reserved. 1 # Copyright 2014 Google Inc. All rights reserved.
2 # 2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License. 4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at 5 # You may obtain a copy of the License at
6 # 6 #
7 # http://www.apache.org/licenses/LICENSE-2.0 7 # http://www.apache.org/licenses/LICENSE-2.0
8 # 8 #
9 # Unless required by applicable law or agreed to in writing, software 9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 10 # distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 try: 338 try:
339 names = self._name_list_from_args(args) 339 names = self._name_list_from_args(args)
340 classifier = self.classifier or _default_classifier(args) 340 classifier = self.classifier or _default_classifier(args)
341 341
342 for name in names: 342 for name in names:
343 try: 343 try:
344 self._add_tests_to_set(test_set, args.suffixes, 344 self._add_tests_to_set(test_set, args.suffixes,
345 self.top_level_dir, classifier, 345 self.top_level_dir, classifier,
346 name) 346 name)
347 except (AttributeError, ImportError, SyntaxError) as e: 347 except (AttributeError, ImportError, SyntaxError) as e:
348 self.print_('Failed to load "%s": %s' % (name, e)) 348 ex_str = traceback.format_exc()
349 self.print_('Failed to load "%s" in find_tests: %s' %
350 (name, e))
351 self.print_(' %s' %
352 '\n '.join(ex_str.splitlines()))
353 self.print_(ex_str)
349 return 1, None 354 return 1, None
350 except _AddTestsError as e: 355 except _AddTestsError as e:
351 self.print_(str(e)) 356 self.print_(str(e))
352 return 1, None 357 return 1, None
353 358
354 # TODO: Add support for discovering setupProcess/teardownProcess? 359 # TODO: Add support for discovering setupProcess/teardownProcess?
355 360
356 shard_index = args.shard_index 361 shard_index = args.shard_index
357 total_shards = args.total_shards 362 total_shards = args.total_shards
358 assert total_shards >= 1 363 assert total_shards >= 1
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 possible_dir = name.replace('.', h.sep) 407 possible_dir = name.replace('.', h.sep)
403 if h.isdir(top_level_dir, possible_dir): 408 if h.isdir(top_level_dir, possible_dir):
404 for suffix in suffixes: 409 for suffix in suffixes:
405 path = h.join(top_level_dir, possible_dir) 410 path = h.join(top_level_dir, possible_dir)
406 suite = loader.discover(path, suffix, top_level_dir) 411 suite = loader.discover(path, suffix, top_level_dir)
407 add_tests(suite) 412 add_tests(suite)
408 else: 413 else:
409 add_tests(loader.loadTestsFromName(name)) 414 add_tests(loader.loadTestsFromName(name))
410 415
411 # pylint: disable=no-member 416 # pylint: disable=no-member
412 if hasattr(loader, 'errors') and loader.errors: 417 if hasattr(loader, 'errors') and loader.errors: # pragma: python3
413 # In Python3's version of unittest, loader failures get converted 418 # In Python3's version of unittest, loader failures get converted
414 # into failed test cases, rather than raising exceptions. However, 419 # into failed test cases, rather than raising exceptions. However,
415 # the errors also get recorded so you can err out immediately. 420 # the errors also get recorded so you can err out immediately.
416 raise ImportError(loader.errors) 421 raise ImportError(loader.errors)
417 422
418 def _run_tests(self, result_set, test_set): 423 def _run_tests(self, result_set, test_set):
419 h = self.host 424 h = self.host
420 if not test_set.parallel_tests and not test_set.isolated_tests: 425 if not test_set.parallel_tests and not test_set.isolated_tests:
421 self.print_('No tests to run.') 426 self.print_('No tests to run.')
422 return 1, None 427 return 1, None
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 804
800 # It is important to capture the output before loading the test 805 # It is important to capture the output before loading the test
801 # to ensure that 806 # to ensure that
802 # 1) the loader doesn't logs something we don't captured 807 # 1) the loader doesn't logs something we don't captured
803 # 2) neither the loader nor the test case grab a reference to the 808 # 2) neither the loader nor the test case grab a reference to the
804 # uncaptured stdout or stderr that later is used when the test is run. 809 # uncaptured stdout or stderr that later is used when the test is run.
805 # This comes up when using the FakeTestLoader and testing typ itself, 810 # This comes up when using the FakeTestLoader and testing typ itself,
806 # but could come up when testing non-typ code as well. 811 # but could come up when testing non-typ code as well.
807 h.capture_output(divert=not child.passthrough) 812 h.capture_output(divert=not child.passthrough)
808 813
809 tb_str = '' 814 ex_str = ''
810 try: 815 try:
811 orig_skip = unittest.skip 816 orig_skip = unittest.skip
812 orig_skip_if = unittest.skipIf 817 orig_skip_if = unittest.skipIf
813 if child.all: 818 if child.all:
814 unittest.skip = lambda reason: lambda x: x 819 unittest.skip = lambda reason: lambda x: x
815 unittest.skipIf = lambda condition, reason: lambda x: x 820 unittest.skipIf = lambda condition, reason: lambda x: x
816 821
817 try: 822 try:
818 suite = child.loader.loadTestsFromName(test_name) 823 suite = child.loader.loadTestsFromName(test_name)
819 except Exception as e: 824 except Exception as e:
825 ex_str = ('loadTestsFromName("%s") failed: %s\n%s\n' %
826 (test_name, e, traceback.format_exc()))
820 try: 827 try:
821 suite = _load_via_load_tests(child, test_name) 828 suite = _load_via_load_tests(child, test_name)
829 ex_str += ('\nload_via_load_tests(\"%s\") returned %d tests\n' %
830 (test_name, len(list(suite))))
822 except Exception as e: # pragma: untested 831 except Exception as e: # pragma: untested
823 suite = [] 832 suite = []
824 tb_str = traceback.format_exc(e) 833 ex_str += ('\nload_via_load_tests("%s") failed: %s\n%s\n' %
834 (test_name, e, traceback.format_exc()))
825 finally: 835 finally:
826 unittest.skip = orig_skip 836 unittest.skip = orig_skip
827 unittest.skipIf = orig_skip_if 837 unittest.skipIf = orig_skip_if
828 838
829 tests = list(suite) 839 tests = list(suite)
830 if len(tests) != 1: 840 if len(tests) != 1:
831 err = 'Failed to load %s' % test_name 841 err = 'Failed to load "%s" in run_one_test' % test_name
832 if tb_str: # pragma: untested 842 if ex_str: # pragma: untested
833 err += (' (traceback follows):\n %s' % 843 err += '\n ' + '\n '.join(ex_str.splitlines())
834 ' \n'.join(tb_str.splitlines()))
835 844
836 h.restore_output() 845 h.restore_output()
837 return Result(test_name, ResultType.Failure, start, 0, 846 return Result(test_name, ResultType.Failure, start, 0,
838 child.worker_num, unexpected=True, code=1, 847 child.worker_num, unexpected=True, code=1,
839 err=err, pid=pid) 848 err=err, pid=pid)
840 849
841 test_case = tests[0] 850 test_case = tests[0]
842 if isinstance(test_case, TypTestCase): 851 if isinstance(test_case, TypTestCase):
843 test_case.child = child 852 test_case.child = child
844 test_case.context = child.context_after_setup 853 test_case.context = child.context_after_setup
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 module = importlib.import_module(name) 940 module = importlib.import_module(name)
932 except ImportError: 941 except ImportError:
933 pass 942 pass
934 if module: 943 if module:
935 suite = loader.loadTestsFromModule(module) 944 suite = loader.loadTestsFromModule(module)
936 child.loaded_suites[name] = suite 945 child.loaded_suites[name] = suite
937 suite = child.loaded_suites[name] 946 suite = child.loaded_suites[name]
938 if suite: 947 if suite:
939 for test_case in suite: 948 for test_case in suite:
940 assert isinstance(test_case, unittest.TestCase) 949 assert isinstance(test_case, unittest.TestCase)
941 if test_case.id() == test_name: 950 if test_case.id() == test_name: # pragma: untested
942 new_suite.addTest(test_case) 951 new_suite.addTest(test_case)
943 break 952 break
944 comps.pop() 953 comps.pop()
945 return new_suite 954 return new_suite
946 955
947 956
948 def _sort_inputs(inps): 957 def _sort_inputs(inps):
949 return sorted(inps, key=lambda inp: inp.name) 958 return sorted(inps, key=lambda inp: inp.name)
950 959
951 960
952 if __name__ == '__main__': # pragma: no cover 961 if __name__ == '__main__': # pragma: no cover
953 sys.modules['__main__'].__file__ = path_to_file 962 sys.modules['__main__'].__file__ = path_to_file
954 sys.exit(main(win_multiprocessing=WinMultiprocessing.importable)) 963 sys.exit(main(win_multiprocessing=WinMultiprocessing.importable))
OLDNEW
« no previous file with comments | « typ/json_results.py ('k') | typ/tests/main_test.py » ('j') | typ/tests/main_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698