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 // A test application for the RLZ library. 6 // 7 // These tests should not be executed on the build server: 8 // - They assert for the failed cases. 9 // - They modify machine state (registry). 10 // 11 // These tests require write access to HKLM and HKCU. 12 // 13 // The "GGLA" brand is used to test the normal code flow of the code, and the 14 // "TEST" brand is used to test the supplementary brand code code flow. 15 16 #include "base/posix/eintr_wrapper.h" 17 #include "base/logging.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 #include "rlz/lib/rlz_lib.h" 23 #include "rlz/lib/rlz_value_store.h" 24 #include "rlz/test/rlz_test_helpers.h" 25 26 #if defined(OS_WIN) 27 #include <Windows.h> 28 #include "rlz/win/lib/machine_deal.h" 29 #endif 30 31 #if defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET) 32 #include "base/mac/scoped_nsautorelease_pool.h" 33 #include "base/threading/thread.h" 34 #include "net/url_request/url_request_test_util.h" 35 #endif 36 37 38 class MachineDealCodeHelper 39 #if defined(OS_WIN) 40 : public rlz_lib::MachineDealCode 41 #endif 42 { 43 public: 44 static bool Clear() { 45 #if defined(OS_WIN) 46 return rlz_lib::MachineDealCode::Clear(); 47 #else 48 return true; 49 #endif 50 } 51 52 private: 53 MachineDealCodeHelper() {} 54 ~MachineDealCodeHelper() {} 55 }; 56 57 class RlzLibTest : public RlzLibTestBase { 58 }; 59 60 TEST_F(RlzLibTest, RecordProductEvent) { 61 char cgi_50[50]; 62 63 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 64 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 65 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 66 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 67 cgi_50, 50)); 68 EXPECT_STREQ("events=I7S", cgi_50); 69 70 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 71 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 72 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 73 cgi_50, 50)); 74 EXPECT_STREQ("events=I7S,W1I", cgi_50); 75 76 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 77 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 78 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 79 cgi_50, 50)); 80 EXPECT_STREQ("events=I7S,W1I", cgi_50); 81 } 82 83 TEST_F(RlzLibTest, ClearProductEvent) { 84 char cgi_50[50]; 85 86 // Clear 1 of 1 events. 87 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 88 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 89 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 90 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 91 cgi_50, 50)); 92 EXPECT_STREQ("events=I7S", cgi_50); 93 EXPECT_TRUE(rlz_lib::ClearProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 94 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 95 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 96 cgi_50, 50)); 97 EXPECT_STREQ("", cgi_50); 98 99 // Clear 1 of 2 events. 100 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 101 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 102 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 103 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 104 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 105 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 106 cgi_50, 50)); 107 EXPECT_STREQ("events=I7S,W1I", cgi_50); 108 EXPECT_TRUE(rlz_lib::ClearProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 109 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 110 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 111 cgi_50, 50)); 112 EXPECT_STREQ("events=W1I", cgi_50); 113 114 // Clear a non-recorded event. 115 EXPECT_TRUE(rlz_lib::ClearProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 116 rlz_lib::IETB_SEARCH_BOX, rlz_lib::FIRST_SEARCH)); 117 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 118 cgi_50, 50)); 119 EXPECT_STREQ("events=W1I", cgi_50); 120 } 121 122 123 TEST_F(RlzLibTest, GetProductEventsAsCgi) { 124 char cgi_50[50]; 125 char cgi_1[1]; 126 127 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 128 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 129 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 130 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 131 cgi_50, 50)); 132 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 133 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 134 135 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 136 cgi_1, 1)); 137 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 138 cgi_50, 50)); 139 EXPECT_STREQ("events=I7S,W1I", cgi_50); 140 } 141 142 TEST_F(RlzLibTest, ClearAllAllProductEvents) { 143 char cgi_50[50]; 144 145 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 146 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 147 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 148 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 149 cgi_50, 50)); 150 EXPECT_STREQ("events=I7S", cgi_50); 151 152 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 153 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 154 cgi_50, 50)); 155 EXPECT_STREQ("", cgi_50); 156 } 157 158 TEST_F(RlzLibTest, SetAccessPointRlz) { 159 char rlz_50[50]; 160 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "")); 161 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_50, 50)); 162 EXPECT_STREQ("", rlz_50); 163 164 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "IeTbRlz")); 165 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_50, 50)); 166 EXPECT_STREQ("IeTbRlz", rlz_50); 167 } 168 169 TEST_F(RlzLibTest, GetAccessPointRlz) { 170 char rlz_1[1]; 171 char rlz_50[50]; 172 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "")); 173 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_1, 1)); 174 EXPECT_STREQ("", rlz_1); 175 176 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "IeTbRlz")); 177 EXPECT_FALSE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_1, 1)); 178 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_50, 50)); 179 EXPECT_STREQ("IeTbRlz", rlz_50); 180 } 181 182 TEST_F(RlzLibTest, GetPingParams) { 183 MachineDealCodeHelper::Clear(); 184 185 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, 186 "TbRlzValue")); 187 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IE_HOME_PAGE, "")); 188 189 char cgi[2048]; 190 rlz_lib::AccessPoint points[] = 191 {rlz_lib::IETB_SEARCH_BOX, rlz_lib::NO_ACCESS_POINT, 192 rlz_lib::NO_ACCESS_POINT}; 193 194 EXPECT_TRUE(rlz_lib::GetPingParams(rlz_lib::TOOLBAR_NOTIFIER, points, 195 cgi, 2048)); 196 EXPECT_STREQ("rep=2&rlz=T4:TbRlzValue", cgi); 197 198 #if defined(OS_WIN) 199 EXPECT_TRUE(rlz_lib::MachineDealCode::Set("dcc_value")); 200 #define DCC_PARAM "&dcc=dcc_value" 201 #else 202 #define DCC_PARAM "" 203 #endif 204 205 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "")); 206 EXPECT_TRUE(rlz_lib::GetPingParams(rlz_lib::TOOLBAR_NOTIFIER, points, 207 cgi, 2048)); 208 EXPECT_STREQ("rep=2&rlz=T4:" DCC_PARAM, cgi); 209 210 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, 211 "TbRlzValue")); 212 EXPECT_FALSE(rlz_lib::GetPingParams(rlz_lib::TOOLBAR_NOTIFIER, points, 213 cgi, 23 + strlen(DCC_PARAM))); 214 EXPECT_STREQ("", cgi); 215 EXPECT_TRUE(rlz_lib::GetPingParams(rlz_lib::TOOLBAR_NOTIFIER, points, 216 cgi, 24 + strlen(DCC_PARAM))); 217 EXPECT_STREQ("rep=2&rlz=T4:TbRlzValue" DCC_PARAM, cgi); 218 219 EXPECT_TRUE(GetAccessPointRlz(rlz_lib::IE_HOME_PAGE, cgi, 2048)); 220 points[2] = rlz_lib::IE_HOME_PAGE; 221 EXPECT_TRUE(rlz_lib::GetPingParams(rlz_lib::TOOLBAR_NOTIFIER, points, 222 cgi, 2048)); 223 EXPECT_STREQ("rep=2&rlz=T4:TbRlzValue" DCC_PARAM, cgi); 224 } 225 226 TEST_F(RlzLibTest, IsPingResponseValid) { 227 const char* kBadPingResponses[] = { 228 // No checksum. 229 "version: 3.0.914.7250\r\n" 230 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 231 "launch-action: custom-action\r\n" 232 "launch-target: SearchWithGoogleUpdate.exe\r\n" 233 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 234 "rlz: 1R1_____en__252\r\n" 235 "rlzXX: 1R1_____en__250\r\n", 236 237 // Invalid checksum. 238 "version: 3.0.914.7250\r\n" 239 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 240 "launch-action: custom-action\r\n" 241 "launch-target: SearchWithGoogleUpdate.exe\r\n" 242 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 243 "rlz: 1R1_____en__252\r\n" 244 "rlzXX: 1R1_____en__250\r\n" 245 "rlzT4 1T4_____en__251\r\n" 246 "rlzT4: 1T4_____en__252\r\n" 247 "rlz\r\n" 248 "crc32: B12CC79A", 249 250 // Misplaced checksum. 251 "version: 3.0.914.7250\r\n" 252 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 253 "launch-action: custom-action\r\n" 254 "launch-target: SearchWithGoogleUpdate.exe\r\n" 255 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 256 "rlz: 1R1_____en__252\r\n" 257 "rlzXX: 1R1_____en__250\r\n" 258 "crc32: B12CC79C\r\n" 259 "rlzT4 1T4_____en__251\r\n" 260 "rlzT4: 1T4_____en__252\r\n" 261 "rlz\r\n", 262 263 NULL 264 }; 265 266 const char* kGoodPingResponses[] = { 267 "version: 3.0.914.7250\r\n" 268 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 269 "launch-action: custom-action\r\n" 270 "launch-target: SearchWithGoogleUpdate.exe\r\n" 271 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 272 "rlz: 1R1_____en__252\r\n" 273 "rlzXX: 1R1_____en__250\r\n" 274 "rlzT4 1T4_____en__251\r\n" 275 "rlzT4: 1T4_____en__252\r\n" 276 "rlz\r\n" 277 "crc32: D6FD55A3", 278 279 "version: 3.0.914.7250\r\n" 280 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 281 "launch-action: custom-action\r\n" 282 "launch-target: SearchWithGoogleUpdate.exe\r\n" 283 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 284 "rlz: 1R1_____en__252\r\n" 285 "rlzXX: 1R1_____en__250\r\n" 286 "rlzT4 1T4_____en__251\r\n" 287 "rlzT4: 1T4_____en__252\r\n" 288 "rlz\r\n" 289 "crc32: D6FD55A3\r\n" 290 "extradata: not checksummed", 291 292 NULL 293 }; 294 295 for (int i = 0; kBadPingResponses[i]; i++) 296 EXPECT_FALSE(rlz_lib::IsPingResponseValid(kBadPingResponses[i], NULL)); 297 298 for (int i = 0; kGoodPingResponses[i]; i++) 299 EXPECT_TRUE(rlz_lib::IsPingResponseValid(kGoodPingResponses[i], NULL)); 300 } 301 302 TEST_F(RlzLibTest, ParsePingResponse) { 303 const char* kPingResponse = 304 "version: 3.0.914.7250\r\n" 305 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 306 "launch-action: custom-action\r\n" 307 "launch-target: SearchWithGoogleUpdate.exe\r\n" 308 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 309 "rlz: 1R1_____en__252\r\n" // Invalid RLZ - no access point. 310 "rlzXX: 1R1_____en__250\r\n" // Invalid RLZ - bad access point. 311 "rlzT4 1T4_____en__251\r\n" // Invalid RLZ - missing colon. 312 "rlzT4: 1T4_____en__252\r\n" // GoodRLZ. 313 "events: I7S,W1I\r\n" // Clear all events. 314 "rlz\r\n" 315 "dcc: dcc_value\r\n" 316 "crc32: F9070F81"; 317 318 #if defined(OS_WIN) 319 EXPECT_TRUE(rlz_lib::MachineDealCode::Set("dcc_value2")); 320 #endif 321 322 // Record some product events to check that they get cleared. 323 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 324 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 325 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 326 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 327 328 EXPECT_TRUE(rlz_lib::SetAccessPointRlz( 329 rlz_lib::IETB_SEARCH_BOX, "TbRlzValue")); 330 331 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER, 332 kPingResponse)); 333 334 #if defined(OS_WIN) 335 EXPECT_TRUE(rlz_lib::MachineDealCode::Set("dcc_value")); 336 #endif 337 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER, 338 kPingResponse)); 339 340 char value[50]; 341 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, value, 50)); 342 EXPECT_STREQ("1T4_____en__252", value); 343 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 344 value, 50)); 345 EXPECT_STREQ("", value); 346 347 const char* kPingResponse2 = 348 "rlzT4: 1T4_____de__253 \r\n" // Good with extra spaces. 349 "crc32: 321334F5\r\n"; 350 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER, 351 kPingResponse2)); 352 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, value, 50)); 353 EXPECT_STREQ("1T4_____de__253", value); 354 355 const char* kPingResponse3 = 356 "crc32: 0\r\n"; // Good RLZ - empty response. 357 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER, 358 kPingResponse3)); 359 EXPECT_STREQ("1T4_____de__253", value); 360 } 361 362 // Test whether a stateful event will only be sent in financial pings once. 363 TEST_F(RlzLibTest, ParsePingResponseWithStatefulEvents) { 364 const char* kPingResponse = 365 "version: 3.0.914.7250\r\n" 366 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 367 "launch-action: custom-action\r\n" 368 "launch-target: SearchWithGoogleUpdate.exe\r\n" 369 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 370 "rlzT4: 1T4_____en__252\r\n" // GoodRLZ. 371 "events: I7S,W1I\r\n" // Clear all events. 372 "stateful-events: W1I\r\n" // W1I as an stateful event. 373 "rlz\r\n" 374 "dcc: dcc_value\r\n" 375 "crc32: 55191759"; 376 377 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 378 379 // Record some product events to check that they get cleared. 380 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 381 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 382 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 383 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 384 385 EXPECT_TRUE(rlz_lib::SetAccessPointRlz( 386 rlz_lib::IETB_SEARCH_BOX, "TbRlzValue")); 387 388 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER, 389 kPingResponse)); 390 391 // Check all the events sent earlier are cleared. 392 char value[50]; 393 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 394 value, 50)); 395 EXPECT_STREQ("", value); 396 397 // Record both events (one is stateless and the other is stateful) again. 398 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 399 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 400 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 401 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 402 403 // Check the stateful event won't be sent again while the stateless one will. 404 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 405 value, 50)); 406 EXPECT_STREQ("events=I7S", value); 407 408 // Test that stateful events are cleared by ClearAllProductEvents(). After 409 // calling it, trying to record a stateful again should result in it being 410 // recorded again. 411 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 412 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 413 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 414 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 415 value, 50)); 416 EXPECT_STREQ("events=W1I", value); 417 } 418 419 TEST_F(RlzLibTest, SendFinancialPing) { 420 // We don't really check a value or result in this test. All this does is 421 // attempt to ping the financial server, which you can verify in Fiddler. 422 // TODO: Make this a measurable test. 423 424 #if defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET) 425 #if defined(OS_MACOSX) 426 base::mac::ScopedNSAutoreleasePool pool; 427 #endif 428 429 base::Thread::Options options; 430 options.message_loop_type = base::MessageLoop::TYPE_IO; 431 432 base::Thread io_thread("rlz_unittest_io_thread"); 433 ASSERT_TRUE(io_thread.StartWithOptions(options)); 434 435 scoped_refptr<net::TestURLRequestContextGetter> context = 436 new net::TestURLRequestContextGetter( 437 io_thread.message_loop()->message_loop_proxy()); 438 rlz_lib::SetURLRequestContext(context.get()); 439 440 class URLRequestRAII { 441 public: 442 URLRequestRAII(net::URLRequestContextGetter* context) { 443 rlz_lib::SetURLRequestContext(context); 444 } 445 ~URLRequestRAII() { 446 rlz_lib::SetURLRequestContext(NULL); 447 } 448 }; 449 450 URLRequestRAII set_context(context.get()); 451 #endif 452 453 MachineDealCodeHelper::Clear(); 454 #if defined(OS_WIN) 455 EXPECT_TRUE(rlz_lib::MachineDealCode::Set("dcc_value")); 456 #endif 457 458 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, 459 "TbRlzValue")); 460 461 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 462 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 463 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 464 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 465 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 466 467 rlz_lib::AccessPoint points[] = 468 {rlz_lib::IETB_SEARCH_BOX, rlz_lib::NO_ACCESS_POINT, 469 rlz_lib::NO_ACCESS_POINT}; 470 471 std::string request; 472 rlz_lib::SendFinancialPing(rlz_lib::TOOLBAR_NOTIFIER, points, 473 "swg", "GGLA", "SwgProductId1234", "en-UK", false, 474 /*skip_time_check=*/true); 475 } 476 477 TEST_F(RlzLibTest, ClearProductState) { 478 MachineDealCodeHelper::Clear(); 479 480 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, 481 "TbRlzValue")); 482 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::GD_DESKBAND, 483 "GdbRlzValue")); 484 485 rlz_lib::AccessPoint points[] = 486 { rlz_lib::IETB_SEARCH_BOX, rlz_lib::NO_ACCESS_POINT }; 487 488 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 489 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 490 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 491 rlz_lib::IETB_SEARCH_BOX, rlz_lib::INSTALL)); 492 493 rlz_lib::AccessPoint points2[] = 494 { rlz_lib::IETB_SEARCH_BOX, 495 rlz_lib::GD_DESKBAND, 496 rlz_lib::NO_ACCESS_POINT }; 497 498 char cgi[2048]; 499 EXPECT_TRUE(rlz_lib::GetPingParams(rlz_lib::TOOLBAR_NOTIFIER, points2, 500 cgi, 2048)); 501 EXPECT_STREQ("rep=2&rlz=T4:TbRlzValue,D1:GdbRlzValue", cgi); 502 503 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 504 cgi, 2048)); 505 std::string events(cgi); 506 EXPECT_LT(0u, events.find("I7S")); 507 EXPECT_LT(0u, events.find("T4I")); 508 EXPECT_LT(0u, events.find("T4R")); 509 510 rlz_lib::ClearProductState(rlz_lib::TOOLBAR_NOTIFIER, points); 511 512 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, 513 cgi, 2048)); 514 EXPECT_STREQ("", cgi); 515 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::GD_DESKBAND, 516 cgi, 2048)); 517 EXPECT_STREQ("GdbRlzValue", cgi); 518 519 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 520 cgi, 2048)); 521 EXPECT_STREQ("", cgi); 522 } 523 524 #if defined(OS_WIN) 525 template<class T> 526 class typed_buffer_ptr { 527 scoped_ptr<char[]> buffer_; 528 529 public: 530 typed_buffer_ptr() { 531 } 532 533 explicit typed_buffer_ptr(size_t size) : buffer_(new char[size]) { 534 } 535 536 void reset(size_t size) { 537 buffer_.reset(new char[size]); 538 } 539 540 operator T*() { 541 return reinterpret_cast<T*>(buffer_.get()); 542 } 543 }; 544 545 namespace rlz_lib { 546 bool HasAccess(PSID sid, ACCESS_MASK access_mask, ACL* dacl); 547 } 548 549 bool EmptyAcl(ACL* acl) { 550 ACL_SIZE_INFORMATION info; 551 bool ret = GetAclInformation(acl, &info, sizeof(info), AclSizeInformation); 552 EXPECT_TRUE(ret); 553 554 for (DWORD i = 0; i < info.AceCount && ret; ++i) { 555 ret = DeleteAce(acl, 0); 556 EXPECT_TRUE(ret); 557 } 558 559 return ret; 560 } 561 562 TEST_F(RlzLibTest, HasAccess) { 563 // Create a SID that represents ALL USERS. 564 DWORD users_sid_size = SECURITY_MAX_SID_SIZE; 565 typed_buffer_ptr<SID> users_sid(users_sid_size); 566 CreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &users_sid_size); 567 568 // RLZ always asks for KEY_ALL_ACCESS access to the key. This is what we 569 // test here. 570 571 // No ACL mean no access. 572 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, NULL)); 573 574 // Create an ACL for these tests. 575 const DWORD kMaxAclSize = 1024; 576 typed_buffer_ptr<ACL> dacl(kMaxAclSize); 577 InitializeAcl(dacl, kMaxAclSize, ACL_REVISION); 578 579 // Empty DACL mean no access. 580 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 581 582 // ACE without all needed privileges should mean no access. 583 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_READ, users_sid)); 584 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 585 586 // ACE without all needed privileges should mean no access. 587 EXPECT_TRUE(EmptyAcl(dacl)); 588 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_WRITE, users_sid)); 589 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 590 591 // A deny ACE before an allow ACE should not give access. 592 EXPECT_TRUE(EmptyAcl(dacl)); 593 EXPECT_TRUE(AddAccessDeniedAce(dacl, ACL_REVISION, KEY_ALL_ACCESS, 594 users_sid)); 595 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_ALL_ACCESS, 596 users_sid)); 597 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 598 599 // A deny ACE before an allow ACE should not give access. 600 EXPECT_TRUE(EmptyAcl(dacl)); 601 EXPECT_TRUE(AddAccessDeniedAce(dacl, ACL_REVISION, KEY_READ, users_sid)); 602 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_ALL_ACCESS, 603 users_sid)); 604 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 605 606 607 // An allow ACE without all required bits should not give access. 608 EXPECT_TRUE(EmptyAcl(dacl)); 609 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_WRITE, users_sid)); 610 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 611 612 // An allow ACE with all required bits should give access. 613 EXPECT_TRUE(EmptyAcl(dacl)); 614 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_ALL_ACCESS, 615 users_sid)); 616 EXPECT_TRUE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 617 618 // A deny ACE after an allow ACE should not give access. 619 EXPECT_TRUE(EmptyAcl(dacl)); 620 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_ALL_ACCESS, 621 users_sid)); 622 EXPECT_TRUE(AddAccessDeniedAce(dacl, ACL_REVISION, KEY_READ, users_sid)); 623 EXPECT_TRUE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 624 625 // An inherit-only allow ACE should not give access. 626 EXPECT_TRUE(EmptyAcl(dacl)); 627 EXPECT_TRUE(AddAccessAllowedAceEx(dacl, ACL_REVISION, INHERIT_ONLY_ACE, 628 KEY_ALL_ACCESS, users_sid)); 629 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 630 631 // An inherit-only deny ACE should not apply. 632 EXPECT_TRUE(EmptyAcl(dacl)); 633 EXPECT_TRUE(AddAccessDeniedAceEx(dacl, ACL_REVISION, INHERIT_ONLY_ACE, 634 KEY_ALL_ACCESS, users_sid)); 635 EXPECT_TRUE(AddAccessAllowedAce(dacl, ACL_REVISION, KEY_ALL_ACCESS, 636 users_sid)); 637 EXPECT_TRUE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl)); 638 } 639 #endif 640 641 TEST_F(RlzLibTest, BrandingRecordProductEvent) { 642 // Don't run these tests if a supplementary brand is already in place. That 643 // way we can control the branding. 644 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 645 return; 646 647 char cgi_50[50]; 648 649 // Record different events for the same product with diffrent branding, and 650 // make sure that the information remains separate. 651 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 652 { 653 rlz_lib::SupplementaryBranding branding("TEST"); 654 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 655 } 656 657 // Test that recording events with the default brand and a supplementary 658 // brand don't overwrite each other. 659 660 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 661 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 662 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 663 cgi_50, 50)); 664 EXPECT_STREQ("events=I7S", cgi_50); 665 666 { 667 rlz_lib::SupplementaryBranding branding("TEST"); 668 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 669 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::INSTALL)); 670 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 671 cgi_50, 50)); 672 EXPECT_STREQ("events=I7I", cgi_50); 673 } 674 675 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 676 cgi_50, 50)); 677 EXPECT_STREQ("events=I7S", cgi_50); 678 } 679 680 TEST_F(RlzLibTest, BrandingSetAccessPointRlz) { 681 // Don't run these tests if a supplementary brand is already in place. That 682 // way we can control the branding. 683 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 684 return; 685 686 char rlz_50[50]; 687 688 // Test that setting RLZ strings with the default brand and a supplementary 689 // brand don't overwrite each other. 690 691 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "IeTbRlz")); 692 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_50, 50)); 693 EXPECT_STREQ("IeTbRlz", rlz_50); 694 695 { 696 rlz_lib::SupplementaryBranding branding("TEST"); 697 698 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "SuppRlz")); 699 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_50, 700 50)); 701 EXPECT_STREQ("SuppRlz", rlz_50); 702 } 703 704 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_50, 50)); 705 EXPECT_STREQ("IeTbRlz", rlz_50); 706 707 } 708 709 TEST_F(RlzLibTest, BrandingWithStatefulEvents) { 710 // Don't run these tests if a supplementary brand is already in place. That 711 // way we can control the branding. 712 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 713 return; 714 715 const char* kPingResponse = 716 "version: 3.0.914.7250\r\n" 717 "url: http://www.corp.google.com/~av/45/opt/SearchWithGoogleUpdate.exe\r\n" 718 "launch-action: custom-action\r\n" 719 "launch-target: SearchWithGoogleUpdate.exe\r\n" 720 "signature: c08a3f4438e1442c4fe5678ee147cf6c5516e5d62bb64e\r\n" 721 "rlzT4: 1T4_____en__252\r\n" // GoodRLZ. 722 "events: I7S,W1I\r\n" // Clear all events. 723 "stateful-events: W1I\r\n" // W1I as an stateful event. 724 "rlz\r\n" 725 "dcc: dcc_value\r\n" 726 "crc32: 55191759"; 727 728 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 729 { 730 rlz_lib::SupplementaryBranding branding("TEST"); 731 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 732 } 733 734 // Record some product events for the default and supplementary brand. 735 // Check that they get cleared only for the default brand. 736 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 737 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 738 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 739 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 740 741 { 742 rlz_lib::SupplementaryBranding branding("TEST"); 743 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 744 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 745 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 746 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 747 } 748 749 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER, 750 kPingResponse)); 751 752 // Check all the events sent earlier are cleared only for default brand. 753 char value[50]; 754 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 755 value, 50)); 756 EXPECT_STREQ("", value); 757 758 { 759 rlz_lib::SupplementaryBranding branding("TEST"); 760 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 761 value, 50)); 762 EXPECT_STREQ("events=I7S,W1I", value); 763 } 764 765 // Record both events (one is stateless and the other is stateful) again. 766 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 767 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 768 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 769 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 770 771 // Check the stateful event won't be sent again while the stateless one will. 772 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 773 value, 50)); 774 EXPECT_STREQ("events=I7S", value); 775 776 { 777 rlz_lib::SupplementaryBranding branding("TEST"); 778 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER, 779 kPingResponse)); 780 781 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 782 value, 50)); 783 EXPECT_STREQ("", value); 784 } 785 786 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER, 787 value, 50)); 788 EXPECT_STREQ("events=I7S", value); 789 } 790 791 #if defined(OS_POSIX) 792 class ReadonlyRlzDirectoryTest : public RlzLibTestNoMachineState { 793 protected: 794 virtual void SetUp() OVERRIDE; 795 }; 796 797 void ReadonlyRlzDirectoryTest::SetUp() { 798 RlzLibTestNoMachineState::SetUp(); 799 // Make the rlz directory non-writeable. 800 int chmod_result = chmod(temp_dir_.path().value().c_str(), 0500); 801 ASSERT_EQ(0, chmod_result); 802 } 803 804 TEST_F(ReadonlyRlzDirectoryTest, WriteFails) { 805 // The rlz test runner runs every test twice: Once normally, and once with 806 // a SupplementaryBranding on the stack. In the latter case, the rlz lock 807 // has already been acquired before the rlz directory got changed to 808 // read-only, which makes this test pointless. So run it only in the first 809 // pass. 810 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 811 return; 812 813 EXPECT_FALSE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 814 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 815 } 816 817 // Regression test for http://crbug.com/121255 818 TEST_F(ReadonlyRlzDirectoryTest, SupplementaryBrandingDoesNotCrash) { 819 // See the comment at the top of WriteFails. 820 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 821 return; 822 823 rlz_lib::SupplementaryBranding branding("TEST"); 824 EXPECT_FALSE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 825 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::INSTALL)); 826 } 827 828 // Regression test for http://crbug.com/141108 829 TEST_F(RlzLibTest, ConcurrentStoreAccessWithProcessExitsWhileLockHeld) { 830 // See the comment at the top of WriteFails. 831 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 832 return; 833 834 std::vector<pid_t> pids; 835 for (int i = 0; i < 10; ++i) { 836 pid_t pid = fork(); 837 ASSERT_NE(-1, pid); 838 if (pid == 0) { 839 // Child. 840 { 841 // SupplementaryBranding is a RAII object for the rlz lock. 842 rlz_lib::SupplementaryBranding branding("TEST"); 843 844 // Simulate a crash while holding the lock in some of the children. 845 if (i > 0 && i % 3 == 0) 846 _exit(0); 847 848 // Note: Since this is in a forked child, a failing expectation won't 849 // make the test fail. It does however cause lots of "check failed" 850 // error output. The parent process will then check the exit code 851 // below to make the test fail. 852 bool success = rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 853 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::INSTALL); 854 EXPECT_TRUE(success); 855 _exit(success ? 0 : 1); 856 } 857 _exit(0); 858 } else { 859 // Parent. 860 pids.push_back(pid); 861 } 862 } 863 864 int status; 865 for (size_t i = 0; i < pids.size(); ++i) { 866 if (HANDLE_EINTR(waitpid(pids[i], &status, 0)) != -1) 867 EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0); 868 } 869 870 // No child should have the lock at this point, not even the crashed ones. 871 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 872 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::INSTALL)); 873 } 874 875 TEST_F(RlzLibTest, LockAcquistionSucceedsButStoreFileCannotBeCreated) { 876 // See the comment at the top of WriteFails. 877 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 878 return; 879 880 // Create a directory where the rlz file is supposed to appear. This way, 881 // the lock file can be created successfully, but creation of the rlz file 882 // itself will fail. 883 int mkdir_result = mkdir(rlz_lib::testing::RlzStoreFilenameStr().c_str(), 884 0500); 885 ASSERT_EQ(0, mkdir_result); 886 887 rlz_lib::SupplementaryBranding branding("TEST"); 888 EXPECT_FALSE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 889 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::INSTALL)); 890 } 891 892 #endif 893