aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/test_runner.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2019-01-31 20:06:51 -0500
committerJack Lloyd <[email protected]>2019-01-31 20:06:51 -0500
commita4e93f43889f07433a378e0168d06a2fd8a1cdfe (patch)
tree8c2e57634db3f766055b5c0125713ac5dfcebf68 /src/tests/test_runner.cpp
parent870cc9a11af2f0dd4351b822f151a0d5c1803354 (diff)
parentf52cde49f5fcf8aa3a72c15c665940c16756a16b (diff)
Merge GH #1819 Add Thread_Pool and use it for running tests
Diffstat (limited to 'src/tests/test_runner.cpp')
-rw-r--r--src/tests/test_runner.cpp131
1 files changed, 91 insertions, 40 deletions
diff --git a/src/tests/test_runner.cpp b/src/tests/test_runner.cpp
index e346e9afa..86ceab1f8 100644
--- a/src/tests/test_runner.cpp
+++ b/src/tests/test_runner.cpp
@@ -12,6 +12,10 @@
#include <botan/loadstor.h>
#include <botan/cpuid.h>
+#if defined(BOTAN_HAS_THREAD_UTILS)
+ #include <botan/internal/thread_pool.h>
+#endif
+
namespace Botan_Tests {
Test_Runner::Test_Runner(std::ostream& out) : m_output(out) {}
@@ -196,7 +200,7 @@ int Test_Runner::run(const Test_Options& opts)
Botan_Tests::Test::set_test_rng(std::move(rng));
- const size_t failed = run_tests(req, i, opts.test_runs());
+ const size_t failed = run_tests(req, opts.test_threads(), i, opts.test_runs());
if(failed > 0)
return static_cast<int>(failed);
}
@@ -236,9 +240,68 @@ std::string report_out(const std::vector<Botan_Tests::Test::Result>& results,
return out.str();
}
+std::vector<Test::Result> run_a_test(const std::string& test_name)
+ {
+ std::vector<Test::Result> results;
+
+ try
+ {
+ if(test_name == "simd_32" && Botan::CPUID::has_simd_32() == false)
+ {
+ results.push_back(Test::Result::Note(test_name, "SIMD not available on this platform"));
+ }
+ else if(std::unique_ptr<Test> test = Test::get_test(test_name))
+ {
+ std::vector<Test::Result> test_results = test->run();
+ results.insert(results.end(), test_results.begin(), test_results.end());
+ }
+ else
+ {
+ results.push_back(Test::Result::Note(test_name, "Test missing or unavailable"));
+ }
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure(test_name, e.what()));
+ }
+ catch(...)
+ {
+ results.push_back(Test::Result::Failure(test_name, "unknown exception"));
+ }
+
+ return results;
+ }
+
+std::string test_summary(size_t test_run, size_t tot_test_runs, uint64_t total_ns,
+ size_t tests_ran, size_t tests_failed)
+ {
+ std::ostringstream oss;
+
+ if(test_run == 0 && tot_test_runs == 1)
+ oss << "Tests";
+ else
+ oss << "Test run " << (1+test_run) << "/" << tot_test_runs;
+
+ oss << " complete ran " << tests_ran << " tests in "
+ << Botan_Tests::Test::format_time(total_ns) << " ";
+
+ if(tests_failed > 0)
+ {
+ oss << tests_failed << " tests failed";
+ }
+ else if(tests_ran > 0)
+ {
+ oss << "all tests ok";
+ }
+
+ oss << "\n";
+ return oss.str();
+ }
+
}
size_t Test_Runner::run_tests(const std::vector<std::string>& tests_to_run,
+ size_t test_threads,
size_t test_run,
size_t tot_test_runs)
{
@@ -246,60 +309,48 @@ size_t Test_Runner::run_tests(const std::vector<std::string>& tests_to_run,
const uint64_t start_time = Botan_Tests::Test::timestamp();
- for(auto const& test_name : tests_to_run)
+ if(test_threads != 1)
{
- output() << test_name << ':' << std::endl;
+#if defined(BOTAN_HAS_THREAD_UTILS)
+ // If 0 then we let thread pool select the count
+ Botan::Thread_Pool pool(test_threads);
- std::vector<Test::Result> results;
+ std::vector<std::future<std::vector<Test::Result>>> m_fut_results;
- try
+ for(auto const& test_name : tests_to_run)
{
- if(test_name == "simd_32" && Botan::CPUID::has_simd_32() == false)
- {
- results.push_back(Test::Result::Note(test_name, "SIMD not available on this platform"));
- }
- else if(Test* test = Test::get_test(test_name))
- {
- std::vector<Test::Result> test_results = test->run();
- results.insert(results.end(), test_results.begin(), test_results.end());
- }
- else
- {
- results.push_back(Test::Result::Note(test_name, "Test missing or unavailable"));
- }
+ m_fut_results.push_back(pool.run(run_a_test, test_name));
}
- catch(std::exception& e)
- {
- results.push_back(Test::Result::Failure(test_name, e.what()));
- }
- catch(...)
+
+ for(size_t i = 0; i != m_fut_results.size(); ++i)
{
- results.push_back(Test::Result::Failure(test_name, "unknown exception"));
+ output() << tests_to_run[i] << ':' << std::endl;
+ const std::vector<Test::Result> results = m_fut_results[i].get();
+ output() << report_out(results, tests_failed, tests_ran) << std::flush;
}
- output() << report_out(results, tests_failed, tests_ran) << std::flush;
- }
-
- const uint64_t total_ns = Botan_Tests::Test::timestamp() - start_time;
+ pool.shutdown();
- if(test_run == 0 && tot_test_runs == 1)
- output() << "Tests";
- else
- output() << "Test run " << (1+test_run) << "/" << tot_test_runs;
+ const uint64_t total_ns = Botan_Tests::Test::timestamp() - start_time;
- output() << " complete ran " << tests_ran << " tests in "
- << Botan_Tests::Test::format_time(total_ns) << " ";
+ output() << test_summary(test_run, tot_test_runs, total_ns, tests_ran, tests_failed);
- if(tests_failed > 0)
- {
- output() << tests_failed << " tests failed";
+ return tests_failed;
+#else
+ output() << "Running tests in multiple threads not enabled in this build\n";
+#endif
}
- else if(tests_ran > 0)
+
+ for(auto const& test_name : tests_to_run)
{
- output() << "all tests ok";
+ output() << test_name << ':' << std::endl;
+ const std::vector<Test::Result> results = run_a_test(test_name);
+ output() << report_out(results, tests_failed, tests_ran) << std::flush;
}
- output() << std::endl;
+ const uint64_t total_ns = Botan_Tests::Test::timestamp() - start_time;
+
+ output() << test_summary(test_run, tot_test_runs, total_ns, tests_ran, tests_failed);
return tests_failed;
}