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

Unified Diff: sync/notifier/gcm_network_channel_unittest.cc

Issue 140513002: Client-to-server messages in GCMNetworkChannel (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Two more tests Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: sync/notifier/gcm_network_channel_unittest.cc
diff --git a/sync/notifier/gcm_network_channel_unittest.cc b/sync/notifier/gcm_network_channel_unittest.cc
index 8656385dbcc61a148622d819b7dbbfab4f1e0f17..272477e9c7142bf285c280c77ef51f5d9c58fb63 100644
--- a/sync/notifier/gcm_network_channel_unittest.cc
+++ b/sync/notifier/gcm_network_channel_unittest.cc
@@ -2,28 +2,66 @@
// 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 "google_apis/gaia/google_service_auth_error.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_request_test_util.h"
#include "sync/notifier/gcm_network_channel.h"
-
-#include "base/compiler_specific.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
namespace {
+class TestGCMNetworkChannelDelegate : public GCMNetworkChannelDelegate {
+ public:
+ virtual void RequestToken(RequestTokenCallback callback) OVERRIDE {
+ request_token_callback = callback;
+ }
+
+ virtual void InvalidateToken(const std::string& token) OVERRIDE {
+ invalidated_token = token;
+ }
+
+ virtual void Register(RegisterCallback callback) OVERRIDE {
+ register_callback = callback;
+ }
+
+ RequestTokenCallback request_token_callback;
+ std::string invalidated_token;
+ RegisterCallback register_callback;
+};
+
class GCMNetworkChannelTest
tim (not reviewing) 2014/01/17 19:33:42 nice tests!
: public ::testing::Test,
public SyncNetworkChannel::Observer {
protected:
GCMNetworkChannelTest()
- : gcm_network_channel_() {
- gcm_network_channel_.AddObserver(this);
- gcm_network_channel_.SetMessageReceiver(
+ : url_fetchers_created_count_(0) {
tim (not reviewing) 2014/01/17 19:33:42 nit - init |delegate_| to NULL.
pavely 2014/01/17 22:52:26 Done.
+ }
+
+ virtual ~GCMNetworkChannelTest() {
+ }
+
+ virtual void SetUp() {
+ request_context_getter_ = new net::TestURLRequestContextGetter(
+ base::MessageLoopProxy::current());
+ // Ownership of delegate goes to GCNMentworkChannel but test needs pointer
+ // to it.
+ delegate_ = new TestGCMNetworkChannelDelegate();
+ scoped_ptr<GCMNetworkChannelDelegate> delegate(delegate_);
+ gcm_network_channel_.reset(new GCMNetworkChannel(request_context_getter_,
+ delegate.Pass()));
+ gcm_network_channel_->AddObserver(this);
+ gcm_network_channel_->SetMessageReceiver(
invalidation::NewPermanentCallback(
this, &GCMNetworkChannelTest::OnIncomingMessage));
+ url_fetcher_factory_.reset(new net::FakeURLFetcherFactory(NULL,
+ base::Bind(&GCMNetworkChannelTest::CreateURLFetcher,
+ base::Unretained(this))));
}
- virtual ~GCMNetworkChannelTest() {
- gcm_network_channel_.RemoveObserver(this);
+ virtual void TearDown() {
+ gcm_network_channel_->RemoveObserver(this);
}
virtual void OnNetworkChannelStateChanged(
@@ -33,8 +71,179 @@ class GCMNetworkChannelTest
void OnIncomingMessage(std::string incoming_message) {
}
- GCMNetworkChannel gcm_network_channel_;
+ GCMNetworkChannel* network_channel() {
+ return gcm_network_channel_.get();
+ }
+
+ TestGCMNetworkChannelDelegate* delegate() {
+ return delegate_;
+ }
+
+ int url_fetchers_created_count() {
+ return url_fetchers_created_count_;
+ }
+
+ net::FakeURLFetcherFactory* url_fetcher_factory() {
+ return url_fetcher_factory_.get();
+ }
+
+ scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
+ const GURL& url,
+ net::URLFetcherDelegate* delegate,
+ const std::string& response_data,
+ net::HttpStatusCode response_code,
+ net::URLRequestStatus::Status status) {
+ url_fetchers_created_count_++;
+ return scoped_ptr<net::FakeURLFetcher>(new net::FakeURLFetcher(
+ url, delegate, response_data, response_code, status));
+ }
+
+ private:
+ base::MessageLoop message_loop_;
+ TestGCMNetworkChannelDelegate* delegate_;
+ scoped_ptr<GCMNetworkChannel> gcm_network_channel_;
+ scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
+ scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_;
+ int url_fetchers_created_count_;
};
+TEST_F(GCMNetworkChannelTest, HappyCase) {
+ GURL url("http://invalid.url.com");
+ url_fetcher_factory()->SetFakeResponse(url, "", net::HTTP_OK,
tim (not reviewing) 2014/01/17 19:33:42 nit - prefer std::string to "".
pavely 2014/01/17 22:52:26 Done.
+ net::URLRequestStatus::SUCCESS);
+
+ // After construction GCMNetworkChannel should have called Register.
+ EXPECT_FALSE(delegate()->register_callback.is_null());
+ // Return valid registration id.
+ delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS);
+
+ network_channel()->SendMessage("abra.cadabra");
+ // SendMessage should have triggered RequestToken. No HTTP request should be
+ // started yet.
+ EXPECT_FALSE(delegate()->request_token_callback.is_null());
+ EXPECT_EQ(url_fetchers_created_count(), 0);
+ // Return valid access token. This should trigger HTTP request.
+ delegate()->request_token_callback.Run(
+ GoogleServiceAuthError::AuthErrorNone(), "access.token");
+ {
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ }
+ EXPECT_EQ(url_fetchers_created_count(), 1);
+
+ // Return another access token. Message should be cleared by now and shouldn't
+ // be sent.
+ delegate()->request_token_callback.Run(
+ GoogleServiceAuthError::AuthErrorNone(), "access.token2");
+ {
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ }
+ EXPECT_EQ(url_fetchers_created_count(), 1);
+}
+
+TEST_F(GCMNetworkChannelTest, FailedRegister) {
+ // After construction GCMNetworkChannel should have called Register.
+ EXPECT_FALSE(delegate()->register_callback.is_null());
+ // Return error from Register call.
+ delegate()->register_callback.Run("", gcm::GCMClient::SERVER_ERROR);
+
+ network_channel()->SendMessage("abra.cadabra");
+ // SendMessage shouldn't trigger RequestToken.
+ EXPECT_TRUE(delegate()->request_token_callback.is_null());
+ EXPECT_EQ(url_fetchers_created_count(), 0);
+}
+
+TEST_F(GCMNetworkChannelTest, RegisterFinishesAfterSendMessage) {
+ GURL url("http://invalid.url.com");
+ url_fetcher_factory()->SetFakeResponse(url, "", net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+
+ // After construction GCMNetworkChannel should have called Register.
+ EXPECT_FALSE(delegate()->register_callback.is_null());
+
+ network_channel()->SendMessage("abra.cadabra");
+ // SendMessage shouldn't trigger RequestToken.
+ EXPECT_TRUE(delegate()->request_token_callback.is_null());
+ EXPECT_EQ(url_fetchers_created_count(), 0);
+
+ // Return valid registration id.
+ delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS);
+
+ EXPECT_FALSE(delegate()->request_token_callback.is_null());
+ EXPECT_EQ(url_fetchers_created_count(), 0);
+ // Return valid access token. This should trigger HTTP request.
+ delegate()->request_token_callback.Run(
+ GoogleServiceAuthError::AuthErrorNone(), "access.token");
+ {
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ }
+ EXPECT_EQ(url_fetchers_created_count(), 1);
+}
+
+TEST_F(GCMNetworkChannelTest, RequestTokenFailure) {
+ // After construction GCMNetworkChannel should have called Register.
+ EXPECT_FALSE(delegate()->register_callback.is_null());
+ // Return valid registration id.
+ delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS);
+
+ network_channel()->SendMessage("abra.cadabra");
+ // SendMessage should have triggered RequestToken. No HTTP request should be
+ // started yet.
+ EXPECT_FALSE(delegate()->request_token_callback.is_null());
+ EXPECT_EQ(url_fetchers_created_count(), 0);
+ // RequestToken returns failure.
+ delegate()->request_token_callback.Run(
+ GoogleServiceAuthError::FromConnectionError(1), "");
+
+ // Should be no HTTP requests.
+ EXPECT_EQ(url_fetchers_created_count(), 0);
+}
+
+TEST_F(GCMNetworkChannelTest, AuthErrorFromTango) {
tim (not reviewing) 2014/01/17 19:33:42 nit - avoid the word 'Tango' in chromium.
pavely 2014/01/17 22:52:26 Done.
+ // Setup fake response to return AUTH_ERROR.
+ GURL url("http://invalid.url.com");
+ url_fetcher_factory()->SetFakeResponse(url, "", net::HTTP_UNAUTHORIZED,
+ net::URLRequestStatus::SUCCESS);
+
+ // After construction GCMNetworkChannel should have called Register.
+ EXPECT_FALSE(delegate()->register_callback.is_null());
+ // Return valid registration id.
+ delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS);
+
+ network_channel()->SendMessage("abra.cadabra");
+ // SendMessage should have triggered RequestToken. No HTTP request should be
+ // started yet.
+ EXPECT_FALSE(delegate()->request_token_callback.is_null());
+ EXPECT_EQ(url_fetchers_created_count(), 0);
+ // Return valid access token. This should trigger HTTP request.
+ delegate()->request_token_callback.Run(
+ GoogleServiceAuthError::AuthErrorNone(), "access.token");
+ {
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ }
+ EXPECT_EQ(url_fetchers_created_count(), 1);
+ EXPECT_EQ(delegate()->invalidated_token, "access.token");
+}
+
+// Following two tests are to check for memory leaks/crashes when Register and
+// RequestToken don't complete by the teardown.
+TEST_F(GCMNetworkChannelTest, RegisterNeverCompletes) {
+ network_channel()->SendMessage("abra.cadabra");
+ // Register should be called by now. Let's not complete and see what happens.
+ EXPECT_FALSE(delegate()->register_callback.is_null());
+}
+
+TEST_F(GCMNetworkChannelTest, RequestTokenNeverCompletes) {
+ network_channel()->SendMessage("abra.cadabra");
+ // Return valid registration id.
+ delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS);
+ // RequestToken should be called by now. Let's not complete and see what
+ // happens.
+ EXPECT_FALSE(delegate()->request_token_callback.is_null());
+}
+
} // namespace
} // namespace syncer

Powered by Google App Engine
This is Rietveld 408576698