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

Unified Diff: components/gcm_driver/gcm_client_impl_unittest.cc

Issue 2578583002: Provide a mechanism for the GCM driver to send message receipts to GCM.
Patch Set: Fix issue with rebase Created 3 years, 10 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
« no previous file with comments | « components/gcm_driver/gcm_client_impl.cc ('k') | components/gcm_driver/gcm_driver.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/gcm_driver/gcm_client_impl_unittest.cc
diff --git a/components/gcm_driver/gcm_client_impl_unittest.cc b/components/gcm_driver/gcm_client_impl_unittest.cc
index 827a6056d468ff5ed8c453cc1b578ccfa889cf69..7802fe9ffa3f8d3f8ea7578f4a0bfa3c9566b477 100644
--- a/components/gcm_driver/gcm_client_impl_unittest.cc
+++ b/components/gcm_driver/gcm_client_impl_unittest.cc
@@ -15,8 +15,13 @@
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_param_associator.h"
+#include "base/metrics/field_trial_params.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/histogram_tester.h"
+#include "base/test/mock_entropy_provider.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/clock.h"
@@ -268,6 +273,7 @@ class GCMClientImplTest : public testing::Test,
void SetUp() override;
void SetUpUrlFetcherFactory();
+ void InitializeFieldTrials(int messages_to_send);
void BuildGCMClient(base::TimeDelta clock_step);
void InitializeGCMClient();
@@ -309,8 +315,10 @@ class GCMClientImplTest : public testing::Test,
void OnSendFinished(const std::string& app_id,
const std::string& message_id,
GCMClient::Result result) override {}
- void OnMessageReceived(const std::string& registration_id,
- const IncomingMessage& message) override;
+ void OnMessageReceived(
+ const std::string& registration_id,
+ const IncomingMessage& message,
+ const MessageReceiptCallback& optional_receipt_callback) override;
void OnMessagesDeleted(const std::string& app_id) override;
void OnMessageSendError(
const std::string& app_id,
@@ -397,6 +405,10 @@ class GCMClientImplTest : public testing::Test,
return task_runner_.get();
}
+ void set_successful_receipt_generation(bool successful_receipt_generation) {
+ successful_receipt_generation_ = successful_receipt_generation;
+ }
+
private:
// Must be declared first so that it is destroyed last. Injected to
// GCM client.
@@ -412,6 +424,9 @@ class GCMClientImplTest : public testing::Test,
GCMClient::SendErrorDetails last_error_details_;
base::Time last_token_fetch_time_;
std::vector<AccountMapping> last_account_mappings_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+ std::unique_ptr<base::FieldTrialList> field_trial_list_;
+ bool successful_receipt_generation_ = false;
std::unique_ptr<GCMClientImpl> gcm_client_;
@@ -427,11 +442,12 @@ class GCMClientImplTest : public testing::Test,
GCMClientImplTest::GCMClientImplTest()
: last_event_(NONE),
last_result_(GCMClient::UNKNOWN_ERROR),
+ field_trial_list_(base::MakeUnique<base::FieldTrialList>(
+ base::MakeUnique<base::MockEntropyProvider>())),
task_runner_(new base::TestMockTimeTaskRunner),
task_runner_handle_(task_runner_),
url_request_context_getter_(
- new net::TestURLRequestContextGetter(task_runner_)) {
-}
+ new net::TestURLRequestContextGetter(task_runner_)) {}
GCMClientImplTest::~GCMClientImplTest() {}
@@ -451,6 +467,34 @@ void GCMClientImplTest::SetUpUrlFetcherFactory() {
url_fetcher_factory_.set_remove_fetcher_on_delete(true);
}
+void GCMClientImplTest::InitializeFieldTrials(int messages_to_send) {
+ const std::string kTrialName = "TestGCMMessageReceipts";
+ const std::string kGroupName = "UnusedName";
+ // kFeatureName and kParam name are also defined in gcm_client_impl.cc.
+ const std::string kFeatureName = "GCMMessageReceiptsFeature";
+ const std::string kParamName = "message_receipts_to_send";
+
+ // Cleanup any old field trial state and reinitialize.
+ field_trial_list_.reset();
+ field_trial_list_ = base::MakeUnique<base::FieldTrialList>(
+ base::MakeUnique<base::MockEntropyProvider>());
+ base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
+
+ // Create a field trial with message receipts set to messages_to_send.
+ scoped_refptr<base::FieldTrial> trial =
+ base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
+ std::map<std::string, std::string> trial_params;
+ trial_params[kParamName] = base::IntToString(messages_to_send);
+ base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
+ kTrialName, kGroupName, trial_params);
+
+ // Create a FeatureList and add the new trial to the list.
+ std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
+ feature_list->RegisterFieldTrialOverride(
+ kFeatureName, base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
+ scoped_feature_list_.InitWithFeatureList(std::move(feature_list));
+}
+
void GCMClientImplTest::PumpLoopUntilIdle() {
task_runner_->RunUntilIdle();
}
@@ -616,11 +660,17 @@ void GCMClientImplTest::OnGCMReady(
last_token_fetch_time_ = last_token_fetch_time;
}
-void GCMClientImplTest::OnMessageReceived(const std::string& registration_id,
- const IncomingMessage& message) {
+void GCMClientImplTest::OnMessageReceived(
+ const std::string& registration_id,
+ const IncomingMessage& message,
+ const MessageReceiptCallback& optional_receipt_callback) {
last_event_ = MESSAGE_RECEIVED;
last_app_id_ = registration_id;
last_message_ = message;
+
+ // If receipt sending is enabled, then send success.
+ if (successful_receipt_generation_)
+ optional_receipt_callback.Run(GCMMessageStatus::GCM_SUCCESS);
}
void GCMClientImplTest::OnRegisterFinished(
@@ -936,6 +986,9 @@ TEST_F(GCMClientImplTest, DispatchDownstreamMessage) {
EXPECT_TRUE(message3.IsValid());
ReceiveMessageFromMCS(message3);
+ // TODO(harkness): Add a check for invalid app handler once the
+ // DefaultAppHandler is removed.
+
EXPECT_NE(MESSAGE_RECEIVED, last_event());
EXPECT_NE(kExtensionAppId, last_app_id());
}
@@ -1772,6 +1825,10 @@ TEST_F(GCMClientInstanceIDTest, DeleteAllTokensBeforeGetAnyToken) {
}
TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithoutSubtype) {
+ // Initialize a field trial for sending message receipts and set the messages
+ // to send to 2 = ALL.
+ InitializeFieldTrials(2);
+
AddInstanceID(kExtensionAppId, kInstanceID);
GetToken(kExtensionAppId, kSender, kScope);
ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
@@ -1789,6 +1846,24 @@ TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithoutSubtype) {
EXPECT_NE(MESSAGE_RECEIVED, last_event());
+ // Check that the last message sent was a message receipt for a failed message
+ // and that it had the values expected.
+ mcs_proto::DataMessageStanza stanza =
+ mcs_client()->last_data_message_stanza();
+ EXPECT_EQ(kExtensionAppId, stanza.category());
+ const auto& app_data = stanza.app_data();
+ ASSERT_EQ(3, app_data.size());
+ for (const auto& pair : app_data) {
+ if (pair.key() == "message_id")
+ EXPECT_EQ("", pair.value());
+ else if (pair.key() == "status")
+ EXPECT_EQ("2", pair.value());
+ else if (pair.key() == "message_type")
+ EXPECT_EQ("message_receipt", pair.value());
+ else
+ FAIL() << "Unexpected key: " << pair.key();
+ }
+
reset_last_event();
// Message for kSender will be received.
@@ -1832,7 +1907,110 @@ TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithoutSubtype) {
EXPECT_NE(kExtensionAppId, last_app_id());
}
+// Do not initialize a FieldTrial for sending receipts. Default state of the
+// field trial should be SEND_NONE, so check that no receipt was sent.
+TEST_F(GCMClientInstanceIDTest, ReceiptFieldTrialTestingSendNone) {
+ AddInstanceID(kExtensionAppId, kInstanceID);
+ GetToken(kExtensionAppId, kSender, kScope);
+ ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
+
+ std::map<std::string, std::string> expected_data;
+
+ // Message for kSender with a subtype will be dropped and would cause an error
+ // receipt to be generated.
+ MCSMessage message0(BuildDownstreamMessage(
+ kSender, kProductCategoryForSubtypes, kExtensionAppId /* subtype */,
+ expected_data, std::string() /* raw_data */));
+ EXPECT_TRUE(message0.IsValid());
+ ReceiveMessageFromMCS(message0);
+
+ EXPECT_NE(MESSAGE_RECEIVED, last_event());
+
+ // The only way to check that no messages were sent is to check that the tag
+ // is still the default value.
+ EXPECT_EQ(MCSProtoTag::kNumProtoTypes, mcs_client()->last_message_tag());
+}
+
+TEST_F(GCMClientInstanceIDTest, ReceiptFieldTrialTestingSendAll) {
+ // Initialize a field trial for sending message receipts and set the messages
+ // to send to 2 = ALL.
+ InitializeFieldTrials(2);
+ set_successful_receipt_generation(true);
+
+ AddInstanceID(kExtensionAppId, kInstanceID);
+ GetToken(kExtensionAppId, kSender, kScope);
+ ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
+
+ std::map<std::string, std::string> expected_data;
+
+ // Message for kSender will be received.
+ MCSMessage message1(BuildDownstreamMessage(
+ kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
+ std::string() /* raw_data */));
+ EXPECT_TRUE(message1.IsValid());
+ ReceiveMessageFromMCS(message1);
+
+ EXPECT_EQ(MESSAGE_RECEIVED, last_event());
+ EXPECT_EQ(kExtensionAppId, last_app_id());
+ EXPECT_EQ(expected_data.size(), last_message().data.size());
+ EXPECT_EQ(expected_data, last_message().data);
+ EXPECT_EQ(kSender, last_message().sender_id);
+
+ // Check that the last message sent was a message receipt for a successful
+ // message and that it had the values expected.
+ mcs_proto::DataMessageStanza stanza =
+ mcs_client()->last_data_message_stanza();
+ EXPECT_EQ(kExtensionAppId, stanza.category());
+ const auto& app_data = stanza.app_data();
+ ASSERT_EQ(3, app_data.size());
+ for (const auto& pair : app_data) {
+ if (pair.key() == "message_id")
+ EXPECT_EQ("", pair.value());
+ else if (pair.key() == "status")
+ EXPECT_EQ("1", pair.value()); // Status should be GCM_SUCCESS = 1.
+ else if (pair.key() == "message_type")
+ EXPECT_EQ("message_receipt", pair.value());
+ else
+ FAIL() << "Unexpected key: " << pair.key();
+ }
+}
+
+TEST_F(GCMClientInstanceIDTest, ReceiptFieldTrialTestingSendFailures) {
+ // Initialize a field trial for sending message receipts and set the messages
+ // to send to 1 = SEND_FAILURES. Then when a successful message generates a
+ // receipt, it should not be sent.
+ InitializeFieldTrials(1);
+ set_successful_receipt_generation(true);
+
+ AddInstanceID(kExtensionAppId, kInstanceID);
+ GetToken(kExtensionAppId, kSender, kScope);
+ ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
+
+ std::map<std::string, std::string> expected_data;
+
+ // Message for kSender will be received.
+ MCSMessage message1(BuildDownstreamMessage(
+ kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
+ std::string() /* raw_data */));
+ EXPECT_TRUE(message1.IsValid());
+ ReceiveMessageFromMCS(message1);
+
+ EXPECT_EQ(MESSAGE_RECEIVED, last_event());
+ EXPECT_EQ(kExtensionAppId, last_app_id());
+ EXPECT_EQ(expected_data.size(), last_message().data.size());
+ EXPECT_EQ(expected_data, last_message().data);
+ EXPECT_EQ(kSender, last_message().sender_id);
+
+ // The only way to check that no messages were sent is to check that the tag
+ // is still the default value.
+ EXPECT_EQ(MCSProtoTag::kNumProtoTypes, mcs_client()->last_message_tag());
+}
+
TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithSubtype) {
+ // Initialize a field trial for sending message receipts and set the messages
+ // to send to 2 = ALL.
+ InitializeFieldTrials(2);
+
AddInstanceID(kSubtypeAppId, kInstanceID);
GetToken(kSubtypeAppId, kSender, kScope);
ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
@@ -1850,6 +2028,24 @@ TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithSubtype) {
EXPECT_NE(MESSAGE_RECEIVED, last_event());
+ // Check that the last message sent was a message receipt for a failed message
+ // and that it had the values expected.
+ mcs_proto::DataMessageStanza stanza =
+ mcs_client()->last_data_message_stanza();
+ EXPECT_EQ(kSubtypeAppId, stanza.category());
+ const auto& app_data = stanza.app_data();
+ ASSERT_EQ(3, app_data.size());
+ for (const auto& pair : app_data) {
+ if (pair.key() == "message_id")
+ EXPECT_EQ("", pair.value());
+ else if (pair.key() == "status")
+ EXPECT_EQ("2", pair.value());
+ else if (pair.key() == "message_type")
+ EXPECT_EQ("message_receipt", pair.value());
+ else
+ FAIL() << "Unexpected key: " << pair.key();
+ }
+
reset_last_event();
// Message for kSender will be received.
« no previous file with comments | « components/gcm_driver/gcm_client_impl.cc ('k') | components/gcm_driver/gcm_driver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698