blob: cea0a9f7680009da1c157d6c551052506b0a2a11 [file] [log] [blame]
Paul Stewart3f43f432012-07-16 12:12:45 -07001// Copyright (c) 2012 The Chromium OS 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.
4
5#include "shill/link_monitor.h"
6
Paul Stewart6c72c972012-07-27 11:29:20 -07007#include <base/bind.h>
Paul Stewart3f43f432012-07-16 12:12:45 -07008#include <gtest/gtest.h>
9
Paul Stewart6c72c972012-07-27 11:29:20 -070010#include "shill/arp_packet.h"
11#include "shill/ip_address.h"
12#include "shill/mock_arp_client.h"
Paul Stewart3f43f432012-07-16 12:12:45 -070013#include "shill/mock_control.h"
Paul Stewart6c72c972012-07-27 11:29:20 -070014#include "shill/mock_connection.h"
Paul Stewart3f43f432012-07-16 12:12:45 -070015#include "shill/mock_device_info.h"
16#include "shill/mock_event_dispatcher.h"
Paul Stewart6c72c972012-07-27 11:29:20 -070017#include "shill/mock_log.h"
Paul Stewartff845fc2012-08-07 07:28:44 -070018#include "shill/mock_metrics.h"
Paul Stewart3f43f432012-07-16 12:12:45 -070019#include "shill/mock_sockets.h"
Paul Stewart6c72c972012-07-27 11:29:20 -070020#include "shill/mock_time.h"
21#include "shill/scope_logger.h"
Paul Stewart3f43f432012-07-16 12:12:45 -070022
Paul Stewart6c72c972012-07-27 11:29:20 -070023using base::Bind;
24using base::Unretained;
25using testing::_;
26using testing::AnyNumber;
27using testing::HasSubstr;
28using testing::Invoke;
29using testing::Mock;
30using testing::NiceMock;
31using testing::Return;
32using testing::ReturnRef;
33using testing::SetArgumentPointee;
Paul Stewart3f43f432012-07-16 12:12:45 -070034using testing::StrictMock;
35using testing::Test;
36
37namespace shill {
38
Paul Stewart6c72c972012-07-27 11:29:20 -070039namespace {
40const int kInterfaceIndex = 123;
41const char kLocalIPAddress[] = "10.0.1.1";
42const uint8 kLocalMACAddress[] = { 0, 1, 2, 3, 4, 5 };
43const char kRemoteIPAddress[] = "10.0.1.2";
44const uint8 kRemoteMACAddress[] = { 6, 7, 8, 9, 10, 11 };
45} // namespace {}
46
47
48class LinkMonitorForTest : public LinkMonitor {
49 public:
50 LinkMonitorForTest(const ConnectionRefPtr &connection,
51 EventDispatcher *dispatcher,
Paul Stewartff845fc2012-08-07 07:28:44 -070052 Metrics *metrics,
Paul Stewart6c72c972012-07-27 11:29:20 -070053 DeviceInfo *device_info)
Paul Stewartff845fc2012-08-07 07:28:44 -070054 : LinkMonitor(connection, dispatcher, metrics, device_info,
Paul Stewart6c72c972012-07-27 11:29:20 -070055 Bind(&LinkMonitorForTest::FailureCallback,
56 Unretained(this))) {}
57
58 virtual ~LinkMonitorForTest() {}
59
60 MOCK_METHOD0(CreateClient, bool());
61 MOCK_METHOD0(FailureCallback, void());
62};
63
64MATCHER_P4(IsArpRequest, local_ip, remote_ip, local_mac, remote_mac, "") {
65 return
66 local_ip.Equals(arg.local_ip_address()) &&
67 remote_ip.Equals(arg.remote_ip_address()) &&
68 local_mac.Equals(arg.local_mac_address()) &&
69 remote_mac.Equals(arg.remote_mac_address());
70}
71
Paul Stewart3f43f432012-07-16 12:12:45 -070072class LinkMonitorTest : public Test {
73 public:
74 LinkMonitorTest()
Paul Stewart6c72c972012-07-27 11:29:20 -070075 : device_info_(
76 &control_,
77 reinterpret_cast<EventDispatcher*>(NULL),
78 reinterpret_cast<Metrics*>(NULL),
79 reinterpret_cast<Manager*>(NULL)),
Paul Stewart3f43f432012-07-16 12:12:45 -070080 connection_(new StrictMock<MockConnection>(&device_info_)),
Paul Stewartff845fc2012-08-07 07:28:44 -070081 monitor_(connection_, &dispatcher_, &metrics_, &device_info_),
Paul Stewart6c72c972012-07-27 11:29:20 -070082 client_(NULL),
83 next_client_(new StrictMock<MockArpClient>()),
84 gateway_ip_(IPAddress::kFamilyIPv4),
85 local_ip_(IPAddress::kFamilyIPv4),
86 gateway_mac_(kRemoteMACAddress, arraysize(kRemoteMACAddress)),
87 local_mac_(kLocalMACAddress, arraysize(kLocalMACAddress)),
88 zero_mac_(arraysize(kLocalMACAddress)),
89 link_scope_logging_was_enabled_(false) {}
Paul Stewart3f43f432012-07-16 12:12:45 -070090 virtual ~LinkMonitorTest() {}
91
Paul Stewart6c72c972012-07-27 11:29:20 -070092 virtual void SetUp() {
93 link_scope_logging_was_enabled_ = SLOG_IS_ON(Link, 0);
94 if (!link_scope_logging_was_enabled_) {
95 ScopeLogger::GetInstance()->EnableScopesByName("link");
96 ScopeLogger::GetInstance()->set_verbose_level(4);
97 }
98 monitor_.time_ = &time_;
99 EXPECT_CALL(time_, GetTimeMonotonic(_))
100 .WillRepeatedly(DoAll(SetArgumentPointee<0>(time_val_), Return(0)));
101 EXPECT_TRUE(local_ip_.SetAddressFromString(kLocalIPAddress));
102 EXPECT_CALL(*connection_, local()).WillRepeatedly(ReturnRef(local_ip_));
103 EXPECT_TRUE(gateway_ip_.SetAddressFromString(kRemoteIPAddress));
104 EXPECT_CALL(*connection_, gateway()).WillRepeatedly(ReturnRef(gateway_ip_));
105 }
106
107 virtual void TearDown() {
108 if (!link_scope_logging_was_enabled_) {
109 ScopeLogger::GetInstance()->EnableScopesByName("-link");
110 ScopeLogger::GetInstance()->set_verbose_level(0);
111 }
112 }
113
114 void AdvanceTime(unsigned int time_ms) {
115 struct timeval adv_time = { time_ms/1000, (time_ms % 1000) * 1000 };
116 timeradd(&time_val_, &adv_time, &time_val_);
117 EXPECT_CALL(time_, GetTimeMonotonic(_))
118 .WillRepeatedly(DoAll(SetArgumentPointee<0>(time_val_), Return(0)));
119 }
120
121 bool CreateMockClient() {
122 EXPECT_FALSE(monitor_.arp_client_.get());
123 if (client_) {
124 Mock::VerifyAndClearExpectations(client_);
125 }
126 client_ = next_client_;
127 next_client_ = new StrictMock<MockArpClient>();
128 monitor_.arp_client_.reset(client_);
129 return true;
130 }
Paul Stewart3f43f432012-07-16 12:12:45 -0700131
132 protected:
Paul Stewart6c72c972012-07-27 11:29:20 -0700133 void ExpectReset() {
134 EXPECT_FALSE(monitor_.GetResponseTimeMilliseconds());
135 EXPECT_FALSE(GetArpClient());
136 EXPECT_TRUE(GetSendRequestCallback().IsCancelled());
137 EXPECT_EQ(0, GetBroadcastFailureCount());
138 EXPECT_EQ(0, GetUnicastFailureCount());
139 EXPECT_FALSE(IsUnicast());
140 }
141 const ArpClient *GetArpClient() { return monitor_.arp_client_.get(); }
142 void TriggerRequestTimer() {
143 GetSendRequestCallback().callback().Run();
144 }
145 const base::CancelableClosure &GetSendRequestCallback() {
146 return monitor_.send_request_callback_;
147 }
148 unsigned int GetBroadcastFailureCount() {
149 return monitor_.broadcast_failure_count_;
150 }
151 unsigned int GetUnicastFailureCount() {
152 return monitor_.unicast_failure_count_;
153 }
154 bool IsUnicast() { return monitor_.is_unicast_; }
155 unsigned int GetTestPeriodMilliseconds() {
156 return LinkMonitor::kTestPeriodMilliseconds;
157 }
158 unsigned int GetFailureThreshold() {
159 return LinkMonitor::kFailureThreshold;
160 }
161 unsigned int GetMaxResponseSampleFilterDepth() {
162 return LinkMonitor::kMaxResponseSampleFilterDepth;
163 }
164 void ExpectTransmit(bool is_unicast) {
165 const ByteString &destination_mac = is_unicast ? gateway_mac_ : zero_mac_;
166 if (monitor_.arp_client_.get()) {
167 EXPECT_EQ(client_, monitor_.arp_client_.get());
168 EXPECT_CALL(*client_, TransmitRequest(
169 IsArpRequest(local_ip_, gateway_ip_, local_mac_, destination_mac)))
170 .WillOnce(Return(true));
171 } else {
172 EXPECT_CALL(monitor_, CreateClient())
173 .WillOnce(Invoke(this, &LinkMonitorTest::CreateMockClient));
174 EXPECT_CALL(*next_client_, TransmitRequest(
175 IsArpRequest(local_ip_, gateway_ip_, local_mac_, destination_mac)))
176 .WillOnce(Return(true));
177 }
178 EXPECT_CALL(dispatcher_, PostDelayedTask(_, GetTestPeriodMilliseconds()));
179 }
180 void SendNextRequest() {
181 EXPECT_CALL(monitor_, CreateClient())
182 .WillOnce(Invoke(this, &LinkMonitorTest::CreateMockClient));
183 EXPECT_CALL(*next_client_, TransmitRequest(_)).WillOnce(Return(true));
184 EXPECT_CALL(dispatcher_, PostDelayedTask(_, GetTestPeriodMilliseconds()));
185 TriggerRequestTimer();
186 }
187 void ExpectNoTransmit() {
188 MockArpClient *client =
189 monitor_.arp_client_.get() ? client_ : next_client_;
190 EXPECT_CALL(*client, TransmitRequest(_)).Times(0);
191 }
192 void StartMonitor() {
193 EXPECT_CALL(device_info_, GetMACAddress(0, _))
194 .WillOnce(DoAll(SetArgumentPointee<1>(local_mac_), Return(true)));
195 ExpectTransmit(false);
196 EXPECT_TRUE(monitor_.Start());
197 EXPECT_TRUE(GetArpClient());
198 EXPECT_FALSE(IsUnicast());
199 EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
200 }
201 bool SimulateReceiveReply(ArpPacket *packet, ByteString *sender) {
202 packet->set_local_ip_address(rx_packet_.local_ip_address());
203 packet->set_remote_ip_address(rx_packet_.remote_ip_address());
204 packet->set_local_mac_address(rx_packet_.local_mac_address());
205 packet->set_remote_mac_address(rx_packet_.remote_mac_address());
206 return true;
207 }
208 void ReceiveResponse(const IPAddress &local_ip,
209 const ByteString &local_mac,
210 const IPAddress &remote_ip,
211 const ByteString &remote_mac) {
212 rx_packet_.set_local_ip_address(local_ip);
213 rx_packet_.set_local_mac_address(local_mac);
214 rx_packet_.set_remote_ip_address(remote_ip);
215 rx_packet_.set_remote_mac_address(remote_mac);
216
217 EXPECT_CALL(*client_, ReceiveReply(_, _))
218 .WillOnce(Invoke(this, &LinkMonitorTest::SimulateReceiveReply));
219 monitor_.ReceiveResponse(0);
220 }
221 void ReceiveCorrectResponse() {
222 ReceiveResponse(local_ip_, local_mac_, gateway_ip_, gateway_mac_);
223 }
224
225 MockEventDispatcher dispatcher_;
Paul Stewartff845fc2012-08-07 07:28:44 -0700226 StrictMock<MockMetrics> metrics_;
Paul Stewart6c72c972012-07-27 11:29:20 -0700227 MockControl control_;
228 NiceMock<MockDeviceInfo> device_info_;
Paul Stewart3f43f432012-07-16 12:12:45 -0700229 scoped_refptr<MockConnection> connection_;
Paul Stewart6c72c972012-07-27 11:29:20 -0700230 StrictMock<LinkMonitorForTest> monitor_;
231 MockTime time_;
232 struct timeval time_val_;
233 // This is owned by the LinkMonitor, and only tracked here for EXPECT*().
234 MockArpClient *client_;
235 // This is owned by the test until it is handed to the LinkMonitorForTest
236 // and placed // in client_ above.
237 MockArpClient *next_client_;
238 IPAddress gateway_ip_;
239 IPAddress local_ip_;
240 ByteString gateway_mac_;
241 ByteString local_mac_;
242 ByteString zero_mac_;
243 ArpPacket rx_packet_;
244 bool link_scope_logging_was_enabled_;
Paul Stewart3f43f432012-07-16 12:12:45 -0700245};
246
Paul Stewart6c72c972012-07-27 11:29:20 -0700247
Paul Stewart3f43f432012-07-16 12:12:45 -0700248TEST_F(LinkMonitorTest, Constructor) {
Paul Stewart6c72c972012-07-27 11:29:20 -0700249 ExpectReset();
250}
251
252TEST_F(LinkMonitorTest, StartFailedGetMACAddress) {
253 ScopedMockLog log;
254 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
255 EXPECT_CALL(log,
256 Log(logging::LOG_ERROR, _,
257 HasSubstr("Could not get local MAC address"))).Times(1);
258 EXPECT_CALL(device_info_, GetMACAddress(0, _)).WillOnce(Return(false));
Paul Stewartff845fc2012-08-07 07:28:44 -0700259 EXPECT_CALL(metrics_, SendEnumToUMA(
260 HasSubstr("LinkMonitorFailure"), Metrics::kLinkMonitorMacAddressNotFound,
261 _));
Paul Stewart6c72c972012-07-27 11:29:20 -0700262 EXPECT_CALL(monitor_, CreateClient()).Times(0);
263 EXPECT_FALSE(monitor_.Start());
264 ExpectReset();
265}
266
267TEST_F(LinkMonitorTest, StartFailedCreateClient) {
268 ScopedMockLog log;
269 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
270 EXPECT_CALL(log,
271 Log(logging::LOG_ERROR, _,
272 HasSubstr("Failed to start ARP client"))).Times(1);
Paul Stewartff845fc2012-08-07 07:28:44 -0700273 EXPECT_CALL(metrics_, SendEnumToUMA(
274 HasSubstr("LinkMonitorFailure"), Metrics::kLinkMonitorClientStartFailure,
275 _));
Paul Stewart6c72c972012-07-27 11:29:20 -0700276 EXPECT_CALL(device_info_, GetMACAddress(0, _)).WillOnce(Return(true));
277 EXPECT_CALL(monitor_, CreateClient()).WillOnce(Return(false));
278 EXPECT_FALSE(monitor_.Start());
279 ExpectReset();
280}
281
282TEST_F(LinkMonitorTest, StartFailedTransmitRequest) {
283 ScopedMockLog log;
284 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
285 EXPECT_CALL(log,
286 Log(logging::LOG_ERROR, _,
287 HasSubstr("Failed to send ARP"))).Times(1);
Paul Stewartff845fc2012-08-07 07:28:44 -0700288 EXPECT_CALL(metrics_, SendEnumToUMA(
289 HasSubstr("LinkMonitorFailure"), Metrics::kLinkMonitorTransmitFailure,
290 _));
Paul Stewart6c72c972012-07-27 11:29:20 -0700291 EXPECT_CALL(device_info_, GetMACAddress(0, _)).WillOnce(Return(true));
292 EXPECT_CALL(monitor_, CreateClient())
293 .WillOnce(Invoke(this, &LinkMonitorTest::CreateMockClient));
294 EXPECT_CALL(*next_client_, TransmitRequest(_)).WillOnce(Return(false));
295 EXPECT_FALSE(monitor_.Start());
296 ExpectReset();
297}
298
299TEST_F(LinkMonitorTest, StartSuccess) {
300 StartMonitor();
301}
302
303TEST_F(LinkMonitorTest, Stop) {
304 StartMonitor();
305 monitor_.Stop();
306 ExpectReset();
307}
308
309TEST_F(LinkMonitorTest, ReplyReception) {
310 StartMonitor();
311 const unsigned int kResponseTime = 1234;
312 AdvanceTime(kResponseTime);
313 ScopedMockLog log;
314
315 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
316 EXPECT_CALL(log, Log(_, _, HasSubstr("not for our IP"))).Times(1);
317 ReceiveResponse(gateway_ip_, local_mac_, gateway_ip_, gateway_mac_);
318 Mock::VerifyAndClearExpectations(&log);
319
320 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
321 EXPECT_CALL(log, Log(_, _, HasSubstr("not for our MAC"))).Times(1);
322 ReceiveResponse(local_ip_, gateway_mac_, gateway_ip_, gateway_mac_);
323 Mock::VerifyAndClearExpectations(&log);
324
325 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
326 EXPECT_CALL(log, Log(_, _, HasSubstr("not from the gateway"))).Times(1);
327 ReceiveResponse(local_ip_, local_mac_, local_ip_, gateway_mac_);
328 Mock::VerifyAndClearExpectations(&log);
329
330 EXPECT_TRUE(GetArpClient());
331 EXPECT_FALSE(monitor_.GetResponseTimeMilliseconds());
332 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
333 EXPECT_CALL(log, Log(_, _, HasSubstr("Found gateway"))).Times(1);
Paul Stewartff845fc2012-08-07 07:28:44 -0700334 EXPECT_CALL(metrics_, SendToUMA(
335 HasSubstr("LinkMonitorResponseTimeSample"), kResponseTime,
336 _, _, _)).Times(1);
Paul Stewart6c72c972012-07-27 11:29:20 -0700337 ReceiveCorrectResponse();
338 EXPECT_FALSE(GetArpClient());
339 EXPECT_EQ(kResponseTime, monitor_.GetResponseTimeMilliseconds());
340 EXPECT_TRUE(IsUnicast());
341}
342
343TEST_F(LinkMonitorTest, TimeoutBroadcast) {
Paul Stewartff845fc2012-08-07 07:28:44 -0700344 EXPECT_CALL(metrics_, SendToUMA(
345 HasSubstr("LinkMonitorResponseTimeSample"), GetTestPeriodMilliseconds(),
346 _, _, _)).Times(GetFailureThreshold());
Paul Stewart6c72c972012-07-27 11:29:20 -0700347 StartMonitor();
348 for (unsigned int i = 1; i < GetFailureThreshold(); ++i) {
349 ExpectTransmit(false);
350 TriggerRequestTimer();
351 EXPECT_FALSE(IsUnicast());
352 EXPECT_EQ(i, GetBroadcastFailureCount());
353 EXPECT_EQ(0, GetUnicastFailureCount());
354 EXPECT_EQ(GetTestPeriodMilliseconds(),
355 monitor_.GetResponseTimeMilliseconds());
356 }
357 ScopedMockLog log;
358 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
359 EXPECT_CALL(log,
360 Log(logging::LOG_ERROR, _,
361 HasSubstr("monitor has reached the failure threshold"))).Times(1);
Paul Stewartff845fc2012-08-07 07:28:44 -0700362 EXPECT_CALL(metrics_, SendEnumToUMA(
363 HasSubstr("LinkMonitorFailure"),
364 Metrics::kLinkMonitorFailureThresholdReached, _));
Paul Stewart6c72c972012-07-27 11:29:20 -0700365 EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
366 ExpectNoTransmit();
367 EXPECT_CALL(monitor_, FailureCallback());
368 TriggerRequestTimer();
369 ExpectReset();
370}
371
372TEST_F(LinkMonitorTest, TimeoutUnicast) {
373 StartMonitor();
Paul Stewartff845fc2012-08-07 07:28:44 -0700374 // Successful broadcast receptions.
375 EXPECT_CALL(metrics_, SendToUMA(
376 HasSubstr("LinkMonitorResponseTimeSample"), 0, _, _, _))
377 .Times(GetFailureThreshold());
378 // Unsuccessful unicast receptions.
379 EXPECT_CALL(metrics_, SendToUMA(
380 HasSubstr("LinkMonitorResponseTimeSample"), GetTestPeriodMilliseconds(),
381 _, _, _)).Times(GetFailureThreshold());
Paul Stewart6c72c972012-07-27 11:29:20 -0700382 ReceiveCorrectResponse();
383 for (unsigned int i = 1; i < GetFailureThreshold(); ++i) {
384 // Failed unicast ARP.
385 ExpectTransmit(true);
386 TriggerRequestTimer();
387
388 // Successful broadcast ARP.
389 ExpectTransmit(false);
390 TriggerRequestTimer();
391 ReceiveCorrectResponse();
392
393 EXPECT_EQ(0, GetBroadcastFailureCount());
394 EXPECT_EQ(i, GetUnicastFailureCount());
395 }
396 // Last unicast ARP transmission.
397 ExpectTransmit(true);
398 TriggerRequestTimer();
399
400 ScopedMockLog log;
401 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
402 EXPECT_CALL(log,
403 Log(logging::LOG_ERROR, _,
404 HasSubstr("monitor has reached the failure threshold"))).Times(1);
Paul Stewartff845fc2012-08-07 07:28:44 -0700405 EXPECT_CALL(metrics_, SendEnumToUMA(
406 HasSubstr("LinkMonitorFailure"),
407 Metrics::kLinkMonitorFailureThresholdReached, _));
Paul Stewart6c72c972012-07-27 11:29:20 -0700408 EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
409 ExpectNoTransmit();
410 EXPECT_CALL(monitor_, FailureCallback());
411 TriggerRequestTimer();
412 ExpectReset();
413}
414
415TEST_F(LinkMonitorTest, Average) {
416 const unsigned int kSamples[] = { 200, 950, 1200, 4096, 5000,
417 86, 120, 3060, 842, 750 };
418 const unsigned int filter_depth = GetMaxResponseSampleFilterDepth();
Paul Stewartff845fc2012-08-07 07:28:44 -0700419 EXPECT_CALL(metrics_, SendToUMA(
420 HasSubstr("LinkMonitorResponseTimeSample"), _, _, _, _))
421 .Times(arraysize(kSamples));
Paul Stewart6c72c972012-07-27 11:29:20 -0700422 ASSERT_GT(arraysize(kSamples), filter_depth);
423 StartMonitor();
424 unsigned int i = 0;
425 unsigned int sum = 0;
426 for (; i < filter_depth; ++i) {
427 AdvanceTime(kSamples[i]);
428 ReceiveCorrectResponse();
429 sum += kSamples[i];
430 EXPECT_EQ(sum / (i + 1), monitor_.GetResponseTimeMilliseconds());
431 SendNextRequest();
432 }
433 for (; i < arraysize(kSamples); ++i) {
434 AdvanceTime(kSamples[i]);
435 ReceiveCorrectResponse();
436 sum = (sum + kSamples[i]) * filter_depth / (filter_depth + 1);
437 EXPECT_EQ(sum / filter_depth, monitor_.GetResponseTimeMilliseconds());
438 SendNextRequest();
439 }
440}
441
442TEST_F(LinkMonitorTest, ImpulseResponse) {
443 const unsigned int kNormalValue = 50;
444 const unsigned int kExceptionalValue = 5000;
445 const unsigned int filter_depth = GetMaxResponseSampleFilterDepth();
Paul Stewartff845fc2012-08-07 07:28:44 -0700446 EXPECT_CALL(metrics_, SendToUMA(
447 HasSubstr("LinkMonitorResponseTimeSample"), _, _, _, _))
448 .Times(AnyNumber());
Paul Stewart6c72c972012-07-27 11:29:20 -0700449 StartMonitor();
450 for (unsigned int i = 0; i < filter_depth * 2; ++i) {
451 AdvanceTime(kNormalValue);
452 ReceiveCorrectResponse();
453 EXPECT_EQ(kNormalValue, monitor_.GetResponseTimeMilliseconds());
454 SendNextRequest();
455 }
456 AdvanceTime(kExceptionalValue);
457 ReceiveCorrectResponse();
458 // Our expectation is that an impulse input will be a
459 // impulse_height / (filter_depth + 1) increase to the running average.
460 unsigned int expected_impulse_response =
461 kNormalValue + (kExceptionalValue - kNormalValue) / (filter_depth + 1);
462 EXPECT_EQ(expected_impulse_response, monitor_.GetResponseTimeMilliseconds());
463 SendNextRequest();
464
465 // From here, if we end up continuing to receive normal values, our
466 // running average should decay backwards to the normal value.
467 const unsigned int failsafe = 100;
468 unsigned int last_value = monitor_.GetResponseTimeMilliseconds();
469 for (unsigned int i = 0; i < failsafe && last_value != kNormalValue; ++i) {
470 AdvanceTime(kNormalValue);
471 ReceiveCorrectResponse();
472 // We should advance monotonically (but not necessarily linearly)
473 // back towards the normal value.
474 EXPECT_GE(last_value, monitor_.GetResponseTimeMilliseconds());
475 SendNextRequest();
476 last_value = monitor_.GetResponseTimeMilliseconds();
477 }
478 EXPECT_EQ(kNormalValue, last_value);
Paul Stewart3f43f432012-07-16 12:12:45 -0700479}
480
481} // namespace shill