1 // Copyright 2019 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TEST_SCOPED_RUN_LOOP_TIMEOUT_H_ 6 #define BASE_TEST_SCOPED_RUN_LOOP_TIMEOUT_H_ 7 8 #include <string> 9 10 #include "base/functional/callback.h" 11 #include "base/gtest_prod_util.h" 12 #include "base/location.h" 13 #include "base/memory/raw_ptr.h" 14 #include "base/memory/raw_ptr_exclusion.h" 15 #include "base/run_loop.h" 16 #include "base/time/time.h" 17 18 namespace content { 19 FORWARD_DECLARE_TEST(ContentBrowserTest, RunTimeoutInstalled); 20 } 21 22 namespace base { 23 namespace test { 24 25 FORWARD_DECLARE_TEST(TaskEnvironmentTest, SetsDefaultRunTimeout); 26 27 // Configures all RunLoop::Run() calls on the current thread to run the 28 // supplied |on_timeout| callback if they run for longer than |timeout|. 29 // 30 // Specifying Run() timeouts per-thread avoids the need to cope with Run()s 31 // executing concurrently with ScopedRunLoopTimeout initialization or 32 // teardown, and allows "default" timeouts to be specified by suites, rather 33 // than explicitly configuring them for every RunLoop, in each test. 34 // 35 // This is used by test classes including TaskEnvironment and TestSuite to 36 // set a default Run() timeout on the main thread of all tests which use them. 37 // 38 // Tests which have steps which need to Run() for longer than their suite's 39 // default (if any) allows can override the active timeout by creating a nested 40 // ScopedRunLoopTimeout on their stack, e.g: 41 // 42 // ScopedRunLoopTimeout default_timeout(kDefaultRunTimeout); 43 // ... do other test stuff ... 44 // RunLoop().Run(); // Run for up to kDefaultRunTimeout. 45 // ... 46 // { 47 // ScopedRunLoopTimeout specific_timeout(kTestSpecificTimeout); 48 // RunLoop().Run(); // Run for up to kTestSpecificTimeout. 49 // } 50 // ... 51 // RunLoop().Run(); // Run for up to kDefaultRunTimeout. 52 // 53 // The currently-active timeout can also be temporarily disabled: 54 // ScopedDisableRunLoopTimeout disable_timeout; 55 // 56 // By default LOG(FATAL) will be invoked on Run() timeout. Test binaries 57 // can opt-in to using ADD_FAILURE() instead by calling 58 // SetAddGTestFailureOnTimeout() during process initialization. 59 // 60 // TaskEnvironment applies a default Run() timeout. 61 62 class ScopedRunLoopTimeout { 63 public: 64 ScopedRunLoopTimeout(const Location& timeout_enabled_from_here, 65 TimeDelta timeout); 66 ~ScopedRunLoopTimeout(); 67 68 // Invokes |on_timeout_log| if |timeout| expires, and appends it to the 69 // logged error message. 70 ScopedRunLoopTimeout(const Location& timeout_enabled_from_here, 71 TimeDelta timeout, 72 RepeatingCallback<std::string()> on_timeout_log); 73 74 ScopedRunLoopTimeout(const ScopedRunLoopTimeout&) = delete; 75 ScopedRunLoopTimeout& operator=(const ScopedRunLoopTimeout&) = delete; 76 77 // Returns true if there is a Run() timeout configured on the current thread. 78 static bool ExistsForCurrentThread(); 79 80 static void SetAddGTestFailureOnTimeout(); 81 82 protected: 83 FRIEND_TEST_ALL_PREFIXES(ScopedRunLoopRunTimeoutTest, TimesOut); 84 FRIEND_TEST_ALL_PREFIXES(ScopedRunLoopRunTimeoutTest, RunTasksUntilTimeout); 85 FRIEND_TEST_ALL_PREFIXES(TaskEnvironmentTest, SetsDefaultRunTimeout); 86 FRIEND_TEST_ALL_PREFIXES(content::ContentBrowserTest, RunTimeoutInstalled); 87 88 // Exposes the RunLoopTimeout to the friend tests (see above). 89 static const RunLoop::RunLoopTimeout* GetTimeoutForCurrentThread(); 90 91 // This field is not a raw_ptr<> because it was filtered by the rewriter for: 92 // #union 93 RAW_PTR_EXCLUSION const RunLoop::RunLoopTimeout* const nested_timeout_; 94 RunLoop::RunLoopTimeout run_timeout_; 95 }; 96 97 class ScopedDisableRunLoopTimeout { 98 public: 99 ScopedDisableRunLoopTimeout(); 100 ~ScopedDisableRunLoopTimeout(); 101 102 ScopedDisableRunLoopTimeout(const ScopedDisableRunLoopTimeout&) = delete; 103 ScopedDisableRunLoopTimeout& operator=(const ScopedDisableRunLoopTimeout&) = 104 delete; 105 106 private: 107 const raw_ptr<const RunLoop::RunLoopTimeout> nested_timeout_; 108 }; 109 110 } // namespace test 111 } // namespace base 112 113 #endif // BASE_TEST_SCOPED_RUN_LOOP_TIMEOUT_H_ 114