mute_utils.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import operator
  2. import re
  3. import xml.etree.ElementTree as ET
  4. from junit_utils import add_junit_property
  5. def pattern_to_re(pattern):
  6. res = []
  7. for c in pattern:
  8. if c == '*':
  9. res.append('.*')
  10. else:
  11. res.append(re.escape(c))
  12. return f"(?:^{''.join(res)}$)"
  13. class MuteTestCheck:
  14. def __init__(self, fn):
  15. self.regexps = []
  16. with open(fn, 'r') as fp:
  17. for line in fp:
  18. line = line.strip()
  19. pattern = pattern_to_re(line)
  20. try:
  21. self.regexps.append(re.compile(pattern))
  22. except re.error:
  23. print(f"Unable to compile regex {pattern!r}")
  24. raise
  25. def __call__(self, fullname):
  26. for r in self.regexps:
  27. if r.match(fullname):
  28. return True
  29. return False
  30. def mute_target(testcase):
  31. err_text = []
  32. err_msg = None
  33. found = False
  34. for node_name in ('failure', 'error'):
  35. while 1:
  36. err_node = testcase.find(node_name)
  37. if err_node is None:
  38. break
  39. msg = err_node.get('message')
  40. if msg:
  41. if err_msg is None:
  42. err_msg = msg
  43. else:
  44. err_text.append(msg)
  45. if err_node.text:
  46. err_text.append(err_node.text)
  47. found = True
  48. testcase.remove(err_node)
  49. if not found:
  50. return False
  51. skipped = ET.Element("skipped")
  52. if err_msg:
  53. skipped.set('message', err_msg)
  54. if err_text:
  55. skipped.text = '\n'.join(err_text)
  56. testcase.append(skipped)
  57. add_junit_property(testcase, "mute", "automatically muted based on rules")
  58. return True
  59. def remove_failure(node):
  60. while 1:
  61. failure = node.find("failure")
  62. if failure is None:
  63. break
  64. node.remove(failure)
  65. def op_attr(node, attr, op, value):
  66. v = int(node.get(attr, 0))
  67. node.set(attr, str(op(v, value)))
  68. def inc_attr(node, attr, value):
  69. return op_attr(node, attr, operator.add, value)
  70. def dec_attr(node, attr, value):
  71. return op_attr(node, attr, operator.sub, value)
  72. def update_suite_info(root, n_remove_failures=None, n_remove_errors=None, n_skipped=None):
  73. if n_remove_failures:
  74. dec_attr(root, "failures", n_remove_failures)
  75. if n_remove_errors:
  76. dec_attr(root, "errors", n_remove_errors)
  77. if n_skipped:
  78. inc_attr(root, "skipped", n_skipped)
  79. def recalc_suite_info(suite):
  80. tests = failures = skipped = 0
  81. elapsed = 0.0
  82. for case in suite.findall("testcase"):
  83. tests += 1
  84. elapsed += float(case.get("time", 0))
  85. if case.find("skipped"):
  86. skipped += 1
  87. if case.find("failure"):
  88. failures += 1
  89. suite.set("tests", str(tests))
  90. suite.set("failures", str(failures))
  91. suite.set("skipped", str(skipped))
  92. suite.set("time", str(elapsed))