1+ #pragma once
2+
3+ #include < gtest/gtest.h>
4+
5+ #include < cstdlib>
6+ #include < cstring>
7+ #include < iostream>
8+
9+ namespace test_utils {
10+
11+ static int getFlakyRetries () {
12+ const char * retry_env = std::getenv (" FLAKY_RETRIES" );
13+ if (retry_env != nullptr ) {
14+ try {
15+ int retries = std::stoi (retry_env);
16+ return std::max (1 , std::min (retries, 100 ));
17+ } catch (const std::exception&) {
18+ return 10 ;
19+ }
20+ }
21+ return 10 ;
22+ }
23+
24+ static bool isFlakyTestsEnabled () {
25+ const char * disabled = std::getenv (" DISABLE_FLAKY_TESTS" );
26+ if (disabled == nullptr ) {
27+ return true ;
28+ }
29+ return std::strcmp (disabled, " 1" ) != 0 && std::strcmp (disabled, " true" ) != 0 ;
30+ }
31+
32+ template <typename TestFunc>
33+ void runFlakyTest (const char * test_name, TestFunc test_func) {
34+ if (!isFlakyTestsEnabled ()) {
35+ test_func ();
36+ return ;
37+ }
38+
39+ int max_retries = getFlakyRetries ();
40+
41+ for (int attempt = 1 ; attempt <= max_retries; ++attempt) {
42+ try {
43+ if (attempt > 1 ) {
44+ std::cout << " [FLAKY RETRY " << attempt << " /" << max_retries << " ] "
45+ << test_name << std::endl;
46+ }
47+
48+ test_func ();
49+
50+ if (attempt > 1 ) {
51+ std::cout << " [FLAKY SUCCESS] " << test_name << " passed on attempt "
52+ << attempt << std::endl;
53+ }
54+ return ;
55+
56+ } catch (...) {
57+ if (attempt == max_retries) {
58+ std::cout << " [FLAKY EXHAUSTED] " << test_name << " failed after "
59+ << max_retries << " attempts" << std::endl;
60+ throw ;
61+ } else if (attempt == 1 ) {
62+ std::cout << " [FLAKY FAILED] " << test_name << " failed on attempt "
63+ << attempt << " , retrying..." << std::endl;
64+ }
65+ }
66+ }
67+ }
68+
69+ #define FLAKY_TEST (test_case_name, test_name ) \
70+ TEST (test_case_name, test_name) { \
71+ auto flaky_test_body = []()
72+
73+ #define FLAKY_TEST_F (test_fixture, test_name ) \
74+ TEST_F (test_fixture, test_name) { \
75+ auto flaky_test_body = [this ]()
76+
77+ #define FLAKY_END_TEST \
78+ ; \
79+ test_utils::runFlakyTest ( \
80+ testing::UnitTest::GetInstance ()->current_test_info ()->name (), \
81+ flaky_test_body); \
82+ }
83+
84+ }
0 commit comments