1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2013 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
1643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
17c54afe521739065a5d77e7c049acdb5e603f0592Ben Chan#include "shill/cellular/active_passive_out_of_credits_detector.h"
1843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
198a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko#include <string>
208a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko#include <vector>
218a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko
2243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le#include <gtest/gtest.h>
2343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
24c54afe521739065a5d77e7c049acdb5e603f0592Ben Chan#include "shill/cellular/mock_cellular.h"
25c54afe521739065a5d77e7c049acdb5e603f0592Ben Chan#include "shill/cellular/mock_cellular_service.h"
26c54afe521739065a5d77e7c049acdb5e603f0592Ben Chan#include "shill/cellular/mock_modem_info.h"
2743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le#include "shill/mock_connection.h"
2843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le#include "shill/mock_connection_health_checker.h"
2943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le#include "shill/mock_device_info.h"
3043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le#include "shill/mock_manager.h"
3143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le#include "shill/mock_traffic_monitor.h"
3205d87e34869f44473edc1eec25d2fe1110d777a7Peter Qiu#include "shill/test_event_dispatcher.h"
3343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
3443ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing base::Bind;
3543ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing base::Unretained;
3643ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing std::string;
3743ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing std::vector;
3843ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::_;
3943ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::AnyNumber;
4043ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::Mock;
4143ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::NiceMock;
4243ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::Return;
4343ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::ReturnPointee;
4443ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::ReturnRef;
4543ce4d428d619bda64eea6d37534f02c179a1756Thieu Leusing testing::StrictMock;
4643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
4743ce4d428d619bda64eea6d37534f02c179a1756Thieu Lenamespace shill {
4843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
4943ce4d428d619bda64eea6d37534f02c179a1756Thieu Leclass ActivePassiveOutOfCreditsDetectorTest : public testing::Test {
5043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le public:
5143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  ActivePassiveOutOfCreditsDetectorTest()
52bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal      : modem_info_(nullptr, &dispatcher_, &metrics_, &manager_),
5343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        device_info_(modem_info_.control_interface(), modem_info_.dispatcher(),
5443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                     modem_info_.metrics(), modem_info_.manager()),
5543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        manager_(modem_info_.control_interface(), modem_info_.dispatcher(),
56bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal                 modem_info_.metrics()),
5743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        metrics_(modem_info_.dispatcher()),
5843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        cellular_(new NiceMock<MockCellular>(&modem_info_,
5943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                                             "usb0",
6043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                                             kAddress,
6143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                                             3,
6243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                                             Cellular::kTypeCDMA,
6343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                                             "",
64608ec29525f553d51f0a92e84176e3d4b45930a9Peter Qiu                                             "")),
6543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        service_(new NiceMock<MockCellularService>(&modem_info_, cellular_)),
6643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        connection_(new NiceMock<MockConnection>(&device_info_)),
6743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        out_of_credits_detector_(
6843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le            new ActivePassiveOutOfCreditsDetector(
6943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                modem_info_.dispatcher(), modem_info_.manager(),
700951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko                modem_info_.metrics(), service_.get())) {}
7143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
7243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  virtual void SetUp() {
7343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    service_->connection_ = connection_;
7443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    cellular_->service_ = service_;
7543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    service_->SetRoamingState(kRoamingStateHome);
7643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ON_CALL(*connection_, interface_name())
7743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        .WillByDefault(ReturnRef(interface_name_));
7843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ON_CALL(*connection_, dns_servers())
7943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        .WillByDefault(ReturnRef(dns_servers_));
8043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ON_CALL(manager_, GetPortalCheckURL())
8143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        .WillByDefault(ReturnRef(portal_check_url_));
8243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ON_CALL(*service_, explicitly_disconnected()).WillByDefault(Return(false));
8343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ON_CALL(*service_, resume_start_time())
8443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le        .WillByDefault(ReturnRef(resume_start_time_));
8543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  }
8643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
8743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  virtual void TearDown() {
88ea18c6c99743aeee9b2e544532ef9fe55dbd182dBen Chan    cellular_->service_ = nullptr;  // Break circular reference.
8943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  }
9043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
9143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  void OnConnectionHealthCheckerResult(
9243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      ConnectionHealthChecker::Result result) {}
9343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
9443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le protected:
9543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  static const char kAddress[];
9643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
9743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  void SetMockServiceState(Service::ConnectState old_state,
9843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le                           Service::ConnectState new_state) {
9943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    out_of_credits_detector_->NotifyServiceStateChanged(old_state, new_state);
10043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  }
10143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
1022f6c78991e37f5fa71f2ba4d1669be73f0a6dfd4Paul Stewart  void SetTrafficMonitor(TrafficMonitor* traffic_monitor) {
10343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    out_of_credits_detector_->set_traffic_monitor(traffic_monitor);
10443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  }
10543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
1062f6c78991e37f5fa71f2ba4d1669be73f0a6dfd4Paul Stewart  void SetConnectionHealthChecker(ConnectionHealthChecker* health_checker) {
10743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    out_of_credits_detector_->set_connection_health_checker(health_checker);
10843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  }
10943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
11005d87e34869f44473edc1eec25d2fe1110d777a7Peter Qiu  EventDispatcherForTest dispatcher_;
11143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  MockModemInfo modem_info_;
11243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  NiceMock<MockDeviceInfo> device_info_;
11343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  NiceMock<MockManager> manager_;
11443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  NiceMock<MockMetrics> metrics_;
11543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  scoped_refptr<NiceMock<MockCellular>> cellular_;
11643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  scoped_refptr<NiceMock<MockCellularService>> service_;
11743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  scoped_refptr<NiceMock<MockConnection>> connection_;
11843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  string interface_name_;
11943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  vector<string> dns_servers_;
12043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  string portal_check_url_;
12143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  base::Time resume_start_time_;
122c20ed13f5c0e87e7a5164d1b5330ccd99cced58fBen Chan  std::unique_ptr<ActivePassiveOutOfCreditsDetector> out_of_credits_detector_;
12343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le};
12443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
12543ce4d428d619bda64eea6d37534f02c179a1756Thieu Leconst char ActivePassiveOutOfCreditsDetectorTest::kAddress[] = "000102030405";
12643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
12743ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
12843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ConnectDisconnectLoopOutOfCreditsDetected) {
12943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, Connect(_, _)).Times(2);
13043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
13143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
13243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateFailure);
13343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_TRUE(out_of_credits_detector_->IsDetecting());
13443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
13543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
13643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConfiguring);
13743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConfiguring, Service::kStateIdle);
13843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_TRUE(out_of_credits_detector_->IsDetecting());
13943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
14043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
14143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
14243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
14343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_TRUE(out_of_credits_detector_->out_of_credits());
14443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->IsDetecting());
14543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
14643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
14743ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
14843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ConnectDisconnectLoopDetectionNotSkippedAfterSlowResume) {
14943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  resume_start_time_ =
15043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      base::Time::Now() -
15143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      base::TimeDelta::FromSeconds(
15243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      ActivePassiveOutOfCreditsDetector::kOutOfCreditsResumeIgnoreSeconds + 1);
15343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, Connect(_, _)).Times(2);
15443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
15543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateFailure);
15643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_TRUE(out_of_credits_detector_->IsDetecting());
15743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
15843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
15943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConfiguring);
16043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConfiguring, Service::kStateIdle);
16143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_TRUE(out_of_credits_detector_->IsDetecting());
16243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
16343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
16443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
16543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
16643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_TRUE(out_of_credits_detector_->out_of_credits());
16743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->IsDetecting());
16843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
16943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
17043ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
17143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ConnectDisconnectLoopDetectionSkippedAfterResume) {
17243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  resume_start_time_ = base::Time::Now();
17343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  ON_CALL(*service_, resume_start_time())
17443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      .WillByDefault(ReturnRef(resume_start_time_));
17543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, Connect(_, _)).Times(0);
17643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
17743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
17843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
17943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
18043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->IsDetecting());
18143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // There should not be any pending connect requests but dispatch pending
18243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // events anyway to be sure.
18343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
18443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
18543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
18643ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
18743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ConnectDisconnectLoopDetectionSkippedAlreadyOutOfCredits) {
18843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, Connect(_, _)).Times(0);
18943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  out_of_credits_detector_->ReportOutOfCredits(true);
19043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
19143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
19243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->IsDetecting());
19343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // There should not be any pending connect requests but dispatch pending
19443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // events anyway to be sure.
19543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
19643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
19743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
19843ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
19943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ConnectDisconnectLoopDetectionSkippedExplicitDisconnect) {
20043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, Connect(_, _)).Times(0);
20143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
20243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
20343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, explicitly_disconnected()).WillOnce(Return(true));
20443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
20543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
20643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->IsDetecting());
20743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // There should not be any pending connect requests but dispatch pending
20843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // events anyway to be sure.
20943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
21043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
21143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
21243ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
21343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ConnectDisconnectLoopDetectionConnectionNotDropped) {
21443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, Connect(_, _)).Times(0);
21543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
21643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConfiguring);
21743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConfiguring, Service::kStateConnected);
21843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
21943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->IsDetecting());
22043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // There should not be any pending connect requests but dispatch pending
22143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // events anyway to be sure.
22243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
22343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
22443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
22543ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
22643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    ConnectDisconnectLoopDetectionIntermittentNetwork) {
22743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*service_, Connect(_, _)).Times(0);
22843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
22943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  out_of_credits_detector_->connect_start_time_ =
23043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      base::Time::Now() -
23143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      base::TimeDelta::FromSeconds(
23243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le          ActivePassiveOutOfCreditsDetector::
23343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le          kOutOfCreditsConnectionDropSeconds + 1);
23443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
23543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
23643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->IsDetecting());
23743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // There should not be any pending connect requests but dispatch pending
23843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // events anyway to be sure.
23943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  dispatcher_.DispatchPendingEvents();
24043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
24143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
24243ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest, StartTrafficMonitor) {
2432f6c78991e37f5fa71f2ba4d1669be73f0a6dfd4Paul Stewart  MockTrafficMonitor* traffic_monitor = new StrictMock<MockTrafficMonitor>();
24443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetTrafficMonitor(traffic_monitor);  // Passes ownership.
24543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
24643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // Traffic monitor should only start when the service is connected.
24743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Start()).Times(1);
24843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
24943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  Mock::VerifyAndClearExpectations(traffic_monitor);
25043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
25143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // Traffic monitor should not start for other state transitions.
25243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Start()).Times(0);
25343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Stop()).Times(AnyNumber());
25443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
25543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateConfiguring);
25643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConfiguring, Service::kStateFailure);
25743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateAssociating);
25843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConfiguring, Service::kStatePortal);
25943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStatePortal, Service::kStateOnline);
26043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
26143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
26243ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest, StopTrafficMonitor) {
26343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // Traffic monitor should stop when the service is disconnected.
2642f6c78991e37f5fa71f2ba4d1669be73f0a6dfd4Paul Stewart  MockTrafficMonitor* traffic_monitor = new StrictMock<MockTrafficMonitor>();
26543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetTrafficMonitor(traffic_monitor);  // Passes ownership.
26643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Start());
26743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Stop());
26843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateAssociating, Service::kStateConnected);
26943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateIdle);
27043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  Mock::VerifyAndClearExpectations(traffic_monitor);
27143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
27243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Start());
27343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Stop());
27443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateIdle, Service::kStateConnected);
27543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetMockServiceState(Service::kStateConnected, Service::kStateFailure);
27643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  Mock::VerifyAndClearExpectations(traffic_monitor);
27743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
27843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // Need an additional call to Stop() because |traffic_monitor| destructor
27943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // will call stop.
28043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*traffic_monitor, Stop());
28143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
28243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
28343ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest, OnNoNetworkRouting) {
28443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // Make sure the connection health checker starts when there is no network
28543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // routing.
28643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
2872f6c78991e37f5fa71f2ba4d1669be73f0a6dfd4Paul Stewart  MockConnectionHealthChecker* health_checker =
28843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      new MockConnectionHealthChecker(
28943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le          service_->connection(),
29043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le          modem_info_.dispatcher(),
29143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le          manager_.health_checker_remote_ips(),
29243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le          Bind(&ActivePassiveOutOfCreditsDetectorTest::
29343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le               OnConnectionHealthCheckerResult,
29443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le               Unretained(this)));
29543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  SetConnectionHealthChecker(health_checker);  // Passes ownership.
29643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*health_checker, Start());
297dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu  out_of_credits_detector_->OnNoNetworkRouting(0);
29843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
29943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  Mock::VerifyAndClearExpectations(health_checker);
30043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
30143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // Make sure connection health checker does not start again if there is a
30243ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  // health check in progress.
30343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*health_checker, health_check_in_progress())
30443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      .WillOnce(Return(true));
30543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_CALL(*health_checker, Start()).Times(0);
306dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu  out_of_credits_detector_->OnNoNetworkRouting(0);
30743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
30843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
30943ce4d428d619bda64eea6d37534f02c179a1756Thieu LeTEST_F(ActivePassiveOutOfCreditsDetectorTest,
31043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le    OnConnectionHealthCheckerResult) {
31143ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
3120d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan  EXPECT_CALL(*service_, Disconnect(_, _)).Times(0);
31343ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  out_of_credits_detector_->OnConnectionHealthCheckerResult(
31443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      ConnectionHealthChecker::kResultUnknown);
31543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
31643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  out_of_credits_detector_->OnConnectionHealthCheckerResult(
31743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      ConnectionHealthChecker::kResultConnectionFailure);
31843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
3190951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko  Mock::VerifyAndClearExpectations(service_.get());
32043ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
3210d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan  EXPECT_CALL(*service_, Disconnect(_,
3220d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan      ::testing::StrEq("out-of-credits"))).
3230d06119be3224788ba1aa65ed24bc8e46b56b949Samuel Tan          Times(1);
32443ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  out_of_credits_detector_->OnConnectionHealthCheckerResult(
32543ce4d428d619bda64eea6d37534f02c179a1756Thieu Le      ConnectionHealthChecker::kResultCongestedTxQueue);
32643ce4d428d619bda64eea6d37534f02c179a1756Thieu Le  EXPECT_TRUE(out_of_credits_detector_->out_of_credits());
32743ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}
32843ce4d428d619bda64eea6d37534f02c179a1756Thieu Le
32943ce4d428d619bda64eea6d37534f02c179a1756Thieu Le}  // namespace shill
330