[3.6] bpo-30523, bpo-30764, bpo-30776: Sync regrtest from master (#2441) · python/cpython@35d2ca2
@@ -377,19 +377,19 @@ def parse_executed_tests(self, output):
377377return list(match.group(1) for match in parser)
378378379379def check_executed_tests(self, output, tests, skipped=(), failed=(),
380-omitted=(), randomize=False, interrupted=False):
380+env_changed=(), omitted=(),
381+randomize=False, interrupted=False,
382+fail_env_changed=False):
381383if isinstance(tests, str):
382384tests = [tests]
383385if isinstance(skipped, str):
384386skipped = [skipped]
385387if isinstance(failed, str):
386388failed = [failed]
389+if isinstance(env_changed, str):
390+env_changed = [env_changed]
387391if isinstance(omitted, str):
388392omitted = [omitted]
389-ntest = len(tests)
390-nskipped = len(skipped)
391-nfailed = len(failed)
392-nomitted = len(omitted)
393393394394executed = self.parse_executed_tests(output)
395395if randomize:
@@ -415,11 +415,17 @@ def list_regex(line_format, tests):
415415regex = list_regex('%s test%s failed', failed)
416416self.check_line(output, regex)
417417418+if env_changed:
419+regex = list_regex('%s test%s altered the execution environment',
420+env_changed)
421+self.check_line(output, regex)
422+418423if omitted:
419424regex = list_regex('%s test%s omitted', omitted)
420425self.check_line(output, regex)
421426422-good = ntest - nskipped - nfailed - nomitted
427+good = (len(tests) - len(skipped) - len(failed)
428+- len(omitted) - len(env_changed))
423429if good:
424430regex = r'%s test%s OK\.$' % (good, plural(good))
425431if not skipped and not failed and good > 1:
@@ -429,10 +435,12 @@ def list_regex(line_format, tests):
429435if interrupted:
430436self.check_line(output, 'Test suite interrupted by signal SIGINT.')
431437432-if nfailed:
438+if failed:
433439result = 'FAILURE'
434440elif interrupted:
435441result = 'INTERRUPTED'
442+elif fail_env_changed and env_changed:
443+result = 'ENV CHANGED'
436444else:
437445result = 'SUCCESS'
438446self.check_line(output, 'Tests result: %s' % result)
@@ -604,7 +612,7 @@ def test_failing(self):
604612test_failing = self.create_test('failing', code=code)
605613tests = [test_ok, test_failing]
606614607-output = self.run_tests(*tests, exitcode=1)
615+output = self.run_tests(*tests, exitcode=2)
608616self.check_executed_tests(output, tests, failed=test_failing)
609617610618def test_resources(self):
@@ -703,7 +711,7 @@ def test_fromfile(self):
703711def test_interrupted(self):
704712code = TEST_INTERRUPTED
705713test = self.create_test('sigint', code=code)
706-output = self.run_tests(test, exitcode=1)
714+output = self.run_tests(test, exitcode=130)
707715self.check_executed_tests(output, test, omitted=test,
708716interrupted=True)
709717@@ -732,7 +740,7 @@ def test_slow_interrupted(self):
732740args = ("--slowest", "-j2", test)
733741else:
734742args = ("--slowest", test)
735-output = self.run_tests(*args, exitcode=1)
743+output = self.run_tests(*args, exitcode=130)
736744self.check_executed_tests(output, test,
737745omitted=test, interrupted=True)
738746@@ -772,9 +780,43 @@ def test_run(self):
772780 builtins.__dict__['RUN'] = 1
773781 """)
774782test = self.create_test('forever', code=code)
775-output = self.run_tests('--forever', test, exitcode=1)
783+output = self.run_tests('--forever', test, exitcode=2)
776784self.check_executed_tests(output, [test]*3, failed=test)
777785786+def check_leak(self, code, what):
787+test = self.create_test('huntrleaks', code=code)
788+789+filename = 'reflog.txt'
790+self.addCleanup(support.unlink, filename)
791+output = self.run_tests('--huntrleaks', '3:3:', test,
792+exitcode=2,
793+stderr=subprocess.STDOUT)
794+self.check_executed_tests(output, [test], failed=test)
795+796+line = 'beginning 6 repetitions\n123456\n......\n'
797+self.check_line(output, re.escape(line))
798+799+line2 = '%s leaked [1, 1, 1] %s, sum=3\n' % (test, what)
800+self.assertIn(line2, output)
801+802+with open(filename) as fp:
803+reflog = fp.read()
804+self.assertIn(line2, reflog)
805+806+@unittest.skipUnless(Py_DEBUG, 'need a debug build')
807+def test_huntrleaks(self):
808+# test --huntrleaks
809+code = textwrap.dedent("""
810+ import unittest
811+812+ GLOBAL_LIST = []
813+814+ class RefLeakTest(unittest.TestCase):
815+ def test_leak(self):
816+ GLOBAL_LIST.append(object())
817+ """)
818+self.check_leak(code, 'references')
819+778820@unittest.skipUnless(Py_DEBUG, 'need a debug build')
779821def test_huntrleaks_fd_leak(self):
780822# test --huntrleaks for file descriptor leak
@@ -799,24 +841,7 @@ def test_leak(self):
799841 fd = os.open(__file__, os.O_RDONLY)
800842 # bug: never cloes the file descriptor
801843 """)
802-test = self.create_test('huntrleaks', code=code)
803-804-filename = 'reflog.txt'
805-self.addCleanup(support.unlink, filename)
806-output = self.run_tests('--huntrleaks', '3:3:', test,
807-exitcode=1,
808-stderr=subprocess.STDOUT)
809-self.check_executed_tests(output, [test], failed=test)
810-811-line = 'beginning 6 repetitions\n123456\n......\n'
812-self.check_line(output, re.escape(line))
813-814-line2 = '%s leaked [1, 1, 1] file descriptors, sum=3\n' % test
815-self.assertIn(line2, output)
816-817-with open(filename) as fp:
818-reflog = fp.read()
819-self.assertIn(line2, reflog)
844+self.check_leak(code, 'file descriptors')
820845821846def test_list_tests(self):
822847# test --list-tests
@@ -837,19 +862,28 @@ def test_method2(self):
837862 pass
838863 """)
839864testname = self.create_test(code=code)
865+866+# Test --list-cases
840867all_methods = ['%s.Tests.test_method1' % testname,
841868'%s.Tests.test_method2' % testname]
842869output = self.run_tests('--list-cases', testname)
843870self.assertEqual(output.splitlines(), all_methods)
844871872+# Test --list-cases with --match
873+all_methods = ['%s.Tests.test_method1' % testname]
874+output = self.run_tests('--list-cases',
875+'-m', 'test_method1',
876+testname)
877+self.assertEqual(output.splitlines(), all_methods)
878+845879def test_crashed(self):
846880# Any code which causes a crash
847881code = 'import faulthandler; faulthandler._sigsegv()'
848882crash_test = self.create_test(name="crash", code=code)
849883ok_test = self.create_test(name="ok")
850884851885tests = [crash_test, ok_test]
852-output = self.run_tests("-j2", *tests, exitcode=1)
886+output = self.run_tests("-j2", *tests, exitcode=2)
853887self.check_executed_tests(output, tests, failed=crash_test,
854888randomize=True)
855889@@ -898,6 +932,25 @@ def test_method4(self):
898932subset = ['test_method1', 'test_method3']
899933self.assertEqual(methods, subset)
900934935+def test_env_changed(self):
936+code = textwrap.dedent("""
937+ import unittest
938+939+ class Tests(unittest.TestCase):
940+ def test_env_changed(self):
941+ open("env_changed", "w").close()
942+ """)
943+testname = self.create_test(code=code)
944+945+# don't fail by default
946+output = self.run_tests(testname)
947+self.check_executed_tests(output, [testname], env_changed=testname)
948+949+# fail with --fail-env-changed
950+output = self.run_tests("--fail-env-changed", testname, exitcode=3)
951+self.check_executed_tests(output, [testname], env_changed=testname,
952+fail_env_changed=True)
953+901954902955if __name__ == '__main__':
903956unittest.main()