Browse Source

Executing tests is useful. Let's do that

default_compile_flags
vector-of-bool 5 years ago
parent
commit
9fbfc71369
5 changed files with 69 additions and 13 deletions
  1. +7
    -13
      src/dds/build.cpp
  2. +30
    -0
      src/dds/build/plan/exe.cpp
  3. +10
    -0
      src/dds/build/plan/exe.hpp
  4. +20
    -0
      src/dds/build/plan/full.cpp
  5. +2
    -0
      src/dds/build/plan/full.hpp

+ 7
- 13
src/dds/build.cpp View File

@@ -162,19 +162,13 @@ void dds::build(const build_params& params, const package_manifest& man) {
plan.archive_all(env, params.parallel_jobs);
plan.link_all(env, params.parallel_jobs);

// int n_test_fails = 0;
// for (path_ref test_exe : all_tests) {
// spdlog::info("Running test: {}", fs::relative(test_exe, params.out_root).string());
// const auto test_res = run_proc({test_exe.string()});
// if (!test_res.okay()) {
// spdlog::error("TEST FAILED\n{}", test_res.output);
// n_test_fails++;
// }
// }

// if (n_test_fails) {
// throw compile_failure("Test failures during build");
// }
auto test_failures = plan.run_all_tests(env, params.parallel_jobs);
for (auto& failures : test_failures) {
spdlog::error("Test {} failed! Output:\n{}[dds - test output end]", failures.executable_path.string(), failures.output);
}
if (!test_failures.empty()) {
throw compile_failure("Test failures during the build!");
}

if (params.do_export) {
export_project(pkg, env);

+ 30
- 0
src/dds/build/plan/exe.cpp View File

@@ -5,6 +5,7 @@

#include <spdlog/spdlog.h>

#include <chrono>
#include <algorithm>
#include <cassert>

@@ -41,3 +42,32 @@ void link_executable_plan::link(build_env_ref env, const library_plan& lib) cons
proc_res.output));
}
}

bool link_executable_plan::is_app() const noexcept {
return _main_compile.source().kind == source_kind::app;
}

bool link_executable_plan::is_test() const noexcept {
return _main_compile.source().kind == source_kind::test;
}

std::optional<test_failure> link_executable_plan::run_test(build_env_ref env) const {
auto exe_path = calc_executable_path(env);
auto msg = fmt::format("Run test: {:30}", fs::relative(exe_path, env.output_root).string());
spdlog::info(msg);
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);
if (res.okay()) {
spdlog::info("{} - PASSED in {:>6n}μs", msg, dur.count());
return std::nullopt;
} else {
spdlog::error("{} - FAILED in {:>6n}μs [exitted {}]", msg, dur.count(), res.retc);
test_failure f;
f.executable_path = exe_path;
f.output = res.output;
f.retc = res.retc;
return f;
}
}

+ 10
- 0
src/dds/build/plan/exe.hpp View File

@@ -11,6 +11,12 @@ namespace dds {

class library_plan;

struct test_failure {
fs::path executable_path;
std::string output;
int retc;
};

class link_executable_plan {
std::vector<fs::path> _input_libs;
compile_file_plan _main_compile;
@@ -32,6 +38,10 @@ public:
fs::path calc_executable_path(const build_env& env) const noexcept;

void link(const build_env&, const library_plan&) const;
std::optional<test_failure> run_test(build_env_ref) const;

bool is_test() const noexcept;
bool is_app() const noexcept;
};

} // namespace dds

+ 20
- 0
src/dds/build/plan/full.cpp View File

@@ -114,4 +114,24 @@ void build_plan::link_all(const build_env& env, int njobs) const {
}
}

std::vector<test_failure> build_plan::run_all_tests(build_env_ref env, int njobs) const {
using namespace ranges::views;
auto test_executables = //
iter_libraries(*this) //
| transform(&library_plan::executables) //
| join //
| filter(&link_executable_plan::is_test) //
;

std::mutex mut;
std::vector<test_failure> fails;

parallel_run(test_executables, njobs, [&](const auto& exe) {
auto fail_info = exe.run_test(env);
if (fail_info) {
std::scoped_lock lk{mut};
fails.emplace_back(std::move(*fail_info));
}
});
return fails;
}

+ 2
- 0
src/dds/build/plan/full.hpp View File

@@ -21,6 +21,8 @@ public:
void compile_all(const build_env& env, int njobs) const;
void archive_all(const build_env& env, int njobs) const;
void link_all(const build_env& env, int njobs) const;

std::vector<test_failure> run_all_tests(build_env_ref env, int njobs) const;
};

} // namespace dds

Loading…
Cancel
Save