Home | History | Annotate | Download | only in shill
      1 //
      2 // Copyright (C) 2015 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "shill/active_link_monitor.h"
     18 
     19 #include <net/if_arp.h>
     20 
     21 #include <string>
     22 
     23 #include <base/bind.h>
     24 #include <gtest/gtest.h>
     25 
     26 #include "shill/arp_client_test_helper.h"
     27 #include "shill/arp_packet.h"
     28 #include "shill/logging.h"
     29 #include "shill/mock_arp_client.h"
     30 #include "shill/mock_connection.h"
     31 #include "shill/mock_control.h"
     32 #include "shill/mock_device_info.h"
     33 #include "shill/mock_event_dispatcher.h"
     34 #include "shill/mock_log.h"
     35 #include "shill/mock_metrics.h"
     36 #include "shill/net/byte_string.h"
     37 #include "shill/net/ip_address.h"
     38 #include "shill/net/mock_sockets.h"
     39 #include "shill/net/mock_time.h"
     40 
     41 using base::Bind;
     42 using base::Unretained;
     43 using std::string;
     44 using testing::_;
     45 using testing::AnyNumber;
     46 using testing::HasSubstr;
     47 using testing::Invoke;
     48 using testing::Mock;
     49 using testing::NiceMock;
     50 using testing::Return;
     51 using testing::ReturnRef;
     52 using testing::SetArgumentPointee;
     53 using testing::StrictMock;
     54 using testing::Test;
     55 
     56 namespace shill {
     57 
     58 namespace {
     59 const char kInterfaceName[] = "int0";
     60 const char kLocalIPAddress[] = "10.0.1.1";
     61 const uint8_t kLocalMACAddress[] = { 0, 1, 2, 3, 4, 5 };
     62 const char kRemoteIPAddress[] = "10.0.1.2";
     63 const uint8_t kRemoteMACAddress[] = { 6, 7, 8, 9, 10, 11 };
     64 const char kDBusPath[] = "/dbus/path";
     65 }  // namespace
     66 
     67 
     68 class ActiveLinkMonitorObserver {
     69  public:
     70   ActiveLinkMonitorObserver()
     71       : failure_callback_(
     72             Bind(&ActiveLinkMonitorObserver::OnFailureCallback,
     73                  Unretained(this))),
     74         success_callback_(
     75             Bind(&ActiveLinkMonitorObserver::OnSuccessCallback,
     76                  Unretained(this))) {}
     77   virtual ~ActiveLinkMonitorObserver() {}
     78 
     79   MOCK_METHOD3(OnFailureCallback,
     80                void(Metrics::LinkMonitorFailure failrue_code,
     81                     int broadcast_failure_count,
     82                     int unicast_failure_count));
     83   MOCK_METHOD0(OnSuccessCallback, void());
     84 
     85   const ActiveLinkMonitor::FailureCallback failure_callback() {
     86     return failure_callback_;
     87   }
     88 
     89   const ActiveLinkMonitor::SuccessCallback success_callback() {
     90     return success_callback_;
     91   }
     92 
     93  private:
     94   ActiveLinkMonitor::FailureCallback failure_callback_;
     95   ActiveLinkMonitor::SuccessCallback success_callback_;
     96 
     97   DISALLOW_COPY_AND_ASSIGN(ActiveLinkMonitorObserver);
     98 };
     99 
    100 MATCHER_P4(IsArpRequest, local_ip, remote_ip, local_mac, remote_mac, "") {
    101   if (local_ip.Equals(arg.local_ip_address()) &&
    102       remote_ip.Equals(arg.remote_ip_address()) &&
    103       local_mac.Equals(arg.local_mac_address()) &&
    104       remote_mac.Equals(arg.remote_mac_address()))
    105     return true;
    106 
    107   if (!local_ip.Equals(arg.local_ip_address())) {
    108     *result_listener << "Local IP '" << arg.local_ip_address().ToString()
    109                      << "' (wanted '" << local_ip.ToString() << "').";
    110   }
    111 
    112   if (!remote_ip.Equals(arg.remote_ip_address())) {
    113     *result_listener << "Remote IP '" << arg.remote_ip_address().ToString()
    114                      << "' (wanted '" << remote_ip.ToString() << "').";
    115   }
    116 
    117   if (!local_mac.Equals(arg.local_mac_address())) {
    118     *result_listener << "Local MAC '" << arg.local_mac_address().HexEncode()
    119                      << "' (wanted " << local_mac.HexEncode() << ")'.";
    120   }
    121 
    122   if (!remote_mac.Equals(arg.remote_mac_address())) {
    123     *result_listener << "Remote MAC '" << arg.remote_mac_address().HexEncode()
    124                      << "' (wanted " << remote_mac.HexEncode() << ")'.";
    125   }
    126 
    127   return false;
    128 }
    129 
    130 class ActiveLinkMonitorTest : public Test {
    131  public:
    132   ActiveLinkMonitorTest()
    133       : metrics_(&dispatcher_),
    134         device_info_(&control_, nullptr, nullptr, nullptr),
    135         connection_(new StrictMock<MockConnection>(&device_info_)),
    136         client_(new MockArpClient()),
    137         client_test_helper_(client_),
    138         gateway_ip_(IPAddress::kFamilyIPv4),
    139         local_ip_(IPAddress::kFamilyIPv4),
    140         gateway_mac_(kRemoteMACAddress, arraysize(kRemoteMACAddress)),
    141         local_mac_(kLocalMACAddress, arraysize(kLocalMACAddress)),
    142         zero_mac_(arraysize(kLocalMACAddress)),
    143         link_scope_logging_was_enabled_(false),
    144         interface_name_(kInterfaceName),
    145         monitor_(connection_,
    146                  &dispatcher_,
    147                  &metrics_,
    148                  &device_info_,
    149                  observer_.failure_callback(),
    150                  observer_.success_callback()) {}
    151   virtual ~ActiveLinkMonitorTest() {}
    152 
    153   virtual void SetUp() {
    154     link_scope_logging_was_enabled_ = SLOG_IS_ON(Link, 0);
    155     if (!link_scope_logging_was_enabled_) {
    156       ScopeLogger::GetInstance()->EnableScopesByName("link");
    157       ScopeLogger::GetInstance()->set_verbose_level(4);
    158     }
    159     monitor_.arp_client_.reset(client_);
    160     monitor_.time_ = &time_;
    161     time_val_.tv_sec = 0;
    162     time_val_.tv_usec = 0;
    163     EXPECT_CALL(time_, GetTimeMonotonic(_))
    164         .WillRepeatedly(DoAll(SetArgumentPointee<0>(time_val_), Return(0)));
    165     EXPECT_TRUE(local_ip_.SetAddressFromString(kLocalIPAddress));
    166     EXPECT_CALL(*connection_, local()).WillRepeatedly(ReturnRef(local_ip_));
    167     EXPECT_TRUE(gateway_ip_.SetAddressFromString(kRemoteIPAddress));
    168     EXPECT_CALL(*connection_, gateway()).WillRepeatedly(ReturnRef(gateway_ip_));
    169     EXPECT_CALL(*connection_, technology())
    170         .WillRepeatedly(Return(Technology::kEthernet));
    171     EXPECT_CALL(*connection_, ipconfig_rpc_identifier())
    172         .WillRepeatedly(testing::ReturnPointee(&kDBusPath));
    173     EXPECT_CALL(*connection_, interface_name())
    174         .WillRepeatedly(ReturnRef(interface_name_));
    175   }
    176 
    177   virtual void TearDown() {
    178     if (!link_scope_logging_was_enabled_) {
    179       ScopeLogger::GetInstance()->EnableScopesByName("-link");
    180       ScopeLogger::GetInstance()->set_verbose_level(0);
    181     }
    182   }
    183 
    184   void AdvanceTime(int time_ms) {
    185     struct timeval adv_time = {
    186       static_cast<time_t>(time_ms/1000),
    187       static_cast<time_t>((time_ms % 1000) * 1000) };
    188     timeradd(&time_val_, &adv_time, &time_val_);
    189     EXPECT_CALL(time_, GetTimeMonotonic(_))
    190         .WillRepeatedly(DoAll(SetArgumentPointee<0>(time_val_), Return(0)));
    191   }
    192 
    193   string HardwareAddressToString(const ByteString& address) {
    194     return ActiveLinkMonitor::HardwareAddressToString(address);
    195   }
    196 
    197  protected:
    198   void ExpectReset() {
    199     EXPECT_FALSE(monitor_.GetResponseTimeMilliseconds());
    200     EXPECT_TRUE(GetSendRequestCallback().IsCancelled());
    201     EXPECT_EQ(0, GetBroadcastFailureCount());
    202     EXPECT_EQ(0, GetUnicastFailureCount());
    203     EXPECT_EQ(0, GetBroadcastSuccessCount());
    204     EXPECT_EQ(0, GetUnicastSuccessCount());
    205     EXPECT_FALSE(IsUnicast());
    206     EXPECT_FALSE(GatewaySupportsUnicastArp());
    207   }
    208   void TriggerRequestTimer() {
    209     GetSendRequestCallback().callback().Run();
    210   }
    211   const base::CancelableClosure& GetSendRequestCallback() {
    212     return monitor_.send_request_callback_;
    213   }
    214   int GetBroadcastFailureCount() {
    215     return monitor_.broadcast_failure_count_;
    216   }
    217   int GetUnicastFailureCount() {
    218     return monitor_.unicast_failure_count_;
    219   }
    220   int GetBroadcastSuccessCount() {
    221     return monitor_.broadcast_success_count_;
    222   }
    223   int GetUnicastSuccessCount() {
    224     return monitor_.unicast_success_count_;
    225   }
    226   bool IsUnicast() { return monitor_.is_unicast_; }
    227   bool GatewaySupportsUnicastArp() {
    228     return monitor_.gateway_supports_unicast_arp_;
    229   }
    230   int GetCurrentTestPeriodMilliseconds() {
    231     return monitor_.test_period_milliseconds_;
    232   }
    233   int GetDefaultTestPeriodMilliseconds() {
    234     return ActiveLinkMonitor::kDefaultTestPeriodMilliseconds;
    235   }
    236   size_t GetFailureThreshold() {
    237     return ActiveLinkMonitor::kFailureThreshold;
    238   }
    239   size_t GetUnicastReplyReliabilityThreshold() {
    240     return ActiveLinkMonitor::kUnicastReplyReliabilityThreshold;
    241   }
    242   int GetFastTestPeriodMilliseconds() {
    243     return ActiveLinkMonitor::kFastTestPeriodMilliseconds;
    244   }
    245   int GetMaxResponseSampleFilterDepth() {
    246     return ActiveLinkMonitor::kMaxResponseSampleFilterDepth;
    247   }
    248   void ExpectTransmit(bool is_unicast, int transmit_period_milliseconds) {
    249     const ByteString& destination_mac = is_unicast ? gateway_mac_ : zero_mac_;
    250     EXPECT_CALL(*client_, TransmitRequest(
    251         IsArpRequest(local_ip_, gateway_ip_, local_mac_, destination_mac)))
    252         .WillOnce(Return(true));
    253     EXPECT_CALL(dispatcher_,
    254                 PostDelayedTask(_, transmit_period_milliseconds));
    255   }
    256   void SendNextRequest() {
    257     EXPECT_CALL(*client_, TransmitRequest(_)).WillOnce(Return(true));
    258     EXPECT_CALL(dispatcher_,
    259                 PostDelayedTask(_, GetCurrentTestPeriodMilliseconds()));
    260     TriggerRequestTimer();
    261   }
    262   void ExpectNoTransmit() {
    263     EXPECT_CALL(*client_, TransmitRequest(_)).Times(0);
    264   }
    265   void StartMonitor() {
    266     EXPECT_CALL(device_info_, GetMACAddress(0, _))
    267         .WillOnce(DoAll(SetArgumentPointee<1>(local_mac_), Return(true)));
    268     EXPECT_CALL(*client_, StartReplyListener()).WillOnce(Return(true));
    269     EXPECT_CALL(dispatcher_, PostTask(_)).Times(1);
    270     EXPECT_TRUE(monitor_.Start(
    271         ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
    272     EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
    273   }
    274   void ReceiveResponse(uint16_t operation,
    275                        const IPAddress& local_ip,
    276                        const ByteString& local_mac,
    277                        const IPAddress& remote_ip,
    278                        const ByteString& remote_mac) {
    279     client_test_helper_.GeneratePacket(operation,
    280                                        local_ip,
    281                                        local_mac,
    282                                        remote_ip,
    283                                        remote_mac);
    284     monitor_.ReceiveResponse(0);
    285   }
    286   void ReceiveCorrectResponse() {
    287     ReceiveResponse(ARPOP_REPLY, gateway_ip_, gateway_mac_,
    288                     local_ip_, local_mac_);
    289   }
    290   void ReceiveReplyAndRestartMonitorCycle() {
    291     EXPECT_CALL(observer_, OnSuccessCallback()).Times(1);
    292     ReceiveCorrectResponse();
    293     Mock::VerifyAndClearExpectations(&observer_);
    294     StartMonitor();
    295   }
    296   void RunUnicastResponseCycle(int cycle_count,
    297                                bool should_respond_to_unicast_probes,
    298                                bool should_count_failures) {
    299     // This method expects the ActiveLinkMonitor to be in a state where it
    300     // is waiting for a broadcast response.  It also returns with the
    301     // ActiveLinkMonitor in the same state.
    302     // Successful receptions.
    303     EXPECT_CALL(metrics_, SendToUMA(
    304         HasSubstr("LinkMonitorResponseTimeSample"), 0, _, _, _))
    305         .Times(cycle_count * (should_respond_to_unicast_probes ? 2 : 1));
    306     // Unsuccessful unicast receptions.
    307     EXPECT_CALL(metrics_, SendToUMA(
    308         HasSubstr("LinkMonitorResponseTimeSample"),
    309         GetDefaultTestPeriodMilliseconds(),
    310         _, _, _)).Times(cycle_count *
    311                         (should_respond_to_unicast_probes ? 0 : 1));
    312 
    313     // Account for any successes / failures before we started.
    314     int expected_broadcast_success_count = GetBroadcastSuccessCount();
    315     int expected_unicast_success_count = GetUnicastSuccessCount();
    316     int expected_unicast_failure_count = GetUnicastFailureCount();
    317 
    318     LOG(INFO) << "RunUnicastResponseCycle: " << cycle_count;
    319 
    320     for (int i = 0; i < cycle_count; ++i) {
    321       // Respond to the pending broadcast request.
    322       ReceiveReplyAndRestartMonitorCycle();
    323 
    324       // Unicast ARP.
    325       ExpectTransmit(true, GetDefaultTestPeriodMilliseconds());
    326       TriggerRequestTimer();
    327       if (should_respond_to_unicast_probes) {
    328         ReceiveReplyAndRestartMonitorCycle();
    329       }
    330 
    331       // Initiate broadcast ARP.
    332       ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
    333       TriggerRequestTimer();
    334 
    335       ++expected_broadcast_success_count;
    336       if (should_respond_to_unicast_probes) {
    337         ++expected_unicast_success_count;
    338         expected_unicast_failure_count = 0;
    339       } else {
    340         if (should_count_failures) {
    341           ++expected_unicast_failure_count;
    342         }
    343         expected_unicast_success_count = 0;
    344       }
    345       EXPECT_EQ(expected_unicast_failure_count, GetUnicastFailureCount());
    346       EXPECT_EQ(expected_unicast_success_count, GetUnicastSuccessCount());
    347       EXPECT_EQ(0, GetBroadcastFailureCount());
    348       EXPECT_EQ(expected_broadcast_success_count, GetBroadcastSuccessCount());
    349     }
    350   }
    351 
    352   MockEventDispatcher dispatcher_;
    353   StrictMock<MockMetrics> metrics_;
    354   MockControl control_;
    355   NiceMock<MockDeviceInfo> device_info_;
    356   scoped_refptr<MockConnection> connection_;
    357   MockTime time_;
    358   struct timeval time_val_;
    359   // This is owned by the LinkMonitor, and only tracked here for EXPECT*().
    360   MockArpClient* client_;
    361   ArpClientTestHelper client_test_helper_;
    362   ActiveLinkMonitorObserver observer_;
    363   IPAddress gateway_ip_;
    364   IPAddress local_ip_;
    365   ByteString gateway_mac_;
    366   ByteString local_mac_;
    367   ByteString zero_mac_;
    368   bool link_scope_logging_was_enabled_;
    369   const string interface_name_;
    370   ActiveLinkMonitor monitor_;
    371 };
    372 
    373 
    374 TEST_F(ActiveLinkMonitorTest, Constructor) {
    375   ExpectReset();
    376 }
    377 
    378 TEST_F(ActiveLinkMonitorTest, StartFailedGetMACAddress) {
    379   ScopedMockLog log;
    380   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    381   EXPECT_CALL(log,
    382       Log(logging::LOG_ERROR, _,
    383           HasSubstr("Could not get local MAC address"))).Times(1);
    384   EXPECT_CALL(device_info_, GetMACAddress(0, _)).WillOnce(Return(false));
    385   EXPECT_CALL(metrics_, SendEnumToUMA(
    386       HasSubstr("LinkMonitorFailure"), Metrics::kLinkMonitorMacAddressNotFound,
    387       _));
    388   EXPECT_CALL(*client_, StartReplyListener()).Times(0);
    389   EXPECT_FALSE(monitor_.Start(
    390       ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
    391   ExpectReset();
    392 }
    393 
    394 TEST_F(ActiveLinkMonitorTest, StartFailedArpClient) {
    395   ScopedMockLog log;
    396   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    397   EXPECT_CALL(log,
    398       Log(logging::LOG_ERROR, _,
    399           HasSubstr("Failed to start ARP client"))).Times(1);
    400   EXPECT_CALL(metrics_, SendEnumToUMA(
    401       HasSubstr("LinkMonitorFailure"), Metrics::kLinkMonitorClientStartFailure,
    402       _));
    403   EXPECT_CALL(device_info_, GetMACAddress(0, _)).WillOnce(Return(true));
    404   EXPECT_CALL(*client_, StartReplyListener()).WillOnce(Return(false));
    405   EXPECT_FALSE(monitor_.Start(
    406       ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
    407   ExpectReset();
    408 }
    409 
    410 TEST_F(ActiveLinkMonitorTest, StartSuccess) {
    411   StartMonitor();
    412 }
    413 
    414 TEST_F(ActiveLinkMonitorTest, Stop) {
    415   StartMonitor();
    416   EXPECT_CALL(*client_, Stop()).Times(1);
    417   monitor_.Stop();
    418   ExpectReset();
    419   Mock::VerifyAndClearExpectations(client_);
    420 }
    421 
    422 TEST_F(ActiveLinkMonitorTest, ReplyReception) {
    423   StartMonitor();
    424   const int kResponseTime = 1234;
    425   AdvanceTime(kResponseTime);
    426   ScopedMockLog log;
    427 
    428   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    429   EXPECT_CALL(log, Log(_, _, HasSubstr("not for our IP"))).Times(1);
    430   ReceiveResponse(ARPOP_REPLY, gateway_ip_, gateway_mac_,
    431                   gateway_ip_, local_mac_);
    432   Mock::VerifyAndClearExpectations(&log);
    433 
    434   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    435   EXPECT_CALL(log, Log(_, _, HasSubstr("not for our MAC"))).Times(1);
    436   ReceiveResponse(ARPOP_REPLY, gateway_ip_, gateway_mac_,
    437                   local_ip_, gateway_mac_);
    438   Mock::VerifyAndClearExpectations(&log);
    439 
    440   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    441   EXPECT_CALL(log, Log(_, _, HasSubstr("not from the gateway"))).Times(1);
    442   ReceiveResponse(ARPOP_REPLY, local_ip_, gateway_mac_, local_ip_, local_mac_);
    443   Mock::VerifyAndClearExpectations(&log);
    444 
    445   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    446   EXPECT_CALL(log, Log(_, _, HasSubstr("This is not a reply packet"))).Times(1);
    447   ReceiveResponse(ARPOP_REQUEST, gateway_ip_, gateway_mac_,
    448                   local_ip_, local_mac_);
    449   Mock::VerifyAndClearExpectations(&log);
    450 
    451   EXPECT_FALSE(monitor_.GetResponseTimeMilliseconds());
    452   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    453   EXPECT_CALL(log, Log(_, _, HasSubstr("Found gateway"))).Times(1);
    454   EXPECT_CALL(metrics_, SendToUMA(
    455       HasSubstr("LinkMonitorResponseTimeSample"), kResponseTime,
    456        _, _, _)).Times(1);
    457   EXPECT_CALL(*client_, Stop()).Times(1);
    458   EXPECT_CALL(observer_, OnSuccessCallback()).Times(1);
    459   ReceiveCorrectResponse();
    460   EXPECT_EQ(kResponseTime, monitor_.GetResponseTimeMilliseconds());
    461   EXPECT_TRUE(IsUnicast());
    462   Mock::VerifyAndClearExpectations(client_);
    463 }
    464 
    465 TEST_F(ActiveLinkMonitorTest, TimeoutBroadcast) {
    466   EXPECT_CALL(metrics_, SendToUMA(
    467       HasSubstr("LinkMonitorResponseTimeSample"),
    468       GetDefaultTestPeriodMilliseconds(),
    469       _, _, _)).Times(GetFailureThreshold());
    470   StartMonitor();
    471   // This value doesn't match real life (the timer in this scenario
    472   // should advance by LinkMonitor::kDefaultTestPeriodMilliseconds),
    473   // but this demonstrates the LinkMonitorSecondsToFailure independent
    474   // from the response-time figures.
    475   const int kTimeIncrement = 1000;
    476   // Transmit initial request.
    477   ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
    478   AdvanceTime(kTimeIncrement);
    479   TriggerRequestTimer();
    480   for (size_t i = 1; i < GetFailureThreshold(); ++i) {
    481     ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
    482     AdvanceTime(kTimeIncrement);
    483     TriggerRequestTimer();
    484     EXPECT_FALSE(IsUnicast());
    485     EXPECT_EQ(i, GetBroadcastFailureCount());
    486     EXPECT_EQ(0, GetUnicastFailureCount());
    487     EXPECT_EQ(0, GetBroadcastSuccessCount());
    488     EXPECT_EQ(0, GetUnicastSuccessCount());
    489     EXPECT_EQ(GetDefaultTestPeriodMilliseconds(),
    490               monitor_.GetResponseTimeMilliseconds());
    491   }
    492   ScopedMockLog log;
    493   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    494   EXPECT_CALL(log,
    495       Log(logging::LOG_ERROR, _,
    496           HasSubstr("monitor has reached the failure threshold"))).Times(1);
    497   EXPECT_CALL(observer_,
    498               OnFailureCallback(Metrics::kLinkMonitorFailureThresholdReached,
    499                                 GetFailureThreshold(),
    500                                 0)).Times(1);
    501   EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
    502   // Transmit final request.
    503   ExpectNoTransmit();
    504   AdvanceTime(kTimeIncrement);
    505   TriggerRequestTimer();
    506   ExpectReset();
    507 }
    508 
    509 TEST_F(ActiveLinkMonitorTest, TimeoutUnicast) {
    510   StartMonitor();
    511 
    512   // Setup expectation for Time::GetTimeMonotonic.
    513   const int kTimeIncrement = 1000;
    514   AdvanceTime(kTimeIncrement);
    515   // Initiate a broadcast ARP.
    516   ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
    517   TriggerRequestTimer();
    518 
    519   ScopedMockLog log;
    520   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    521   EXPECT_CALL(log,
    522       Log(logging::LOG_ERROR, _,
    523           HasSubstr("monitor has reached the failure threshold"))).Times(0);
    524 
    525   // Unicast failures should not cause LinkMonitor errors if we haven't
    526   // noted the gateway as reliably replying to unicast ARP messages.  Test
    527   // this by doing threshold - 1 successful unicast responses, followed
    528   // by a ton of unicast failures.
    529   // Initiate broadcast ARP.
    530   RunUnicastResponseCycle(GetUnicastReplyReliabilityThreshold() - 1,
    531                           true, false);
    532   EXPECT_EQ(GetUnicastReplyReliabilityThreshold() - 1,
    533             GetUnicastSuccessCount());
    534   RunUnicastResponseCycle(GetFailureThreshold() +
    535                           GetUnicastReplyReliabilityThreshold(), false, false);
    536   EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
    537   EXPECT_FALSE(GatewaySupportsUnicastArp());
    538   EXPECT_EQ(0, GetUnicastSuccessCount());
    539   EXPECT_EQ(0, GetUnicastFailureCount());
    540 
    541   // Cross the the unicast reliability threshold.
    542   RunUnicastResponseCycle(GetUnicastReplyReliabilityThreshold() - 1,
    543                           true, false);
    544   EXPECT_CALL(log,
    545       Log(_, _, HasSubstr("Unicast failures will now count")));
    546   EXPECT_FALSE(GatewaySupportsUnicastArp());
    547   RunUnicastResponseCycle(1, true, false);
    548   EXPECT_TRUE(GatewaySupportsUnicastArp());
    549 
    550   // Induce one less failures than will cause a link monitor failure, and
    551   // confirm that these failures are counted.
    552   RunUnicastResponseCycle(GetFailureThreshold() - 1, false, true);
    553   EXPECT_EQ(GetFailureThreshold() - 1, GetUnicastFailureCount());
    554 
    555   Mock::VerifyAndClearExpectations(&log);
    556   EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    557 
    558   // Induce a final broadcast success followed by a unicast failure.
    559   EXPECT_CALL(metrics_, SendToUMA(
    560       HasSubstr("LinkMonitorResponseTimeSample"), 0, _, _, _));
    561   ReceiveReplyAndRestartMonitorCycle();
    562 
    563   ExpectTransmit(true, GetDefaultTestPeriodMilliseconds());
    564   TriggerRequestTimer();
    565   EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
    566 
    567   EXPECT_CALL(metrics_, SendToUMA(
    568       HasSubstr("LinkMonitorResponseTimeSample"),
    569       GetDefaultTestPeriodMilliseconds(),
    570       _, _, _));
    571   EXPECT_CALL(log,
    572       Log(logging::LOG_ERROR, _,
    573           HasSubstr("monitor has reached the failure threshold"))).Times(1);
    574   EXPECT_CALL(observer_,
    575               OnFailureCallback(Metrics::kLinkMonitorFailureThresholdReached,
    576                                 0,
    577                                 GetFailureThreshold())).Times(1);
    578   ExpectNoTransmit();
    579   TriggerRequestTimer();
    580   ExpectReset();
    581 }
    582 
    583 TEST_F(ActiveLinkMonitorTest, Average) {
    584   const int kSamples[] = { 200, 950, 1200, 4096, 5000,
    585                            86, 120, 3060, 842, 750 };
    586   const size_t filter_depth = GetMaxResponseSampleFilterDepth();
    587   EXPECT_CALL(metrics_, SendToUMA(
    588       HasSubstr("LinkMonitorResponseTimeSample"), _, _, _, _))
    589       .Times(arraysize(kSamples));
    590   ASSERT_GT(arraysize(kSamples), filter_depth);
    591   StartMonitor();
    592   size_t i = 0;
    593   int sum = 0;
    594   for (; i < filter_depth; ++i) {
    595     AdvanceTime(kSamples[i]);
    596     ReceiveReplyAndRestartMonitorCycle();
    597     sum += kSamples[i];
    598     EXPECT_EQ(sum / (i + 1), monitor_.GetResponseTimeMilliseconds());
    599     SendNextRequest();
    600   }
    601   for (; i < arraysize(kSamples); ++i) {
    602     AdvanceTime(kSamples[i]);
    603     ReceiveReplyAndRestartMonitorCycle();
    604     sum = (sum + kSamples[i]) * filter_depth / (filter_depth + 1);
    605     EXPECT_EQ(sum / filter_depth, monitor_.GetResponseTimeMilliseconds());
    606     SendNextRequest();
    607   }
    608 }
    609 
    610 TEST_F(ActiveLinkMonitorTest, ImpulseResponse) {
    611   const int kNormalValue = 50;
    612   const int kExceptionalValue = 5000;
    613   const int filter_depth = GetMaxResponseSampleFilterDepth();
    614   EXPECT_CALL(metrics_, SendToUMA(
    615       HasSubstr("LinkMonitorResponseTimeSample"), _, _, _, _))
    616       .Times(AnyNumber());
    617   StartMonitor();
    618   for (int i = 0; i < filter_depth * 2; ++i) {
    619     AdvanceTime(kNormalValue);
    620     ReceiveReplyAndRestartMonitorCycle();
    621     EXPECT_EQ(kNormalValue, monitor_.GetResponseTimeMilliseconds());
    622     SendNextRequest();
    623   }
    624   AdvanceTime(kExceptionalValue);
    625   ReceiveReplyAndRestartMonitorCycle();
    626   // Our expectation is that an impulse input will be a
    627   // impulse_height / (filter_depth + 1) increase to the running average.
    628   int expected_impulse_response =
    629       kNormalValue + (kExceptionalValue - kNormalValue) / (filter_depth + 1);
    630   EXPECT_EQ(expected_impulse_response, monitor_.GetResponseTimeMilliseconds());
    631   SendNextRequest();
    632 
    633   // From here, if we end up continuing to receive normal values, our
    634   // running average should decay backwards to the normal value.
    635   const int failsafe = 100;
    636   int last_value = monitor_.GetResponseTimeMilliseconds();
    637   for (int i = 0; i < failsafe && last_value != kNormalValue; ++i) {
    638     AdvanceTime(kNormalValue);
    639     ReceiveReplyAndRestartMonitorCycle();
    640     // We should advance monotonically (but not necessarily linearly)
    641     // back towards the normal value.
    642     EXPECT_GE(last_value, monitor_.GetResponseTimeMilliseconds());
    643     SendNextRequest();
    644     last_value = monitor_.GetResponseTimeMilliseconds();
    645   }
    646   EXPECT_EQ(kNormalValue, last_value);
    647 }
    648 
    649 TEST_F(ActiveLinkMonitorTest, HardwareAddressToString) {
    650   const uint8_t address0[] = { 0, 1, 2, 3, 4, 5 };
    651   EXPECT_EQ("00:01:02:03:04:05",
    652             HardwareAddressToString(ByteString(address0, arraysize(address0))));
    653   const uint8_t address1[] = { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd };
    654   EXPECT_EQ("88:99:aa:bb:cc:dd",
    655             HardwareAddressToString(ByteString(address1, arraysize(address1))));
    656 }
    657 
    658 }  // namespace shill
    659