xref: /aosp_15_r20/external/cronet/base/test/scoped_run_loop_timeout.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 <optional>
9 #include <string>
10 
11 #include "base/functional/callback.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/location.h"
14 #include "base/memory/raw_ptr.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::test {
23 
24 FORWARD_DECLARE_TEST(TaskEnvironmentTest, SetsDefaultRunTimeout);
25 
26 // Configures all RunLoop::Run() calls on the current thread to run the
27 // supplied |on_timeout| callback if they run for longer than |timeout|.
28 //
29 // Specifying Run() timeouts per-thread avoids the need to cope with Run()s
30 // executing concurrently with ScopedRunLoopTimeout initialization or
31 // teardown, and allows "default" timeouts to be specified by suites, rather
32 // than explicitly configuring them for every RunLoop, in each test.
33 //
34 // This is used by test classes including TaskEnvironment and TestSuite to
35 // set a default Run() timeout on the main thread of all tests which use them.
36 //
37 // Tests which have steps which need to Run() for longer than their suite's
38 // default (if any) allows can override the active timeout by creating a nested
39 // ScopedRunLoopTimeout on their stack, e.g:
40 //
41 //   ScopedRunLoopTimeout default_timeout(kDefaultRunTimeout);
42 //   ... do other test stuff ...
43 //   RunLoop().Run(); // Run for up to kDefaultRunTimeout.
44 //   ...
45 //   {
46 //     ScopedRunLoopTimeout specific_timeout(kTestSpecificTimeout);
47 //     RunLoop().Run(); // Run for up to kTestSpecificTimeout.
48 //   }
49 //   ...
50 //   RunLoop().Run(); // Run for up to kDefaultRunTimeout.
51 //
52 // The currently-active timeout can also be temporarily disabled:
53 //   ScopedDisableRunLoopTimeout disable_timeout;
54 //
55 // By default LOG(FATAL) will be invoked on Run() timeout. Test binaries
56 // can opt-in to using ADD_FAILURE() instead by calling
57 // SetAddGTestFailureOnTimeout() during process initialization.
58 //
59 // TaskEnvironment applies a default Run() timeout.
60 
61 class ScopedRunLoopTimeout {
62  public:
63   // This callback is the one called upon run loop timeouts.
64   // RunLoop inner mechanism will call this callback after having quit the run
65   // loop. Implementer might chose to log locations, crash the process, dump a
66   // stack trace, depending on the desired behaviour for run loop timeouts.
67   // Invoking `on_timeout_log` might return a personalized timeouts message
68   // string. This callback was sent at ScopedRunLoopTimeout creation. Invoking
69   // this callback is not mandatory, as it depends on the desired behaviour of
70   // this function.
71   using TimeoutCallback = base::RepeatingCallback<void(
72       const Location& timeout_enabled_from_here,
73       RepeatingCallback<std::string()> on_timeout_log,
74       const Location& run_from_here)>;
75 
76   ScopedRunLoopTimeout(const Location& timeout_enabled_from_here,
77                        TimeDelta timeout);
78   ~ScopedRunLoopTimeout();
79 
80   // Invokes |on_timeout_log| if |timeout| expires, and appends it to the
81   // logged error message. If `timeout` is not specified the current timeout is
82   // used and only the log message is overridden.
83   ScopedRunLoopTimeout(const Location& timeout_enabled_from_here,
84                        std::optional<TimeDelta> timeout,
85                        RepeatingCallback<std::string()> on_timeout_log);
86 
87   ScopedRunLoopTimeout(const ScopedRunLoopTimeout&) = delete;
88   ScopedRunLoopTimeout& operator=(const ScopedRunLoopTimeout&) = delete;
89 
90   // Returns true if there is a Run() timeout configured on the current thread.
91   static bool ExistsForCurrentThread();
92 
93   // Important note:
94   // The two following static methods will alter the behaviour on run loop
95   // timeouts. If both methods are being called (whatever the ordering), the
96   // behaviour will be chained, which means that both callbacks will be invoked.
97   // If the custom callback handling is reset (`SetTimeoutCallbackForTesting`
98   // called with `nullptr`), then we reset the behaviour to its previous state,
99   // which is, if `SetAddGTestFailureOnTimeout`, it will invoke GTest timeout
100   // handling. Otherwise, it will invoke the default function.
101 
102   // Add GTest timeout handler.
103   static void SetAddGTestFailureOnTimeout();
104 
105   // Add provided callback as timeout handler.
106   static void SetTimeoutCallbackForTesting(std::unique_ptr<TimeoutCallback> cb);
107 
108  private:
109   TimeoutCallback GetTimeoutCallback();
110 
111  protected:
112   FRIEND_TEST_ALL_PREFIXES(ScopedRunLoopRunTimeoutTest, TimesOut);
113   FRIEND_TEST_ALL_PREFIXES(ScopedRunLoopRunTimeoutTest, RunTasksUntilTimeout);
114   FRIEND_TEST_ALL_PREFIXES(TaskEnvironmentTest, SetsDefaultRunTimeout);
115   FRIEND_TEST_ALL_PREFIXES(content::ContentBrowserTest, RunTimeoutInstalled);
116 
117   // Exposes the RunLoopTimeout to the friend tests (see above).
118   static const RunLoop::RunLoopTimeout* GetTimeoutForCurrentThread();
119 
120   raw_ptr<const RunLoop::RunLoopTimeout> const nested_timeout_;
121   RunLoop::RunLoopTimeout run_timeout_;
122 };
123 
124 class ScopedDisableRunLoopTimeout {
125  public:
126   ScopedDisableRunLoopTimeout();
127   ~ScopedDisableRunLoopTimeout();
128 
129   ScopedDisableRunLoopTimeout(const ScopedDisableRunLoopTimeout&) = delete;
130   ScopedDisableRunLoopTimeout& operator=(const ScopedDisableRunLoopTimeout&) =
131       delete;
132 
133  private:
134   const raw_ptr<const RunLoop::RunLoopTimeout> nested_timeout_;
135 };
136 
137 }  // namespace base::test
138 
139 #endif  // BASE_TEST_SCOPED_RUN_LOOP_TIMEOUT_H_
140