Home | History | Annotate | Download | only in engine
      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/strings/string_number_conversions.h"
      6 #include "google_apis/gcm/engine/gservices_settings.h"
      7 #include "google_apis/gcm/engine/registration_info.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 namespace gcm {
     11 
     12 namespace {
     13 
     14 const int64 kAlternativeCheckinInterval = 16 * 60 * 60;
     15 const char kAlternativeCheckinURL[] = "http://alternative.url/checkin";
     16 const char kAlternativeMCSHostname[] = "alternative.gcm.host";
     17 const int kAlternativeMCSSecurePort = 7777;
     18 const char kAlternativeRegistrationURL[] =
     19     "http://alternative.url/registration";
     20 
     21 const int64 kDefaultCheckinInterval = 2 * 24 * 60 * 60;  // seconds = 2 days.
     22 const char kDefaultCheckinURL[] = "https://android.clients.google.com/checkin";
     23 const char kDefaultRegistrationURL[] =
     24     "https://android.clients.google.com/c2dm/register3";
     25 const char kDefaultSettingsDigest[] =
     26     "1-da39a3ee5e6b4b0d3255bfef95601890afd80709";
     27 const char kAlternativeSettingsDigest[] =
     28     "1-7da4aa4eb38a8bd3e330e3751cc0899924499134";
     29 
     30 void AddSettingsToResponse(
     31     checkin_proto::AndroidCheckinResponse& checkin_response,
     32     const GServicesSettings::SettingsMap& settings,
     33     bool settings_diff) {
     34   for (GServicesSettings::SettingsMap::const_iterator iter = settings.begin();
     35        iter != settings.end();
     36        ++iter) {
     37     checkin_proto::GservicesSetting* setting = checkin_response.add_setting();
     38     setting->set_name(iter->first);
     39     setting->set_value(iter->second);
     40   }
     41   checkin_response.set_settings_diff(settings_diff);
     42 }
     43 
     44 }  // namespace
     45 
     46 class GServicesSettingsTest : public testing::Test {
     47  public:
     48   GServicesSettingsTest();
     49   virtual ~GServicesSettingsTest();
     50 
     51   void CheckAllSetToDefault();
     52 
     53   GServicesSettings& settings() {
     54     return gserivces_settings_;
     55   }
     56 
     57  private:
     58   GServicesSettings gserivces_settings_;
     59 };
     60 
     61 GServicesSettingsTest::GServicesSettingsTest()
     62     : gserivces_settings_() {
     63 }
     64 
     65 GServicesSettingsTest::~GServicesSettingsTest() {}
     66 
     67 void GServicesSettingsTest::CheckAllSetToDefault() {
     68   EXPECT_EQ(base::TimeDelta::FromSeconds(kDefaultCheckinInterval),
     69             settings().GetCheckinInterval());
     70   EXPECT_EQ(GURL(kDefaultCheckinURL), settings().GetCheckinURL());
     71   EXPECT_EQ(GURL("https://mtalk.google.com:5228"),
     72             settings().GetMCSMainEndpoint());
     73   EXPECT_EQ(GURL("https://mtalk.google.com:443"),
     74             settings().GetMCSFallbackEndpoint());
     75   EXPECT_EQ(GURL(kDefaultRegistrationURL), settings().GetRegistrationURL());
     76 }
     77 
     78 // Verifies default values of the G-services settings and settings digest.
     79 TEST_F(GServicesSettingsTest, DefaultSettingsAndDigest) {
     80   CheckAllSetToDefault();
     81   EXPECT_EQ(kDefaultSettingsDigest, settings().digest());
     82   EXPECT_EQ(kDefaultSettingsDigest,
     83             GServicesSettings::CalculateDigest(settings().settings_map()));
     84 }
     85 
     86 // Verifies digest calculation for the sample provided by protocol owners.
     87 TEST_F(GServicesSettingsTest, CalculateDigest) {
     88   GServicesSettings::SettingsMap settings_map;
     89   settings_map["android_id"] = "55XXXXXXXXXXXXXXXX0";
     90   settings_map["checkin_interval"] = "86400";
     91   settings_map["checkin_url"] =
     92       "https://fake.address.google.com/canary/checkin";
     93   settings_map["chrome_device"] = "1";
     94   settings_map["device_country"] = "us";
     95   settings_map["gcm_hostname"] = "fake.address.google.com";
     96   settings_map["gcm_secure_port"] = "443";
     97 
     98   EXPECT_EQ("1-33381ccd1cf5791dc0e6dfa234266fa9f1259197",
     99             GServicesSettings::CalculateDigest(settings_map));
    100 }
    101 
    102 // Verifies that settings are not updated when load result is empty.
    103 TEST_F(GServicesSettingsTest, UpdateFromEmptyLoadResult) {
    104   GCMStore::LoadResult result;
    105   result.gservices_digest = "";
    106   settings().UpdateFromLoadResult(result);
    107 
    108   CheckAllSetToDefault();
    109   EXPECT_EQ(kDefaultSettingsDigest, settings().digest());
    110 }
    111 
    112 // Verifies that settings are not when digest value does not match.
    113 TEST_F(GServicesSettingsTest, UpdateFromLoadResultWithSettingMissing) {
    114   GCMStore::LoadResult result;
    115   result.gservices_settings["checkin_internval"] = "100000";
    116   result.gservices_digest = "digest_value";
    117   settings().UpdateFromLoadResult(result);
    118 
    119   CheckAllSetToDefault();
    120   EXPECT_EQ(kDefaultSettingsDigest, settings().digest());
    121 }
    122 
    123 // Verifies that the settings are set correctly based on the load result.
    124 TEST_F(GServicesSettingsTest, UpdateFromLoadResult) {
    125   GCMStore::LoadResult result;
    126   result.gservices_settings["checkin_interval"] =
    127       base::Int64ToString(kAlternativeCheckinInterval);
    128   result.gservices_settings["checkin_url"] = kAlternativeCheckinURL;
    129   result.gservices_settings["gcm_hostname"] = kAlternativeMCSHostname;
    130   result.gservices_settings["gcm_secure_port"] =
    131       base::IntToString(kAlternativeMCSSecurePort);
    132   result.gservices_settings["gcm_registration_url"] =
    133       kAlternativeRegistrationURL;
    134   result.gservices_digest = kAlternativeSettingsDigest;
    135   settings().UpdateFromLoadResult(result);
    136 
    137   EXPECT_EQ(base::TimeDelta::FromSeconds(kAlternativeCheckinInterval),
    138             settings().GetCheckinInterval());
    139   EXPECT_EQ(GURL(kAlternativeCheckinURL), settings().GetCheckinURL());
    140   EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
    141             settings().GetMCSMainEndpoint());
    142   EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
    143             settings().GetMCSFallbackEndpoint());
    144   EXPECT_EQ(GURL(kAlternativeRegistrationURL), settings().GetRegistrationURL());
    145   EXPECT_EQ(GServicesSettings::CalculateDigest(result.gservices_settings),
    146             settings().digest());
    147 }
    148 
    149 // Verifies that the checkin interval is updated to minimum if the original
    150 // value is less than minimum.
    151 TEST_F(GServicesSettingsTest, CheckinResponseMinimumCheckinInterval) {
    152   // Setting the checkin interval to less than minimum.
    153   checkin_proto::AndroidCheckinResponse checkin_response;
    154   GServicesSettings::SettingsMap new_settings;
    155   new_settings["checkin_interval"] = "3600";
    156   AddSettingsToResponse(checkin_response, new_settings, false);
    157 
    158   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    159 
    160   EXPECT_EQ(GServicesSettings::MinimumCheckinInterval(),
    161             settings().GetCheckinInterval());
    162   EXPECT_EQ(GServicesSettings::CalculateDigest(new_settings),
    163             settings().digest());
    164 }
    165 
    166 // Verifies that default checkin interval can be selectively overwritten.
    167 TEST_F(GServicesSettingsTest, CheckinResponseUpdateCheckinInterval) {
    168   checkin_proto::AndroidCheckinResponse checkin_response;
    169   GServicesSettings::SettingsMap new_settings;
    170   new_settings["checkin_interval"] = "86400";
    171   AddSettingsToResponse(checkin_response, new_settings, false);
    172 
    173   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    174 
    175   // Only the checkin interval was updated:
    176   EXPECT_EQ(base::TimeDelta::FromSeconds(86400),
    177             settings().GetCheckinInterval());
    178 
    179   // Other settings still set to default.
    180   EXPECT_EQ(GURL("https://mtalk.google.com:5228"),
    181             settings().GetMCSMainEndpoint());
    182   EXPECT_EQ(GURL("https://mtalk.google.com:443"),
    183             settings().GetMCSFallbackEndpoint());
    184   EXPECT_EQ(GURL(kDefaultCheckinURL), settings().GetCheckinURL());
    185   EXPECT_EQ(GURL(kDefaultRegistrationURL), settings().GetRegistrationURL());
    186 
    187   EXPECT_EQ(GServicesSettings::CalculateDigest(new_settings),
    188             settings().digest());
    189 }
    190 
    191 // Verifies that default registration URL can be selectively overwritten.
    192 TEST_F(GServicesSettingsTest, CheckinResponseUpdateRegistrationURL) {
    193   checkin_proto::AndroidCheckinResponse checkin_response;
    194   GServicesSettings::SettingsMap new_settings;
    195   new_settings["gcm_registration_url"] = "https://new.registration.url";
    196   AddSettingsToResponse(checkin_response, new_settings, false);
    197 
    198   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    199 
    200   // Only the registration URL was updated:
    201   EXPECT_EQ(GURL("https://new.registration.url"),
    202             settings().GetRegistrationURL());
    203 
    204   // Other settings still set to default.
    205   EXPECT_EQ(base::TimeDelta::FromSeconds(kDefaultCheckinInterval),
    206             settings().GetCheckinInterval());
    207   EXPECT_EQ(GURL("https://mtalk.google.com:5228"),
    208             settings().GetMCSMainEndpoint());
    209   EXPECT_EQ(GURL("https://mtalk.google.com:443"),
    210             settings().GetMCSFallbackEndpoint());
    211   EXPECT_EQ(GURL(kDefaultCheckinURL), settings().GetCheckinURL());
    212 
    213   EXPECT_EQ(GServicesSettings::CalculateDigest(new_settings),
    214             settings().digest());
    215 }
    216 
    217 // Verifies that default checkin URL can be selectively overwritten.
    218 TEST_F(GServicesSettingsTest, CheckinResponseUpdateCheckinURL) {
    219   checkin_proto::AndroidCheckinResponse checkin_response;
    220   GServicesSettings::SettingsMap new_settings;
    221   new_settings["checkin_url"] = "https://new.checkin.url";
    222   AddSettingsToResponse(checkin_response, new_settings, false);
    223 
    224   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    225 
    226   // Only the checkin URL was updated:
    227   EXPECT_EQ(GURL("https://new.checkin.url"), settings().GetCheckinURL());
    228 
    229   // Other settings still set to default.
    230   EXPECT_EQ(base::TimeDelta::FromSeconds(kDefaultCheckinInterval),
    231             settings().GetCheckinInterval());
    232   EXPECT_EQ(GURL("https://mtalk.google.com:5228"),
    233             settings().GetMCSMainEndpoint());
    234   EXPECT_EQ(GURL("https://mtalk.google.com:443"),
    235             settings().GetMCSFallbackEndpoint());
    236   EXPECT_EQ(GURL(kDefaultRegistrationURL), settings().GetRegistrationURL());
    237 
    238   EXPECT_EQ(GServicesSettings::CalculateDigest(new_settings),
    239             settings().digest());
    240 }
    241 
    242 // Verifies that default MCS hostname can be selectively overwritten.
    243 TEST_F(GServicesSettingsTest, CheckinResponseUpdateMCSHostname) {
    244   checkin_proto::AndroidCheckinResponse checkin_response;
    245   GServicesSettings::SettingsMap new_settings;
    246   new_settings["gcm_hostname"] = "new.gcm.hostname";
    247   AddSettingsToResponse(checkin_response, new_settings, false);
    248 
    249   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    250 
    251   // Only the MCS endpoints were updated:
    252   EXPECT_EQ(GURL("https://new.gcm.hostname:5228"),
    253             settings().GetMCSMainEndpoint());
    254   EXPECT_EQ(GURL("https://new.gcm.hostname:443"),
    255             settings().GetMCSFallbackEndpoint());
    256 
    257   // Other settings still set to default.
    258   EXPECT_EQ(base::TimeDelta::FromSeconds(kDefaultCheckinInterval),
    259             settings().GetCheckinInterval());
    260   EXPECT_EQ(GURL(kDefaultCheckinURL), settings().GetCheckinURL());
    261   EXPECT_EQ(GURL(kDefaultRegistrationURL), settings().GetRegistrationURL());
    262 
    263   EXPECT_EQ(GServicesSettings::CalculateDigest(new_settings),
    264             settings().digest());
    265 }
    266 
    267 // Verifies that default MCS secure port can be selectively overwritten.
    268 TEST_F(GServicesSettingsTest, CheckinResponseUpdateMCSSecurePort) {
    269   checkin_proto::AndroidCheckinResponse checkin_response;
    270   GServicesSettings::SettingsMap new_settings;
    271   new_settings["gcm_secure_port"] = "5229";
    272   AddSettingsToResponse(checkin_response, new_settings, false);
    273 
    274   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    275 
    276   // Only the main MCS endpoint was updated:
    277   EXPECT_EQ(GURL("https://mtalk.google.com:5229"),
    278             settings().GetMCSMainEndpoint());
    279 
    280   // Other settings still set to default.
    281   EXPECT_EQ(base::TimeDelta::FromSeconds(kDefaultCheckinInterval),
    282             settings().GetCheckinInterval());
    283   EXPECT_EQ(GURL(kDefaultCheckinURL), settings().GetCheckinURL());
    284   EXPECT_EQ(GURL("https://mtalk.google.com:443"),
    285             settings().GetMCSFallbackEndpoint());
    286   EXPECT_EQ(GURL(kDefaultRegistrationURL), settings().GetRegistrationURL());
    287 
    288   EXPECT_EQ(GServicesSettings::CalculateDigest(new_settings),
    289             settings().digest());
    290 }
    291 
    292 // Update from checkin response should also do incremental update for both cases
    293 // where some settings are removed or added.
    294 TEST_F(GServicesSettingsTest, UpdateFromCheckinResponseSettingsDiff) {
    295   checkin_proto::AndroidCheckinResponse checkin_response;
    296 
    297   // Only the new settings will be included in the response with settings diff.
    298   GServicesSettings::SettingsMap settings_diff;
    299   settings_diff["new_setting_1"] = "new_setting_1_value";
    300   settings_diff["new_setting_2"] = "new_setting_2_value";
    301   settings_diff["gcm_secure_port"] = "5229";
    302 
    303   // Full settings are necessary to calculate digest.
    304   GServicesSettings::SettingsMap full_settings(settings_diff);
    305   std::string digest = GServicesSettings::CalculateDigest(full_settings);
    306 
    307   checkin_response.Clear();
    308   AddSettingsToResponse(checkin_response, settings_diff, true);
    309   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    310   EXPECT_EQ(full_settings, settings().settings_map());
    311   // Default setting overwritten by settings diff.
    312   EXPECT_EQ(GURL("https://mtalk.google.com:5229"),
    313             settings().GetMCSMainEndpoint());
    314 
    315   // Setting up diff removing some of the values (including default setting).
    316   settings_diff.clear();
    317   settings_diff["delete_new_setting_1"] = "";
    318   settings_diff["delete_gcm_secure_port"] = "";
    319   settings_diff["new_setting_3"] = "new_setting_3_value";
    320 
    321   // Updating full settings to calculate digest.
    322   full_settings.erase(full_settings.find("new_setting_1"));
    323   full_settings.erase(full_settings.find("gcm_secure_port"));
    324   full_settings["new_setting_3"] = "new_setting_3_value";
    325   digest = GServicesSettings::CalculateDigest(full_settings);
    326 
    327   checkin_response.Clear();
    328   AddSettingsToResponse(checkin_response, settings_diff, true);
    329   EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
    330   EXPECT_EQ(full_settings, settings().settings_map());
    331   // Default setting back to norm.
    332   EXPECT_EQ(GURL("https://mtalk.google.com:5228"),
    333             settings().GetMCSMainEndpoint());
    334 }
    335 
    336 }  // namespace gcm
    337