1#!/usr/local/bin/python3.8 2 3# Copyright 2008 Jurko Gospodnetic 4# Copyright 2017 Steven Watanabe 5# Distributed under the Boost Software License, Version 1.0. 6# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 7 8# Tests different aspects of Boost Builds automated testing support. 9 10import BoostBuild 11import TestCmd 12 13def test_run(): 14 t = BoostBuild.Tester(use_test_config=False) 15 16 t.write("pass.cpp", "int main() {}\n") 17 t.write("fail-compile.cpp", "#error expected to fail\n") 18 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 19 t.write("fail-run.cpp", "int main() { return 1; }\n") 20 21 t.write("Jamroot.jam", """import testing ; 22run pass.cpp ; 23run fail-compile.cpp ; 24run fail-link.cpp ; 25run fail-run.cpp ; 26""") 27 28 t.run_build_system(status=1) 29 t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") 30 t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") 31 t.expect_addition("bin/pass.test/$toolset/debug*/pass.output") 32 t.expect_addition("bin/pass.test/$toolset/debug*/pass.run") 33 t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") 34 35 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") 36 37 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") 38 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.exe") 39 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.output") 40 41 t.ignore_addition("bin/pass.test/*/pass.rsp") 42 t.ignore_addition("bin/fail-link.test/*/fail-link.rsp") 43 t.ignore_addition("bin/fail-run.test/*/fail-run.rsp") 44 45 t.expect_nothing_more() 46 47 t.cleanup() 48 49def test_run_fail(): 50 t = BoostBuild.Tester(use_test_config=False) 51 52 t.write("pass.cpp", "int main() {}\n") 53 t.write("fail-compile.cpp", "#error expected to fail\n") 54 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 55 t.write("fail-run.cpp", "int main() { return 1; }\n") 56 57 t.write("Jamroot.jam", """import testing ; 58run-fail pass.cpp ; 59run-fail fail-compile.cpp ; 60run-fail fail-link.cpp ; 61run-fail fail-run.cpp ; 62""") 63 64 t.run_build_system(status=1) 65 t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") 66 t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") 67 t.expect_addition("bin/pass.test/$toolset/debug*/pass.output") 68 69 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") 70 71 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") 72 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.exe") 73 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.output") 74 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.run") 75 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") 76 77 t.ignore_addition("bin/pass.test/*/pass.rsp") 78 t.ignore_addition("bin/fail-link.test/*/fail-link.rsp") 79 t.ignore_addition("bin/fail-run.test/*/fail-run.rsp") 80 81 t.expect_nothing_more() 82 83 t.cleanup() 84 85def test_run_change(): 86 """Tests that the test file is removed when a test fails after it 87 previously passed.""" 88 89 t = BoostBuild.Tester(use_test_config=False) 90 91 t.write("pass.cpp", "int main() { return 1; }\n") 92 t.write("fail-compile.cpp", "int main() {}\n") 93 t.write("fail-link.cpp", "int main() {}\n") 94 t.write("fail-run.cpp", "int main() {}\n") 95 96 t.write("Jamroot.jam", """import testing ; 97run-fail pass.cpp ; 98run fail-compile.cpp ; 99run fail-link.cpp ; 100run fail-run.cpp ; 101""") 102 t.run_build_system() 103 # Sanity check 104 t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") 105 t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 106 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") 107 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") 108 t.expect_output_lines("...failed*", False) 109 110 # Now make them fail 111 t.write("pass.cpp", "int main() {}\n") 112 t.write("fail-compile.cpp", "#error expected to fail\n") 113 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 114 t.write("fail-run.cpp", "int main() { return 1; }\n") 115 t.run_build_system(status=1) 116 117 t.expect_removal("bin/pass.test/$toolset/debug*/pass.test") 118 t.expect_removal("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 119 t.expect_removal("bin/fail-link.test/$toolset/debug*/fail-link.test") 120 t.expect_removal("bin/fail-run.test/$toolset/debug*/fail-run.test") 121 122 t.cleanup() 123 124def test_run_path(): 125 """Tests that run can find shared libraries even without 126 hardcode-dll-paths. Important: The library is in neither the 127 current working directory, nor any system path, nor the same 128 directory as the executable, so it should never be found without 129 help from B2.""" 130 t = BoostBuild.Tester(["hardcode-dll-paths=false"], use_test_config=False) 131 132 t.write("l.cpp", """ 133void 134#if defined(_WIN32) 135__declspec(dllexport) 136#endif 137f() {} 138""") 139 t.write("pass.cpp", "void f(); int main() { f(); }\n") 140 141 t.write("Jamroot.jam", """import testing ; 142lib l : l.cpp : <link>shared ; 143run pass.cpp l ; 144""") 145 146 t.run_build_system() 147 t.expect_addition("bin/$toolset/debug*/l.obj") 148 t.expect_addition("bin/$toolset/debug*/l.dll") 149 t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") 150 t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") 151 t.expect_addition("bin/pass.test/$toolset/debug*/pass.output") 152 t.expect_addition("bin/pass.test/$toolset/debug*/pass.run") 153 t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") 154 155 t.cleanup() 156 157def test_run_args(): 158 """Tests the handling of args and input-files""" 159 t = BoostBuild.Tester(use_test_config=False) 160 t.write("test.cpp", """ 161#include <iostream> 162#include <fstream> 163int main(int argc, const char ** argv) 164{ 165 for(int i = 1; i < argc; ++i) 166 { 167 if(argv[i][0] == '-') 168 { 169 std::cout << argv[i] << std::endl; 170 } 171 else 172 { 173 std::ifstream ifs(argv[i]); 174 std::cout << ifs.rdbuf(); 175 } 176 } 177} 178""") 179 t.write("input1.in", "first input\n") 180 t.write("input2.in", "second input\n") 181 t.write("Jamroot.jam", """import testing ; 182import common ; 183# FIXME: The order actually depends on the lexigraphical 184# ordering of the virtual target objects, which is just 185# crazy. Switch the order of input1.txt and input2.txt 186# to make this fail. Joining the arguments with && might 187# work, but might get a bit complicated to implement as 188# dependency properties do not currently support &&. 189make input1.txt : input1.in : @common.copy ; 190make input2.txt : input2.in : @common.copy ; 191run test.cpp : -y -a : input1.txt input2.txt ; 192""") 193 t.run_build_system() 194 t.expect_content("bin/test.test/$toolset/debug*/test.output", """\ 195-y 196-a 197first input 198second input 199 200EXIT STATUS: 0 201""") 202 t.cleanup() 203 204def test_link(): 205 t = BoostBuild.Tester(use_test_config=False) 206 207 t.write("pass.cpp", "int main() {}\n") 208 t.write("fail-compile.cpp", "#error expected to fail\n") 209 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 210 t.write("fail-run.cpp", "int main() { return 1; }\n") 211 212 t.write("Jamroot.jam", """import testing ; 213link pass.cpp ; 214link fail-compile.cpp ; 215link fail-link.cpp ; 216link fail-run.cpp ; 217""") 218 219 t.run_build_system(status=1) 220 t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") 221 t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") 222 t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") 223 224 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") 225 226 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") 227 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.exe") 228 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") 229 230 t.ignore_addition("bin/pass.test/*/pass.rsp") 231 t.ignore_addition("bin/fail-link.test/*/fail-link.rsp") 232 t.ignore_addition("bin/fail-run.test/*/fail-run.rsp") 233 234 t.expect_nothing_more() 235 236 t.cleanup() 237 238def test_link_fail(): 239 t = BoostBuild.Tester(use_test_config=False) 240 241 t.write("pass.cpp", "int main() {}\n") 242 t.write("fail-compile.cpp", "#error expected to fail\n") 243 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 244 t.write("fail-run.cpp", "int main() { return 1; }\n") 245 246 t.write("Jamroot.jam", """import testing ; 247link-fail pass.cpp ; 248link-fail fail-compile.cpp ; 249link-fail fail-link.cpp ; 250link-fail fail-run.cpp ; 251""") 252 253 t.run_build_system(status=1) 254 t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") 255 256 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") 257 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.exe") 258 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") 259 260 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") 261 262 t.ignore_addition("bin/pass.test/*/pass.rsp") 263 t.ignore_addition("bin/fail-link.test/*/fail-link.rsp") 264 t.ignore_addition("bin/fail-run.test/*/fail-run.rsp") 265 266 t.expect_nothing_more() 267 268 t.cleanup() 269 270def test_link_change(): 271 """Tests that the test file is removed when a test fails after it 272 previously passed.""" 273 274 t = BoostBuild.Tester(use_test_config=False) 275 276 t.write("pass.cpp", "int f();\nint main() { return f(); }\n") 277 t.write("fail-compile.cpp", "int main() {}\n") 278 t.write("fail-link.cpp", "int main() {}\n") 279 280 t.write("Jamroot.jam", """import testing ; 281link-fail pass.cpp ; 282link fail-compile.cpp ; 283link fail-link.cpp ; 284""") 285 t.run_build_system() 286 # Sanity check 287 t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") 288 t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 289 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") 290 t.expect_output_lines("...failed*", False) 291 292 # Now make them fail 293 t.write("pass.cpp", "int main() {}\n") 294 t.write("fail-compile.cpp", "#error expected to fail\n") 295 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 296 t.run_build_system(status=1) 297 298 t.expect_removal("bin/pass.test/$toolset/debug*/pass.test") 299 t.expect_removal("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 300 t.expect_removal("bin/fail-link.test/$toolset/debug*/fail-link.test") 301 302 t.cleanup() 303 304def test_compile(): 305 t = BoostBuild.Tester(use_test_config=False) 306 307 t.write("pass.cpp", "int main() {}\n") 308 t.write("fail-compile.cpp", "#error expected to fail\n") 309 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 310 t.write("fail-run.cpp", "int main() { return 1; }\n") 311 312 t.write("Jamroot.jam", """import testing ; 313compile pass.cpp ; 314compile fail-compile.cpp ; 315compile fail-link.cpp ; 316compile fail-run.cpp ; 317""") 318 319 t.run_build_system(status=1) 320 t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") 321 t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") 322 323 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") 324 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") 325 326 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") 327 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") 328 329 t.expect_nothing_more() 330 331 t.cleanup() 332 333def test_compile_fail(): 334 t = BoostBuild.Tester(use_test_config=False) 335 336 t.write("pass.cpp", "int main() {}\n") 337 t.write("fail-compile.cpp", "#error expected to fail\n") 338 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 339 t.write("fail-run.cpp", "int main() { return 1; }\n") 340 341 t.write("Jamroot.jam", """import testing ; 342compile-fail pass.cpp ; 343compile-fail fail-compile.cpp ; 344compile-fail fail-link.cpp ; 345compile-fail fail-run.cpp ; 346""") 347 348 t.run_build_system(status=1) 349 t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.obj") 350 t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 351 352 t.expect_nothing_more() 353 354 t.cleanup() 355 356def test_compile_change(): 357 """Tests that the test file is removed when a test fails after it 358 previously passed.""" 359 360 t = BoostBuild.Tester(use_test_config=False) 361 362 t.write("pass.cpp", "#error expected to fail\n") 363 t.write("fail-compile.cpp", "int main() {}\n") 364 365 t.write("Jamroot.jam", """import testing ; 366compile-fail pass.cpp ; 367compile fail-compile.cpp ; 368""") 369 t.run_build_system() 370 # Sanity check 371 t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") 372 t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 373 t.expect_output_lines("...failed*", False) 374 375 # Now make them fail 376 t.write("pass.cpp", "int main() {}\n") 377 t.write("fail-compile.cpp", "#error expected to fail\n") 378 t.run_build_system(status=1) 379 380 t.expect_removal("bin/pass.test/$toolset/debug*/pass.test") 381 t.expect_removal("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 382 383 t.cleanup() 384 385def test_remove_test_targets(option): 386 t = BoostBuild.Tester(use_test_config=False) 387 388 t.write("pass-compile.cpp", "int main() {}\n") 389 t.write("pass-link.cpp", "int main() {}\n") 390 t.write("pass-run.cpp", "int main() {}\n") 391 t.write("fail-compile.cpp", "#error expected to fail\n") 392 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 393 t.write("fail-run.cpp", "int main() { return 1; }\n") 394 t.write("source.cpp", "int f();\n") 395 396 t.write("Jamroot.jam", """import testing ; 397obj source.o : source.cpp ; 398compile pass-compile.cpp ; 399link pass-link.cpp source.o ; 400run pass-run.cpp source.o ; 401compile-fail fail-compile.cpp ; 402link-fail fail-link.cpp ; 403run-fail fail-run.cpp ; 404""") 405 406 t.run_build_system([option]) 407 408 t.expect_addition("bin/$toolset/debug*/source.obj") 409 410 t.expect_addition("bin/pass-compile.test/$toolset/debug*/pass-compile.test") 411 412 t.expect_addition("bin/pass-link.test/$toolset/debug*/pass-link.test") 413 414 t.expect_addition("bin/pass-run.test/$toolset/debug*/pass-run.output") 415 t.expect_addition("bin/pass-run.test/$toolset/debug*/pass-run.run") 416 t.expect_addition("bin/pass-run.test/$toolset/debug*/pass-run.test") 417 418 t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") 419 420 t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") 421 422 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.output") 423 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.run") 424 t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") 425 426 t.ignore_addition("bin/pass-link.test/*/pass-link.rsp") 427 t.ignore_addition("bin/pass-run.test/*/pass-run.rsp") 428 t.ignore_addition("bin/fail-link.test/*/fail-link.rsp") 429 t.ignore_addition("bin/fail-run.test/*/fail-run.rsp") 430 431 t.expect_nothing_more() 432 433 t.cleanup() 434 435def test_dump_tests(): 436 """Tests the output of the --dump-tests option""" 437 t = BoostBuild.Tester(use_test_config=False) 438 439 t.write("pass-compile.cpp", "int main() {}\n") 440 t.write("pass-link.cpp", "int main() {}\n") 441 t.write("pass-run.cpp", "int main() {}\n") 442 t.write("fail-compile.cpp", "#error expected to fail\n") 443 t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") 444 t.write("fail-run.cpp", "int main() { return 1; }\n") 445 446 t.write("Jamroot.jam", """import testing ; 447run pass-run.cpp ; 448run-fail fail-run.cpp ; 449link pass-link.cpp ; 450link-fail fail-link.cpp ; 451compile pass-compile.cpp ; 452compile-fail fail-compile.cpp ; 453build-project libs/any/test ; 454build-project libs/any/example ; 455build-project libs/any ; 456build-project tools/bcp/test ; 457build-project tools/bcp/example ; 458build-project subdir/test ; 459build-project status ; 460build-project outside/project ; 461""") 462 def write_subdir(dir): 463 t.write(dir + "/test.cpp", "int main() {}\n") 464 t.write(dir + "/Jamfile", "run test.cpp ;") 465 write_subdir("libs/any/test") 466 write_subdir("libs/any/example") 467 write_subdir("libs/any") 468 write_subdir("tools/bcp/test") 469 write_subdir("tools/bcp/example") 470 write_subdir("status") 471 write_subdir("subdir/test") 472 t.write("outside/other/test.cpp", "int main() {}\n") 473 t.write("outside/project/Jamroot", "run ../other/test.cpp ;") 474 t.run_build_system(["--dump-tests", "-n", "-d0"], 475 match=TestCmd.match_re, stdout= 476"""boost-test\(RUN\) ".*/pass-run" : "pass-run\.cpp" 477boost-test\(RUN_FAIL\) ".*/fail-run" : "fail-run\.cpp" 478boost-test\(LINK\) ".*/pass-link" : "pass-link\.cpp" 479boost-test\(LINK_FAIL\) ".*/fail-link" : "fail-link\.cpp" 480boost-test\(COMPILE\) ".*/pass-compile" : "pass-compile\.cpp" 481boost-test\(COMPILE_FAIL\) ".*/fail-compile" : "fail-compile\.cpp" 482boost-test\(RUN\) "any/test" : "libs/any/test\.cpp" 483boost-test\(RUN\) "any/test" : "libs/any/test/test\.cpp" 484boost-test\(RUN\) "any/test" : "libs/any/example/test\.cpp" 485boost-test\(RUN\) "bcp/test" : "tools/bcp/test/test\.cpp" 486boost-test\(RUN\) "bcp/test" : "tools/bcp/example/test\.cpp" 487boost-test\(RUN\) ".*/subdir/test/test" : "subdir/test/test\.cpp" 488boost-test\(RUN\) "test" : "status/test\.cpp" 489boost-test\(RUN\) ".*/outside/project/test" : "../other/test.cpp" 490""") 491 t.cleanup() 492 493################################################################################ 494# 495# test_files_with_spaces_in_their_name() 496# -------------------------------------- 497# 498################################################################################ 499 500def test_files_with_spaces_in_their_name(): 501 """Regression test making sure test result files get created correctly when 502 testing files with spaces in their name. 503 """ 504 505 t = BoostBuild.Tester(use_test_config=False) 506 507 t.write("valid source.cpp", "int main() {}\n"); 508 509 t.write("invalid source.cpp", "this is not valid source code"); 510 511 t.write("jamroot.jam", """ 512import testing ; 513testing.compile "valid source.cpp" ; 514testing.compile-fail "invalid source.cpp" ; 515""") 516 517 t.run_build_system(status=0) 518 t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.obj") 519 t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.test") 520 t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.obj") 521 t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.test") 522 523 t.expect_content("bin/valid source.test/$toolset/debug*/valid source.test", \ 524 "passed" ) 525 t.expect_content( \ 526 "bin/invalid source.test/$toolset/debug*/invalid source.test", \ 527 "passed" ) 528 t.expect_content( \ 529 "bin/invalid source.test/$toolset/debug*/invalid source.obj", \ 530 "failed as expected" ) 531 532 t.cleanup() 533 534 535################################################################################ 536# 537# main() 538# ------ 539# 540################################################################################ 541 542test_run() 543test_run_fail() 544test_run_change() 545test_run_path() 546test_run_args() 547test_link() 548test_link_fail() 549test_link_change() 550test_compile() 551test_compile_fail() 552test_compile_change() 553test_remove_test_targets("--remove-test-targets") 554test_remove_test_targets("preserve-test-targets=off") 555test_dump_tests() 556test_files_with_spaces_in_their_name() 557