Mercurial > hg
comparison tests/run-tests.py @ 35450:e31773898197
run-tests: use context managers for file descriptors
I've seen the following error a few times recently when running the tests with
`yes | ./run-tests.py --local -j9 -i`:
Errored test-add.t: Traceback (most recent call last):
File "./run-tests.py", line 821, in run
self.runTest()
File "./run-tests.py", line 910, in runTest
if self._result.addOutputMismatch(self, ret, out, self._refout):
File "./run-tests.py", line 1774, in addOutputMismatch
rename(test.errpath, test.path)
File "./run-tests.py", line 571, in rename
os.remove(src)
WindowsError: [Error 32] The process cannot access the file because it is being
used by another process: 'c:\\Users\\Matt\\projects\\hg\\tests\\test-add.t.err'
This change doesn't fix the problem, but it seems like a simple enough
improvement.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sun, 17 Dec 2017 14:06:49 -0500 |
parents | 24528dba0e64 |
children | 4f5596e5e311 |
comparison
equal
deleted
inserted
replaced
35449:24528dba0e64 | 35450:e31773898197 |
---|---|
899 self.fail('no result code from test') | 899 self.fail('no result code from test') |
900 elif out != self._refout: | 900 elif out != self._refout: |
901 # Diff generation may rely on written .err file. | 901 # Diff generation may rely on written .err file. |
902 if (ret != 0 or out != self._refout) and not self._skipped \ | 902 if (ret != 0 or out != self._refout) and not self._skipped \ |
903 and not self._debug: | 903 and not self._debug: |
904 f = open(self.errpath, 'wb') | 904 with open(self.errpath, 'wb') as f: |
905 for line in out: | 905 for line in out: |
906 f.write(line) | 906 f.write(line) |
907 f.close() | |
908 | 907 |
909 # The result object handles diff calculation for us. | 908 # The result object handles diff calculation for us. |
910 if self._result.addOutputMismatch(self, ret, out, self._refout): | 909 if self._result.addOutputMismatch(self, ret, out, self._refout): |
911 # change was accepted, skip failing | 910 # change was accepted, skip failing |
912 return | 911 return |
939 # files are deleted | 938 # files are deleted |
940 shutil.rmtree(self._chgsockdir, True) | 939 shutil.rmtree(self._chgsockdir, True) |
941 | 940 |
942 if (self._ret != 0 or self._out != self._refout) and not self._skipped \ | 941 if (self._ret != 0 or self._out != self._refout) and not self._skipped \ |
943 and not self._debug and self._out: | 942 and not self._debug and self._out: |
944 f = open(self.errpath, 'wb') | 943 with open(self.errpath, 'wb') as f: |
945 for line in self._out: | 944 for line in self._out: |
946 f.write(line) | 945 f.write(line) |
947 f.close() | |
948 | 946 |
949 vlog("# Ret was:", self._ret, '(%s)' % self.name) | 947 vlog("# Ret was:", self._ret, '(%s)' % self.name) |
950 | 948 |
951 def _run(self, env): | 949 def _run(self, env): |
952 # This should be implemented in child classes to run tests. | 950 # This should be implemented in child classes to run tests. |
1085 | 1083 |
1086 return env | 1084 return env |
1087 | 1085 |
1088 def _createhgrc(self, path): | 1086 def _createhgrc(self, path): |
1089 """Create an hgrc file for this test.""" | 1087 """Create an hgrc file for this test.""" |
1090 hgrc = open(path, 'wb') | 1088 with open(path, 'wb') as hgrc: |
1091 hgrc.write(b'[ui]\n') | 1089 hgrc.write(b'[ui]\n') |
1092 hgrc.write(b'slash = True\n') | 1090 hgrc.write(b'slash = True\n') |
1093 hgrc.write(b'interactive = False\n') | 1091 hgrc.write(b'interactive = False\n') |
1094 hgrc.write(b'mergemarkers = detailed\n') | 1092 hgrc.write(b'mergemarkers = detailed\n') |
1095 hgrc.write(b'promptecho = True\n') | 1093 hgrc.write(b'promptecho = True\n') |
1096 hgrc.write(b'[defaults]\n') | 1094 hgrc.write(b'[defaults]\n') |
1097 hgrc.write(b'[devel]\n') | 1095 hgrc.write(b'[devel]\n') |
1098 hgrc.write(b'all-warnings = true\n') | 1096 hgrc.write(b'all-warnings = true\n') |
1099 hgrc.write(b'default-date = 0 0\n') | 1097 hgrc.write(b'default-date = 0 0\n') |
1100 hgrc.write(b'[largefiles]\n') | 1098 hgrc.write(b'[largefiles]\n') |
1101 hgrc.write(b'usercache = %s\n' % | 1099 hgrc.write(b'usercache = %s\n' % |
1102 (os.path.join(self._testtmp, b'.cache/largefiles'))) | 1100 (os.path.join(self._testtmp, b'.cache/largefiles'))) |
1103 hgrc.write(b'[lfs]\n') | 1101 hgrc.write(b'[lfs]\n') |
1104 hgrc.write(b'usercache = %s\n' % | 1102 hgrc.write(b'usercache = %s\n' % |
1105 (os.path.join(self._testtmp, b'.cache/lfs'))) | 1103 (os.path.join(self._testtmp, b'.cache/lfs'))) |
1106 hgrc.write(b'[web]\n') | 1104 hgrc.write(b'[web]\n') |
1107 hgrc.write(b'address = localhost\n') | 1105 hgrc.write(b'address = localhost\n') |
1108 hgrc.write(b'ipv6 = %s\n' % str(self._useipv6).encode('ascii')) | 1106 hgrc.write(b'ipv6 = %s\n' % str(self._useipv6).encode('ascii')) |
1109 | 1107 |
1110 for opt in self._extraconfigopts: | 1108 for opt in self._extraconfigopts: |
1111 section, key = opt.encode('utf-8').split(b'.', 1) | 1109 section, key = opt.encode('utf-8').split(b'.', 1) |
1112 assert b'=' in key, ('extra config opt %s must ' | 1110 assert b'=' in key, ('extra config opt %s must ' |
1113 'have an = for assignment' % opt) | 1111 'have an = for assignment' % opt) |
1114 hgrc.write(b'[%s]\n%s\n' % (section, key)) | 1112 hgrc.write(b'[%s]\n%s\n' % (section, key)) |
1115 hgrc.close() | |
1116 | 1113 |
1117 def fail(self, msg): | 1114 def fail(self, msg): |
1118 # unittest differentiates between errored and failed. | 1115 # unittest differentiates between errored and failed. |
1119 # Failed is denoted by AssertionError (by default at least). | 1116 # Failed is denoted by AssertionError (by default at least). |
1120 raise AssertionError(msg) | 1117 raise AssertionError(msg) |
1230 @property | 1227 @property |
1231 def refpath(self): | 1228 def refpath(self): |
1232 return os.path.join(self._testdir, self.bname) | 1229 return os.path.join(self._testdir, self.bname) |
1233 | 1230 |
1234 def _run(self, env): | 1231 def _run(self, env): |
1235 f = open(self.path, 'rb') | 1232 with open(self.path, 'rb') as f: |
1236 lines = f.readlines() | 1233 lines = f.readlines() |
1237 f.close() | |
1238 | 1234 |
1239 # .t file is both reference output and the test input, keep reference | 1235 # .t file is both reference output and the test input, keep reference |
1240 # output updated with the the test input. This avoids some race | 1236 # output updated with the the test input. This avoids some race |
1241 # conditions where the reference output does not match the actual test. | 1237 # conditions where the reference output does not match the actual test. |
1242 if self._refout is not None: | 1238 if self._refout is not None: |
1244 | 1240 |
1245 salt, script, after, expected = self._parsetest(lines) | 1241 salt, script, after, expected = self._parsetest(lines) |
1246 | 1242 |
1247 # Write out the generated script. | 1243 # Write out the generated script. |
1248 fname = b'%s.sh' % self._testtmp | 1244 fname = b'%s.sh' % self._testtmp |
1249 f = open(fname, 'wb') | 1245 with open(fname, 'wb') as f: |
1250 for l in script: | 1246 for l in script: |
1251 f.write(l) | 1247 f.write(l) |
1252 f.close() | |
1253 | 1248 |
1254 cmd = b'%s "%s"' % (self._shell, fname) | 1249 cmd = b'%s "%s"' % (self._shell, fname) |
1255 vlog("# Running", cmd) | 1250 vlog("# Running", cmd) |
1256 | 1251 |
1257 exitcode, output = self._runcommand(cmd, env) | 1252 exitcode, output = self._runcommand(cmd, env) |
1882 if self._retest and not os.path.exists(test.errpath): | 1877 if self._retest and not os.path.exists(test.errpath): |
1883 result.addIgnore(test, 'not retesting') | 1878 result.addIgnore(test, 'not retesting') |
1884 continue | 1879 continue |
1885 | 1880 |
1886 if self._keywords: | 1881 if self._keywords: |
1887 f = open(test.path, 'rb') | 1882 with open(test.path, 'rb') as f: |
1888 t = f.read().lower() + test.bname.lower() | 1883 t = f.read().lower() + test.bname.lower() |
1889 f.close() | |
1890 ignored = False | 1884 ignored = False |
1891 for k in self._keywords.lower().split(): | 1885 for k in self._keywords.lower().split(): |
1892 if k not in t: | 1886 if k not in t: |
1893 result.addIgnore(test, "doesn't match keyword") | 1887 result.addIgnore(test, "doesn't match keyword") |
1894 ignored = True | 1888 ignored = True |
2820 os.remove(installerrs) | 2814 os.remove(installerrs) |
2821 except OSError as e: | 2815 except OSError as e: |
2822 if e.errno != errno.ENOENT: | 2816 if e.errno != errno.ENOENT: |
2823 raise | 2817 raise |
2824 else: | 2818 else: |
2825 f = open(installerrs, 'rb') | 2819 with open(installerrs, 'rb') as f: |
2826 for line in f: | 2820 for line in f: |
2827 if PYTHON3: | 2821 if PYTHON3: |
2828 sys.stdout.buffer.write(line) | 2822 sys.stdout.buffer.write(line) |
2829 else: | 2823 else: |
2830 sys.stdout.write(line) | 2824 sys.stdout.write(line) |
2831 f.close() | |
2832 sys.exit(1) | 2825 sys.exit(1) |
2833 os.chdir(self._testdir) | 2826 os.chdir(self._testdir) |
2834 | 2827 |
2835 self._usecorrectpython() | 2828 self._usecorrectpython() |
2836 | 2829 |
2837 if self.options.py3k_warnings and not self.options.anycoverage: | 2830 if self.options.py3k_warnings and not self.options.anycoverage: |
2838 vlog("# Updating hg command to enable Py3k Warnings switch") | 2831 vlog("# Updating hg command to enable Py3k Warnings switch") |
2839 f = open(os.path.join(self._bindir, 'hg'), 'rb') | 2832 with open(os.path.join(self._bindir, 'hg'), 'rb') as f: |
2840 lines = [line.rstrip() for line in f] | 2833 lines = [line.rstrip() for line in f] |
2841 lines[0] += ' -3' | 2834 lines[0] += ' -3' |
2842 f.close() | 2835 with open(os.path.join(self._bindir, 'hg'), 'wb') as f: |
2843 f = open(os.path.join(self._bindir, 'hg'), 'wb') | 2836 for line in lines: |
2844 for line in lines: | 2837 f.write(line + '\n') |
2845 f.write(line + '\n') | |
2846 f.close() | |
2847 | 2838 |
2848 hgbat = os.path.join(self._bindir, b'hg.bat') | 2839 hgbat = os.path.join(self._bindir, b'hg.bat') |
2849 if os.path.isfile(hgbat): | 2840 if os.path.isfile(hgbat): |
2850 # hg.bat expects to be put in bin/scripts while run-tests.py | 2841 # hg.bat expects to be put in bin/scripts while run-tests.py |
2851 # installation layout put it in bin/ directly. Fix it | 2842 # installation layout put it in bin/ directly. Fix it |
2852 f = open(hgbat, 'rb') | 2843 with open(hgbat, 'rb') as f: |
2853 data = f.read() | 2844 data = f.read() |
2854 f.close() | |
2855 if b'"%~dp0..\python" "%~dp0hg" %*' in data: | 2845 if b'"%~dp0..\python" "%~dp0hg" %*' in data: |
2856 data = data.replace(b'"%~dp0..\python" "%~dp0hg" %*', | 2846 data = data.replace(b'"%~dp0..\python" "%~dp0hg" %*', |
2857 b'"%~dp0python" "%~dp0hg" %*') | 2847 b'"%~dp0python" "%~dp0hg" %*') |
2858 f = open(hgbat, 'wb') | 2848 with open(hgbat, 'wb') as f: |
2859 f.write(data) | 2849 f.write(data) |
2860 f.close() | |
2861 else: | 2850 else: |
2862 print('WARNING: cannot fix hg.bat reference to python.exe') | 2851 print('WARNING: cannot fix hg.bat reference to python.exe') |
2863 | 2852 |
2864 if self.options.anycoverage: | 2853 if self.options.anycoverage: |
2865 custom = os.path.join(self._testdir, 'sitecustomize.py') | 2854 custom = os.path.join(self._testdir, 'sitecustomize.py') |