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