##// END OF EJS Templates
run-tests: support multiple cases in .t test...
Jun Wu -
r32317:7340465b default
parent child Browse files
Show More
@@ -216,6 +216,22 b' def parselistfiles(files, listtype, warn'
216 f.close()
216 f.close()
217 return entries
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 def getparser():
235 def getparser():
220 """Obtain the OptionParser used by the CLI."""
236 """Obtain the OptionParser used by the CLI."""
221 parser = optparse.OptionParser("%prog [options] [tests]")
237 parser = optparse.OptionParser("%prog [options] [tests]")
@@ -587,6 +603,7 b' class Test(unittest.TestCase):'
587 self.bname = os.path.basename(path)
603 self.bname = os.path.basename(path)
588 self.name = _strpath(self.bname)
604 self.name = _strpath(self.bname)
589 self._testdir = os.path.dirname(path)
605 self._testdir = os.path.dirname(path)
606 self._tmpname = os.path.basename(path)
590 self.errpath = os.path.join(self._testdir, b'%s.err' % self.bname)
607 self.errpath = os.path.join(self._testdir, b'%s.err' % self.bname)
591
608
592 self._threadtmp = tmpdir
609 self._threadtmp = tmpdir
@@ -646,7 +663,7 b' class Test(unittest.TestCase):'
646 if e.errno != errno.EEXIST:
663 if e.errno != errno.EEXIST:
647 raise
664 raise
648
665
649 name = os.path.basename(self.path)
666 name = self._tmpname
650 self._testtmp = os.path.join(self._threadtmp, name)
667 self._testtmp = os.path.join(self._threadtmp, name)
651 os.mkdir(self._testtmp)
668 os.mkdir(self._testtmp)
652
669
@@ -1055,6 +1072,19 b' class TTest(Test):'
1055 ESCAPEMAP = dict((bchr(i), br'\x%02x' % i) for i in range(256))
1072 ESCAPEMAP = dict((bchr(i), br'\x%02x' % i) for i in range(256))
1056 ESCAPEMAP.update({b'\\': b'\\\\', b'\r': br'\r'})
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 @property
1088 @property
1059 def refpath(self):
1089 def refpath(self):
1060 return os.path.join(self._testdir, self.bname)
1090 return os.path.join(self._testdir, self.bname)
@@ -1110,6 +1140,20 b' class TTest(Test):'
1110 self._timeout = self._slowtimeout
1140 self._timeout = self._slowtimeout
1111 return True, None
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 def _parsetest(self, lines):
1157 def _parsetest(self, lines):
1114 # We generate a shell script which outputs unique markers to line
1158 # We generate a shell script which outputs unique markers to line
1115 # up script results with our source. These markers include input
1159 # up script results with our source. These markers include input
@@ -1167,7 +1211,7 b' class TTest(Test):'
1167 after.setdefault(pos, []).append(' !!! invalid #if\n')
1211 after.setdefault(pos, []).append(' !!! invalid #if\n')
1168 if skipping is not None:
1212 if skipping is not None:
1169 after.setdefault(pos, []).append(' !!! nested #if\n')
1213 after.setdefault(pos, []).append(' !!! nested #if\n')
1170 skipping = not self._hghave(lsplit[1:])[0]
1214 skipping = not self._iftest(lsplit[1:])
1171 after.setdefault(pos, []).append(l)
1215 after.setdefault(pos, []).append(l)
1172 elif l.startswith(b'#else'):
1216 elif l.startswith(b'#else'):
1173 if skipping is None:
1217 if skipping is None:
@@ -2263,14 +2307,29 b' class TestRunner(object):'
2263 else:
2307 else:
2264 args = os.listdir(b'.')
2308 args = os.listdir(b'.')
2265
2309
2266 return [{'path': t} for t in args
2310 tests = []
2267 if os.path.basename(t).startswith(b'test-')
2311 for t in args:
2268 and (t.endswith(b'.py') or t.endswith(b'.t'))]
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 def _runtests(self, testdescs):
2326 def _runtests(self, testdescs):
2271 def _reloadtest(test, i):
2327 def _reloadtest(test, i):
2272 # convert a test back to its description dict
2328 # convert a test back to its description dict
2273 desc = {'path': test.path}
2329 desc = {'path': test.path}
2330 case = getattr(test, '_case', None)
2331 if case:
2332 desc['case'] = case
2274 return self._gettest(desc, i)
2333 return self._gettest(desc, i)
2275
2334
2276 try:
2335 try:
@@ -2286,7 +2345,12 b' class TestRunner(object):'
2286 if self.options.restart:
2345 if self.options.restart:
2287 orig = list(testdescs)
2346 orig = list(testdescs)
2288 while testdescs:
2347 while testdescs:
2289 if os.path.exists(testdescs[0]['path'] + ".err"):
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 break
2354 break
2291 testdescs.pop(0)
2355 testdescs.pop(0)
2292 if not testdescs:
2356 if not testdescs:
@@ -2369,6 +2433,9 b' class TestRunner(object):'
2369 refpath = os.path.join(self._testdir, path)
2433 refpath = os.path.join(self._testdir, path)
2370 tmpdir = os.path.join(self._hgtmp, b'child%d' % count)
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 t = testcls(refpath, tmpdir,
2439 t = testcls(refpath, tmpdir,
2373 keeptmpdir=self.options.keep_tmpdir,
2440 keeptmpdir=self.options.keep_tmpdir,
2374 debug=self.options.debug,
2441 debug=self.options.debug,
@@ -2379,7 +2446,7 b' class TestRunner(object):'
2379 shell=self.options.shell,
2446 shell=self.options.shell,
2380 hgcommand=self._hgcommand,
2447 hgcommand=self._hgcommand,
2381 usechg=bool(self.options.with_chg or self.options.chg),
2448 usechg=bool(self.options.with_chg or self.options.chg),
2382 useipv6=useipv6)
2449 useipv6=useipv6, **kwds)
2383 t.should_reload = True
2450 t.should_reload = True
2384 return t
2451 return t
2385
2452
@@ -900,3 +900,78 b' support for bisecting failed tests autom'
900 # Ran 1 tests, 0 skipped, 0 warned, 1 failed.
900 # Ran 1 tests, 0 skipped, 0 warned, 1 failed.
901 python hash seed: * (glob)
901 python hash seed: * (glob)
902 [1]
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