- add sources.
[platform/framework/web/crosswalk.git] / src / rlz / lib / rlz_lib_test.cc
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