• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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