1- #include < chrono>
21#include < functional>
32#include < future>
43#include < iostream>
@@ -128,15 +127,18 @@ void spamCall(std::function<void()>&& call_to_spam, const uint32_t num_threads)
128127 std::promise<void > signal_all_threads_running;
129128 std::shared_future<void > future (signal_all_threads_running.get_future ());
130129
130+ std::atomic<uint32_t > runcount = 0 ;
131131 for (auto & thread : threads) {
132- thread = std::thread ([future, &call_to_spam] {
132+ thread = std::thread ([future, &call_to_spam, &runcount] {
133+ runcount++;
133134 future.wait ();
134135 call_to_spam ();
135136 });
136137 }
137138 // Allow threads to accrue on future.wait() to maximize concurrency on the call
138139 // we are testing.
139- sleep (1 );
140+ while (runcount != num_threads) {
141+ }
140142 signal_all_threads_running.set_value ();
141143 for (std::thread& thread : threads) {
142144 thread.join ();
@@ -152,7 +154,7 @@ TEST(Logger, SparseLogMacros) {
152154 void logSomethingBelowLogLevelOnce () { ENVOY_LOG_ONCE (debug, " foo3 '{}'" , evaluations ()++); }
153155 void logSomethingThrice () { ENVOY_LOG_FIRST_N (error, 3 , " foo4 '{}'" , evaluations ()++); }
154156 void logEverySeventh () { ENVOY_LOG_EVERY_NTH (error, 7 , " foo5 '{}'" , evaluations ()++); }
155- void logEverySecond () { ENVOY_LOG_PERIODIC (error, 1s , " foo6 '{}'" , evaluations ()++); }
157+ void logWithBackoff () { ENVOY_LOG_WITH_BACKOFF (error, " foo6 '{}'" , evaluations ()++); }
156158 std::atomic<int32_t >& evaluations () { MUTABLE_CONSTRUCT_ON_FIRST_USE (std::atomic<int32_t >); };
157159 };
158160 constexpr uint32_t kNumThreads = 100 ;
@@ -181,20 +183,20 @@ TEST(Logger, SparseLogMacros) {
181183 // (100 threads / log every 7th) + 1s = 15 more evaluations upon logging very 7th.
182184 EXPECT_EQ (20 , helper.evaluations ());
183185
184- // So use our knowledge that spamCall will sleep 1 second in the following lines:
185- // We expect one log entry / second. Therefore each spamCall ought to result in one
186- // more evaluation. This depends on real time and not sim time, hopefully 1 second
187- // is enough to not introduce flakes in practice.
188- spamCall ([&helper]() { helper.logEverySecond (); }, kNumThreads );
186+ helper.logWithBackoff ();
187+ // First call ought to propagate.
189188 EXPECT_EQ (21 , helper.evaluations ());
190- spamCall ([&helper]() { helper.logEverySecond (); }, kNumThreads );
191- EXPECT_EQ (22 , helper.evaluations ());
189+
190+ spamCall ([&helper]() { helper.logWithBackoff (); }, kNumThreads );
191+ // 64 is the highest power of two that fits when kNumThreads == 100.
192+ // We should log on 2, 4, 8, 16, 32, 64, which means we can expect to add 6 more evaluations.
193+ EXPECT_EQ (27 , helper.evaluations ());
192194
193195 spamCall ([&helper]() { helper.logSomethingBelowLogLevelOnce (); }, kNumThreads );
194196 // Without fine-grained logging, we shouldn't observe additional argument evaluations
195197 // for log lines below the configured log level.
196198 // TODO(#12885): fancy logger shouldn't always evaluate variadic macro arguments.
197- EXPECT_EQ (::Envoy::Logger::Context::useFancyLogger () ? 23 : 22 , helper.evaluations ());
199+ EXPECT_EQ (::Envoy::Logger::Context::useFancyLogger () ? 28 : 27 , helper.evaluations ());
198200}
199201
200202TEST (RegistryTest, LoggerWithName) {
0 commit comments