Home | History | Annotate | Download | only in lib
      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