Fix build break
[chromium-blink-merge.git] / rlz / lib / rlz_lib_test.cc
blobb5ef72edb938ff7c22403d3ae821fe7b76a4df01
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).
11 // These tests require write access to HKLM and HKCU.
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.
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"
22 #include "rlz/lib/rlz_lib.h"
23 #include "rlz/lib/rlz_value_store.h"
24 #include "rlz/test/rlz_test_helpers.h"
26 #if defined(OS_WIN)
27 #include <Windows.h>
28 #include "rlz/win/lib/machine_deal.h"
29 #endif
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
38 class MachineDealCodeHelper
39 #if defined(OS_WIN)
40 : public rlz_lib::MachineDealCode
41 #endif
43 public:
44 static bool Clear() {
45 #if defined(OS_WIN)
46 return rlz_lib::MachineDealCode::Clear();
47 #else
48 return true;
49 #endif
52 private:
53 MachineDealCodeHelper() {}
54 ~MachineDealCodeHelper() {}
57 class RlzLibTest : public RlzLibTestBase {
60 TEST_F(RlzLibTest, RecordProductEvent) {
61 char cgi_50[50];
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);
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);
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);
83 TEST_F(RlzLibTest, ClearProductEvent) {
84 char cgi_50[50];
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);
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);
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);
123 TEST_F(RlzLibTest, GetProductEventsAsCgi) {
124 char cgi_50[50];
125 char cgi_1[1];
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));
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);
142 TEST_F(RlzLibTest, ClearAllAllProductEvents) {
143 char cgi_50[50];
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);
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);
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);
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);
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);
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);
182 TEST_F(RlzLibTest, GetPingParams) {
183 MachineDealCodeHelper::Clear();
185 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX,
186 "TbRlzValue"));
187 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IE_HOME_PAGE, ""));
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};
194 EXPECT_TRUE(rlz_lib::GetPingParams(rlz_lib::TOOLBAR_NOTIFIER, points,
195 cgi, 2048));
196 EXPECT_STREQ("rep=2&rlz=T4:TbRlzValue", cgi);
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
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);
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);
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);
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",
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",
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",
263 NULL
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",
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",
292 NULL
295 for (int i = 0; kBadPingResponses[i]; i++)
296 EXPECT_FALSE(rlz_lib::IsPingResponseValid(kBadPingResponses[i], NULL));
298 for (int i = 0; kGoodPingResponses[i]; i++)
299 EXPECT_TRUE(rlz_lib::IsPingResponseValid(kGoodPingResponses[i], NULL));
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";
318 #if defined(OS_WIN)
319 EXPECT_TRUE(rlz_lib::MachineDealCode::Set("dcc_value2"));
320 #endif
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));
328 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(
329 rlz_lib::IETB_SEARCH_BOX, "TbRlzValue"));
331 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER,
332 kPingResponse));
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));
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);
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);
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);
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";
377 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER));
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));
385 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(
386 rlz_lib::IETB_SEARCH_BOX, "TbRlzValue"));
388 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER,
389 kPingResponse));
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);
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));
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);
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);
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.
424 #if defined(RLZ_NETWORK_IMPLEMENTATION_CHROME_NET)
425 #if defined(OS_MACOSX)
426 base::mac::ScopedNSAutoreleasePool pool;
427 #endif
429 base::Thread::Options options;
430 options.message_loop_type = MessageLoop::TYPE_IO;
432 base::Thread io_thread("rlz_unittest_io_thread");
433 ASSERT_TRUE(io_thread.StartWithOptions(options));
435 scoped_refptr<net::TestURLRequestContextGetter> context =
436 new net::TestURLRequestContextGetter(
437 io_thread.message_loop()->message_loop_proxy());
438 rlz_lib::SetURLRequestContext(context.get());
440 class URLRequestRAII {
441 public:
442 URLRequestRAII(net::URLRequestContextGetter* context) {
443 rlz_lib::SetURLRequestContext(context);
445 ~URLRequestRAII() {
446 rlz_lib::SetURLRequestContext(NULL);
450 URLRequestRAII set_context(context.get());
451 #endif
453 MachineDealCodeHelper::Clear();
454 #if defined(OS_WIN)
455 EXPECT_TRUE(rlz_lib::MachineDealCode::Set("dcc_value"));
456 #endif
458 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX,
459 "TbRlzValue"));
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));
467 rlz_lib::AccessPoint points[] =
468 {rlz_lib::IETB_SEARCH_BOX, rlz_lib::NO_ACCESS_POINT,
469 rlz_lib::NO_ACCESS_POINT};
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);
477 TEST_F(RlzLibTest, ClearProductState) {
478 MachineDealCodeHelper::Clear();
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"));
485 rlz_lib::AccessPoint points[] =
486 { rlz_lib::IETB_SEARCH_BOX, rlz_lib::NO_ACCESS_POINT };
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));
493 rlz_lib::AccessPoint points2[] =
494 { rlz_lib::IETB_SEARCH_BOX,
495 rlz_lib::GD_DESKBAND,
496 rlz_lib::NO_ACCESS_POINT };
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);
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"));
510 rlz_lib::ClearProductState(rlz_lib::TOOLBAR_NOTIFIER, points);
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);
519 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER,
520 cgi, 2048));
521 EXPECT_STREQ("", cgi);
524 #if defined(OS_WIN)
525 template<class T>
526 class typed_buffer_ptr {
527 scoped_ptr<char[]> buffer_;
529 public:
530 typed_buffer_ptr() {
533 explicit typed_buffer_ptr(size_t size) : buffer_(new char[size]) {
536 void reset(size_t size) {
537 buffer_.reset(new char[size]);
540 operator T*() {
541 return reinterpret_cast<T*>(buffer_.get());
545 namespace rlz_lib {
546 bool HasAccess(PSID sid, ACCESS_MASK access_mask, ACL* dacl);
549 bool EmptyAcl(ACL* acl) {
550 ACL_SIZE_INFORMATION info;
551 bool ret = GetAclInformation(acl, &info, sizeof(info), AclSizeInformation);
552 EXPECT_TRUE(ret);
554 for (DWORD i = 0; i < info.AceCount && ret; ++i) {
555 ret = DeleteAce(acl, 0);
556 EXPECT_TRUE(ret);
559 return ret;
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);
568 // RLZ always asks for KEY_ALL_ACCESS access to the key. This is what we
569 // test here.
571 // No ACL mean no access.
572 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, NULL));
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);
579 // Empty DACL mean no access.
580 EXPECT_FALSE(rlz_lib::HasAccess(users_sid, KEY_ALL_ACCESS, dacl));
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));
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));
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));
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));
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));
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));
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));
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));
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));
639 #endif
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;
647 char cgi_50[50];
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));
653 rlz_lib::SupplementaryBranding branding("TEST");
654 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER));
657 // Test that recording events with the default brand and a supplementary
658 // brand don't overwrite each other.
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);
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);
675 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER,
676 cgi_50, 50));
677 EXPECT_STREQ("events=I7S", cgi_50);
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;
686 char rlz_50[50];
688 // Test that setting RLZ strings with the default brand and a supplementary
689 // brand don't overwrite each other.
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);
696 rlz_lib::SupplementaryBranding branding("TEST");
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);
704 EXPECT_TRUE(rlz_lib::GetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, rlz_50, 50));
705 EXPECT_STREQ("IeTbRlz", rlz_50);
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;
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";
728 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER));
730 rlz_lib::SupplementaryBranding branding("TEST");
731 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER));
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));
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));
749 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER,
750 kPingResponse));
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);
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);
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));
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);
777 rlz_lib::SupplementaryBranding branding("TEST");
778 EXPECT_TRUE(rlz_lib::ParsePingResponse(rlz_lib::TOOLBAR_NOTIFIER,
779 kPingResponse));
781 EXPECT_FALSE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER,
782 value, 50));
783 EXPECT_STREQ("", value);
786 EXPECT_TRUE(rlz_lib::GetProductEventsAsCgi(rlz_lib::TOOLBAR_NOTIFIER,
787 value, 50));
788 EXPECT_STREQ("events=I7S", value);
791 #if defined(OS_POSIX)
792 class ReadonlyRlzDirectoryTest : public RlzLibTestNoMachineState {
793 protected:
794 virtual void SetUp() OVERRIDE;
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);
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;
813 EXPECT_FALSE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER,
814 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE));
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;
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));
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;
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.
841 // SupplementaryBranding is a RAII object for the rlz lock.
842 rlz_lib::SupplementaryBranding branding("TEST");
844 // Simulate a crash while holding the lock in some of the children.
845 if (i > 0 && i % 3 == 0)
846 _exit(0);
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);
857 _exit(0);
858 } else {
859 // Parent.
860 pids.push_back(pid);
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);
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));
875 TEST_F(RlzLibTest, LockAcquistionSucceedsButStoreFileCannotBeCreated) {
876 // See the comment at the top of WriteFails.
877 if (!rlz_lib::SupplementaryBranding::GetBrand().empty())
878 return;
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);
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));
892 #endif