1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/api/cast_channel/keep_alive_delegate.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/test/simple_test_clock.h"
10 #include "base/timer/mock_timer.h"
11 #include "extensions/browser/api/cast_channel/cast_test_util.h"
12 #include "net/base/net_errors.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
18 namespace extensions
{
20 namespace cast_channel
{
23 const int64 kTestPingTimeoutMillis
= 1000;
24 const int64 kTestLivenessTimeoutMillis
= 10000;
26 // Extends MockTimer with a mockable method ResetTriggered() which permits
27 // test code to set GMock expectations for Timer::Reset().
28 class MockTimerWithMonitoredReset
: public base::MockTimer
{
30 MockTimerWithMonitoredReset(bool retain_user_task
, bool is_repeating
)
31 : base::MockTimer(retain_user_task
, is_repeating
) {}
32 ~MockTimerWithMonitoredReset() override
{}
34 // Instrumentation point for determining how many times Reset() was called.
35 MOCK_METHOD0(ResetTriggered
, void(void));
36 MOCK_METHOD0(Stop
, void(void));
38 // Passes through the Reset call to the base MockTimer and visits the mock
39 // ResetTriggered method.
40 void Reset() override
{
41 base::MockTimer::Reset();
46 class KeepAliveDelegateTest
: public testing::Test
{
48 KeepAliveDelegateTest() {}
49 ~KeepAliveDelegateTest() override
{}
52 void SetUp() override
{
53 inner_delegate_
= new MockCastTransportDelegate
;
54 logger_
= new Logger(scoped_ptr
<base::Clock
>(new base::SimpleTestClock
),
56 keep_alive_
.reset(new KeepAliveDelegate(
57 &socket_
, logger_
, make_scoped_ptr(inner_delegate_
),
58 base::TimeDelta::FromMilliseconds(kTestPingTimeoutMillis
),
59 base::TimeDelta::FromMilliseconds(kTestLivenessTimeoutMillis
)));
60 liveness_timer_
= new MockTimerWithMonitoredReset(true, false);
61 ping_timer_
= new MockTimerWithMonitoredReset(true, false);
62 EXPECT_CALL(*liveness_timer_
, Stop()).Times(0);
63 EXPECT_CALL(*ping_timer_
, Stop()).Times(0);
64 keep_alive_
->SetTimersForTest(make_scoped_ptr(ping_timer_
),
65 make_scoped_ptr(liveness_timer_
));
68 // Runs all pending tasks in the message loop.
69 void RunPendingTasks() {
70 base::RunLoop run_loop
;
71 run_loop
.RunUntilIdle();
74 base::MessageLoop message_loop_
;
75 MockCastSocket socket_
;
76 scoped_ptr
<KeepAliveDelegate
> keep_alive_
;
77 scoped_refptr
<Logger
> logger_
;
78 MockCastTransportDelegate
* inner_delegate_
;
79 MockTimerWithMonitoredReset
* liveness_timer_
;
80 MockTimerWithMonitoredReset
* ping_timer_
;
83 DISALLOW_COPY_AND_ASSIGN(KeepAliveDelegateTest
);
86 TEST_F(KeepAliveDelegateTest
, TestErrorHandledBeforeStarting
) {
87 keep_alive_
->OnError(CHANNEL_ERROR_CONNECT_ERROR
);
90 TEST_F(KeepAliveDelegateTest
, TestPing
) {
91 EXPECT_CALL(*socket_
.mock_transport(),
92 SendMessage(EqualsProto(KeepAliveDelegate::CreateKeepAliveMessage(
93 KeepAliveDelegate::kHeartbeatPingType
)),
95 .WillOnce(PostCompletionCallbackTask
<1>(net::OK
));
96 EXPECT_CALL(*inner_delegate_
, Start());
97 EXPECT_CALL(*ping_timer_
, ResetTriggered()).Times(2);
98 EXPECT_CALL(*liveness_timer_
, ResetTriggered()).Times(2);
99 EXPECT_CALL(*ping_timer_
, Stop());
101 keep_alive_
->Start();
103 keep_alive_
->OnMessage(KeepAliveDelegate::CreateKeepAliveMessage(
104 KeepAliveDelegate::kHeartbeatPongType
));
108 TEST_F(KeepAliveDelegateTest
, TestPingFailed
) {
109 EXPECT_CALL(*socket_
.mock_transport(),
110 SendMessage(EqualsProto(KeepAliveDelegate::CreateKeepAliveMessage(
111 KeepAliveDelegate::kHeartbeatPingType
)),
113 .WillOnce(PostCompletionCallbackTask
<1>(net::ERR_CONNECTION_RESET
));
114 EXPECT_CALL(*inner_delegate_
, Start());
115 EXPECT_CALL(*inner_delegate_
, OnError(CHANNEL_ERROR_SOCKET_ERROR
));
116 EXPECT_CALL(*ping_timer_
, ResetTriggered()).Times(1);
117 EXPECT_CALL(*liveness_timer_
, ResetTriggered()).Times(1);
118 EXPECT_CALL(*liveness_timer_
, Stop());
119 EXPECT_CALL(*ping_timer_
, Stop()).Times(2);
121 keep_alive_
->Start();
124 EXPECT_EQ(proto::PING_WRITE_ERROR
,
125 logger_
->GetLastErrors(socket_
.id()).event_type
);
126 EXPECT_EQ(net::ERR_CONNECTION_RESET
,
127 logger_
->GetLastErrors(socket_
.id()).net_return_value
);
130 TEST_F(KeepAliveDelegateTest
, TestPingAndLivenessTimeout
) {
131 EXPECT_CALL(*socket_
.mock_transport(),
132 SendMessage(EqualsProto(KeepAliveDelegate::CreateKeepAliveMessage(
133 KeepAliveDelegate::kHeartbeatPingType
)),
135 .WillOnce(PostCompletionCallbackTask
<1>(net::OK
));
136 EXPECT_CALL(*inner_delegate_
, OnError(CHANNEL_ERROR_PING_TIMEOUT
));
137 EXPECT_CALL(*inner_delegate_
, Start());
138 EXPECT_CALL(*ping_timer_
, ResetTriggered()).Times(1);
139 EXPECT_CALL(*liveness_timer_
, ResetTriggered()).Times(1);
140 EXPECT_CALL(*liveness_timer_
, Stop()).Times(2);
141 EXPECT_CALL(*ping_timer_
, Stop()).Times(2);
143 keep_alive_
->Start();
145 liveness_timer_
->Fire();
149 TEST_F(KeepAliveDelegateTest
, TestResetTimersAndPassthroughAllOtherTraffic
) {
150 CastMessage other_message
=
151 KeepAliveDelegate::CreateKeepAliveMessage("NEITHER_PING_NOR_PONG");
153 EXPECT_CALL(*inner_delegate_
, OnMessage(EqualsProto(other_message
)));
154 EXPECT_CALL(*inner_delegate_
, Start());
155 EXPECT_CALL(*ping_timer_
, ResetTriggered()).Times(2);
156 EXPECT_CALL(*liveness_timer_
, ResetTriggered()).Times(2);
158 keep_alive_
->Start();
159 keep_alive_
->OnMessage(other_message
);
164 } // namespace cast_channel
166 } // namespace extensions