1 /*
2 * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #include "net/dcsctp/timer/task_queue_timeout.h"
11
12 #include <memory>
13
14 #include "api/task_queue/task_queue_base.h"
15 #include "api/task_queue/test/mock_task_queue_base.h"
16 #include "rtc_base/gunit.h"
17 #include "test/gmock.h"
18 #include "test/time_controller/simulated_time_controller.h"
19
20 namespace dcsctp {
21 namespace {
22 using ::testing::_;
23 using ::testing::MockFunction;
24 using ::testing::NiceMock;
25
26 class TaskQueueTimeoutTest : public testing::Test {
27 protected:
TaskQueueTimeoutTest()28 TaskQueueTimeoutTest()
29 : time_controller_(webrtc::Timestamp::Millis(1234)),
30 task_queue_(time_controller_.GetMainThread()),
31 factory_(
32 *task_queue_,
33 [this]() {
34 return TimeMs(time_controller_.GetClock()->CurrentTime().ms());
35 },
36 on_expired_.AsStdFunction()) {}
37
AdvanceTime(DurationMs duration)38 void AdvanceTime(DurationMs duration) {
39 time_controller_.AdvanceTime(webrtc::TimeDelta::Millis(*duration));
40 }
41
42 MockFunction<void(TimeoutID)> on_expired_;
43 webrtc::GlobalSimulatedTimeController time_controller_;
44
45 rtc::Thread* task_queue_;
46 TaskQueueTimeoutFactory factory_;
47 };
48
TEST_F(TaskQueueTimeoutTest,StartPostsDelayedTask)49 TEST_F(TaskQueueTimeoutTest, StartPostsDelayedTask) {
50 std::unique_ptr<Timeout> timeout = factory_.CreateTimeout();
51 timeout->Start(DurationMs(1000), TimeoutID(1));
52
53 EXPECT_CALL(on_expired_, Call).Times(0);
54 AdvanceTime(DurationMs(999));
55
56 EXPECT_CALL(on_expired_, Call(TimeoutID(1)));
57 AdvanceTime(DurationMs(1));
58 }
59
TEST_F(TaskQueueTimeoutTest,StopBeforeExpiringDoesntTrigger)60 TEST_F(TaskQueueTimeoutTest, StopBeforeExpiringDoesntTrigger) {
61 std::unique_ptr<Timeout> timeout = factory_.CreateTimeout();
62 timeout->Start(DurationMs(1000), TimeoutID(1));
63
64 EXPECT_CALL(on_expired_, Call).Times(0);
65 AdvanceTime(DurationMs(999));
66
67 timeout->Stop();
68
69 AdvanceTime(DurationMs(1));
70 AdvanceTime(DurationMs(1000));
71 }
72
TEST_F(TaskQueueTimeoutTest,RestartPrologingTimeoutDuration)73 TEST_F(TaskQueueTimeoutTest, RestartPrologingTimeoutDuration) {
74 std::unique_ptr<Timeout> timeout = factory_.CreateTimeout();
75 timeout->Start(DurationMs(1000), TimeoutID(1));
76
77 EXPECT_CALL(on_expired_, Call).Times(0);
78 AdvanceTime(DurationMs(500));
79
80 timeout->Restart(DurationMs(1000), TimeoutID(2));
81
82 AdvanceTime(DurationMs(999));
83
84 EXPECT_CALL(on_expired_, Call(TimeoutID(2)));
85 AdvanceTime(DurationMs(1));
86 }
87
TEST_F(TaskQueueTimeoutTest,RestartWithShorterDurationExpiresWhenExpected)88 TEST_F(TaskQueueTimeoutTest, RestartWithShorterDurationExpiresWhenExpected) {
89 std::unique_ptr<Timeout> timeout = factory_.CreateTimeout();
90 timeout->Start(DurationMs(1000), TimeoutID(1));
91
92 EXPECT_CALL(on_expired_, Call).Times(0);
93 AdvanceTime(DurationMs(500));
94
95 timeout->Restart(DurationMs(200), TimeoutID(2));
96
97 AdvanceTime(DurationMs(199));
98
99 EXPECT_CALL(on_expired_, Call(TimeoutID(2)));
100 AdvanceTime(DurationMs(1));
101
102 EXPECT_CALL(on_expired_, Call).Times(0);
103 AdvanceTime(DurationMs(1000));
104 }
105
TEST_F(TaskQueueTimeoutTest,KilledBeforeExpired)106 TEST_F(TaskQueueTimeoutTest, KilledBeforeExpired) {
107 std::unique_ptr<Timeout> timeout = factory_.CreateTimeout();
108 timeout->Start(DurationMs(1000), TimeoutID(1));
109
110 EXPECT_CALL(on_expired_, Call).Times(0);
111 AdvanceTime(DurationMs(500));
112
113 timeout = nullptr;
114
115 EXPECT_CALL(on_expired_, Call).Times(0);
116 AdvanceTime(DurationMs(1000));
117 }
118
TEST(TaskQueueTimeoutWithMockTaskQueueTest,CanSetTimeoutPrecisionToLow)119 TEST(TaskQueueTimeoutWithMockTaskQueueTest, CanSetTimeoutPrecisionToLow) {
120 NiceMock<webrtc::MockTaskQueueBase> mock_task_queue;
121 EXPECT_CALL(mock_task_queue, PostDelayedTask(_, _));
122 TaskQueueTimeoutFactory factory(
123 mock_task_queue, []() { return TimeMs(1337); },
124 [](TimeoutID timeout_id) {});
125 std::unique_ptr<Timeout> timeout =
126 factory.CreateTimeout(webrtc::TaskQueueBase::DelayPrecision::kLow);
127 timeout->Start(DurationMs(1), TimeoutID(1));
128 }
129
TEST(TaskQueueTimeoutWithMockTaskQueueTest,CanSetTimeoutPrecisionToHigh)130 TEST(TaskQueueTimeoutWithMockTaskQueueTest, CanSetTimeoutPrecisionToHigh) {
131 NiceMock<webrtc::MockTaskQueueBase> mock_task_queue;
132 EXPECT_CALL(mock_task_queue, PostDelayedHighPrecisionTask(_, _));
133 TaskQueueTimeoutFactory factory(
134 mock_task_queue, []() { return TimeMs(1337); },
135 [](TimeoutID timeout_id) {});
136 std::unique_ptr<Timeout> timeout =
137 factory.CreateTimeout(webrtc::TaskQueueBase::DelayPrecision::kHigh);
138 timeout->Start(DurationMs(1), TimeoutID(1));
139 }
140
TEST(TaskQueueTimeoutWithMockTaskQueueTest,TimeoutPrecisionIsLowByDefault)141 TEST(TaskQueueTimeoutWithMockTaskQueueTest, TimeoutPrecisionIsLowByDefault) {
142 NiceMock<webrtc::MockTaskQueueBase> mock_task_queue;
143 EXPECT_CALL(mock_task_queue, PostDelayedTask(_, _));
144 TaskQueueTimeoutFactory factory(
145 mock_task_queue, []() { return TimeMs(1337); },
146 [](TimeoutID timeout_id) {});
147 std::unique_ptr<Timeout> timeout = factory.CreateTimeout();
148 timeout->Start(DurationMs(1), TimeoutID(1));
149 }
150
151 } // namespace
152 } // namespace dcsctp
153