testBazelReporter.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/env python3
  2. # Copyright Catch2 Authors
  3. # Distributed under the Boost Software License, Version 1.0.
  4. # (See accompanying file LICENSE_1_0.txt or copy at
  5. # https://www.boost.org/LICENSE_1_0.txt)
  6. # SPDX-License-Identifier: BSL-1.0
  7. import os
  8. import re
  9. import sys
  10. import xml.etree.ElementTree as ET
  11. import subprocess
  12. """
  13. Test that Catch2 recognizes `XML_OUTPUT_FILE` env variable and creates
  14. a junit reporter that writes to the provided path.
  15. Requires 2 arguments, path to Catch2 binary configured with
  16. `CATCH_CONFIG_BAZEL_SUPPORT`, and the output directory for the output file.
  17. """
  18. if len(sys.argv) != 3:
  19. print("Wrong number of arguments: {}".format(len(sys.argv)))
  20. print("Usage: {} test-bin-path output-dir".format(sys.argv[0]))
  21. exit(1)
  22. bin_path = os.path.abspath(sys.argv[1])
  23. output_dir = os.path.abspath(sys.argv[2])
  24. xml_out_path = os.path.join(output_dir, '{}.xml'.format(os.path.basename(bin_path)))
  25. # Ensure no file exists from previous test runs
  26. if os.path.isfile(xml_out_path):
  27. os.remove(xml_out_path)
  28. print('bin path:', bin_path)
  29. print('xml out path:', xml_out_path)
  30. env = os.environ.copy()
  31. env["XML_OUTPUT_FILE"] = xml_out_path
  32. test_passing = True
  33. try:
  34. ret = subprocess.run(
  35. bin_path,
  36. stdout=subprocess.PIPE,
  37. stderr=subprocess.PIPE,
  38. check=True,
  39. universal_newlines=True,
  40. env=env
  41. )
  42. stdout = ret.stdout
  43. except subprocess.SubprocessError as ex:
  44. if ex.returncode == 1:
  45. # The test cases are allowed to fail.
  46. test_passing = False
  47. stdout = ex.stdout
  48. else:
  49. print('Could not run "{}"'.format(args))
  50. print("Return code: {}".format(ex.returncode))
  51. print("stdout: {}".format(ex.stdout))
  52. print("stderr: {}".format(ex.stdout))
  53. raise
  54. # Check for valid XML output
  55. try:
  56. tree = ET.parse(xml_out_path)
  57. except ET.ParseError as ex:
  58. print("Invalid XML: '{}'".format(ex))
  59. raise
  60. except FileNotFoundError as ex:
  61. print("Could not find '{}'".format(xml_out_path))
  62. raise
  63. bin_name = os.path.basename(bin_path)
  64. # Check for matching testsuite
  65. if not tree.find('.//testsuite[@name="{}"]'.format(bin_name)):
  66. print("Could not find '{}' testsuite".format(bin_name))
  67. exit(2)
  68. # Check that we haven't disabled the default reporter
  69. summary_test_cases = re.findall(r'test cases: \d* \| \d* passed \| \d* failed', stdout)
  70. if len(summary_test_cases) == 0:
  71. print("Could not find test summary in {}".format(stdout))
  72. exit(2)
  73. total, passed, failed = [int(s) for s in summary_test_cases[0].split() if s.isdigit()]
  74. if failed == 0 and not test_passing:
  75. print("Expected at least 1 test failure!")
  76. exit(2)
  77. if len(tree.findall('.//testcase')) != total:
  78. print("Unexpected number of test cases!")
  79. exit(2)
  80. if len(tree.findall('.//failure')) != failed:
  81. print("Unexpected number of test failures!")
  82. exit(2)
  83. if (passed + failed) != total:
  84. print("Something has gone very wrong, ({} + {}) != {}".format(passed, failed, total))
  85. exit(2)