1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/run_loop.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/geolocation/simple_geolocation_provider.h"
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_response_headers.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_status_code.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_fetcher_impl.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request_status.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kRequestRetryIntervalMilliSeconds = 200;
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This should be different from default to prevent SimpleGeolocationRequest
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// from modifying it.
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kTestGeolocationProviderUrl[] =
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "https://localhost/geolocation/v1/geolocate?";
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kSimpleResponseBody[] =
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "{\n"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "  \"location\": {\n"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    \"lat\": 51.0,\n"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    \"lng\": -0.1\n"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "  },\n"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "  \"accuracy\": 1200.4\n"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "}";
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // anonymous namespace
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chromeos {
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This is helper class for net::FakeURLFetcherFactory.
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class TestGeolocationAPIURLFetcherCallback {
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestGeolocationAPIURLFetcherCallback(const GURL& url,
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       const size_t require_retries,
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       const std::string& response,
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       SimpleGeolocationProvider* provider)
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : url_(url),
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        require_retries_(require_retries),
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        response_(response),
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        factory_(NULL),
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        attempts_(0),
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        provider_(provider) {}
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& url,
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLFetcherDelegate* delegate,
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const std::string& response_data,
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::HttpStatusCode response_code,
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::Status status) {
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(provider_->requests_.size(), 1U);
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SimpleGeolocationRequest* geolocation_request = provider_->requests_[0];
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::TimeDelta base_retry_interval =
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(kRequestRetryIntervalMilliSeconds);
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    geolocation_request->set_retry_sleep_on_server_error_for_testing(
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base_retry_interval);
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    geolocation_request->set_retry_sleep_on_bad_response_for_testing(
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base_retry_interval);
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++attempts_;
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (attempts_ > require_retries_) {
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      response_code = net::HTTP_OK;
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      status = net::URLRequestStatus::SUCCESS;
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      factory_->SetFakeResponse(url, response_, response_code, status);
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher(
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        url, delegate, response_, response_code, status));
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> download_headers =
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new net::HttpResponseHeaders(std::string());
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    download_headers->AddHeader("Content-Type: application/json");
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    fetcher->set_response_headers(download_headers);
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return fetcher.Pass();
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void Initialize(net::FakeURLFetcherFactory* factory) {
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    factory_ = factory;
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    factory_->SetFakeResponse(url_,
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              std::string(),
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              net::HTTP_INTERNAL_SERVER_ERROR,
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              net::URLRequestStatus::FAILED);
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t attempts() const { return attempts_; }
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const GURL url_;
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Respond with OK on required retry attempt.
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const size_t require_retries_;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string response_;
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::FakeURLFetcherFactory* factory_;
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t attempts_;
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SimpleGeolocationProvider* provider_;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestGeolocationAPIURLFetcherCallback);
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This implements fake Google MAPS Geolocation API remote endpoint.
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Response data is served to SimpleGeolocationProvider via
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// net::FakeURLFetcher.
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class GeolocationAPIFetcherFactory {
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationAPIFetcherFactory(const GURL& url,
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               const std::string& response,
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               const size_t require_retries,
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               SimpleGeolocationProvider* provider) {
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    url_callback_.reset(new TestGeolocationAPIURLFetcherCallback(
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        url, require_retries, response, provider));
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLFetcherImpl::set_factory(NULL);
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    fetcher_factory_.reset(new net::FakeURLFetcherFactory(
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NULL,
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(&TestGeolocationAPIURLFetcherCallback::CreateURLFetcher,
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   base::Unretained(url_callback_.get()))));
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    url_callback_->Initialize(fetcher_factory_.get());
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t attempts() const { return url_callback_->attempts(); }
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<TestGeolocationAPIURLFetcherCallback> url_callback_;
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<net::FakeURLFetcherFactory> fetcher_factory_;
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GeolocationAPIFetcherFactory);
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class GeolocationReceiver {
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationReceiver() : server_error_(false) {}
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void OnRequestDone(const Geoposition& position,
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     bool server_error,
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     const base::TimeDelta elapsed) {
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    position_ = position;
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    server_error_ = server_error;
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    elapsed_ = elapsed;
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_runner_->Quit();
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void WaitUntilRequestDone() {
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_runner_.reset(new base::RunLoop);
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    message_loop_runner_->Run();
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Geoposition& position() const { return position_; }
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool server_error() const { return server_error_; }
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta elapsed() const { return elapsed_; }
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Geoposition position_;
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool server_error_;
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta elapsed_;
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::RunLoop> message_loop_runner_;
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class SimpleGeolocationTest : public testing::Test {
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SimpleGeolocationTest, ResponseOK) {
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           std::string(kSimpleResponseBody),
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           0 /* require_retries */,
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           &provider);
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationReceiver receiver;
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  provider.RequestGeolocation(base::TimeDelta::FromSeconds(1),
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              base::Bind(&GeolocationReceiver::OnRequestDone,
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         base::Unretained(&receiver)));
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  receiver.WaitUntilRequestDone();
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "latitude=51.000000, longitude=-0.100000, accuracy=1200.400000, "
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "error_code=0, error_message='', status=1 (OK)",
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      receiver.position().ToString());
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(receiver.server_error());
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1U, url_factory.attempts());
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SimpleGeolocationTest, ResponseOKWithRetries) {
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           std::string(kSimpleResponseBody),
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           3 /* require_retries */,
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           &provider);
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationReceiver receiver;
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  provider.RequestGeolocation(base::TimeDelta::FromSeconds(1),
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              base::Bind(&GeolocationReceiver::OnRequestDone,
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         base::Unretained(&receiver)));
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  receiver.WaitUntilRequestDone();
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "latitude=51.000000, longitude=-0.100000, accuracy=1200.400000, "
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "error_code=0, error_message='', status=1 (OK)",
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      receiver.position().ToString());
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(receiver.server_error());
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(4U, url_factory.attempts());
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SimpleGeolocationTest, InvalidResponse) {
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           "invalid JSON string",
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           0 /* require_retries */,
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           &provider);
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GeolocationReceiver receiver;
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int timeout_seconds = 1;
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t expected_retries = static_cast<size_t>(
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      timeout_seconds * 1000 / kRequestRetryIntervalMilliSeconds);
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_GE(expected_retries, 2U);
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  provider.RequestGeolocation(base::TimeDelta::FromSeconds(timeout_seconds),
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              base::Bind(&GeolocationReceiver::OnRequestDone,
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         base::Unretained(&receiver)));
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  receiver.WaitUntilRequestDone();
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "latitude=200.000000, longitude=200.000000, accuracy=-1.000000, "
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "error_code=0, error_message='SimpleGeolocation provider at "
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "'https://localhost/' : JSONReader failed: Line: 1, column: 1, "
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "Unexpected token..', status=4 (TIMEOUT)",
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      receiver.position().ToString());
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(receiver.server_error());
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_GE(url_factory.attempts(), 2U);
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (url_factory.attempts() > expected_retries + 1) {
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(WARNING)
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << "SimpleGeolocationTest::InvalidResponse: Too many attempts ("
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << url_factory.attempts() << "), no more then " << expected_retries + 1
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << " expected.";
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (url_factory.attempts() < expected_retries - 1) {
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(WARNING)
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << "SimpleGeolocationTest::InvalidResponse: Too little attempts ("
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << url_factory.attempts() << "), greater then " << expected_retries - 1
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << " expected.";
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace chromeos
253