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 FinancialPing class. 6// 7// These tests should not be executed on the build server: 8// - They modify machine state (registry). 9// 10// These tests require write access to HKCU and HKLM. 11// 12// The "GGLA" brand is used to test the normal code flow of the code, and the 13// "TEST" brand is used to test the supplementary brand code code flow. In one 14// case below, the brand "GOOG" is used because the code wants to use a brand 15// that is neither of the two mentioned above. 16 17#include "rlz/lib/financial_ping.h" 18 19#include "base/basictypes.h" 20#include "base/logging.h" 21#include "base/strings/string_util.h" 22#include "base/strings/stringprintf.h" 23#include "base/strings/utf_string_conversions.h" 24#include "rlz/lib/lib_values.h" 25#include "rlz/lib/machine_id.h" 26#include "rlz/lib/rlz_lib.h" 27#include "rlz/lib/rlz_value_store.h" 28#include "rlz/test/rlz_test_helpers.h" 29#include "testing/gmock/include/gmock/gmock.h" 30#include "testing/gtest/include/gtest/gtest.h" 31 32#if defined(OS_WIN) 33#include "rlz/win/lib/machine_deal.h" 34#else 35#include "base/time/time.h" 36#endif 37 38namespace { 39 40// Must match the implementation in file_time.cc. 41int64 GetSystemTimeAsInt64() { 42#if defined(OS_WIN) 43 FILETIME now_as_file_time; 44 GetSystemTimeAsFileTime(&now_as_file_time); 45 LARGE_INTEGER integer; 46 integer.HighPart = now_as_file_time.dwHighDateTime; 47 integer.LowPart = now_as_file_time.dwLowDateTime; 48 return integer.QuadPart; 49#else 50 double now_seconds = base::Time::Now().ToDoubleT(); 51 return static_cast<int64>(now_seconds * 1000 * 1000 * 10); 52#endif 53} 54 55// Ping times in 100-nanosecond intervals. 56const int64 k1MinuteInterval = 60LL * 10000000LL; // 1 minute 57 58} // namespace anonymous 59 60class FinancialPingTest : public RlzLibTestBase { 61}; 62 63TEST_F(FinancialPingTest, FormRequest) { 64 std::string brand_string = rlz_lib::SupplementaryBranding::GetBrand(); 65 const char* brand = brand_string.empty() ? "GGLA" : brand_string.c_str(); 66 67#if defined(OS_WIN) 68 EXPECT_TRUE(rlz_lib::MachineDealCode::Set("dcc_value")); 69#define DCC_PARAM "&dcc=dcc_value" 70#else 71#define DCC_PARAM "" 72#endif 73 74 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, 75 "TbRlzValue")); 76 77 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 78 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 79 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 80 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 81 rlz_lib::IE_HOME_PAGE, rlz_lib::INSTALL)); 82 83 rlz_lib::AccessPoint points[] = 84 {rlz_lib::IETB_SEARCH_BOX, rlz_lib::NO_ACCESS_POINT, 85 rlz_lib::NO_ACCESS_POINT}; 86 87 std::string machine_id; 88 bool got_machine_id = rlz_lib::GetMachineId(&machine_id); 89 90 std::string request; 91 EXPECT_TRUE(rlz_lib::FinancialPing::FormRequest(rlz_lib::TOOLBAR_NOTIFIER, 92 points, "swg", brand, NULL, "en", false, &request)); 93 std::string expected_response; 94 base::StringAppendF(&expected_response, 95 "/tools/pso/ping?as=swg&brand=%s&hl=en&" 96 "events=I7S,W1I&rep=2&rlz=T4:TbRlzValue" DCC_PARAM 97, brand); 98 99 if (got_machine_id) 100 base::StringAppendF(&expected_response, "&id=%s", machine_id.c_str()); 101 EXPECT_EQ(expected_response, request); 102 103 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, "")); 104 EXPECT_TRUE(rlz_lib::FinancialPing::FormRequest(rlz_lib::TOOLBAR_NOTIFIER, 105 points, "swg", brand, "IdOk2", NULL, false, &request)); 106 expected_response.clear(); 107 base::StringAppendF(&expected_response, 108 "/tools/pso/ping?as=swg&brand=%s&pid=IdOk2&" 109 "events=I7S,W1I&rep=2&rlz=T4:" DCC_PARAM, brand); 110 111 if (got_machine_id) 112 base::StringAppendF(&expected_response, "&id=%s", machine_id.c_str()); 113 EXPECT_EQ(expected_response, request); 114 115 EXPECT_TRUE(rlz_lib::FinancialPing::FormRequest(rlz_lib::TOOLBAR_NOTIFIER, 116 points, "swg", brand, "IdOk", NULL, true, &request)); 117 expected_response.clear(); 118 base::StringAppendF(&expected_response, 119 "/tools/pso/ping?as=swg&brand=%s&pid=IdOk&" 120 "events=I7S,W1I&rep=2&rlz=T4:" DCC_PARAM, brand); 121 EXPECT_EQ(expected_response, request); 122 123 EXPECT_TRUE(rlz_lib::FinancialPing::FormRequest(rlz_lib::TOOLBAR_NOTIFIER, 124 points, "swg", brand, NULL, NULL, true, &request)); 125 expected_response.clear(); 126 base::StringAppendF(&expected_response, 127 "/tools/pso/ping?as=swg&brand=%s&events=I7S,W1I&rep=2" 128 "&rlz=T4:" DCC_PARAM, brand); 129 EXPECT_EQ(expected_response, request); 130 131 132 // Clear all events. 133 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 134 135 // Clear all RLZs. 136 char rlz[rlz_lib::kMaxRlzLength + 1]; 137 for (int ap = rlz_lib::NO_ACCESS_POINT + 1; 138 ap < rlz_lib::LAST_ACCESS_POINT; ap++) { 139 rlz[0] = 0; 140 rlz_lib::AccessPoint point = static_cast<rlz_lib::AccessPoint>(ap); 141 if (rlz_lib::GetAccessPointRlz(point, rlz, arraysize(rlz)) && rlz[0]) { 142 rlz_lib::SetAccessPointRlz(point, ""); 143 } 144 } 145 146 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::IETB_SEARCH_BOX, 147 "TbRlzValue")); 148 EXPECT_TRUE(rlz_lib::SetAccessPointRlz(rlz_lib::QUICK_SEARCH_BOX, 149 "QsbRlzValue")); 150 EXPECT_TRUE(rlz_lib::FinancialPing::FormRequest(rlz_lib::TOOLBAR_NOTIFIER, 151 points, "swg", brand, NULL, NULL, false, &request)); 152 expected_response.clear(); 153 base::StringAppendF(&expected_response, 154 "/tools/pso/ping?as=swg&brand=%s&rep=2&rlz=T4:TbRlzValue," 155 "Q1:QsbRlzValue" DCC_PARAM, brand); 156 EXPECT_STREQ(expected_response.c_str(), request.c_str()); 157 158 if (!GetAccessPointRlz(rlz_lib::IE_HOME_PAGE, rlz, arraysize(rlz))) { 159 points[2] = rlz_lib::IE_HOME_PAGE; 160 EXPECT_TRUE(rlz_lib::FinancialPing::FormRequest(rlz_lib::TOOLBAR_NOTIFIER, 161 points, "swg", brand, "MyId", "en-US", true, &request)); 162 expected_response.clear(); 163 base::StringAppendF(&expected_response, 164 "/tools/pso/ping?as=swg&brand=%s&hl=en-US&pid=MyId&rep=2" 165 "&rlz=T4:TbRlzValue,Q1:QsbRlzValue" DCC_PARAM, brand); 166 EXPECT_STREQ(expected_response.c_str(), request.c_str()); 167 } 168} 169 170TEST_F(FinancialPingTest, FormRequestBadBrand) { 171 rlz_lib::AccessPoint points[] = 172 {rlz_lib::IETB_SEARCH_BOX, rlz_lib::NO_ACCESS_POINT, 173 rlz_lib::NO_ACCESS_POINT}; 174 175 std::string request; 176 bool ok = rlz_lib::FinancialPing::FormRequest(rlz_lib::TOOLBAR_NOTIFIER, 177 points, "swg", "GOOG", NULL, "en", false, &request); 178 EXPECT_EQ(rlz_lib::SupplementaryBranding::GetBrand().empty(), ok); 179} 180 181 182static void SetLastPingTime(int64 time, rlz_lib::Product product) { 183 rlz_lib::ScopedRlzValueStoreLock lock; 184 rlz_lib::RlzValueStore* store = lock.GetStore(); 185 ASSERT_TRUE(store); 186 ASSERT_TRUE(store->HasAccess(rlz_lib::RlzValueStore::kWriteAccess)); 187 store->WritePingTime(product, time); 188} 189 190TEST_F(FinancialPingTest, IsPingTime) { 191 int64 now = GetSystemTimeAsInt64(); 192 int64 last_ping = now - rlz_lib::kEventsPingInterval - k1MinuteInterval; 193 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 194 195 // No events, last ping just over a day ago. 196 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 197 EXPECT_FALSE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 198 false)); 199 200 // Has events, last ping just over a day ago. 201 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 202 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 203 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 204 false)); 205 206 // Has events, last ping just under a day ago. 207 last_ping = now - rlz_lib::kEventsPingInterval + k1MinuteInterval; 208 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 209 EXPECT_FALSE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 210 false)); 211 212 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 213 214 // No events, last ping just under a week ago. 215 last_ping = now - rlz_lib::kNoEventsPingInterval + k1MinuteInterval; 216 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 217 EXPECT_FALSE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 218 false)); 219 220 // No events, last ping just over a week ago. 221 last_ping = now - rlz_lib::kNoEventsPingInterval - k1MinuteInterval; 222 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 223 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 224 false)); 225 226 // Last ping was in future (invalid). 227 last_ping = now + k1MinuteInterval; 228 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 229 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 230 false)); 231 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 232 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 233 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 234 false)); 235} 236 237TEST_F(FinancialPingTest, BrandingIsPingTime) { 238 // Don't run these tests if a supplementary brand is already in place. That 239 // way we can control the branding. 240 if (!rlz_lib::SupplementaryBranding::GetBrand().empty()) 241 return; 242 243 int64 now = GetSystemTimeAsInt64(); 244 int64 last_ping = now - rlz_lib::kEventsPingInterval - k1MinuteInterval; 245 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 246 247 // Has events, last ping just over a day ago. 248 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 249 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 250 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 251 false)); 252 253 { 254 rlz_lib::SupplementaryBranding branding("TEST"); 255 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 256 257 // Has events, last ping just over a day ago. 258 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 259 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 260 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 261 false)); 262 } 263 264 last_ping = now - k1MinuteInterval; 265 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 266 267 EXPECT_FALSE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 268 false)); 269 270 { 271 rlz_lib::SupplementaryBranding branding("TEST"); 272 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 273 false)); 274 } 275} 276 277TEST_F(FinancialPingTest, ClearLastPingTime) { 278 int64 now = GetSystemTimeAsInt64(); 279 int64 last_ping = now - rlz_lib::kEventsPingInterval + k1MinuteInterval; 280 SetLastPingTime(last_ping, rlz_lib::TOOLBAR_NOTIFIER); 281 282 // Has events, last ping just under a day ago. 283 EXPECT_TRUE(rlz_lib::ClearAllProductEvents(rlz_lib::TOOLBAR_NOTIFIER)); 284 EXPECT_TRUE(rlz_lib::RecordProductEvent(rlz_lib::TOOLBAR_NOTIFIER, 285 rlz_lib::IE_DEFAULT_SEARCH, rlz_lib::SET_TO_GOOGLE)); 286 EXPECT_FALSE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 287 false)); 288 289 EXPECT_TRUE(rlz_lib::FinancialPing::ClearLastPingTime( 290 rlz_lib::TOOLBAR_NOTIFIER)); 291 EXPECT_TRUE(rlz_lib::FinancialPing::IsPingTime(rlz_lib::TOOLBAR_NOTIFIER, 292 false)); 293} 294