1 // Copyright (c) 2012 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 "base/message_loop/message_loop.h"
6 #include "net/base/network_change_notifier.h"
7 #include "net/base/network_change_notifier_factory.h"
8 #include "net/base/network_change_notifier_win.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using ::testing::AtLeast
;
13 using ::testing::Invoke
;
14 using ::testing::Return
;
15 using ::testing::StrictMock
;
21 // Subclass of NetworkChangeNotifierWin that overrides functions so that no
22 // Windows API networking functions are ever called.
23 class TestNetworkChangeNotifierWin
: public NetworkChangeNotifierWin
{
25 TestNetworkChangeNotifierWin() {}
27 ~TestNetworkChangeNotifierWin() override
{
28 // This is needed so we don't try to stop watching for IP address changes,
29 // as we never actually started.
30 set_is_watching(false);
33 // From NetworkChangeNotifierWin.
34 NetworkChangeNotifier::ConnectionType
RecomputeCurrentConnectionType()
36 return NetworkChangeNotifier::CONNECTION_UNKNOWN
;
39 // From NetworkChangeNotifierWin.
40 MOCK_METHOD0(WatchForAddressChangeInternal
, bool());
43 DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifierWin
);
46 class TestIPAddressObserver
: public NetworkChangeNotifier::IPAddressObserver
{
48 TestIPAddressObserver() {
49 NetworkChangeNotifier::AddIPAddressObserver(this);
52 ~TestIPAddressObserver() {
53 NetworkChangeNotifier::RemoveIPAddressObserver(this);
56 MOCK_METHOD0(OnIPAddressChanged
, void());
59 DISALLOW_COPY_AND_ASSIGN(TestIPAddressObserver
);
62 bool ExitMessageLoopAndReturnFalse() {
63 base::MessageLoop::current()->Quit();
69 class NetworkChangeNotifierWinTest
: public testing::Test
{
71 // Calls WatchForAddressChange, and simulates a WatchForAddressChangeInternal
72 // success. Expects that |network_change_notifier_| has just been created, so
73 // it's not watching anything yet, and there have been no previous
74 // WatchForAddressChangeInternal failures.
75 void StartWatchingAndSucceed() {
76 EXPECT_FALSE(network_change_notifier_
.is_watching());
77 EXPECT_EQ(0, network_change_notifier_
.sequential_failures());
79 EXPECT_CALL(test_ip_address_observer_
, OnIPAddressChanged()).Times(0);
80 EXPECT_CALL(network_change_notifier_
, WatchForAddressChangeInternal())
82 .WillOnce(Return(true));
84 network_change_notifier_
.WatchForAddressChange();
86 EXPECT_TRUE(network_change_notifier_
.is_watching());
87 EXPECT_EQ(0, network_change_notifier_
.sequential_failures());
89 // If a task to notify observers of the IP address change event was
90 // incorrectly posted, make sure it gets run to trigger a failure.
91 base::MessageLoop::current()->RunUntilIdle();
94 // Calls WatchForAddressChange, and simulates a WatchForAddressChangeInternal
96 void StartWatchingAndFail() {
97 EXPECT_FALSE(network_change_notifier_
.is_watching());
98 EXPECT_EQ(0, network_change_notifier_
.sequential_failures());
100 EXPECT_CALL(test_ip_address_observer_
, OnIPAddressChanged()).Times(0);
101 EXPECT_CALL(network_change_notifier_
, WatchForAddressChangeInternal())
102 // Due to an expected race, it's theoretically possible for more than
103 // one call to occur, though unlikely.
105 .WillRepeatedly(Return(false));
107 network_change_notifier_
.WatchForAddressChange();
109 EXPECT_FALSE(network_change_notifier_
.is_watching());
110 EXPECT_LT(0, network_change_notifier_
.sequential_failures());
112 // If a task to notify observers of the IP address change event was
113 // incorrectly posted, make sure it gets run.
114 base::MessageLoop::current()->RunUntilIdle();
117 // Simulates a network change event, resulting in a call to OnObjectSignaled.
118 // The resulting call to WatchForAddressChangeInternal then succeeds.
119 void SignalAndSucceed() {
120 EXPECT_TRUE(network_change_notifier_
.is_watching());
121 EXPECT_EQ(0, network_change_notifier_
.sequential_failures());
123 EXPECT_CALL(test_ip_address_observer_
, OnIPAddressChanged()).Times(1);
124 EXPECT_CALL(network_change_notifier_
, WatchForAddressChangeInternal())
126 .WillOnce(Return(true));
128 network_change_notifier_
.OnObjectSignaled(INVALID_HANDLE_VALUE
);
130 EXPECT_TRUE(network_change_notifier_
.is_watching());
131 EXPECT_EQ(0, network_change_notifier_
.sequential_failures());
133 // Run the task to notify observers of the IP address change event.
134 base::MessageLoop::current()->RunUntilIdle();
137 // Simulates a network change event, resulting in a call to OnObjectSignaled.
138 // The resulting call to WatchForAddressChangeInternal then fails.
139 void SignalAndFail() {
140 EXPECT_TRUE(network_change_notifier_
.is_watching());
141 EXPECT_EQ(0, network_change_notifier_
.sequential_failures());
143 EXPECT_CALL(test_ip_address_observer_
, OnIPAddressChanged()).Times(1);
144 EXPECT_CALL(network_change_notifier_
, WatchForAddressChangeInternal())
145 // Due to an expected race, it's theoretically possible for more than
146 // one call to occur, though unlikely.
148 .WillRepeatedly(Return(false));
150 network_change_notifier_
.OnObjectSignaled(INVALID_HANDLE_VALUE
);
152 EXPECT_FALSE(network_change_notifier_
.is_watching());
153 EXPECT_LT(0, network_change_notifier_
.sequential_failures());
155 // Run the task to notify observers of the IP address change event.
156 base::MessageLoop::current()->RunUntilIdle();
159 // Runs the message loop until WatchForAddressChange is called again, as a
160 // result of the already posted task after a WatchForAddressChangeInternal
161 // failure. Simulates a success on the resulting call to
162 // WatchForAddressChangeInternal.
163 void RetryAndSucceed() {
164 EXPECT_FALSE(network_change_notifier_
.is_watching());
165 EXPECT_LT(0, network_change_notifier_
.sequential_failures());
167 EXPECT_CALL(test_ip_address_observer_
, OnIPAddressChanged()).Times(1)
169 Invoke(base::MessageLoop::current(), &base::MessageLoop::Quit
));
170 EXPECT_CALL(network_change_notifier_
, WatchForAddressChangeInternal())
171 .Times(1).WillOnce(Return(true));
173 base::MessageLoop::current()->Run();
175 EXPECT_TRUE(network_change_notifier_
.is_watching());
176 EXPECT_EQ(0, network_change_notifier_
.sequential_failures());
179 // Runs the message loop until WatchForAddressChange is called again, as a
180 // result of the already posted task after a WatchForAddressChangeInternal
181 // failure. Simulates a failure on the resulting call to
182 // WatchForAddressChangeInternal.
183 void RetryAndFail() {
184 EXPECT_FALSE(network_change_notifier_
.is_watching());
185 EXPECT_LT(0, network_change_notifier_
.sequential_failures());
187 int initial_sequential_failures
=
188 network_change_notifier_
.sequential_failures();
190 EXPECT_CALL(test_ip_address_observer_
, OnIPAddressChanged()).Times(0);
191 EXPECT_CALL(network_change_notifier_
, WatchForAddressChangeInternal())
192 // Due to an expected race, it's theoretically possible for more than
193 // one call to occur, though unlikely.
195 .WillRepeatedly(Invoke(ExitMessageLoopAndReturnFalse
));
197 base::MessageLoop::current()->Run();
199 EXPECT_FALSE(network_change_notifier_
.is_watching());
200 EXPECT_LT(initial_sequential_failures
,
201 network_change_notifier_
.sequential_failures());
203 // If a task to notify observers of the IP address change event was
204 // incorrectly posted, make sure it gets run.
205 base::MessageLoop::current()->RunUntilIdle();
209 // Note that the order of declaration here is important.
211 // Allows creating a new NetworkChangeNotifier. Must be created before
212 // |network_change_notifier_| and destroyed after it to avoid DCHECK failures.
213 NetworkChangeNotifier::DisableForTest disable_for_test_
;
215 StrictMock
<TestNetworkChangeNotifierWin
> network_change_notifier_
;
217 // Must be created after |network_change_notifier_|, so it can add itself as
218 // an IPAddressObserver.
219 StrictMock
<TestIPAddressObserver
> test_ip_address_observer_
;
222 TEST_F(NetworkChangeNotifierWinTest
, NetChangeWinBasic
) {
223 StartWatchingAndSucceed();
226 TEST_F(NetworkChangeNotifierWinTest
, NetChangeWinFailStart
) {
227 StartWatchingAndFail();
230 TEST_F(NetworkChangeNotifierWinTest
, NetChangeWinFailStartOnce
) {
231 StartWatchingAndFail();
235 TEST_F(NetworkChangeNotifierWinTest
, NetChangeWinFailStartTwice
) {
236 StartWatchingAndFail();
241 TEST_F(NetworkChangeNotifierWinTest
, NetChangeWinSignal
) {
242 StartWatchingAndSucceed();
246 TEST_F(NetworkChangeNotifierWinTest
, NetChangeWinFailSignalOnce
) {
247 StartWatchingAndSucceed();
252 TEST_F(NetworkChangeNotifierWinTest
, NetChangeWinFailSignalTwice
) {
253 StartWatchingAndSucceed();