summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos
diff options
context:
space:
mode:
authoralemate@chromium.org <alemate@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-19 22:00:33 +0000
committeralemate@chromium.org <alemate@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-19 22:00:33 +0000
commit4e7fcd383bd764914b268ffb44d44794071408ad (patch)
treebef7277e250464156cf91b076f4beb311531f39a /chrome/browser/chromeos
parent6fc38e51d312607cf3d67d0cf17759b1d288f47f (diff)
downloadchromium_src-4e7fcd383bd764914b268ffb44d44794071408ad.zip
chromium_src-4e7fcd383bd764914b268ffb44d44794071408ad.tar.gz
chromium_src-4e7fcd383bd764914b268ffb44d44794071408ad.tar.bz2
Add SimpleGeolocationTest unit test.
Add test for SimpleGeolocation. BUG=245075 TEST=none Review URL: https://codereview.chromium.org/289313005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271499 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos')
-rw-r--r--chrome/browser/chromeos/geolocation/simple_geolocation_provider.h2
-rw-r--r--chrome/browser/chromeos/geolocation/simple_geolocation_request.cc11
-rw-r--r--chrome/browser/chromeos/geolocation/simple_geolocation_request.h14
-rw-r--r--chrome/browser/chromeos/geolocation/simple_geolocation_unittest.cc238
4 files changed, 262 insertions, 3 deletions
diff --git a/chrome/browser/chromeos/geolocation/simple_geolocation_provider.h b/chrome/browser/chromeos/geolocation/simple_geolocation_provider.h
index a3e3d04..0b0cd81 100644
--- a/chrome/browser/chromeos/geolocation/simple_geolocation_provider.h
+++ b/chrome/browser/chromeos/geolocation/simple_geolocation_provider.h
@@ -41,6 +41,8 @@ class SimpleGeolocationProvider {
static GURL DefaultGeolocationProviderURL();
private:
+ friend class TestGeolocationAPIURLFetcherCallback;
+
// Geolocation response callback. Deletes request from requests_.
void OnGeolocationResponse(
SimpleGeolocationRequest* request,
diff --git a/chrome/browser/chromeos/geolocation/simple_geolocation_request.cc b/chrome/browser/chromeos/geolocation/simple_geolocation_request.cc
index b3b8134..ca1e34a 100644
--- a/chrome/browser/chromeos/geolocation/simple_geolocation_request.cc
+++ b/chrome/browser/chromeos/geolocation/simple_geolocation_request.cc
@@ -205,6 +205,8 @@ bool ParseServerResponse(const GURL& server_url,
// Ignore result (code defaults to zero).
error_object->GetIntegerWithoutPathExpansion(kCodeString,
&(position->error_code));
+ } else {
+ position->error_message.erase();
}
if (location_object) {
@@ -272,6 +274,10 @@ SimpleGeolocationRequest::SimpleGeolocationRequest(
base::TimeDelta timeout)
: url_context_getter_(url_context_getter),
service_url_(service_url),
+ retry_sleep_on_server_error_(base::TimeDelta::FromSeconds(
+ kResolveGeolocationRetrySleepOnServerErrorSeconds)),
+ retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds(
+ kResolveGeolocationRetrySleepBadResponseSeconds)),
timeout_(timeout),
retries_(0) {
}
@@ -314,9 +320,8 @@ void SimpleGeolocationRequest::MakeRequest(const ResponseCallback& callback) {
}
void SimpleGeolocationRequest::Retry(bool server_error) {
- const base::TimeDelta delay = base::TimeDelta::FromSeconds(
- server_error ? kResolveGeolocationRetrySleepOnServerErrorSeconds
- : kResolveGeolocationRetrySleepBadResponseSeconds);
+ base::TimeDelta delay(server_error ? retry_sleep_on_server_error_
+ : retry_sleep_on_bad_response_);
request_scheduled_.Start(
FROM_HERE, delay, this, &SimpleGeolocationRequest::StartRequest);
}
diff --git a/chrome/browser/chromeos/geolocation/simple_geolocation_request.h b/chrome/browser/chromeos/geolocation/simple_geolocation_request.h
index 3cc47e3..f6baf4d 100644
--- a/chrome/browser/chromeos/geolocation/simple_geolocation_request.h
+++ b/chrome/browser/chromeos/geolocation/simple_geolocation_request.h
@@ -55,6 +55,16 @@ class SimpleGeolocationRequest : private net::URLFetcherDelegate {
// request will be silently cancelled.
void MakeRequest(const ResponseCallback& callback);
+ void set_retry_sleep_on_server_error_for_testing(
+ const base::TimeDelta value) {
+ retry_sleep_on_server_error_ = value;
+ }
+
+ void set_retry_sleep_on_bad_response_for_testing(
+ const base::TimeDelta value) {
+ retry_sleep_on_bad_response_ = value;
+ }
+
private:
// net::URLFetcherDelegate
virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
@@ -86,6 +96,10 @@ class SimpleGeolocationRequest : private net::URLFetcherDelegate {
// When request was actually started.
base::Time request_started_at_;
+ base::TimeDelta retry_sleep_on_server_error_;
+
+ base::TimeDelta retry_sleep_on_bad_response_;
+
const base::TimeDelta timeout_;
// Pending retry.
diff --git a/chrome/browser/chromeos/geolocation/simple_geolocation_unittest.cc b/chrome/browser/chromeos/geolocation/simple_geolocation_unittest.cc
new file mode 100644
index 0000000..0137c4b
--- /dev/null
+++ b/chrome/browser/chromeos/geolocation/simple_geolocation_unittest.cc
@@ -0,0 +1,238 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/run_loop.h"
+#include "chrome/browser/chromeos/geolocation/simple_geolocation_provider.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_fetcher_impl.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const int kRequestRetryIntervalMilliSeconds = 200;
+
+// This should be different from default to prevent SimpleGeolocationRequest
+// from modifying it.
+const char kTestGeolocationProviderUrl[] =
+ "https://localhost/geolocation/v1/geolocate?";
+
+const char kSimpleResponseBody[] =
+ "{\n"
+ " \"location\": {\n"
+ " \"lat\": 51.0,\n"
+ " \"lng\": -0.1\n"
+ " },\n"
+ " \"accuracy\": 1200.4\n"
+ "}";
+} // anonymous namespace
+
+namespace chromeos {
+
+// This is helper class for net::FakeURLFetcherFactory.
+class TestGeolocationAPIURLFetcherCallback {
+ public:
+ TestGeolocationAPIURLFetcherCallback(const GURL& url,
+ const size_t require_retries,
+ const std::string& response,
+ SimpleGeolocationProvider* provider)
+ : url_(url),
+ require_retries_(require_retries),
+ response_(response),
+ factory_(NULL),
+ attempts_(0),
+ provider_(provider) {}
+
+ scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
+ const GURL& url,
+ net::URLFetcherDelegate* delegate,
+ const std::string& response_data,
+ net::HttpStatusCode response_code,
+ net::URLRequestStatus::Status status) {
+ EXPECT_EQ(provider_->requests_.size(), 1U);
+
+ SimpleGeolocationRequest* geolocation_request = provider_->requests_[0];
+
+ const base::TimeDelta base_retry_interval =
+ base::TimeDelta::FromMilliseconds(kRequestRetryIntervalMilliSeconds);
+ geolocation_request->set_retry_sleep_on_server_error_for_testing(
+ base_retry_interval);
+ geolocation_request->set_retry_sleep_on_bad_response_for_testing(
+ base_retry_interval);
+
+ ++attempts_;
+ if (attempts_ > require_retries_) {
+ response_code = net::HTTP_OK;
+ status = net::URLRequestStatus::SUCCESS;
+ factory_->SetFakeResponse(url, response_, response_code, status);
+ }
+ scoped_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher(
+ url, delegate, response_, response_code, status));
+ scoped_refptr<net::HttpResponseHeaders> download_headers =
+ new net::HttpResponseHeaders(std::string());
+ download_headers->AddHeader("Content-Type: application/json");
+ fetcher->set_response_headers(download_headers);
+ return fetcher.Pass();
+ }
+
+ void Initialize(net::FakeURLFetcherFactory* factory) {
+ factory_ = factory;
+ factory_->SetFakeResponse(url_,
+ std::string(),
+ net::HTTP_INTERNAL_SERVER_ERROR,
+ net::URLRequestStatus::FAILED);
+ }
+
+ size_t attempts() const { return attempts_; }
+
+ private:
+ const GURL url_;
+ // Respond with OK on required retry attempt.
+ const size_t require_retries_;
+ std::string response_;
+ net::FakeURLFetcherFactory* factory_;
+ size_t attempts_;
+ SimpleGeolocationProvider* provider_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestGeolocationAPIURLFetcherCallback);
+};
+
+// This implements fake Google MAPS Geolocation API remote endpoint.
+// Response data is served to SimpleGeolocationProvider via
+// net::FakeURLFetcher.
+class GeolocationAPIFetcherFactory {
+ public:
+ GeolocationAPIFetcherFactory(const GURL& url,
+ const std::string& response,
+ const size_t require_retries,
+ SimpleGeolocationProvider* provider) {
+ url_callback_.reset(new TestGeolocationAPIURLFetcherCallback(
+ url, require_retries, response, provider));
+ net::URLFetcherImpl::set_factory(NULL);
+ fetcher_factory_.reset(new net::FakeURLFetcherFactory(
+ NULL,
+ base::Bind(&TestGeolocationAPIURLFetcherCallback::CreateURLFetcher,
+ base::Unretained(url_callback_.get()))));
+ url_callback_->Initialize(fetcher_factory_.get());
+ }
+
+ size_t attempts() const { return url_callback_->attempts(); }
+
+ private:
+ scoped_ptr<TestGeolocationAPIURLFetcherCallback> url_callback_;
+ scoped_ptr<net::FakeURLFetcherFactory> fetcher_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeolocationAPIFetcherFactory);
+};
+
+class GeolocationReceiver {
+ public:
+ GeolocationReceiver() : server_error_(false) {}
+
+ void OnRequestDone(const Geoposition& position,
+ bool server_error,
+ const base::TimeDelta elapsed) {
+ position_ = position;
+ server_error_ = server_error;
+ elapsed_ = elapsed;
+
+ message_loop_runner_->Quit();
+ }
+
+ void WaitUntilRequestDone() {
+ message_loop_runner_.reset(new base::RunLoop);
+ message_loop_runner_->Run();
+ }
+
+ const Geoposition& position() const { return position_; }
+ bool server_error() const { return server_error_; }
+ base::TimeDelta elapsed() const { return elapsed_; }
+
+ private:
+ Geoposition position_;
+ bool server_error_;
+ base::TimeDelta elapsed_;
+ scoped_ptr<base::RunLoop> message_loop_runner_;
+};
+
+class SimpleGeolocationTest : public testing::Test {
+ private:
+ content::TestBrowserThreadBundle thread_bundle_;
+};
+
+TEST_F(SimpleGeolocationTest, ResponseOK) {
+ SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
+
+ GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
+ std::string(kSimpleResponseBody),
+ 0 /* require_retries */,
+ &provider);
+
+ GeolocationReceiver receiver;
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(1),
+ base::Bind(&GeolocationReceiver::OnRequestDone,
+ base::Unretained(&receiver)));
+ receiver.WaitUntilRequestDone();
+
+ EXPECT_EQ(
+ "latitude=51.000000, longitude=-0.100000, accuracy=1200.400000, "
+ "error_code=0, error_message='', status=1 (OK)",
+ receiver.position().ToString());
+ EXPECT_FALSE(receiver.server_error());
+ EXPECT_EQ(1U, url_factory.attempts());
+}
+
+TEST_F(SimpleGeolocationTest, ResponseOKWithRetries) {
+ SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
+
+ GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
+ std::string(kSimpleResponseBody),
+ 3 /* require_retries */,
+ &provider);
+
+ GeolocationReceiver receiver;
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(1),
+ base::Bind(&GeolocationReceiver::OnRequestDone,
+ base::Unretained(&receiver)));
+ receiver.WaitUntilRequestDone();
+ EXPECT_EQ(
+ "latitude=51.000000, longitude=-0.100000, accuracy=1200.400000, "
+ "error_code=0, error_message='', status=1 (OK)",
+ receiver.position().ToString());
+ EXPECT_FALSE(receiver.server_error());
+ EXPECT_EQ(4U, url_factory.attempts());
+}
+
+TEST_F(SimpleGeolocationTest, InvalidResponse) {
+ SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
+
+ GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
+ "invalid JSON string",
+ 0 /* require_retries */,
+ &provider);
+
+ GeolocationReceiver receiver;
+ const int timeout_seconds = 1;
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(timeout_seconds),
+ base::Bind(&GeolocationReceiver::OnRequestDone,
+ base::Unretained(&receiver)));
+ receiver.WaitUntilRequestDone();
+
+ EXPECT_EQ(
+ "latitude=200.000000, longitude=200.000000, accuracy=-1.000000, "
+ "error_code=0, error_message='SimpleGeolocation provider at "
+ "'https://localhost/' : JSONReader failed: Line: 1, column: 1, "
+ "Unexpected token..', status=4 (TIMEOUT)",
+ receiver.position().ToString());
+ EXPECT_TRUE(receiver.server_error());
+ size_t expected_retries = static_cast<size_t>(
+ timeout_seconds * 1000 / kRequestRetryIntervalMilliSeconds);
+ EXPECT_LE(url_factory.attempts(), expected_retries + 1);
+ EXPECT_GE(url_factory.attempts(), expected_retries - 1);
+}
+
+} // namespace chromeos