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 38 namespace { 39 40 // Must match the implementation in file_time.cc. 41 int64 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. 56 const int64 k1MinuteInterval = 60LL * 10000000LL; // 1 minute 57 58 } // namespace anonymous 59 60 class FinancialPingTest : public RlzLibTestBase { 61 }; 62 63 TEST_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 170 TEST_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 182 static 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 190 TEST_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 237 TEST_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 277 TEST_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