Show More
@@ -216,6 +216,22 b' def parselistfiles(files, listtype, warn' | |||
|
216 | 216 | f.close() |
|
217 | 217 | return entries |
|
218 | 218 | |
|
219 | def parsettestcases(path): | |
|
220 | """read a .t test file, return a set of test case names | |
|
221 | ||
|
222 | If path does not exist, return an empty set. | |
|
223 | """ | |
|
224 | cases = set() | |
|
225 | try: | |
|
226 | with open(path, 'rb') as f: | |
|
227 | for l in f: | |
|
228 | if l.startswith(b'#testcases '): | |
|
229 | cases.update(l[11:].split()) | |
|
230 | except IOError as ex: | |
|
231 | if ex.errno != errno.ENOENT: | |
|
232 | raise | |
|
233 | return cases | |
|
234 | ||
|
219 | 235 | def getparser(): |
|
220 | 236 | """Obtain the OptionParser used by the CLI.""" |
|
221 | 237 | parser = optparse.OptionParser("%prog [options] [tests]") |
@@ -587,6 +603,7 b' class Test(unittest.TestCase):' | |||
|
587 | 603 | self.bname = os.path.basename(path) |
|
588 | 604 | self.name = _strpath(self.bname) |
|
589 | 605 | self._testdir = os.path.dirname(path) |
|
606 | self._tmpname = os.path.basename(path) | |
|
590 | 607 | self.errpath = os.path.join(self._testdir, b'%s.err' % self.bname) |
|
591 | 608 | |
|
592 | 609 | self._threadtmp = tmpdir |
@@ -646,7 +663,7 b' class Test(unittest.TestCase):' | |||
|
646 | 663 | if e.errno != errno.EEXIST: |
|
647 | 664 | raise |
|
648 | 665 | |
|
649 |
name = |
|
|
666 | name = self._tmpname | |
|
650 | 667 | self._testtmp = os.path.join(self._threadtmp, name) |
|
651 | 668 | os.mkdir(self._testtmp) |
|
652 | 669 | |
@@ -1055,6 +1072,19 b' class TTest(Test):' | |||
|
1055 | 1072 | ESCAPEMAP = dict((bchr(i), br'\x%02x' % i) for i in range(256)) |
|
1056 | 1073 | ESCAPEMAP.update({b'\\': b'\\\\', b'\r': br'\r'}) |
|
1057 | 1074 | |
|
1075 | def __init__(self, path, *args, **kwds): | |
|
1076 | # accept an extra "case" parameter | |
|
1077 | case = None | |
|
1078 | if 'case' in kwds: | |
|
1079 | case = kwds.pop('case') | |
|
1080 | self._case = case | |
|
1081 | self._allcases = parsettestcases(path) | |
|
1082 | super(TTest, self).__init__(path, *args, **kwds) | |
|
1083 | if case: | |
|
1084 | self.name = '%s (case %s)' % (self.name, _strpath(case)) | |
|
1085 | self.errpath = b'%s.%s.err' % (self.errpath[:-4], case) | |
|
1086 | self._tmpname += b'-%s' % case | |
|
1087 | ||
|
1058 | 1088 | @property |
|
1059 | 1089 | def refpath(self): |
|
1060 | 1090 | return os.path.join(self._testdir, self.bname) |
@@ -1110,6 +1140,20 b' class TTest(Test):' | |||
|
1110 | 1140 | self._timeout = self._slowtimeout |
|
1111 | 1141 | return True, None |
|
1112 | 1142 | |
|
1143 | def _iftest(self, args): | |
|
1144 | # implements "#if" | |
|
1145 | reqs = [] | |
|
1146 | for arg in args: | |
|
1147 | if arg.startswith(b'no-') and arg[3:] in self._allcases: | |
|
1148 | if arg[3:] == self._case: | |
|
1149 | return False | |
|
1150 | elif arg in self._allcases: | |
|
1151 | if arg != self._case: | |
|
1152 | return False | |
|
1153 | else: | |
|
1154 | reqs.append(arg) | |
|
1155 | return self._hghave(reqs)[0] | |
|
1156 | ||
|
1113 | 1157 | def _parsetest(self, lines): |
|
1114 | 1158 | # We generate a shell script which outputs unique markers to line |
|
1115 | 1159 | # up script results with our source. These markers include input |
@@ -1167,7 +1211,7 b' class TTest(Test):' | |||
|
1167 | 1211 | after.setdefault(pos, []).append(' !!! invalid #if\n') |
|
1168 | 1212 | if skipping is not None: |
|
1169 | 1213 | after.setdefault(pos, []).append(' !!! nested #if\n') |
|
1170 |
skipping = not self._ |
|
|
1214 | skipping = not self._iftest(lsplit[1:]) | |
|
1171 | 1215 | after.setdefault(pos, []).append(l) |
|
1172 | 1216 | elif l.startswith(b'#else'): |
|
1173 | 1217 | if skipping is None: |
@@ -2263,14 +2307,29 b' class TestRunner(object):' | |||
|
2263 | 2307 | else: |
|
2264 | 2308 | args = os.listdir(b'.') |
|
2265 | 2309 | |
|
2266 | return [{'path': t} for t in args | |
|
2267 | if os.path.basename(t).startswith(b'test-') | |
|
2268 | and (t.endswith(b'.py') or t.endswith(b'.t'))] | |
|
2310 | tests = [] | |
|
2311 | for t in args: | |
|
2312 | if not (os.path.basename(t).startswith(b'test-') | |
|
2313 | and (t.endswith(b'.py') or t.endswith(b'.t'))): | |
|
2314 | continue | |
|
2315 | if t.endswith(b'.t'): | |
|
2316 | # .t file may contain multiple test cases | |
|
2317 | cases = sorted(parsettestcases(t)) | |
|
2318 | if cases: | |
|
2319 | tests += [{'path': t, 'case': c} for c in sorted(cases)] | |
|
2320 | else: | |
|
2321 | tests.append({'path': t}) | |
|
2322 | else: | |
|
2323 | tests.append({'path': t}) | |
|
2324 | return tests | |
|
2269 | 2325 | |
|
2270 | 2326 | def _runtests(self, testdescs): |
|
2271 | 2327 | def _reloadtest(test, i): |
|
2272 | 2328 | # convert a test back to its description dict |
|
2273 | 2329 | desc = {'path': test.path} |
|
2330 | case = getattr(test, '_case', None) | |
|
2331 | if case: | |
|
2332 | desc['case'] = case | |
|
2274 | 2333 | return self._gettest(desc, i) |
|
2275 | 2334 | |
|
2276 | 2335 | try: |
@@ -2286,7 +2345,12 b' class TestRunner(object):' | |||
|
2286 | 2345 | if self.options.restart: |
|
2287 | 2346 | orig = list(testdescs) |
|
2288 | 2347 | while testdescs: |
|
2289 |
|
|
|
2348 | desc = testdescs[0] | |
|
2349 | if 'case' in desc: | |
|
2350 | errpath = b'%s.%s.err' % (desc['path'], desc['case']) | |
|
2351 | else: | |
|
2352 | errpath = b'%s.err' % desc['path'] | |
|
2353 | if os.path.exists(errpath): | |
|
2290 | 2354 | break |
|
2291 | 2355 | testdescs.pop(0) |
|
2292 | 2356 | if not testdescs: |
@@ -2369,6 +2433,9 b' class TestRunner(object):' | |||
|
2369 | 2433 | refpath = os.path.join(self._testdir, path) |
|
2370 | 2434 | tmpdir = os.path.join(self._hgtmp, b'child%d' % count) |
|
2371 | 2435 | |
|
2436 | # extra keyword parameters. 'case' is used by .t tests | |
|
2437 | kwds = dict((k, testdesc[k]) for k in ['case'] if k in testdesc) | |
|
2438 | ||
|
2372 | 2439 | t = testcls(refpath, tmpdir, |
|
2373 | 2440 | keeptmpdir=self.options.keep_tmpdir, |
|
2374 | 2441 | debug=self.options.debug, |
@@ -2379,7 +2446,7 b' class TestRunner(object):' | |||
|
2379 | 2446 | shell=self.options.shell, |
|
2380 | 2447 | hgcommand=self._hgcommand, |
|
2381 | 2448 | usechg=bool(self.options.with_chg or self.options.chg), |
|
2382 | useipv6=useipv6) | |
|
2449 | useipv6=useipv6, **kwds) | |
|
2383 | 2450 | t.should_reload = True |
|
2384 | 2451 | return t |
|
2385 | 2452 |
@@ -900,3 +900,78 b' support for bisecting failed tests autom' | |||
|
900 | 900 | # Ran 1 tests, 0 skipped, 0 warned, 1 failed. |
|
901 | 901 | python hash seed: * (glob) |
|
902 | 902 | [1] |
|
903 | ||
|
904 | $ cd .. | |
|
905 | ||
|
906 | Test cases in .t files | |
|
907 | ====================== | |
|
908 | $ mkdir cases | |
|
909 | $ cd cases | |
|
910 | $ cat > test-cases-abc.t <<'EOF' | |
|
911 | > #testcases A B C | |
|
912 | > $ V=B | |
|
913 | > #if A | |
|
914 | > $ V=A | |
|
915 | > #endif | |
|
916 | > #if C | |
|
917 | > $ V=C | |
|
918 | > #endif | |
|
919 | > $ echo $V | sed 's/A/C/' | |
|
920 | > C | |
|
921 | > #if C | |
|
922 | > $ [ $V = C ] | |
|
923 | > #endif | |
|
924 | > #if A | |
|
925 | > $ [ $V = C ] | |
|
926 | > [1] | |
|
927 | > #endif | |
|
928 | > #if no-C | |
|
929 | > $ [ $V = C ] | |
|
930 | > [1] | |
|
931 | > #endif | |
|
932 | > $ [ $V = D ] | |
|
933 | > [1] | |
|
934 | > EOF | |
|
935 | $ rt | |
|
936 | . | |
|
937 | --- $TESTTMP/anothertests/cases/test-cases-abc.t | |
|
938 | +++ $TESTTMP/anothertests/cases/test-cases-abc.t.B.err | |
|
939 | @@ -7,7 +7,7 @@ | |
|
940 | $ V=C | |
|
941 | #endif | |
|
942 | $ echo $V | sed 's/A/C/' | |
|
943 | - C | |
|
944 | + B | |
|
945 | #if C | |
|
946 | $ [ $V = C ] | |
|
947 | #endif | |
|
948 | ||
|
949 | ERROR: test-cases-abc.t (case B) output changed | |
|
950 | !. | |
|
951 | Failed test-cases-abc.t (case B): output changed | |
|
952 | # Ran 3 tests, 0 skipped, 0 warned, 1 failed. | |
|
953 | python hash seed: * (glob) | |
|
954 | [1] | |
|
955 | ||
|
956 | --restart works | |
|
957 | ||
|
958 | $ rt --restart | |
|
959 | ||
|
960 | --- $TESTTMP/anothertests/cases/test-cases-abc.t | |
|
961 | +++ $TESTTMP/anothertests/cases/test-cases-abc.t.B.err | |
|
962 | @@ -7,7 +7,7 @@ | |
|
963 | $ V=C | |
|
964 | #endif | |
|
965 | $ echo $V | sed 's/A/C/' | |
|
966 | - C | |
|
967 | + B | |
|
968 | #if C | |
|
969 | $ [ $V = C ] | |
|
970 | #endif | |
|
971 | ||
|
972 | ERROR: test-cases-abc.t (case B) output changed | |
|
973 | !. | |
|
974 | Failed test-cases-abc.t (case B): output changed | |
|
975 | # Ran 2 tests, 0 skipped, 0 warned, 1 failed. | |
|
976 | python hash seed: * (glob) | |
|
977 | [1] |
General Comments 0
You need to be logged in to leave comments.
Login now