test_all.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #!/usr/bin/python
  2. # Copyright 2002-2005 Dave Abrahams.
  3. # Copyright 2002-2006 Vladimir Prus.
  4. # Distributed under the Boost Software License, Version 1.0.
  5. # (See accompanying file LICENSE.txt or copy at
  6. # https://www.bfgroup.xyz/b2/LICENSE.txt)
  7. from __future__ import print_function
  8. import BoostBuild
  9. import os
  10. import os.path
  11. import sys
  12. xml = "--xml" in sys.argv
  13. toolset = BoostBuild.get_toolset()
  14. # Clear environment for testing.
  15. #
  16. for s in ("BOOST_ROOT", "BOOST_BUILD_PATH", "JAM_TOOLSET", "BCCROOT",
  17. "MSVCDir", "MSVC", "MSVCNT", "MINGW", "watcom"):
  18. try:
  19. del os.environ[s]
  20. except:
  21. pass
  22. BoostBuild.set_defer_annotations(1)
  23. def run_tests(critical_tests, other_tests):
  24. """
  25. Runs first the critical_tests and then the other_tests.
  26. Writes the name of the first failed test to test_results.txt. Critical
  27. tests are run in the specified order, other tests are run starting with the
  28. one that failed first on the last test run.
  29. """
  30. last_failed = last_failed_test()
  31. other_tests = reorder_tests(other_tests, last_failed)
  32. all_tests = critical_tests + other_tests
  33. invocation_dir = os.getcwd()
  34. max_test_name_len = 10
  35. for x in all_tests:
  36. if len(x) > max_test_name_len:
  37. max_test_name_len = len(x)
  38. pass_count = 0
  39. failures_count = 0
  40. for test in all_tests:
  41. if not xml:
  42. s = "%%-%ds :" % max_test_name_len % test
  43. print(s, end='')
  44. passed = 0
  45. try:
  46. __import__(test)
  47. passed = 1
  48. except KeyboardInterrupt:
  49. """This allows us to abort the testing manually using Ctrl-C."""
  50. raise
  51. except SystemExit as e:
  52. """This is the regular way our test scripts are supposed to report
  53. test failures."""
  54. if e.code is None or e.code == 0:
  55. passed = 1
  56. except:
  57. exc_type, exc_value, exc_tb = sys.exc_info()
  58. try:
  59. BoostBuild.annotation("failure - unhandled exception", "%s - "
  60. "%s" % (exc_type.__name__, exc_value))
  61. BoostBuild.annotate_stack_trace(exc_tb)
  62. finally:
  63. # Explicitly clear a hard-to-garbage-collect traceback
  64. # related reference cycle as per documented sys.exc_info()
  65. # usage suggestion.
  66. del exc_tb
  67. if passed:
  68. pass_count += 1
  69. else:
  70. failures_count += 1
  71. if failures_count == 1:
  72. f = open(os.path.join(invocation_dir, "test_results.txt"), "w")
  73. try:
  74. f.write(test)
  75. finally:
  76. f.close()
  77. # Restore the current directory, which might have been changed by the
  78. # test.
  79. os.chdir(invocation_dir)
  80. if not xml:
  81. if passed:
  82. print("PASSED")
  83. else:
  84. print("FAILED")
  85. BoostBuild.flush_annotations()
  86. else:
  87. rs = "succeed"
  88. if not passed:
  89. rs = "fail"
  90. print('''
  91. <test-log library="build" test-name="%s" test-type="run" toolset="%s" test-program="%s" target-directory="%s">
  92. <run result="%s">''' % (test, toolset, "tools/build/v2/test/" + test + ".py",
  93. "boost/bin.v2/boost.build.tests/" + toolset + "/" + test, rs))
  94. if not passed:
  95. BoostBuild.flush_annotations(1)
  96. print('''
  97. </run>
  98. </test-log>
  99. ''')
  100. sys.stdout.flush() # Makes testing under emacs more entertaining.
  101. BoostBuild.clear_annotations()
  102. # Erase the file on success.
  103. if failures_count == 0:
  104. open("test_results.txt", "w").close()
  105. if not xml:
  106. print('''
  107. === Test summary ===
  108. PASS: %d
  109. FAIL: %d
  110. ''' % (pass_count, failures_count))
  111. # exit with failure with failures
  112. if failures_count > 0:
  113. sys.exit(1)
  114. def last_failed_test():
  115. "Returns the name of the last failed test or None."
  116. try:
  117. f = open("test_results.txt")
  118. try:
  119. return f.read().strip()
  120. finally:
  121. f.close()
  122. except Exception:
  123. return None
  124. def reorder_tests(tests, first_test):
  125. try:
  126. n = tests.index(first_test)
  127. return [first_test] + tests[:n] + tests[n + 1:]
  128. except ValueError:
  129. return tests
  130. critical_tests = ["unit_tests", "module_actions", "startup_v2", "core_d12",
  131. "core_typecheck", "core_delete_module", "core_language", "core_arguments",
  132. "core_varnames", "core_import_module"]
  133. # We want to collect debug information about the test site before running any
  134. # of the tests, but only when not running the tests interactively. Then the
  135. # user can easily run this always-failing test directly to see what it would
  136. # have returned and there is no need to have it spoil a possible 'all tests
  137. # passed' result.
  138. if xml:
  139. critical_tests.insert(0, "collect_debug_info")
  140. tests = ["abs_workdir",
  141. "absolute_sources",
  142. "alias",
  143. "alternatives",
  144. "always",
  145. "bad_dirname",
  146. "build_dir",
  147. "build_file",
  148. "build_hooks",
  149. "build_no",
  150. "builtin_echo",
  151. "builtin_exit",
  152. "builtin_glob",
  153. "builtin_readlink",
  154. "builtin_split_by_characters",
  155. "bzip2",
  156. "c_file",
  157. "chain",
  158. "clean",
  159. "cli_property_expansion",
  160. "command_line_properties",
  161. "composite",
  162. "conditionals",
  163. "conditionals2",
  164. "conditionals3",
  165. "conditionals4",
  166. "conditionals_multiple",
  167. "configuration",
  168. "configure",
  169. "copy_time",
  170. "core_action_output",
  171. "core_action_status",
  172. "core_actions_quietly",
  173. "core_at_file",
  174. "core_bindrule",
  175. "core_dependencies",
  176. "core_syntax_error_exit_status",
  177. "core_fail_expected",
  178. "core_jamshell",
  179. "core_modifiers",
  180. "core_multifile_actions",
  181. "core_nt_cmd_line",
  182. "core_option_d2",
  183. "core_option_l",
  184. "core_option_n",
  185. "core_parallel_actions",
  186. "core_parallel_multifile_actions_1",
  187. "core_parallel_multifile_actions_2",
  188. "core_scanner",
  189. "core_source_line_tracking",
  190. "core_update_now",
  191. "core_variables_in_actions",
  192. "custom_generator",
  193. "debugger",
  194. # Newly broken?
  195. # "debugger-mi",
  196. "default_build",
  197. "default_features",
  198. # This test is known to be broken itself.
  199. # "default_toolset",
  200. "dependency_property",
  201. "dependency_test",
  202. "disambiguation",
  203. "dll_path",
  204. "double_loading",
  205. "duplicate",
  206. "example_libraries",
  207. "example_make",
  208. "exit_status",
  209. "expansion",
  210. "explicit",
  211. "feature_cxxflags",
  212. "feature_implicit_dependency",
  213. "feature_relevant",
  214. "feature_suppress_import_lib",
  215. "file_types",
  216. "flags",
  217. "generator_selection",
  218. "generators_test",
  219. "implicit_dependency",
  220. "indirect_conditional",
  221. "inherit_toolset",
  222. "inherited_dependency",
  223. "inline",
  224. "install_build_no",
  225. "libjpeg",
  226. "liblzma",
  227. "libpng",
  228. "libtiff",
  229. "libzstd",
  230. "lib_source_property",
  231. "lib_zlib",
  232. "library_chain",
  233. "library_property",
  234. "link",
  235. "load_order",
  236. "loop",
  237. "make_rule",
  238. "message",
  239. "ndebug",
  240. "no_type",
  241. "notfile",
  242. "ordered_include",
  243. # FIXME: Disabled due to bug in B2
  244. # "ordered_properties",
  245. "out_of_tree",
  246. "package",
  247. "param",
  248. "path_features",
  249. "prebuilt",
  250. "preprocessor",
  251. "print",
  252. "project_dependencies",
  253. "project_glob",
  254. "project_id",
  255. "project_root_constants",
  256. "project_root_rule",
  257. "project_test3",
  258. "project_test4",
  259. "property_expansion",
  260. # FIXME: Disabled due lack of qt5 detection
  261. # "qt5",
  262. "rebuilds",
  263. "relative_sources",
  264. "remove_requirement",
  265. "rescan_header",
  266. "resolution",
  267. "rootless",
  268. "scanner_causing_rebuilds",
  269. "searched_lib",
  270. "skipping",
  271. "sort_rule",
  272. "source_locations",
  273. "source_order",
  274. "space_in_path",
  275. "stage",
  276. "standalone",
  277. "static_and_shared_library",
  278. "suffix",
  279. "tag",
  280. "test_rc",
  281. "test1",
  282. "test2",
  283. "testing",
  284. "timedata",
  285. "toolset_clang_darwin",
  286. "toolset_clang_linux",
  287. "toolset_clang_vxworks",
  288. "toolset_darwin",
  289. "toolset_defaults",
  290. "toolset_gcc",
  291. "toolset_intel_darwin",
  292. "toolset_requirements",
  293. "transitive_skip",
  294. "unit_test",
  295. "unused",
  296. "use_requirements",
  297. "using",
  298. "wrapper",
  299. "wrong_project",
  300. ]
  301. if os.name == "posix":
  302. tests.append("symlink")
  303. # On Windows, library order is not important, so skip this test. Besides,
  304. # it fails ;-). Further, the test relies on the fact that on Linux, one can
  305. # build a shared library with unresolved symbols. This is not true on
  306. # Windows, even with cygwin gcc.
  307. # Disable this test until we figure how to address failures due to --as-needed being default now.
  308. # if "CYGWIN" not in os.uname()[0]:
  309. # tests.append("library_order")
  310. if toolset.startswith("gcc") and os.name != "nt":
  311. # On Windows it's allowed to have a static runtime with gcc. But this test
  312. # assumes otherwise. Hence enable it only when not on Windows.
  313. tests.append("gcc_runtime")
  314. if toolset.startswith("clang") or toolset.startswith("gcc") or toolset.startswith("msvc"):
  315. tests.append("pch")
  316. if sys.platform != "darwin": # clang-darwin does not yet support
  317. tests.append("feature_force_include")
  318. # Clang includes Objective-C driver everywhere, but GCC usually in a separate gobj package
  319. if toolset.startswith("clang") or "darwin" in toolset:
  320. tests.append("lang_objc")
  321. # Disable on OSX as it doesn't seem to work for unknown reasons.
  322. if sys.platform != 'darwin':
  323. tests.append("builtin_glob_archive")
  324. if "--extras" in sys.argv:
  325. tests.append("boostbook")
  326. tests.append("qt4")
  327. tests.append("qt5")
  328. tests.append("example_qt4")
  329. # Requires ./whatever.py to work, so is not guaranteed to work everywhere.
  330. tests.append("example_customization")
  331. # Requires gettext tools.
  332. tests.append("example_gettext")
  333. elif not xml:
  334. print("Note: skipping extra tests")
  335. run_tests(critical_tests, tests)