| auto test_failures = plan.run_all_tests(env, params.parallel_jobs); | auto test_failures = plan.run_all_tests(env, params.parallel_jobs); | ||||
| for (auto& failures : test_failures) { | for (auto& failures : test_failures) { | ||||
| spdlog::error("Test {} failed! Output:\n{}[dds - test output end]", failures.executable_path.string(), failures.output); | |||||
| spdlog::error("Test {} failed! Output:\n{}[dds - test output end]", | |||||
| failures.executable_path.string(), | |||||
| failures.output); | |||||
| } | } | ||||
| if (!test_failures.empty()) { | if (!test_failures.empty()) { | ||||
| throw compile_failure("Test failures during the build!"); | throw compile_failure("Test failures during the build!"); |
| const auto obj_path = calc_object_file_path(env); | const auto obj_path = calc_object_file_path(env); | ||||
| fs::create_directories(obj_path.parent_path()); | fs::create_directories(obj_path.parent_path()); | ||||
| auto msg = fmt::format("[{}] Compile: {:40}", _qualifier, fs::relative(_source.path, _source.basis_path).string()); | |||||
| auto msg = fmt::format("[{}] Compile: {:40}", | |||||
| _qualifier, | |||||
| fs::relative(_source.path, _source.basis_path).string()); | |||||
| spdlog::info(msg); | spdlog::info(msg); | ||||
| auto start_time = std::chrono::steady_clock::now(); | auto start_time = std::chrono::steady_clock::now(); |
| #include <spdlog/spdlog.h> | #include <spdlog/spdlog.h> | ||||
| #include <chrono> | |||||
| #include <algorithm> | #include <algorithm> | ||||
| #include <cassert> | #include <cassert> | ||||
| #include <chrono> | |||||
| using namespace dds; | using namespace dds; | ||||
| auto msg = fmt::format("Run test: {:30}", fs::relative(exe_path, env.output_root).string()); | auto msg = fmt::format("Run test: {:30}", fs::relative(exe_path, env.output_root).string()); | ||||
| spdlog::info(msg); | spdlog::info(msg); | ||||
| auto start = std::chrono::high_resolution_clock::now(); | auto start = std::chrono::high_resolution_clock::now(); | ||||
| auto res = run_proc({exe_path}); | |||||
| auto end = std::chrono::high_resolution_clock::now(); | |||||
| auto dur = std::chrono::duration_cast<std::chrono::microseconds>(end - start); | |||||
| auto res = run_proc({exe_path}); | |||||
| auto end = std::chrono::high_resolution_clock::now(); | |||||
| auto dur = std::chrono::duration_cast<std::chrono::microseconds>(end - start); | |||||
| if (res.okay()) { | if (res.okay()) { | ||||
| spdlog::info("{} - PASSED - {:>9n}μs", msg, dur.count()); | spdlog::info("{} - PASSED - {:>9n}μs", msg, dur.count()); | ||||
| return std::nullopt; | return std::nullopt; | ||||
| spdlog::error("{} - FAILED - {:>9n}μs [exited {}]", msg, dur.count(), res.retc); | spdlog::error("{} - FAILED - {:>9n}μs [exited {}]", msg, dur.count(), res.retc); | ||||
| test_failure f; | test_failure f; | ||||
| f.executable_path = exe_path; | f.executable_path = exe_path; | ||||
| f.output = res.output; | |||||
| f.retc = res.retc; | |||||
| f.output = res.output; | |||||
| f.retc = res.retc; | |||||
| return f; | return f; | ||||
| } | } | ||||
| } | } |
| fs::path calc_executable_path(const build_env& env) const noexcept; | fs::path calc_executable_path(const build_env& env) const noexcept; | ||||
| void link(const build_env&, const library_plan&) const; | |||||
| void link(const build_env&, const library_plan&) const; | |||||
| std::optional<test_failure> run_test(build_env_ref) const; | std::optional<test_failure> run_test(build_env_ref) const; | ||||
| bool is_test() const noexcept; | bool is_test() const noexcept; |
| | filter(&link_executable_plan::is_test) // | | filter(&link_executable_plan::is_test) // | ||||
| ; | ; | ||||
| std::mutex mut; | |||||
| std::mutex mut; | |||||
| std::vector<test_failure> fails; | std::vector<test_failure> fails; | ||||
| parallel_run(test_executables, njobs, [&](const auto& exe) { | parallel_run(test_executables, njobs, [&](const auto& exe) { |