Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / net / base / network_change_notifier_win_unittest.cc
blob04b19e6e6d2b5debdd7169029d5f754d054fdbcb
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;
17 namespace net {
19 namespace {
21 // Subclass of NetworkChangeNotifierWin that overrides functions so that no
22 // Windows API networking functions are ever called.
23 class TestNetworkChangeNotifierWin : public NetworkChangeNotifierWin {
24 public:
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()
35 const override {
36 return NetworkChangeNotifier::CONNECTION_UNKNOWN;
39 // From NetworkChangeNotifierWin.
40 MOCK_METHOD0(WatchForAddressChangeInternal, bool());
42 private:
43 DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifierWin);
46 class TestIPAddressObserver : public NetworkChangeNotifier::IPAddressObserver {
47 public:
48 TestIPAddressObserver() {
49 NetworkChangeNotifier::AddIPAddressObserver(this);
52 ~TestIPAddressObserver() {
53 NetworkChangeNotifier::RemoveIPAddressObserver(this);
56 MOCK_METHOD0(OnIPAddressChanged, void());
58 private:
59 DISALLOW_COPY_AND_ASSIGN(TestIPAddressObserver);
62 bool ExitMessageLoopAndReturnFalse() {
63 base::MessageLoop::current()->Quit();
64 return false;
67 } // namespace
69 class NetworkChangeNotifierWinTest : public testing::Test {
70 public:
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())
81 .Times(1)
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
95 // failure.
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.
104 .Times(AtLeast(1))
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())
125 .Times(1)
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.
147 .Times(AtLeast(1))
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)
168 .WillOnce(
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.
194 .Times(AtLeast(1))
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();
208 private:
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();
232 RetryAndSucceed();
235 TEST_F(NetworkChangeNotifierWinTest, NetChangeWinFailStartTwice) {
236 StartWatchingAndFail();
237 RetryAndFail();
238 RetryAndSucceed();
241 TEST_F(NetworkChangeNotifierWinTest, NetChangeWinSignal) {
242 StartWatchingAndSucceed();
243 SignalAndSucceed();
246 TEST_F(NetworkChangeNotifierWinTest, NetChangeWinFailSignalOnce) {
247 StartWatchingAndSucceed();
248 SignalAndFail();
249 RetryAndSucceed();
252 TEST_F(NetworkChangeNotifierWinTest, NetChangeWinFailSignalTwice) {
253 StartWatchingAndSucceed();
254 SignalAndFail();
255 RetryAndFail();
256 RetryAndSucceed();
259 } // namespace net