Home | History | Annotate | Download | only in google_apis
      1 // Copyright (c) 2012 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 // Unit tests for implementation of google_api_keys namespace.
      6 //
      7 // Because the file deals with a lot of preprocessor defines and
      8 // optionally includes an internal header, the way we test is by
      9 // including the .cc file multiple times with different defines set.
     10 // This is a little unorthodox, but it lets us test the behavior as
     11 // close to unmodified as possible.
     12 
     13 #include "google_apis/google_api_keys.h"
     14 
     15 #include "build/build_config.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 // The Win builders fail (with a linker crash) when trying to link
     19 // unit_tests, and the Android builders complain about multiply
     20 // defined symbols (likely they don't do name decoration as well as
     21 // the Mac and Linux linkers).  Therefore these tests are only built
     22 // and run on Mac and Linux, which should provide plenty of coverage
     23 // since there are no platform-specific bits in this code.
     24 #if defined(OS_LINUX) || defined(OS_MACOSX)
     25 
     26 // We need to include everything included by google_api_keys.cc once
     27 // at global scope so that things like STL and classes from base don't
     28 // get defined when we re-include the google_api_keys.cc file
     29 // below. We used to include that file in its entirety here, but that
     30 // can cause problems if the linker decides the version of symbols
     31 // from that file included here is the "right" version.
     32 #include <string>
     33 #include "base/command_line.h"
     34 #include "base/environment.h"
     35 #include "base/lazy_instance.h"
     36 #include "base/logging.h"
     37 #include "base/memory/scoped_ptr.h"
     38 #include "base/strings/stringize_macros.h"
     39 
     40 // This is the default baked-in value for OAuth IDs and secrets.
     41 static const char kDummyToken[] = "dummytoken";
     42 
     43 struct EnvironmentCache {
     44  public:
     45   EnvironmentCache() : variable_name(NULL), was_set(false) {}
     46 
     47   const char* variable_name;
     48   bool was_set;
     49   std::string value;
     50 };
     51 
     52 class GoogleAPIKeysTest : public testing::Test {
     53  public:
     54   GoogleAPIKeysTest() : env_(base::Environment::Create()) {
     55     env_cache_[0].variable_name = "GOOGLE_API_KEY";
     56     env_cache_[1].variable_name = "GOOGLE_CLIENT_ID_MAIN";
     57     env_cache_[2].variable_name = "GOOGLE_CLIENT_SECRET_MAIN";
     58     env_cache_[3].variable_name = "GOOGLE_CLIENT_ID_CLOUD_PRINT";
     59     env_cache_[4].variable_name = "GOOGLE_CLIENT_SECRET_CLOUD_PRINT";
     60     env_cache_[5].variable_name = "GOOGLE_CLIENT_ID_REMOTING";
     61     env_cache_[6].variable_name = "GOOGLE_CLIENT_SECRET_REMOTING";
     62     env_cache_[7].variable_name = "GOOGLE_DEFAULT_CLIENT_ID";
     63     env_cache_[8].variable_name = "GOOGLE_DEFAULT_CLIENT_SECRET";
     64   }
     65 
     66   virtual void SetUp() {
     67     // Unset all environment variables that can affect these tests,
     68     // for the duration of the tests.
     69     for (size_t i = 0; i < arraysize(env_cache_); ++i) {
     70       EnvironmentCache& cache = env_cache_[i];
     71       cache.was_set = env_->HasVar(cache.variable_name);
     72       cache.value.clear();
     73       if (cache.was_set) {
     74         env_->GetVar(cache.variable_name, &cache.value);
     75         env_->UnSetVar(cache.variable_name);
     76       }
     77     }
     78   }
     79 
     80   virtual void TearDown() {
     81     // Restore environment.
     82     for (size_t i = 0; i < arraysize(env_cache_); ++i) {
     83       EnvironmentCache& cache = env_cache_[i];
     84       if (cache.was_set) {
     85         env_->SetVar(cache.variable_name, cache.value);
     86       }
     87     }
     88   }
     89 
     90  private:
     91   scoped_ptr<base::Environment> env_;
     92 
     93   // Why 3?  It is for GOOGLE_API_KEY, GOOGLE_DEFAULT_CLIENT_ID and
     94   // GOOGLE_DEFAULT_CLIENT_SECRET.
     95   //
     96   // Why 2 times CLIENT_NUM_ITEMS?  This is the number of different
     97   // clients in the OAuth2Client enumeration, and for each of these we
     98   // have both an ID and a secret.
     99   EnvironmentCache env_cache_[3 + 2 * google_apis::CLIENT_NUM_ITEMS];
    100 };
    101 
    102 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
    103 // Test official build behavior, since we are in a checkout where this
    104 // is possible.
    105 namespace official_build {
    106 
    107 // We start every test by creating a clean environment for the
    108 // preprocessor defines used in google_api_keys.cc
    109 #undef DUMMY_API_TOKEN
    110 #undef GOOGLE_API_KEY
    111 #undef GOOGLE_CLIENT_ID_MAIN
    112 #undef GOOGLE_CLIENT_SECRET_MAIN
    113 #undef GOOGLE_CLIENT_ID_CLOUD_PRINT
    114 #undef GOOGLE_CLIENT_SECRET_CLOUD_PRINT
    115 #undef GOOGLE_CLIENT_ID_REMOTING
    116 #undef GOOGLE_CLIENT_SECRET_REMOTING
    117 #undef GOOGLE_DEFAULT_CLIENT_ID
    118 #undef GOOGLE_DEFAULT_CLIENT_SECRET
    119 
    120 // Try setting some keys, these should be ignored since it's a build
    121 // with official keys.
    122 #define GOOGLE_API_KEY "bogus api_key"
    123 #define GOOGLE_CLIENT_ID_MAIN "bogus client_id_main"
    124 
    125 // Undef include guard so things get defined again, within this namespace.
    126 #undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
    127 #undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
    128 #include "google_apis/google_api_keys.cc"
    129 
    130 }  // namespace official_build
    131 
    132 TEST_F(GoogleAPIKeysTest, OfficialKeys) {
    133   namespace testcase = official_build::google_apis;
    134 
    135   EXPECT_TRUE(testcase::HasKeysConfigured());
    136 
    137   std::string api_key = testcase::g_api_key_cache.Get().api_key();
    138   std::string id_main = testcase::g_api_key_cache.Get().GetClientID(
    139       testcase::CLIENT_MAIN);
    140   std::string secret_main = testcase::g_api_key_cache.Get().GetClientSecret(
    141       testcase::CLIENT_MAIN);
    142   std::string id_cloud_print =
    143       testcase::g_api_key_cache.Get().GetClientID(
    144           testcase::CLIENT_CLOUD_PRINT);
    145   std::string secret_cloud_print =
    146       testcase::g_api_key_cache.Get().GetClientSecret(
    147           testcase::CLIENT_CLOUD_PRINT);
    148   std::string id_remoting = testcase::g_api_key_cache.Get().GetClientID(
    149       testcase::CLIENT_REMOTING);
    150   std::string secret_remoting =
    151       testcase::g_api_key_cache.Get().GetClientSecret(
    152           testcase::CLIENT_REMOTING);
    153 
    154   EXPECT_NE(0u, api_key.size());
    155   EXPECT_NE(DUMMY_API_TOKEN, api_key);
    156   EXPECT_NE("bogus api_key", api_key);
    157   EXPECT_NE(kDummyToken, api_key);
    158 
    159   EXPECT_NE(0u, id_main.size());
    160   EXPECT_NE(DUMMY_API_TOKEN, id_main);
    161   EXPECT_NE("bogus client_id_main", id_main);
    162   EXPECT_NE(kDummyToken, id_main);
    163 
    164   EXPECT_NE(0u, secret_main.size());
    165   EXPECT_NE(DUMMY_API_TOKEN, secret_main);
    166   EXPECT_NE(kDummyToken, secret_main);
    167 
    168   EXPECT_NE(0u, id_cloud_print.size());
    169   EXPECT_NE(DUMMY_API_TOKEN, id_cloud_print);
    170   EXPECT_NE(kDummyToken, id_cloud_print);
    171 
    172   EXPECT_NE(0u, secret_cloud_print.size());
    173   EXPECT_NE(DUMMY_API_TOKEN, secret_cloud_print);
    174   EXPECT_NE(kDummyToken, secret_cloud_print);
    175 
    176   EXPECT_NE(0u, id_remoting.size());
    177   EXPECT_NE(DUMMY_API_TOKEN, id_remoting);
    178   EXPECT_NE(kDummyToken, id_remoting);
    179 
    180   EXPECT_NE(0u, secret_remoting.size());
    181   EXPECT_NE(DUMMY_API_TOKEN, secret_remoting);
    182   EXPECT_NE(kDummyToken, secret_remoting);
    183 }
    184 #endif  // defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
    185 
    186 // After this test, for the remainder of this compilation unit, we
    187 // need official keys to not be used.
    188 #undef GOOGLE_CHROME_BUILD
    189 #undef USE_OFFICIAL_GOOGLE_API_KEYS
    190 
    191 // Test the set of keys temporarily baked into Chromium by default.
    192 namespace default_keys {
    193 
    194 // We start every test by creating a clean environment for the
    195 // preprocessor defines used in google_api_keys.cc
    196 #undef DUMMY_API_TOKEN
    197 #undef GOOGLE_API_KEY
    198 #undef GOOGLE_CLIENT_ID_MAIN
    199 #undef GOOGLE_CLIENT_SECRET_MAIN
    200 #undef GOOGLE_CLIENT_ID_CLOUD_PRINT
    201 #undef GOOGLE_CLIENT_SECRET_CLOUD_PRINT
    202 #undef GOOGLE_CLIENT_ID_REMOTING
    203 #undef GOOGLE_CLIENT_SECRET_REMOTING
    204 #undef GOOGLE_DEFAULT_CLIENT_ID
    205 #undef GOOGLE_DEFAULT_CLIENT_SECRET
    206 
    207 // Undef include guard so things get defined again, within this namespace.
    208 #undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
    209 #undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
    210 #include "google_apis/google_api_keys.cc"
    211 
    212 }  // namespace default_keys
    213 
    214 TEST_F(GoogleAPIKeysTest, DefaultKeys) {
    215   namespace testcase = default_keys::google_apis;
    216 
    217   EXPECT_FALSE(testcase::HasKeysConfigured());
    218 
    219   std::string api_key = testcase::g_api_key_cache.Get().api_key();
    220   std::string id_main = testcase::g_api_key_cache.Get().GetClientID(
    221       testcase::CLIENT_MAIN);
    222   std::string secret_main = testcase::g_api_key_cache.Get().GetClientSecret(
    223       testcase::CLIENT_MAIN);
    224   std::string id_cloud_print =
    225       testcase::g_api_key_cache.Get().GetClientID(
    226           testcase::CLIENT_CLOUD_PRINT);
    227   std::string secret_cloud_print =
    228       testcase::g_api_key_cache.Get().GetClientSecret(
    229           testcase::CLIENT_CLOUD_PRINT);
    230   std::string id_remoting = testcase::g_api_key_cache.Get().GetClientID(
    231       testcase::CLIENT_REMOTING);
    232   std::string secret_remoting =
    233       testcase::g_api_key_cache.Get().GetClientSecret(
    234           testcase::CLIENT_REMOTING);
    235 
    236   EXPECT_EQ(kDummyToken, api_key);
    237   EXPECT_EQ(kDummyToken, id_main);
    238   EXPECT_EQ(kDummyToken, secret_main);
    239   EXPECT_EQ(kDummyToken, id_cloud_print);
    240   EXPECT_EQ(kDummyToken, secret_cloud_print);
    241   EXPECT_EQ(kDummyToken, id_remoting);
    242   EXPECT_EQ(kDummyToken, secret_remoting);
    243 }
    244 
    245 // Override a couple of keys, leave the rest default.
    246 namespace override_some_keys {
    247 
    248 // We start every test by creating a clean environment for the
    249 // preprocessor defines used in google_api_keys.cc
    250 #undef DUMMY_API_TOKEN
    251 #undef GOOGLE_API_KEY
    252 #undef GOOGLE_CLIENT_ID_MAIN
    253 #undef GOOGLE_CLIENT_SECRET_MAIN
    254 #undef GOOGLE_CLIENT_ID_CLOUD_PRINT
    255 #undef GOOGLE_CLIENT_SECRET_CLOUD_PRINT
    256 #undef GOOGLE_CLIENT_ID_REMOTING
    257 #undef GOOGLE_CLIENT_SECRET_REMOTING
    258 #undef GOOGLE_DEFAULT_CLIENT_ID
    259 #undef GOOGLE_DEFAULT_CLIENT_SECRET
    260 
    261 #define GOOGLE_API_KEY "API_KEY override"
    262 #define GOOGLE_CLIENT_ID_REMOTING "CLIENT_ID_REMOTING override"
    263 
    264 // Undef include guard so things get defined again, within this namespace.
    265 #undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
    266 #undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
    267 #include "google_apis/google_api_keys.cc"
    268 
    269 }  // namespace override_some_keys
    270 
    271 TEST_F(GoogleAPIKeysTest, OverrideSomeKeys) {
    272   namespace testcase = override_some_keys::google_apis;
    273 
    274   EXPECT_FALSE(testcase::HasKeysConfigured());
    275 
    276   std::string api_key = testcase::g_api_key_cache.Get().api_key();
    277   std::string id_main = testcase::g_api_key_cache.Get().GetClientID(
    278       testcase::CLIENT_MAIN);
    279   std::string secret_main = testcase::g_api_key_cache.Get().GetClientSecret(
    280       testcase::CLIENT_MAIN);
    281   std::string id_cloud_print =
    282       testcase::g_api_key_cache.Get().GetClientID(
    283           testcase::CLIENT_CLOUD_PRINT);
    284   std::string secret_cloud_print =
    285       testcase::g_api_key_cache.Get().GetClientSecret(
    286           testcase::CLIENT_CLOUD_PRINT);
    287   std::string id_remoting = testcase::g_api_key_cache.Get().GetClientID(
    288       testcase::CLIENT_REMOTING);
    289   std::string secret_remoting =
    290       testcase::g_api_key_cache.Get().GetClientSecret(
    291           testcase::CLIENT_REMOTING);
    292 
    293   EXPECT_EQ("API_KEY override", api_key);
    294   EXPECT_EQ(kDummyToken, id_main);
    295   EXPECT_EQ(kDummyToken, secret_main);
    296   EXPECT_EQ(kDummyToken, id_cloud_print);
    297   EXPECT_EQ(kDummyToken, secret_cloud_print);
    298   EXPECT_EQ("CLIENT_ID_REMOTING override", id_remoting);
    299   EXPECT_EQ(kDummyToken, secret_remoting);
    300 }
    301 
    302 // Override all keys.
    303 namespace override_all_keys {
    304 
    305 // We start every test by creating a clean environment for the
    306 // preprocessor defines used in google_api_keys.cc
    307 #undef DUMMY_API_TOKEN
    308 #undef GOOGLE_API_KEY
    309 #undef GOOGLE_CLIENT_ID_MAIN
    310 #undef GOOGLE_CLIENT_SECRET_MAIN
    311 #undef GOOGLE_CLIENT_ID_CLOUD_PRINT
    312 #undef GOOGLE_CLIENT_SECRET_CLOUD_PRINT
    313 #undef GOOGLE_CLIENT_ID_REMOTING
    314 #undef GOOGLE_CLIENT_SECRET_REMOTING
    315 #undef GOOGLE_DEFAULT_CLIENT_ID
    316 #undef GOOGLE_DEFAULT_CLIENT_SECRET
    317 
    318 #define GOOGLE_API_KEY "API_KEY"
    319 #define GOOGLE_CLIENT_ID_MAIN "ID_MAIN"
    320 #define GOOGLE_CLIENT_SECRET_MAIN "SECRET_MAIN"
    321 #define GOOGLE_CLIENT_ID_CLOUD_PRINT "ID_CLOUD_PRINT"
    322 #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT "SECRET_CLOUD_PRINT"
    323 #define GOOGLE_CLIENT_ID_REMOTING "ID_REMOTING"
    324 #define GOOGLE_CLIENT_SECRET_REMOTING "SECRET_REMOTING"
    325 
    326 // Undef include guard so things get defined again, within this namespace.
    327 #undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
    328 #undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
    329 #include "google_apis/google_api_keys.cc"
    330 
    331 }  // namespace override_all_keys
    332 
    333 TEST_F(GoogleAPIKeysTest, OverrideAllKeys) {
    334   namespace testcase = override_all_keys::google_apis;
    335 
    336   EXPECT_TRUE(testcase::HasKeysConfigured());
    337 
    338   std::string api_key = testcase::g_api_key_cache.Get().api_key();
    339   std::string id_main = testcase::g_api_key_cache.Get().GetClientID(
    340       testcase::CLIENT_MAIN);
    341   std::string secret_main = testcase::g_api_key_cache.Get().GetClientSecret(
    342       testcase::CLIENT_MAIN);
    343   std::string id_cloud_print =
    344       testcase::g_api_key_cache.Get().GetClientID(
    345           testcase::CLIENT_CLOUD_PRINT);
    346   std::string secret_cloud_print =
    347       testcase::g_api_key_cache.Get().GetClientSecret(
    348           testcase::CLIENT_CLOUD_PRINT);
    349   std::string id_remoting = testcase::g_api_key_cache.Get().GetClientID(
    350       testcase::CLIENT_REMOTING);
    351   std::string secret_remoting =
    352       testcase::g_api_key_cache.Get().GetClientSecret(
    353           testcase::CLIENT_REMOTING);
    354 
    355   EXPECT_EQ("API_KEY", api_key);
    356   EXPECT_EQ("ID_MAIN", id_main);
    357   EXPECT_EQ("SECRET_MAIN", secret_main);
    358   EXPECT_EQ("ID_CLOUD_PRINT", id_cloud_print);
    359   EXPECT_EQ("SECRET_CLOUD_PRINT", secret_cloud_print);
    360   EXPECT_EQ("ID_REMOTING", id_remoting);
    361   EXPECT_EQ("SECRET_REMOTING", secret_remoting);
    362 }
    363 
    364 // Override all keys using both preprocessor defines and environment
    365 // variables.  The environment variables should win.
    366 namespace override_all_keys_env {
    367 
    368 // We start every test by creating a clean environment for the
    369 // preprocessor defines used in google_api_keys.cc
    370 #undef DUMMY_API_TOKEN
    371 #undef GOOGLE_API_KEY
    372 #undef GOOGLE_CLIENT_ID_MAIN
    373 #undef GOOGLE_CLIENT_SECRET_MAIN
    374 #undef GOOGLE_CLIENT_ID_CLOUD_PRINT
    375 #undef GOOGLE_CLIENT_SECRET_CLOUD_PRINT
    376 #undef GOOGLE_CLIENT_ID_REMOTING
    377 #undef GOOGLE_CLIENT_SECRET_REMOTING
    378 #undef GOOGLE_DEFAULT_CLIENT_ID
    379 #undef GOOGLE_DEFAULT_CLIENT_SECRET
    380 
    381 #define GOOGLE_API_KEY "API_KEY"
    382 #define GOOGLE_CLIENT_ID_MAIN "ID_MAIN"
    383 #define GOOGLE_CLIENT_SECRET_MAIN "SECRET_MAIN"
    384 #define GOOGLE_CLIENT_ID_CLOUD_PRINT "ID_CLOUD_PRINT"
    385 #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT "SECRET_CLOUD_PRINT"
    386 #define GOOGLE_CLIENT_ID_REMOTING "ID_REMOTING"
    387 #define GOOGLE_CLIENT_SECRET_REMOTING "SECRET_REMOTING"
    388 
    389 // Undef include guard so things get defined again, within this namespace.
    390 #undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
    391 #undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
    392 #include "google_apis/google_api_keys.cc"
    393 
    394 }  // namespace override_all_keys_env
    395 
    396 TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingEnvironment) {
    397   namespace testcase = override_all_keys_env::google_apis;
    398 
    399   scoped_ptr<base::Environment> env(base::Environment::Create());
    400   env->SetVar("GOOGLE_API_KEY", "env-API_KEY");
    401   env->SetVar("GOOGLE_CLIENT_ID_MAIN", "env-ID_MAIN");
    402   env->SetVar("GOOGLE_CLIENT_ID_CLOUD_PRINT", "env-ID_CLOUD_PRINT");
    403   env->SetVar("GOOGLE_CLIENT_ID_REMOTING", "env-ID_REMOTING");
    404   env->SetVar("GOOGLE_CLIENT_SECRET_MAIN", "env-SECRET_MAIN");
    405   env->SetVar("GOOGLE_CLIENT_SECRET_CLOUD_PRINT", "env-SECRET_CLOUD_PRINT");
    406   env->SetVar("GOOGLE_CLIENT_SECRET_REMOTING", "env-SECRET_REMOTING");
    407 
    408   EXPECT_TRUE(testcase::HasKeysConfigured());
    409 
    410   // It's important that the first call to Get() only happen after the
    411   // environment variables have been set.
    412   std::string api_key = testcase::g_api_key_cache.Get().api_key();
    413   std::string id_main = testcase::g_api_key_cache.Get().GetClientID(
    414       testcase::CLIENT_MAIN);
    415   std::string secret_main = testcase::g_api_key_cache.Get().GetClientSecret(
    416       testcase::CLIENT_MAIN);
    417   std::string id_cloud_print =
    418       testcase::g_api_key_cache.Get().GetClientID(
    419           testcase::CLIENT_CLOUD_PRINT);
    420   std::string secret_cloud_print =
    421       testcase::g_api_key_cache.Get().GetClientSecret(
    422           testcase::CLIENT_CLOUD_PRINT);
    423   std::string id_remoting = testcase::g_api_key_cache.Get().GetClientID(
    424       testcase::CLIENT_REMOTING);
    425   std::string secret_remoting =
    426       testcase::g_api_key_cache.Get().GetClientSecret(
    427           testcase::CLIENT_REMOTING);
    428 
    429   EXPECT_EQ("env-API_KEY", api_key);
    430   EXPECT_EQ("env-ID_MAIN", id_main);
    431   EXPECT_EQ("env-SECRET_MAIN", secret_main);
    432   EXPECT_EQ("env-ID_CLOUD_PRINT", id_cloud_print);
    433   EXPECT_EQ("env-SECRET_CLOUD_PRINT", secret_cloud_print);
    434   EXPECT_EQ("env-ID_REMOTING", id_remoting);
    435   EXPECT_EQ("env-SECRET_REMOTING", secret_remoting);
    436 }
    437 
    438 #endif  // defined(OS_LINUX) || defined(OS_MACOSX)
    439