1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 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//
16e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
17e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include "shill/portal_detector.h"
18e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
19cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan#include <memory>
20e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include <string>
21e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
223e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood#include <base/bind.h>
23e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include <gmock/gmock.h>
24e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include <gtest/gtest.h>
25e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
263d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein#include "shill/connectivity_trial.h"
27e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include "shill/mock_connection.h"
283d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein#include "shill/mock_connectivity_trial.h"
29e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include "shill/mock_control.h"
30e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include "shill/mock_device_info.h"
31e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart#include "shill/mock_event_dispatcher.h"
328d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_time.h"
33e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
343e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Bind;
353e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Callback;
363e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Unretained;
37e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing std::string;
38e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing std::vector;
39e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::_;
40e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::AtLeast;
41e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::DoAll;
42e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::InSequence;
433d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silbersteinusing testing::Mock;
44e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::NiceMock;
45e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::Return;
46e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::ReturnRef;
47e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::SetArgumentPointee;
48e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::StrictMock;
49e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartusing testing::Test;
50e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
51e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartnamespace shill {
52e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
53e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartnamespace {
54e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartconst char kBadURL[] = "badurl";
55e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartconst char kInterfaceName[] = "int0";
56e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartconst char kURL[] = "http://www.chromium.org";
57e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartconst char kDNSServer0[] = "8.8.8.8";
58e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartconst char kDNSServer1[] = "8.8.4.4";
593b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewartconst char* kDNSServers[] = { kDNSServer0, kDNSServer1 };
608a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko}  // namespace
61e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
62e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartMATCHER_P(IsResult, result, "") {
633d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  return (result.trial_result.phase == arg.trial_result.phase &&
643d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          result.trial_result.status == arg.trial_result.status &&
65e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart          result.final == arg.final);
66e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
67e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
683d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
69e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewartclass PortalDetectorTest : public Test {
70e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart public:
71e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  PortalDetectorTest()
72cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan      : device_info_(
73cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan            new NiceMock<MockDeviceInfo>(&control_, nullptr, nullptr, nullptr)),
74e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart        connection_(new StrictMock<MockConnection>(device_info_.get())),
75cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        portal_detector_(
76cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan            new PortalDetector(connection_.get(), &dispatcher_,
77cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan                               callback_target_.result_callback())),
78cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        connectivity_trial_(new StrictMock<MockConnectivityTrial>(
79cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan            connection_, PortalDetector::kRequestTimeoutSeconds)),
80e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart        interface_name_(kInterfaceName),
813d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein        dns_servers_(kDNSServers, kDNSServers + 2) {
82e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    current_time_.tv_sec = current_time_.tv_usec = 0;
83e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
84e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
85e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  virtual void SetUp() {
86f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu    EXPECT_CALL(*connection_.get(), IsIPv6())
87f3a8f9064976d12c4f8ed3c6a5cc9ea4655c686dPeter Qiu        .WillRepeatedly(Return(false));
88e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    EXPECT_CALL(*connection_.get(), interface_name())
89e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart        .WillRepeatedly(ReturnRef(interface_name_));
90e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    portal_detector_->time_ = &time_;
91e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    EXPECT_CALL(time_, GetTimeMonotonic(_))
92e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart        .WillRepeatedly(Invoke(this, &PortalDetectorTest::GetTimeMonotonic));
93e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    EXPECT_CALL(*connection_.get(), dns_servers())
94e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart        .WillRepeatedly(ReturnRef(dns_servers_));
953d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    portal_detector_->connectivity_trial_
963d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein        .reset(connectivity_trial_);  // Passes ownership
973d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    EXPECT_TRUE(portal_detector()->connectivity_trial_.get());
98e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
99e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
100e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  virtual void TearDown() {
1013d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    if (portal_detector()->connectivity_trial_.get()) {
1023d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      EXPECT_CALL(*connectivity_trial(), Stop());
103e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
104e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart      // Delete the portal detector while expectations still exist.
105e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart      portal_detector_.reset();
106e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    }
107e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
108e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
109e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart protected:
11085e050b4923878a57aec1415314d2b39ff233e00Thieu Le  static const int kNumAttempts;
11185e050b4923878a57aec1415314d2b39ff233e00Thieu Le
112e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  class CallbackTarget {
113e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart   public:
114e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    CallbackTarget()
1153e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood        : result_callback_(Bind(&CallbackTarget::ResultCallback,
1163e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood                                Unretained(this))) {
117e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    }
118e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
1193b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    MOCK_METHOD1(ResultCallback, void(const PortalDetector::Result& result));
1203b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    Callback<void(const PortalDetector::Result&)>& result_callback() {
1213e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood      return result_callback_;
122e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    }
123e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
124e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart   private:
1253b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    Callback<void(const PortalDetector::Result&)> result_callback_;
126e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  };
127e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
1283b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  bool StartPortalRequest(const string& url_string) {
129e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    bool ret = portal_detector_->Start(url_string);
130e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    return ret;
131e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
132e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
1333b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  PortalDetector* portal_detector() { return portal_detector_.get(); }
1343b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockConnectivityTrial* connectivity_trial() { return connectivity_trial_; }
1353b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockEventDispatcher& dispatcher() { return dispatcher_; }
1363b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  CallbackTarget& callback_target() { return callback_target_; }
137e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
138e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  void ExpectReset() {
139e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    EXPECT_FALSE(portal_detector_->attempt_count_);
1406e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    EXPECT_FALSE(portal_detector_->failures_in_content_phase_);
1413e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood    EXPECT_TRUE(callback_target_.result_callback().
1423e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood                Equals(portal_detector_->portal_result_callback_));
143e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
144e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
1453b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void ExpectAttemptRetry(const PortalDetector::Result& result) {
146e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    EXPECT_CALL(callback_target(),
147e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                ResultCallback(IsResult(result)));
1483d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    EXPECT_CALL(*connectivity_trial(),
1493d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                Retry(PortalDetector::kMinTimeBetweenAttemptsSeconds * 1000));
150e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
151e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
152e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  void AdvanceTime(int milliseconds) {
153e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    struct timeval tv = { milliseconds / 1000, (milliseconds % 1000) * 1000 };
154e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    timeradd(&current_time_, &tv, &current_time_);
155e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
156e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
157e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  void StartAttempt() {
1583d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    EXPECT_CALL(*connectivity_trial(), Start(_, _)).WillOnce(Return(true));
159e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
1603d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    EXPECT_TRUE(StartPortalRequest(kURL));
161e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
162e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
163e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart private:
1643b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  int GetTimeMonotonic(struct timeval* tv) {
165e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    *tv = current_time_;
166e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    return 0;
167e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
168e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
169e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  StrictMock<MockEventDispatcher> dispatcher_;
170e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  MockControl control_;
171cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  std::unique_ptr<MockDeviceInfo> device_info_;
172e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  scoped_refptr<MockConnection> connection_;
173e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  CallbackTarget callback_target_;
174cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  std::unique_ptr<PortalDetector> portal_detector_;
1753d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  MockConnectivityTrial* connectivity_trial_;
176e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  StrictMock<MockTime> time_;
177e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  struct timeval current_time_;
178e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  const string interface_name_;
179e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  vector<string> dns_servers_;
180e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart};
181e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
18285e050b4923878a57aec1415314d2b39ff233e00Thieu Le// static
18385e050b4923878a57aec1415314d2b39ff233e00Thieu Leconst int PortalDetectorTest::kNumAttempts = 0;
18485e050b4923878a57aec1415314d2b39ff233e00Thieu Le
185e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, Constructor) {
186e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  ExpectReset();
187e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
188e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
189e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, InvalidURL) {
1903d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Start(_, _)).WillOnce(Return(false));
1913d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_FALSE(portal_detector()->Start(kBadURL));
192e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  ExpectReset();
193e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
194e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
195e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, StartAttemptFailed) {
1963d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Start(kURL, 0)).WillOnce(Return(true));
197e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  EXPECT_TRUE(StartPortalRequest(kURL));
198e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
199e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  // Expect that the request will be started -- return failure.
2003d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ConnectivityTrial::Result errorResult =
2013d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      ConnectivityTrial::GetPortalResultForRequestResult(
2023d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          HTTPRequest::kResultConnectionFailure);
2033d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
204e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  // Expect a non-final failure to be relayed to the caller.
2053d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ExpectAttemptRetry(
2063d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      PortalDetector::Result(
2073d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          ConnectivityTrial::Result(
2083d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kPhaseConnection,
2093d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kStatusFailure),
2103d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          kNumAttempts,
2113d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          false));
2123d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
2133d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->CompleteAttempt(errorResult);
214e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
215e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
2163d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca SilbersteinTEST_F(PortalDetectorTest, IsInProgress) {
2173d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_FALSE(portal_detector()->IsInProgress());
2183d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // Starting the attempt immediately should result with IsInProgress returning
2193d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // true
2203d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Start(_, _))
2213d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      .Times(2).WillRepeatedly(Return(true));
2223d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(StartPortalRequest(kURL));
2233d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), IsActive()).WillOnce(Return(true));
2243d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(portal_detector()->IsInProgress());
2253d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
2263d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // Starting the attempt with a delay should result with IsInProgress returning
2273d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // false
2283d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), IsActive()).WillOnce(Return(false));
2293d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->StartAfterDelay(kURL, 2);
2303d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_FALSE(portal_detector()->IsInProgress());
2313d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
2323d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // Advance time, IsInProgress should now be true
2333d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), IsActive()).WillOnce(Return(true));
2343d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  AdvanceTime(2000);
2353d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(portal_detector()->IsInProgress());
236e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
2373d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // Times beyond the start time before the attempt finishes should also return
2383d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // true
2393d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), IsActive()).WillOnce(Return(true));
2403d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  AdvanceTime(1000);
2413d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(portal_detector()->IsInProgress());
2423d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein}
2433d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
2443d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca SilbersteinTEST_F(PortalDetectorTest, AdjustStartDelayImmediate) {
2453d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Start(kURL, 0)).WillOnce(Return(true));
2463d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(StartPortalRequest(kURL));
247c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart
248c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  // A second attempt should be delayed by kMinTimeBetweenAttemptsSeconds.
2493d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(portal_detector()->AdjustStartDelay(0)
2503d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              == PortalDetector::kMinTimeBetweenAttemptsSeconds);
251c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart}
252c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart
2533d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca SilbersteinTEST_F(PortalDetectorTest, AdjustStartDelayAfterDelay) {
254c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  const int kDelaySeconds = 123;
255c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  // The first attempt should be delayed by kDelaySeconds.
2563d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Start(kURL, kDelaySeconds * 1000))
2573d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      .WillOnce(Return(true));
2583d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
2593d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->StartAfterDelay(kURL, kDelaySeconds);
260c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart
261c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  AdvanceTime(kDelaySeconds * 1000);
262e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
263e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  // A second attempt should be delayed by kMinTimeBetweenAttemptsSeconds.
2643d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(portal_detector()->AdjustStartDelay(0)
2653d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              == PortalDetector::kMinTimeBetweenAttemptsSeconds);
266e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
267e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
268e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, AttemptCount) {
269c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  EXPECT_FALSE(portal_detector()->IsInProgress());
270e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  // Expect the PortalDetector to immediately post a task for the each attempt.
2713d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Start(_, _))
2723d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      .Times(2).WillRepeatedly(Return(true));
2733d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), IsActive()).WillOnce(Return(false));
2743d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->StartAfterDelay(kURL, 2);
275e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
276c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  EXPECT_FALSE(portal_detector()->IsInProgress());
277c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart
278e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  // Expect that the request will be started -- return failure.
2793d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Retry(0))
2803d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      .Times(PortalDetector::kMaxRequestAttempts - 1);
281e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
282e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  {
283e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    InSequence s;
284e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
285e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    // Expect non-final failures for all attempts but the last.
286e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    EXPECT_CALL(callback_target(),
287e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                ResultCallback(IsResult(
288e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                    PortalDetector::Result(
2893d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                        ConnectivityTrial::Result(
2903d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kPhaseDNS,
2913d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kStatusFailure),
29285e050b4923878a57aec1415314d2b39ff233e00Thieu Le                        kNumAttempts,
293e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                        false))))
294e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart        .Times(PortalDetector::kMaxRequestAttempts - 1);
295e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
296e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    // Expect a single final failure.
297e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    EXPECT_CALL(callback_target(),
298e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                ResultCallback(IsResult(
299e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                    PortalDetector::Result(
3003d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                        ConnectivityTrial::Result(
3013d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kPhaseDNS,
3023d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kStatusFailure),
30385e050b4923878a57aec1415314d2b39ff233e00Thieu Le                        kNumAttempts,
304e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                        true))))
305e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart        .Times(1);
306e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
307e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
3083d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // Expect the PortalDetector to stop the ConnectivityTrial after
3093d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  // the final attempt.
3103d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Stop()).Times(1);
311e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
3123d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), IsActive()).WillOnce(Return(true));
3133d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->Start(kURL);
314e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  for (int i = 0; i < PortalDetector::kMaxRequestAttempts; i++) {
315c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart    EXPECT_TRUE(portal_detector()->IsInProgress());
316e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart    AdvanceTime(PortalDetector::kMinTimeBetweenAttemptsSeconds * 1000);
3173d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    ConnectivityTrial::Result r =
3183d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein        ConnectivityTrial::GetPortalResultForRequestResult(
3193d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein            HTTPRequest::kResultDNSFailure);
3203d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    portal_detector()->CompleteAttempt(r);
321e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  }
322e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
323c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart  EXPECT_FALSE(portal_detector()->IsInProgress());
324e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  ExpectReset();
325e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
326e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
3276e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley// Exactly like AttemptCount, except that the termination conditions are
3286e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley// different because we're triggering a different sort of error.
3296e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher WileyTEST_F(PortalDetectorTest, ReadBadHeadersRetry) {
3306e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  EXPECT_FALSE(portal_detector()->IsInProgress());
3316e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  // Expect the PortalDetector to immediately post a task for the each attempt.
3323d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Start(_, 0))
3333d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      .Times(2).WillRepeatedly(Return(true));
3346e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley
3353d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_TRUE(StartPortalRequest(kURL));
3366e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley
3376e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  // Expect that the request will be started -- return failure.
3383d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Retry(0))
3393d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      .Times(PortalDetector::kMaxFailuresInContentPhase - 1);
3406e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  {
3416e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    InSequence s;
3426e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley
3436e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    // Expect non-final failures for all attempts but the last.
3446e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    EXPECT_CALL(callback_target(),
3456e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                ResultCallback(IsResult(
3466e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                    PortalDetector::Result(
3473d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                        ConnectivityTrial::Result(
3483d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kPhaseContent,
3493d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kStatusFailure),
3506e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                        kNumAttempts,
3516e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                        false))))
3526e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley        .Times(PortalDetector::kMaxFailuresInContentPhase - 1);
3536e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley
3546e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    // Expect a single final failure.
3556e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    EXPECT_CALL(callback_target(),
3566e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                ResultCallback(IsResult(
3576e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                    PortalDetector::Result(
3583d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                        ConnectivityTrial::Result(
3593d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kPhaseContent,
3603d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                            ConnectivityTrial::kStatusFailure),
3616e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                        kNumAttempts,
3626e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley                        true))))
3636e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley        .Times(1);
3646e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  }
3656e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley
3666e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  // Expect the PortalDetector to stop the current request each time, plus
3676e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  // an extra time in PortalDetector::Stop().
3683d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Stop()).Times(1);
3696e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley
3703d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), IsActive()).WillOnce(Return(true));
3713d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->Start(kURL);
3726e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  for (int i = 0; i < PortalDetector::kMaxFailuresInContentPhase; i++) {
3736e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    EXPECT_TRUE(portal_detector()->IsInProgress());
3746e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley    AdvanceTime(PortalDetector::kMinTimeBetweenAttemptsSeconds * 1000);
3753d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    ConnectivityTrial::Result r =
3763d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein        ConnectivityTrial::Result(ConnectivityTrial::kPhaseContent,
3773d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                                  ConnectivityTrial::kStatusFailure);
3783d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein    portal_detector()->CompleteAttempt(r);
3796e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley  }
3803d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
3813d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_FALSE(portal_detector()->IsInProgress());
3826e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley}
3836e1dc0ff12ceb0fea899ceb5c0f4798e35d86b71Christopher Wiley
384e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, ReadBadHeader) {
385e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  StartAttempt();
386e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
3873d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ExpectAttemptRetry(
3883d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      PortalDetector::Result(
3893d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          ConnectivityTrial::Result(
3903d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kPhaseContent,
3913d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kStatusFailure),
3923d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          kNumAttempts,
3933d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          false));
3943d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
3953d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ConnectivityTrial::Result r =
3963d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      ConnectivityTrial::Result(ConnectivityTrial::kPhaseContent,
3973d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                                ConnectivityTrial::kStatusFailure);
3983d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->CompleteAttempt(r);
399e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
400e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
401e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, RequestTimeout) {
402e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  StartAttempt();
4033d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ExpectAttemptRetry(
4043d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      PortalDetector::Result(
4053d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          ConnectivityTrial::Result(
4063d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kPhaseUnknown,
4073d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kStatusTimeout),
4083d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          kNumAttempts,
4093d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          false));
4103d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
4113d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ConnectivityTrial::Result r =
4123d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      ConnectivityTrial::Result(ConnectivityTrial::kPhaseUnknown,
4133d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                                ConnectivityTrial::kStatusTimeout);
4143d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->CompleteAttempt(r);
415e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
416e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
417e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, ReadPartialHeaderTimeout) {
418e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  StartAttempt();
419e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
4203d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ExpectAttemptRetry(
4213d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      PortalDetector::Result(
4223d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          ConnectivityTrial::Result(
4233d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kPhaseContent,
4243d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein              ConnectivityTrial::kStatusTimeout),
4253d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          kNumAttempts,
4263d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein          false));
4273d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein
4283d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ConnectivityTrial::Result r =
4293d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      ConnectivityTrial::Result(ConnectivityTrial::kPhaseContent,
4303d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                                ConnectivityTrial::kStatusTimeout);
4313d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->CompleteAttempt(r);
432e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
433e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
434e692740c0623d4cb5d92d36214982ee45a03a5dbPaul StewartTEST_F(PortalDetectorTest, ReadCompleteHeader) {
435e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  StartAttempt();
436e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
437e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart  EXPECT_CALL(callback_target(),
438e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart              ResultCallback(IsResult(
439e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                  PortalDetector::Result(
4403d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                      ConnectivityTrial::Result(
4413d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                          ConnectivityTrial::kPhaseContent,
4423d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                          ConnectivityTrial::kStatusSuccess),
44385e050b4923878a57aec1415314d2b39ff233e00Thieu Le                      kNumAttempts,
444e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart                      true))));
445e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart
4463d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Stop()).Times(1);
4473d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ConnectivityTrial::Result r =
4483d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      ConnectivityTrial::Result(ConnectivityTrial::kPhaseContent,
4493d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                                ConnectivityTrial::kStatusSuccess);
4503d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->CompleteAttempt(r);
451e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}
452c681fa0742cabc686ccabaf0fdf6ce12dd7046b2Paul Stewart
45360519993f780c5a0415a56008b5ac81a66ea16c7Paul StewartTEST_F(PortalDetectorTest, ReadMatchingHeader) {
45460519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart  StartAttempt();
45560519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart
45660519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart  EXPECT_CALL(callback_target(),
45760519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart              ResultCallback(IsResult(
45860519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart                  PortalDetector::Result(
4593d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                      ConnectivityTrial::Result(
4603d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                          ConnectivityTrial::kPhaseContent,
4613d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                          ConnectivityTrial::kStatusSuccess),
46260519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart                      kNumAttempts,
46360519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart                      true))));
4643d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  EXPECT_CALL(*connectivity_trial(), Stop()).Times(1);
4653d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  ConnectivityTrial::Result r =
4663d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein      ConnectivityTrial::Result(ConnectivityTrial::kPhaseContent,
4673d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein                                ConnectivityTrial::kStatusSuccess);
4683d49ea435a59436f762c2cc5e750ff27ece0d3c5Rebecca Silberstein  portal_detector()->CompleteAttempt(r);
46960519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart}
47060519993f780c5a0415a56008b5ac81a66ea16c7Paul Stewart
471e692740c0623d4cb5d92d36214982ee45a03a5dbPaul Stewart}  // namespace shill
472