[go: nahoru, domu]

blob: 977fa9641f605066b935c6f04effe74396808198 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2019 The Chromium Authors
Wez9d5dd282020-02-10 17:21:222// 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
Arthur Sonzognie5fff99c2024-02-21 15:58:248#include <optional>
Wez362b6ca2020-02-19 17:17:069#include <string>
10
Avi Drissman63e1f992023-01-13 18:54:4311#include "base/functional/callback.h"
kenkangxgwea7eea822021-08-17 03:21:2412#include "base/gtest_prod_util.h"
Weza3ec3fe2020-02-17 12:52:1613#include "base/location.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
Wez9d5dd282020-02-10 17:21:2215#include "base/run_loop.h"
16#include "base/time/time.h"
17
18namespace content {
19FORWARD_DECLARE_TEST(ContentBrowserTest, RunTimeoutInstalled);
20}
21
Dana Fried0ff12a12023-06-09 16:51:0022namespace base::test {
Wez9d5dd282020-02-10 17:21:2223
24FORWARD_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
61class ScopedRunLoopTimeout {
62 public:
Paul Semel1aba4152023-09-28 16:46:1363 // 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
danakje125e8d62021-01-21 22:06:3176 ScopedRunLoopTimeout(const Location& timeout_enabled_from_here,
77 TimeDelta timeout);
Wez9d5dd282020-02-10 17:21:2278 ~ScopedRunLoopTimeout();
79
Wez362b6ca2020-02-19 17:17:0680 // Invokes |on_timeout_log| if |timeout| expires, and appends it to the
Dana Fried0ff12a12023-06-09 16:51:0081 // logged error message. If `timeout` is not specified the current timeout is
82 // used and only the log message is overridden.
danakje125e8d62021-01-21 22:06:3183 ScopedRunLoopTimeout(const Location& timeout_enabled_from_here,
Arthur Sonzognie5fff99c2024-02-21 15:58:2484 std::optional<TimeDelta> timeout,
Wez362b6ca2020-02-19 17:17:0685 RepeatingCallback<std::string()> on_timeout_log);
86
Wez9d5dd282020-02-10 17:21:2287 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
Paul Semel1aba4152023-09-28 16:46:1393 // 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.
Wez9d5dd282020-02-10 17:21:22103 static void SetAddGTestFailureOnTimeout();
104
Paul Semel1aba4152023-09-28 16:46:13105 // Add provided callback as timeout handler.
106 static void SetTimeoutCallbackForTesting(std::unique_ptr<TimeoutCallback> cb);
107
108 private:
109 TimeoutCallback GetTimeoutCallback();
110
Wez9d5dd282020-02-10 17:21:22111 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
Ho Cheung478b4112023-05-24 22:01:16120 raw_ptr<const RunLoop::RunLoopTimeout> const nested_timeout_;
Wez9d5dd282020-02-10 17:21:22121 RunLoop::RunLoopTimeout run_timeout_;
122};
123
124class ScopedDisableRunLoopTimeout {
125 public:
126 ScopedDisableRunLoopTimeout();
127 ~ScopedDisableRunLoopTimeout();
128
129 ScopedDisableRunLoopTimeout(const ScopedDisableRunLoopTimeout&) = delete;
130 ScopedDisableRunLoopTimeout& operator=(const ScopedDisableRunLoopTimeout&) =
131 delete;
132
133 private:
Keishi Hattori0e45c022021-11-27 09:25:52134 const raw_ptr<const RunLoop::RunLoopTimeout> nested_timeout_;
Wez9d5dd282020-02-10 17:21:22135};
136
Dana Fried0ff12a12023-06-09 16:51:00137} // namespace base::test
Wez9d5dd282020-02-10 17:21:22138
139#endif // BASE_TEST_SCOPED_RUN_LOOP_TIMEOUT_H_