blob: 82ea0fa93da81f78d7cc4a89e6b6638ab29fa539 [file] [log] [blame]
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +01001/*
2 * Copyright (c) 2017 ARM Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "Framework.h"
25
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010026#include "support/ToolchainSupport.h"
27
Moritz Pflanzer47752c92017-07-18 13:38:47 +010028#ifdef ARM_COMPUTE_CL
29#include "arm_compute/core/CL/OpenCL.h"
Anthony Barbierbf959222017-07-19 17:01:42 +010030#include "arm_compute/runtime/CL/CLScheduler.h"
Moritz Pflanzer47752c92017-07-18 13:38:47 +010031#endif /* ARM_COMPUTE_CL */
32
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010033#include <chrono>
34#include <iostream>
35#include <sstream>
36#include <type_traits>
37
38namespace arm_compute
39{
40namespace test
41{
42namespace framework
43{
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010044Framework::Framework()
45{
46 _available_instruments.emplace(InstrumentType::WALL_CLOCK_TIMER, Instrument::make_instrument<WallClockTimer>);
47#ifdef PMU_ENABLED
Moritz Pflanzer09e4f982017-08-30 12:47:06 +010048 _available_instruments.emplace(InstrumentType::PMU, Instrument::make_instrument<PMUCounter>);
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010049#endif /* PMU_ENABLED */
Moritz Pflanzer45634b42017-08-30 12:48:18 +010050#ifdef MALI_ENABLED
51 _available_instruments.emplace(InstrumentType::MALI, Instrument::make_instrument<MaliCounter>);
52#endif /* MALI_ENABLED */
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010053}
54
55std::set<InstrumentType> Framework::available_instruments() const
56{
57 std::set<InstrumentType> types;
58
59 for(const auto &instrument : _available_instruments)
60 {
61 types.emplace(instrument.first);
62 }
63
64 return types;
65}
66
Moritz Pflanzerbf234e02017-07-24 15:04:14 +010067std::map<TestResult::Status, int> Framework::count_test_results() const
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010068{
Moritz Pflanzerbf234e02017-07-24 15:04:14 +010069 std::map<TestResult::Status, int> counts;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010070
71 for(const auto &test : _test_results)
72 {
Moritz Pflanzerbf234e02017-07-24 15:04:14 +010073 ++counts[test.second.status];
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010074 }
75
Moritz Pflanzerbf234e02017-07-24 15:04:14 +010076 return counts;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010077}
78
79Framework &Framework::get()
80{
81 static Framework instance;
82 return instance;
83}
84
Moritz Pflanzerec2de0f2017-07-27 14:43:46 +010085void Framework::init(const std::vector<InstrumentType> &instruments, int num_iterations, DatasetMode mode, const std::string &name_filter, const std::string &id_filter, LogLevel log_level)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010086{
Moritz Pflanzerec2de0f2017-07-27 14:43:46 +010087 _test_filter = TestFilter(mode, name_filter, id_filter);
88 _num_iterations = num_iterations;
89 _log_level = log_level;
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010090
Moritz Pflanzer09e4f982017-08-30 12:47:06 +010091 _instruments = std::set<InstrumentType>(instruments.begin(), instruments.end());
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010092}
93
94std::string Framework::current_suite_name() const
95{
96 return join(_test_suite_name.cbegin(), _test_suite_name.cend(), "/");
97}
98
99void Framework::push_suite(std::string name)
100{
101 _test_suite_name.emplace_back(std::move(name));
102}
103
104void Framework::pop_suite()
105{
106 _test_suite_name.pop_back();
107}
108
Moritz Pflanzerc7d15032017-07-18 16:21:16 +0100109void Framework::add_test_info(std::string info)
110{
111 _test_info.emplace_back(std::move(info));
112}
113
114void Framework::clear_test_info()
115{
116 _test_info.clear();
117}
118
119bool Framework::has_test_info() const
120{
121 return !_test_info.empty();
122}
123
124void Framework::print_test_info(std::ostream &os) const
125{
Moritz Pflanzer8df3faf2017-07-28 13:57:53 +0100126 if(!_test_info.empty())
Moritz Pflanzerc7d15032017-07-18 16:21:16 +0100127 {
Moritz Pflanzer8df3faf2017-07-28 13:57:53 +0100128 os << "CONTEXT:\n";
129
130 for(const auto &str : _test_info)
131 {
132 os << " " << str << "\n";
133 }
Moritz Pflanzerc7d15032017-07-18 16:21:16 +0100134 }
135}
136
Giorgio Arena2d099932017-10-25 15:47:08 +0100137template <typename F>
138void Framework::func_on_all_printers(F &&func)
139{
140 std::for_each(std::begin(_printers), std::end(_printers), func);
141}
142
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100143void Framework::log_test_start(const TestInfo &info)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100144{
Giorgio Arena2d099932017-10-25 15:47:08 +0100145 if(_log_level >= LogLevel::TESTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100146 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100147 func_on_all_printers([&](Printer * p)
148 {
149 p->print_test_header(info);
150 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100151 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100152}
153
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100154void Framework::log_test_skipped(const TestInfo &info)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100155{
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100156 static_cast<void>(info);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100157}
158
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100159void Framework::log_test_end(const TestInfo &info)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100160{
Giorgio Arena2d099932017-10-25 15:47:08 +0100161 if(_log_level >= LogLevel::MEASUREMENTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100162 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100163 func_on_all_printers([&](Printer * p)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100164 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100165 p->print_measurements(_test_results.at(info).measurements);
166 });
167 }
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100168
Giorgio Arena2d099932017-10-25 15:47:08 +0100169 if(_log_level >= LogLevel::TESTS)
170 {
171 func_on_all_printers([](Printer * p)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100172 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100173 p->print_test_footer();
174 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100175 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100176}
177
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100178void Framework::log_failed_expectation(const TestError &error)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100179{
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100180 ARM_COMPUTE_ERROR_ON(_current_test_info == nullptr);
181 ARM_COMPUTE_ERROR_ON(_current_test_result == nullptr);
182
183 const bool is_expected_failure = _current_test_info->status == TestCaseFactory::Status::EXPECTED_FAILURE;
184
Giorgio Arena2d099932017-10-25 15:47:08 +0100185 if(_log_level >= error.level())
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100186 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100187 func_on_all_printers([&](Printer * p)
188 {
189 p->print_error(error, is_expected_failure);
190 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100191 }
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100192
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100193 _current_test_result->status = TestResult::Status::FAILED;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100194}
195
steniu01172c58d2017-08-31 13:49:08 +0100196void Framework::log_info(const std::string &info)
197{
Giorgio Arena2d099932017-10-25 15:47:08 +0100198 if(_log_level >= LogLevel::DEBUG)
steniu01172c58d2017-08-31 13:49:08 +0100199 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100200 func_on_all_printers([&](Printer * p)
201 {
202 p->print_info(info);
203 });
steniu01172c58d2017-08-31 13:49:08 +0100204 }
205}
206
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100207int Framework::num_iterations() const
208{
209 return _num_iterations;
210}
211
212void Framework::set_num_iterations(int num_iterations)
213{
214 _num_iterations = num_iterations;
215}
216
217void Framework::set_throw_errors(bool throw_errors)
218{
219 _throw_errors = throw_errors;
220}
221
222bool Framework::throw_errors() const
223{
224 return _throw_errors;
225}
226
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100227void Framework::set_stop_on_error(bool stop_on_error)
228{
229 _stop_on_error = stop_on_error;
230}
231
232bool Framework::stop_on_error() const
233{
234 return _stop_on_error;
235}
236
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100237void Framework::set_error_on_missing_assets(bool error_on_missing_assets)
238{
239 _error_on_missing_assets = error_on_missing_assets;
240}
241
242bool Framework::error_on_missing_assets() const
243{
244 return _error_on_missing_assets;
245}
246
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100247void Framework::run_test(const TestInfo &info, TestCaseFactory &test_factory)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100248{
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100249 if(test_factory.status() == TestCaseFactory::Status::DISABLED)
250 {
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100251 log_test_skipped(info);
252 set_test_result(info, TestResult(TestResult::Status::DISABLED));
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100253 return;
254 }
255
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100256 log_test_start(info);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100257
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100258 Profiler profiler = get_profiler();
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100259 TestResult result(TestResult::Status::NOT_RUN);
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100260
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100261 _current_test_info = &info;
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100262 _current_test_result = &result;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100263
Giorgio Arena2d099932017-10-25 15:47:08 +0100264 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100265 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100266 func_on_all_printers([](Printer * p)
267 {
268 p->print_errors_header();
269 });
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100270 }
271
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100272 const bool is_expected_failure = info.status == TestCaseFactory::Status::EXPECTED_FAILURE;
Moritz Pflanzer5b61fd32017-09-12 15:51:33 +0100273
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100274 try
275 {
276 std::unique_ptr<TestCase> test_case = test_factory.make();
277
278 try
279 {
280 test_case->do_setup();
281
282 for(int i = 0; i < _num_iterations; ++i)
283 {
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100284 profiler.start();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100285 test_case->do_run();
Anthony Barbierbf959222017-07-19 17:01:42 +0100286#ifdef ARM_COMPUTE_CL
287 if(opencl_is_available())
288 {
289 CLScheduler::get().sync();
290 }
291#endif /* ARM_COMPUTE_CL */
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100292 profiler.stop();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100293 }
294
295 test_case->do_teardown();
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100296
297 // Change status to success if no error has happend
298 if(result.status == TestResult::Status::NOT_RUN)
299 {
300 result.status = TestResult::Status::SUCCESS;
301 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100302 }
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100303 catch(const FileNotFound &error)
304 {
305 if(_error_on_missing_assets)
306 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100307 if(_log_level >= LogLevel::ERRORS)
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100308 {
309 TestError test_error(error.what(), LogLevel::ERRORS);
Giorgio Arena2d099932017-10-25 15:47:08 +0100310 func_on_all_printers([&](Printer * p)
311 {
312 p->print_error(test_error, is_expected_failure);
313 });
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100314 }
315
316 result.status = TestResult::Status::FAILED;
317
318 if(_throw_errors)
319 {
320 throw;
321 }
322 }
323 else
324 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100325 if(_log_level >= LogLevel::DEBUG)
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100326 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100327 func_on_all_printers([&](Printer * p)
328 {
329 p->print_info(error.what());
330 });
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100331 }
332
333 result.status = TestResult::Status::NOT_RUN;
334 }
335 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100336 catch(const TestError &error)
337 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100338 if(_log_level >= error.level())
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100339 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100340 func_on_all_printers([&](Printer * p)
341 {
342 p->print_error(error, is_expected_failure);
343 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100344 }
345
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100346 result.status = TestResult::Status::FAILED;
347
348 if(_throw_errors)
349 {
350 throw;
351 }
352 }
Moritz Pflanzer47752c92017-07-18 13:38:47 +0100353#ifdef ARM_COMPUTE_CL
354 catch(const ::cl::Error &error)
355 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100356 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100357 {
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100358 std::stringstream stream;
359 stream << "Error code: " << error.err();
Moritz Pflanzer5b61fd32017-09-12 15:51:33 +0100360 TestError test_error(error.what(), LogLevel::ERRORS, stream.str());
Giorgio Arena2d099932017-10-25 15:47:08 +0100361 func_on_all_printers([&](Printer * p)
362 {
363 p->print_error(test_error, is_expected_failure);
364 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100365 }
366
Moritz Pflanzer47752c92017-07-18 13:38:47 +0100367 result.status = TestResult::Status::FAILED;
368
369 if(_throw_errors)
370 {
371 throw;
372 }
373 }
374#endif /* ARM_COMPUTE_CL */
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100375 catch(const std::exception &error)
376 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100377 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100378 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100379 func_on_all_printers([&](Printer * p)
380 {
381 p->print_error(error, is_expected_failure);
382 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100383 }
384
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100385 result.status = TestResult::Status::CRASHED;
386
387 if(_throw_errors)
388 {
389 throw;
390 }
391 }
392 catch(...)
393 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100394 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100395 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100396 func_on_all_printers([&](Printer * p)
397 {
398 p->print_error(TestError("Received unknown exception"), is_expected_failure);
399 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100400 }
401
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100402 result.status = TestResult::Status::CRASHED;
403
404 if(_throw_errors)
405 {
406 throw;
407 }
408 }
409 }
410 catch(const std::exception &error)
411 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100412 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100413 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100414 func_on_all_printers([&](Printer * p)
415 {
416 p->print_error(error, is_expected_failure);
417 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100418 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100419
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100420 result.status = TestResult::Status::CRASHED;
421
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100422 if(_throw_errors)
423 {
424 throw;
425 }
426 }
427 catch(...)
428 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100429 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100430 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100431 func_on_all_printers([&](Printer * p)
432 {
433 p->print_error(TestError("Received unknown exception"), is_expected_failure);
434 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100435 }
436
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100437 result.status = TestResult::Status::CRASHED;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100438
439 if(_throw_errors)
440 {
441 throw;
442 }
443 }
444
Giorgio Arena2d099932017-10-25 15:47:08 +0100445 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100446 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100447 func_on_all_printers([](Printer * p)
448 {
449 p->print_errors_footer();
450 });
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100451 }
452
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100453 _current_test_info = nullptr;
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100454 _current_test_result = nullptr;
455
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100456 if(result.status == TestResult::Status::FAILED)
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100457 {
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100458 if(info.status == TestCaseFactory::Status::EXPECTED_FAILURE)
459 {
460 result.status = TestResult::Status::EXPECTED_FAILURE;
461 }
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100462 }
463
464 if(result.status == TestResult::Status::FAILED || result.status == TestResult::Status::CRASHED)
465 {
466 if(_stop_on_error)
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100467 {
468 throw std::runtime_error("Abort on first error.");
469 }
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100470 }
471
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100472 result.measurements = profiler.measurements();
473
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100474 set_test_result(info, result);
475 log_test_end(info);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100476}
477
478bool Framework::run()
479{
480 // Clear old test results
481 _test_results.clear();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100482
Giorgio Arena2d099932017-10-25 15:47:08 +0100483 if(_log_level >= LogLevel::TESTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100484 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100485 func_on_all_printers([](Printer * p)
486 {
487 p->print_run_header();
488 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100489 }
490
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100491 const std::chrono::time_point<std::chrono::high_resolution_clock> start = std::chrono::high_resolution_clock::now();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100492
493 int id = 0;
494
495 for(auto &test_factory : _test_factories)
496 {
497 const std::string test_case_name = test_factory->name();
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100498 const TestInfo test_info{ id, test_case_name, test_factory->mode(), test_factory->status() };
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100499
Moritz Pflanzerec2de0f2017-07-27 14:43:46 +0100500 if(_test_filter.is_selected(test_info))
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100501 {
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100502 run_test(test_info, *test_factory);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100503 }
504
505 ++id;
506 }
507
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100508 const std::chrono::time_point<std::chrono::high_resolution_clock> end = std::chrono::high_resolution_clock::now();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100509
Giorgio Arena2d099932017-10-25 15:47:08 +0100510 if(_log_level >= LogLevel::TESTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100511 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100512 func_on_all_printers([](Printer * p)
513 {
514 p->print_run_footer();
515 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100516 }
517
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100518 auto runtime = std::chrono::duration_cast<std::chrono::seconds>(end - start);
519 std::map<TestResult::Status, int> results = count_test_results();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100520
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100521 if(_log_level > LogLevel::NONE)
522 {
Moritz Pflanzer8df3faf2017-07-28 13:57:53 +0100523 std::cout << "Executed " << _test_results.size() << " test(s) ("
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100524 << results[TestResult::Status::SUCCESS] << " passed, "
525 << results[TestResult::Status::EXPECTED_FAILURE] << " expected failures, "
526 << results[TestResult::Status::FAILED] << " failed, "
527 << results[TestResult::Status::CRASHED] << " crashed, "
528 << results[TestResult::Status::DISABLED] << " disabled) in " << runtime.count() << " second(s)\n";
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100529 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100530
steniu013e05e4e2017-08-25 17:18:01 +0100531 int num_successful_tests = results[TestResult::Status::SUCCESS] + results[TestResult::Status::EXPECTED_FAILURE] + results[TestResult::Status::DISABLED];
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100532
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100533 return (static_cast<unsigned int>(num_successful_tests) == _test_results.size());
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100534}
535
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100536void Framework::set_test_result(TestInfo info, TestResult result)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100537{
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100538 _test_results.emplace(std::move(info), std::move(result));
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100539}
540
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100541void Framework::print_test_results(Printer &printer) const
542{
543 printer.print_run_header();
544
545 for(const auto &test : _test_results)
546 {
547 printer.print_test_header(test.first);
548 printer.print_measurements(test.second.measurements);
549 printer.print_test_footer();
550 }
551
552 printer.print_run_footer();
553}
554
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100555Profiler Framework::get_profiler() const
556{
557 Profiler profiler;
558
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100559 const bool all_instruments = std::any_of(
560 _instruments.begin(),
561 _instruments.end(),
562 [](InstrumentType type) -> bool { return type == InstrumentType::ALL; });
563
564 auto is_selected = [&](InstrumentType instrument) -> bool
565 {
566 return std::find_if(_instruments.begin(), _instruments.end(), [&](InstrumentType type) -> bool {
567 const auto group = static_cast<InstrumentType>(static_cast<uint64_t>(type) & 0xFF00);
568 return group == instrument;
569 })
570 != _instruments.end();
571 };
572
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100573 for(const auto &instrument : _available_instruments)
574 {
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100575 if(all_instruments || is_selected(instrument.first))
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100576 {
577 profiler.add(instrument.second());
578 }
579 }
580
581 return profiler;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100582}
583
Giorgio Arena2d099932017-10-25 15:47:08 +0100584void Framework::add_printer(Printer *printer)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100585{
Giorgio Arena2d099932017-10-25 15:47:08 +0100586 _printers.push_back(printer);
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100587}
588
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100589std::vector<TestInfo> Framework::test_infos() const
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100590{
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100591 std::vector<TestInfo> ids;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100592
593 int id = 0;
594
595 for(const auto &factory : _test_factories)
596 {
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100597 TestInfo test_info{ id, factory->name(), factory->mode(), factory->status() };
598
Moritz Pflanzerec2de0f2017-07-27 14:43:46 +0100599 if(_test_filter.is_selected(test_info))
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100600 {
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100601 ids.emplace_back(std::move(test_info));
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100602 }
603
604 ++id;
605 }
606
607 return ids;
608}
steniu01172c58d2017-08-31 13:49:08 +0100609
610LogLevel Framework::log_level() const
611{
612 return _log_level;
613}
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100614} // namespace framework
615} // namespace test
616} // namespace arm_compute