Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: chrome/browser/chromeos/geolocation/simple_geolocation_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698