16#define TDEBUG(...) Ase::debug ("Test", __VA_ARGS__)
27 deadline_ (deadline_in_secs), test_duration_ (0), n_reps_ (0)
42#define DEBUG_LOOPS_NEEDED(...) while (0) printerr (__VA_ARGS__)
47 if (samples_.
size() < 3)
49 n_reps_ =
MAX (1, n_reps_);
50 DEBUG_LOOPS_NEEDED (
"loops_needed: %d\n", n_reps_);
54 const double deadline =
MAX (deadline_ == 0.0 ? 0.005 : deadline_, resolution * 10000.0);
55 if (test_duration_ < deadline * 0.2)
58 n_reps_ =
MAX (n_reps_ + 1,
int64 (n_reps_ * 1.5)) | 1;
59 DEBUG_LOOPS_NEEDED (
"loops_needed: %d\n", n_reps_);
62 if (test_duration_ < deadline)
64 DEBUG_LOOPS_NEEDED (
"loops_needed: %d\n", n_reps_);
67 DEBUG_LOOPS_NEEDED (
"loops_needed: %d\n", 0);
72Timer::submit (
double elapsed,
int64 repetitions)
74 test_duration_ += elapsed;
76 if (elapsed >= resolution * 500.0)
77 samples_.
push_back (elapsed / repetitions);
79 n_reps_ = (n_reps_ + n_reps_) | 1;
94 for (
size_t i = 0; i < samples_.
size(); i++)
95 m =
MIN (m, samples_[i]);
103 for (
size_t i = 0; i < samples_.
size(); i++)
104 m =
MAX (m, samples_[i]);
109ensure_newline (
const String &s)
111 if (!s.
size() || s[s.
size()-1] !=
'\n')
116static __thread
String *thread_test_start = NULL;
119test_output (
int kind,
const String &msg)
121 if (!thread_test_start)
122 thread_test_start =
new String();
123 String &test_start = *thread_test_start;
125 bool aborting =
false;
129 if (!test_start.
empty())
130 return test_output (
'F',
string_format (
"Unfinished Test: %s\n", test_start));
132 sout =
" START… " + ensure_newline (msg);
135 if (test_start.
empty())
136 return test_output (
'F',
"Extraneous TDONE() call");
138 sout =
" …DONE " + ensure_newline (msg);
142 sout =
" NOTE " + ensure_newline (msg);
145 sout =
" PASS " + ensure_newline (msg);
148 sout =
" BENCH " + ensure_newline (msg);
151 sout =
" FAIL " + ensure_newline (msg);
155 sout =
" INFO " + ensure_newline (msg);
181 return cached_verbose;
209static const TestChain *global_test_chain = NULL;
212 name_ (tname), func_ (tfunc), next_ (global_test_chain), kind_ (kind)
215 global_test_chain =
this;
221 for (
const auto &tname : test_names)
228TestChain::run (ptrdiff_t internal_token,
const StringS *test_names)
230 assert_return (internal_token == ptrdiff_t (global_test_chain));
232 for (
const TestChain *t = global_test_chain; t; t = t->next_)
234 std::sort (tests.begin(), tests.end(), [] (
const TestChain *a,
const TestChain *b) {
235 return std::string (a->name_) < b->name_;
237 for (
const TestChain *t : tests)
239 if (test_names && !match_testname (t->name_, *test_names))
241 if (!test_names && (t->kind_ == SLOW ||
246 printout (
" RUN… %s\n", t->name_);
250 printout (
" PASS %s\n", t->name_);
258 IntegrityCheck::deferred_init();
259 TestChain::run (ptrdiff_t (global_test_chain), &test_names);
266 IntegrityCheck::deferred_init();
267 TestChain::run (ptrdiff_t (global_test_chain), NULL);
274 IntegrityCheck::deferred_init();
276 for (
const TestChain *t = global_test_chain; t; t = t->next())
278 entries.resize (entries.size() + 1);
279 TestEntry &entry = entries.back();
280 entry.ident = t->name();
281 entry.flags = t->flags();
285 [] (
const TestEntry &a,
const TestEntry &b) {
286 return a.ident < b.ident;
290 for (
const auto &entry : entries)
291 if (last == entry.ident)
292 Ase::fatal_error (
"duplicate test entry: %s", entry.ident);
297 [] (
const TestEntry &a,
const TestEntry &b) {
298 const bool aintegrity = a.flags & INTEGRITY;
299 const bool bintegrity = b.flags & INTEGRITY;
300 return aintegrity > bintegrity;
308 IntegrityCheck::deferred_init();
309 for (
const TestChain *t = global_test_chain; t; t = t->next())
310 if (test_identifier == t->name())
313 printout (
" RUN… %s\n", t->name());
317 printout (
" PASS %s\n", t->name());
325IntegrityCheck *IntegrityCheck::first_ =
nullptr;
328IntegrityCheck::deferred_init()
330 static uint integritycheck_count = [] () {
332 for (IntegrityCheck *current = first_; current; current = current->next_)
334 auto *t =
new Ase::Test::TestChain (current->func_, current->name_, Ase::Test::INTEGRITY);
double min_elapsed() const
Minimum time benchmarked for a callee() call.
Timer(double deadline_in_secs=0)
Create a Timer() instance, specifying an optional upper bound for test durations.
double max_elapsed() const
Maximum time benchmarked for a callee() call.
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
#define MIN(a, b)
Yield minimum of a and b.
#define MAX(a, b)
Yield maximum of a and b.
int run(const StringS &test_names)
Run named tests.
bool verbose()
Indicates whether tests should run verbosely.
int64_t random_irange(int64_t begin, int64_t end)
Return random int within range for reproduceble tests.
uint64_t random_int64()
Return random int for reproduceble tests.
double random_float()
Return random double for reproduceble tests.
double random_frange(double begin, double end)
Return random double within range for reproduceble tests.
bool slow()
Indicates whether slow tests should be run.
The Anklang C++ API namespace.
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
uint64 timestamp_resolution()
Provide resolution of timestamp_benchmark() in nano-seconds.
void breakpoint()
Cause a debugging breakpoint, for development only.
uint64 timestamp_benchmark()
Returns benchmark timestamp in nano-seconds, clock starts around program startup.
std::vector< String > StringS
Convenience alias for a std::vector<std::string>.
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
int64_t random_irange(int64_t begin, int64_t end)
std::string String
Convenience alias for std::string.
bool string_to_bool(const String &string, bool fallback)
uint32_t uint
Provide 'uint' as convenience type.
double random_frange(double begin, double end)
std::string_view string_option_find_value(const char *string, const char *feature, const char *fallback, const char *denied, bool matchallnone)
Low level option search, avoids dynamic allocations.