##// END OF EJS Templates
testrunner: allow multiple #testcases...
Martin von Zweigbergk -
r38860:3086a862 default
parent child Browse files
Show More
@@ -285,12 +285,12 b' def parsettestcases(path):'
285
285
286 If path does not exist, return an empty set.
286 If path does not exist, return an empty set.
287 """
287 """
288 cases = set()
288 cases = []
289 try:
289 try:
290 with open(path, 'rb') as f:
290 with open(path, 'rb') as f:
291 for l in f:
291 for l in f:
292 if l.startswith(b'#testcases '):
292 if l.startswith(b'#testcases '):
293 cases.update(l[11:].split())
293 cases.append(sorted(l[11:].split()))
294 except IOError as ex:
294 except IOError as ex:
295 if ex.errno != errno.ENOENT:
295 if ex.errno != errno.ENOENT:
296 raise
296 raise
@@ -1242,14 +1242,15 b' class TTest(Test):'
1242
1242
1243 def __init__(self, path, *args, **kwds):
1243 def __init__(self, path, *args, **kwds):
1244 # accept an extra "case" parameter
1244 # accept an extra "case" parameter
1245 case = kwds.pop('case', None)
1245 case = kwds.pop('case', [])
1246 self._case = case
1246 self._case = case
1247 self._allcases = parsettestcases(path)
1247 self._allcases = {x for y in parsettestcases(path) for x in y}
1248 super(TTest, self).__init__(path, *args, **kwds)
1248 super(TTest, self).__init__(path, *args, **kwds)
1249 if case:
1249 if case:
1250 self.name = '%s#%s' % (self.name, _strpath(case))
1250 casepath = _strpath('#'.join(case))
1251 self.errpath = b'%s#%s.err' % (self.errpath[:-4], case)
1251 self.name = '%s#%s' % (self.name, casepath)
1252 self._tmpname += b'-%s' % case
1252 self.errpath = b'%s#%s.err' % (self.errpath[:-4], casepath)
1253 self._tmpname += b'-%s' % casepath
1253 self._have = {}
1254 self._have = {}
1254
1255
1255 @property
1256 @property
@@ -1323,10 +1324,10 b' class TTest(Test):'
1323 reqs = []
1324 reqs = []
1324 for arg in args:
1325 for arg in args:
1325 if arg.startswith(b'no-') and arg[3:] in self._allcases:
1326 if arg.startswith(b'no-') and arg[3:] in self._allcases:
1326 if arg[3:] == self._case:
1327 if arg[3:] in self._case:
1327 return False
1328 return False
1328 elif arg in self._allcases:
1329 elif arg in self._allcases:
1329 if arg != self._case:
1330 if arg not in self._case:
1330 return False
1331 return False
1331 else:
1332 else:
1332 reqs.append(arg)
1333 reqs.append(arg)
@@ -1370,10 +1371,11 b' class TTest(Test):'
1370 if os.getenv('MSYSTEM'):
1371 if os.getenv('MSYSTEM'):
1371 script.append(b'alias pwd="pwd -W"\n')
1372 script.append(b'alias pwd="pwd -W"\n')
1372 if self._case:
1373 if self._case:
1374 casestr = '#'.join(self._case)
1373 if isinstance(self._case, str):
1375 if isinstance(self._case, str):
1374 quoted = shellquote(self._case)
1376 quoted = shellquote(casestr)
1375 else:
1377 else:
1376 quoted = shellquote(self._case.decode('utf8')).encode('utf8')
1378 quoted = shellquote(casestr.decode('utf8')).encode('utf8')
1377 script.append(b'TESTCASE=%s\n' % quoted)
1379 script.append(b'TESTCASE=%s\n' % quoted)
1378 script.append(b'export TESTCASE\n')
1380 script.append(b'export TESTCASE\n')
1379
1381
@@ -2666,31 +2668,42 b' class TestRunner(object):'
2666 expanded_args.append(arg)
2668 expanded_args.append(arg)
2667 args = expanded_args
2669 args = expanded_args
2668
2670
2669 testcasepattern = re.compile(br'([\w-]+\.t|py)(#([a-zA-Z0-9_\-\.]+))')
2671 testcasepattern = re.compile(br'([\w-]+\.t|py)(#([a-zA-Z0-9_\-\.#]+))')
2670 tests = []
2672 tests = []
2671 for t in args:
2673 for t in args:
2672 case = None
2674 case = []
2673
2675
2674 if not (os.path.basename(t).startswith(b'test-')
2676 if not (os.path.basename(t).startswith(b'test-')
2675 and (t.endswith(b'.py') or t.endswith(b'.t'))):
2677 and (t.endswith(b'.py') or t.endswith(b'.t'))):
2676
2678
2677 m = testcasepattern.match(t)
2679 m = testcasepattern.match(t)
2678 if m is not None:
2680 if m is not None:
2679 t, _, case = m.groups()
2681 t, _, casestr = m.groups()
2682 if casestr:
2683 case = casestr.split('#')
2680 else:
2684 else:
2681 continue
2685 continue
2682
2686
2683 if t.endswith(b'.t'):
2687 if t.endswith(b'.t'):
2684 # .t file may contain multiple test cases
2688 # .t file may contain multiple test cases
2685 cases = sorted(parsettestcases(t))
2689 casedimensions = parsettestcases(t)
2686 if cases:
2690 if casedimensions:
2687 if case is not None and case in cases:
2691 cases = []
2688 tests += [{'path': t, 'case': case}]
2692 def addcases(case, casedimensions):
2689 elif case is not None and case not in cases:
2693 if not casedimensions:
2694 cases.append(case)
2695 else:
2696 for c in casedimensions[0]:
2697 addcases(case + [c], casedimensions[1:])
2698 addcases([], casedimensions)
2699 if case and case in cases:
2700 cases = [case]
2701 elif case:
2690 # Ignore invalid cases
2702 # Ignore invalid cases
2691 pass
2703 cases = []
2692 else:
2704 else:
2693 tests += [{'path': t, 'case': c} for c in sorted(cases)]
2705 pass
2706 tests += [{'path': t, 'case': c} for c in sorted(cases)]
2694 else:
2707 else:
2695 tests.append({'path': t})
2708 tests.append({'path': t})
2696 else:
2709 else:
@@ -2701,7 +2714,7 b' class TestRunner(object):'
2701 def _reloadtest(test, i):
2714 def _reloadtest(test, i):
2702 # convert a test back to its description dict
2715 # convert a test back to its description dict
2703 desc = {'path': test.path}
2716 desc = {'path': test.path}
2704 case = getattr(test, '_case', None)
2717 case = getattr(test, '_case', [])
2705 if case:
2718 if case:
2706 desc['case'] = case
2719 desc['case'] = case
2707 return self._gettest(desc, i)
2720 return self._gettest(desc, i)
@@ -2713,7 +2726,8 b' class TestRunner(object):'
2713 desc = testdescs[0]
2726 desc = testdescs[0]
2714 # desc['path'] is a relative path
2727 # desc['path'] is a relative path
2715 if 'case' in desc:
2728 if 'case' in desc:
2716 errpath = b'%s#%s.err' % (desc['path'], desc['case'])
2729 casestr = '#'.join(desc['case'])
2730 errpath = b'%s#%s.err' % (desc['path'], casestr)
2717 else:
2731 else:
2718 errpath = b'%s.err' % desc['path']
2732 errpath = b'%s.err' % desc['path']
2719 errpath = os.path.join(self._outputdir, errpath)
2733 errpath = os.path.join(self._outputdir, errpath)
@@ -896,6 +896,40 b' When "#testcases" is used in .t files'
896 ..
896 ..
897 # Ran 2 tests, 0 skipped, 0 failed.
897 # Ran 2 tests, 0 skipped, 0 failed.
898
898
899 When using multiple dimensions of "#testcases" in .t files
900
901 $ cat > test-cases.t <<'EOF'
902 > #testcases a b
903 > #testcases c d
904 > #if a d
905 > $ echo $TESTCASE
906 > a#d
907 > #endif
908 > #if b c
909 > $ echo yes
910 > no
911 > #endif
912 > EOF
913 $ rt test-cases.t
914 ..
915 --- $TESTTMP/test-cases.t
916 +++ $TESTTMP/test-cases.t#b#c.err
917 @@ -6,5 +6,5 @@
918 #endif
919 #if b c
920 $ echo yes
921 - no
922 + yes
923 #endif
924
925 ERROR: test-cases.t#b#c output changed
926 !.
927 Failed test-cases.t#b#c: output changed
928 # Ran 4 tests, 0 skipped, 1 failed.
929 python hash seed: * (glob)
930 [1]
931
932 $ rm test-cases.t#b#c.err
899 $ rm test-cases.t
933 $ rm test-cases.t
900
934
901 (reinstall)
935 (reinstall)
General Comments 0
You need to be logged in to leave comments. Login now