comparison tests/run-tests.py @ 25388:6025cac3d02f

tests: add (?) flag for optional lines When the test engine fails to match output on a line marked with (?), it will simply continue to the next expected line and try again. This allows simplifying tests that have either version-specific or non-fixed behavior, for instance: $ coin-flip heads (?) tails (?) (There's no form of back-tracking attempted, so optional matches should be specific.)
author Matt Mackall <mpm@selenic.com>
date Sun, 31 May 2015 16:59:34 -0500
parents 8f88f768e24c
children 905c32321cfb
comparison
equal deleted inserted replaced
25387:390a10b7843b 25388:6025cac3d02f
1041 for l in output: 1041 for l in output:
1042 lout, lcmd = l, None 1042 lout, lcmd = l, None
1043 if salt in l: 1043 if salt in l:
1044 lout, lcmd = l.split(salt, 1) 1044 lout, lcmd = l.split(salt, 1)
1045 1045
1046 if lout: 1046 while lout:
1047 if not lout.endswith(b'\n'): 1047 if not lout.endswith(b'\n'):
1048 lout += b' (no-eol)\n' 1048 lout += b' (no-eol)\n'
1049 1049
1050 # Find the expected output at the current position. 1050 # Find the expected output at the current position.
1051 el = None 1051 el = None
1058 lout = el[:-1] + ' (glob)\n' 1058 lout = el[:-1] + ' (glob)\n'
1059 r = '' # Warn only this line. 1059 r = '' # Warn only this line.
1060 elif r == '-glob': 1060 elif r == '-glob':
1061 lout = ''.join(el.rsplit(' (glob)', 1)) 1061 lout = ''.join(el.rsplit(' (glob)', 1))
1062 r = '' # Warn only this line. 1062 r = '' # Warn only this line.
1063 elif r == "retry":
1064 postout.append(b' ' + el)
1065 continue
1063 else: 1066 else:
1064 log('\ninfo, unknown linematch result: %r\n' % r) 1067 log('\ninfo, unknown linematch result: %r\n' % r)
1065 r = False 1068 r = False
1066 if r: 1069 if r:
1067 postout.append(b' ' + el) 1070 postout.append(b' ' + el)
1072 postout.append(b' ' + lout) # Let diff deal with it. 1075 postout.append(b' ' + lout) # Let diff deal with it.
1073 if r != '': # If line failed. 1076 if r != '': # If line failed.
1074 warnonly = 3 # for sure not 1077 warnonly = 3 # for sure not
1075 elif warnonly == 1: # Is "not yet" and line is warn only. 1078 elif warnonly == 1: # Is "not yet" and line is warn only.
1076 warnonly = 2 # Yes do warn. 1079 warnonly = 2 # Yes do warn.
1080 break
1081
1082 # clean up any optional leftovers
1083 while expected.get(pos, None):
1084 el = expected[pos].pop(0)
1085 if not el.endswith(" (?)\n"):
1086 expected[pos].insert(0, el)
1087 break
1088 postout.append(b' ' + el)
1077 1089
1078 if lcmd: 1090 if lcmd:
1079 # Add on last return code. 1091 # Add on last return code.
1080 ret = int(lcmd.split()[1]) 1092 ret = int(lcmd.split()[1])
1081 if ret != 0: 1093 if ret != 0:
1134 res += re.escape(c) 1146 res += re.escape(c)
1135 return TTest.rematch(res, l) 1147 return TTest.rematch(res, l)
1136 1148
1137 @staticmethod 1149 @staticmethod
1138 def linematch(el, l): 1150 def linematch(el, l):
1151 retry = False
1139 if el == l: # perfect match (fast) 1152 if el == l: # perfect match (fast)
1140 return True 1153 return True
1141 if el: 1154 if el:
1155 if el.endswith(" (?)\n"):
1156 retry = "retry"
1157 el = el[:-5] + "\n"
1142 if el.endswith(b" (esc)\n"): 1158 if el.endswith(b" (esc)\n"):
1143 if PYTHON3: 1159 if PYTHON3:
1144 el = el[:-7].decode('unicode_escape') + '\n' 1160 el = el[:-7].decode('unicode_escape') + '\n'
1145 el = el.encode('utf-8') 1161 el = el.encode('utf-8')
1146 else: 1162 else:
1147 el = el[:-7].decode('string-escape') + '\n' 1163 el = el[:-7].decode('string-escape') + '\n'
1148 if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l: 1164 if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
1149 return True 1165 return True
1150 if el.endswith(b" (re)\n"): 1166 if el.endswith(b" (re)\n"):
1151 return TTest.rematch(el[:-6], l) 1167 return TTest.rematch(el[:-6], l) or retry
1152 if el.endswith(b" (glob)\n"): 1168 if el.endswith(b" (glob)\n"):
1153 # ignore '(glob)' added to l by 'replacements' 1169 # ignore '(glob)' added to l by 'replacements'
1154 if l.endswith(b" (glob)\n"): 1170 if l.endswith(b" (glob)\n"):
1155 l = l[:-8] + b"\n" 1171 l = l[:-8] + b"\n"
1156 return TTest.globmatch(el[:-8], l) 1172 return TTest.globmatch(el[:-8], l)
1157 if os.altsep and l.replace(b'\\', b'/') == el: 1173 if os.altsep and l.replace(b'\\', b'/') == el:
1158 return b'+glob' 1174 return b'+glob'
1159 return False 1175 return retry
1160 1176
1161 @staticmethod 1177 @staticmethod
1162 def parsehghaveoutput(lines): 1178 def parsehghaveoutput(lines):
1163 '''Parse hghave log lines. 1179 '''Parse hghave log lines.
1164 1180