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