1a8c51b3fSopenharmony_ci// Testing:
2a8c51b3fSopenharmony_ci//   State::PauseTiming()
3a8c51b3fSopenharmony_ci//   State::ResumeTiming()
4a8c51b3fSopenharmony_ci// Test that CHECK's within these function diagnose when they are called
5a8c51b3fSopenharmony_ci// outside of the KeepRunning() loop.
6a8c51b3fSopenharmony_ci//
7a8c51b3fSopenharmony_ci// NOTE: Users should NOT include or use src/check.h. This is only done in
8a8c51b3fSopenharmony_ci// order to test library internals.
9a8c51b3fSopenharmony_ci
10a8c51b3fSopenharmony_ci#include <cstdlib>
11a8c51b3fSopenharmony_ci#include <stdexcept>
12a8c51b3fSopenharmony_ci
13a8c51b3fSopenharmony_ci#include "../src/check.h"
14a8c51b3fSopenharmony_ci#include "benchmark/benchmark.h"
15a8c51b3fSopenharmony_ci
16a8c51b3fSopenharmony_ci#if defined(__GNUC__) && !defined(__EXCEPTIONS)
17a8c51b3fSopenharmony_ci#define TEST_HAS_NO_EXCEPTIONS
18a8c51b3fSopenharmony_ci#endif
19a8c51b3fSopenharmony_ci
20a8c51b3fSopenharmony_civoid TestHandler() {
21a8c51b3fSopenharmony_ci#ifndef TEST_HAS_NO_EXCEPTIONS
22a8c51b3fSopenharmony_ci  throw std::logic_error("");
23a8c51b3fSopenharmony_ci#else
24a8c51b3fSopenharmony_ci  std::abort();
25a8c51b3fSopenharmony_ci#endif
26a8c51b3fSopenharmony_ci}
27a8c51b3fSopenharmony_ci
28a8c51b3fSopenharmony_civoid try_invalid_pause_resume(benchmark::State& state) {
29a8c51b3fSopenharmony_ci#if !defined(TEST_BENCHMARK_LIBRARY_HAS_NO_ASSERTIONS) && \
30a8c51b3fSopenharmony_ci    !defined(TEST_HAS_NO_EXCEPTIONS)
31a8c51b3fSopenharmony_ci  try {
32a8c51b3fSopenharmony_ci    state.PauseTiming();
33a8c51b3fSopenharmony_ci    std::abort();
34a8c51b3fSopenharmony_ci  } catch (std::logic_error const&) {
35a8c51b3fSopenharmony_ci  }
36a8c51b3fSopenharmony_ci  try {
37a8c51b3fSopenharmony_ci    state.ResumeTiming();
38a8c51b3fSopenharmony_ci    std::abort();
39a8c51b3fSopenharmony_ci  } catch (std::logic_error const&) {
40a8c51b3fSopenharmony_ci  }
41a8c51b3fSopenharmony_ci#else
42a8c51b3fSopenharmony_ci  (void)state;  // avoid unused warning
43a8c51b3fSopenharmony_ci#endif
44a8c51b3fSopenharmony_ci}
45a8c51b3fSopenharmony_ci
46a8c51b3fSopenharmony_civoid BM_diagnostic_test(benchmark::State& state) {
47a8c51b3fSopenharmony_ci  static bool called_once = false;
48a8c51b3fSopenharmony_ci
49a8c51b3fSopenharmony_ci  if (called_once == false) try_invalid_pause_resume(state);
50a8c51b3fSopenharmony_ci
51a8c51b3fSopenharmony_ci  for (auto _ : state) {
52a8c51b3fSopenharmony_ci    auto iterations = state.iterations();
53a8c51b3fSopenharmony_ci    benchmark::DoNotOptimize(iterations);
54a8c51b3fSopenharmony_ci  }
55a8c51b3fSopenharmony_ci
56a8c51b3fSopenharmony_ci  if (called_once == false) try_invalid_pause_resume(state);
57a8c51b3fSopenharmony_ci
58a8c51b3fSopenharmony_ci  called_once = true;
59a8c51b3fSopenharmony_ci}
60a8c51b3fSopenharmony_ciBENCHMARK(BM_diagnostic_test);
61a8c51b3fSopenharmony_ci
62a8c51b3fSopenharmony_civoid BM_diagnostic_test_keep_running(benchmark::State& state) {
63a8c51b3fSopenharmony_ci  static bool called_once = false;
64a8c51b3fSopenharmony_ci
65a8c51b3fSopenharmony_ci  if (called_once == false) try_invalid_pause_resume(state);
66a8c51b3fSopenharmony_ci
67a8c51b3fSopenharmony_ci  while (state.KeepRunning()) {
68a8c51b3fSopenharmony_ci    auto iterations = state.iterations();
69a8c51b3fSopenharmony_ci    benchmark::DoNotOptimize(iterations);
70a8c51b3fSopenharmony_ci  }
71a8c51b3fSopenharmony_ci
72a8c51b3fSopenharmony_ci  if (called_once == false) try_invalid_pause_resume(state);
73a8c51b3fSopenharmony_ci
74a8c51b3fSopenharmony_ci  called_once = true;
75a8c51b3fSopenharmony_ci}
76a8c51b3fSopenharmony_ciBENCHMARK(BM_diagnostic_test_keep_running);
77a8c51b3fSopenharmony_ci
78a8c51b3fSopenharmony_ciint main(int argc, char* argv[]) {
79a8c51b3fSopenharmony_ci#ifdef NDEBUG
80a8c51b3fSopenharmony_ci  // This test is exercising functionality for debug builds, which are not
81a8c51b3fSopenharmony_ci  // available in release builds. Skip the test if we are in that environment
82a8c51b3fSopenharmony_ci  // to avoid a test failure.
83a8c51b3fSopenharmony_ci  std::cout << "Diagnostic test disabled in release build" << std::endl;
84a8c51b3fSopenharmony_ci  (void)argc;
85a8c51b3fSopenharmony_ci  (void)argv;
86a8c51b3fSopenharmony_ci#else
87a8c51b3fSopenharmony_ci  benchmark::internal::GetAbortHandler() = &TestHandler;
88a8c51b3fSopenharmony_ci  benchmark::Initialize(&argc, argv);
89a8c51b3fSopenharmony_ci  benchmark::RunSpecifiedBenchmarks();
90a8c51b3fSopenharmony_ci#endif
91a8c51b3fSopenharmony_ci}
92