| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2010 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 #include <vector> | |
| 17 #include "omaha/base/const_object_names.h" | |
| 18 #include "omaha/base/error.h" | |
| 19 #include "omaha/base/highres_timer-win32.h" | |
| 20 #include "omaha/base/reg_key.h" | |
| 21 #include "omaha/base/scope_guard.h" | |
| 22 #include "omaha/base/scoped_any.h" | |
| 23 #include "omaha/base/scoped_ptr_address.h" | |
| 24 #include "omaha/base/thread.h" | |
| 25 #include "omaha/base/time.h" | |
| 26 #include "omaha/base/utils.h" | |
| 27 #include "omaha/base/vistautil.h" | |
| 28 #include "omaha/base/wmi_query.h" | |
| 29 #include "omaha/common/app_registry_utils.h" | |
| 30 #include "omaha/common/config_manager.h" | |
| 31 #include "omaha/common/const_goopdate.h" | |
| 32 #include "omaha/goopdate/app_manager.h" | |
| 33 #include "omaha/goopdate/app_unittest_base.h" | |
| 34 #include "omaha/setup/setup_google_update.h" | |
| 35 #include "omaha/testing/unit_test.h" | |
| 36 | |
| 37 using ::testing::_; | |
| 38 using ::testing::Return; | |
| 39 | |
| 40 namespace omaha { | |
| 41 | |
| 42 // TODO(omaha): there is a problem with this unit test. The model is built | |
| 43 // bottom up. This makes it impossible to set the references to parents. Will | |
| 44 // have to fix the code, eventually using Builder DP to create a bunch of | |
| 45 // models containing bundles, apps, and such. | |
| 46 | |
| 47 namespace { | |
| 48 | |
| 49 const TCHAR* const kGuid1 = _T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}"); | |
| 50 const TCHAR* const kGuid2 = _T("{A979ACBD-1F55-4b12-A35F-4DBCA5A7CCB8}"); | |
| 51 const TCHAR* const kGuid3 = _T("{661045C5-4429-4140-BC48-8CEA241D1DEF}"); | |
| 52 const TCHAR* const kGuid4 = _T("{AAFA1CF9-E94F-42e6-A899-4CD27F37D5A7}"); | |
| 53 const TCHAR* const kGuid5 = _T("{3B1A3CCA-0525-4418-93E6-A0DB3398EC9B}"); | |
| 54 const TCHAR* const kGuid6 = _T("{F3F2CFD4-5F98-4bf0-ABB0-BEEEA46C62B4}"); | |
| 55 const TCHAR* const kGuid7 = _T("{6FD2272F-8583-4bbd-895A-E65F8003FC7B}"); | |
| 56 const TCHAR* const kIid1 = _T("{F723495F-8ACF-4746-8240-643741C797B5}"); | |
| 57 | |
| 58 const TCHAR* const kNonExistentClsid = | |
| 59 _T("{BC00156D-3B01-4ba3-9F5E-2C46E8B6E824}"); | |
| 60 | |
| 61 const TCHAR* const kGuid1ClientsKeyPathUser = | |
| 62 _T("HKCU\\Software\\") SHORT_COMPANY_NAME | |
| 63 _T("\\") PRODUCT_NAME _T("\\Clients\\") | |
| 64 _T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}"); | |
| 65 const TCHAR* const kGuid1ClientsKeyPathMachine = | |
| 66 _T("HKLM\\Software\\") SHORT_COMPANY_NAME | |
| 67 _T("\\") PRODUCT_NAME _T("\\Clients\\") | |
| 68 _T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}"); | |
| 69 const TCHAR* const kGuid1ClientStateKeyPathUser = | |
| 70 _T("HKCU\\Software\\") SHORT_COMPANY_NAME | |
| 71 _T("\\") PRODUCT_NAME _T("\\ClientState\\") | |
| 72 _T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}"); | |
| 73 const TCHAR* const kGuid1ClientStateKeyPathMachine = | |
| 74 _T("HKLM\\Software\\") SHORT_COMPANY_NAME | |
| 75 _T("\\") PRODUCT_NAME _T("\\ClientState\\") | |
| 76 _T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}"); | |
| 77 | |
| 78 const TCHAR* const kDefaultAppName = SHORT_COMPANY_NAME _T(" Application"); | |
| 79 | |
| 80 const uint32 kInitialInstallTimeDiff = static_cast<uint32>(-1 * kSecondsPerDay); | |
| 81 | |
| 82 // Initializes a GLock in the same way AppManager does. Used for lock conflict | |
| 83 // tests. | |
| 84 void InitializeAppManagerRegistryLock(bool is_machine, GLock* lock) { | |
| 85 ASSERT1(lock); | |
| 86 NamedObjectAttributes lock_attr; | |
| 87 GetNamedObjectAttributes(kRegistryAccessMutex, is_machine, &lock_attr); | |
| 88 EXPECT_SUCCEEDED(lock->InitializeWithSecAttr(lock_attr.name, &lock_attr.sa)); | |
| 89 } | |
| 90 | |
| 91 } // namespace | |
| 92 | |
| 93 // Helper functions defined in other test files. | |
| 94 void ValidateExpectedValues(const App& expected, const App& actual); | |
| 95 void VerifyHklmKeyHasMediumIntegrity(const CString& key_full_name); | |
| 96 void VerifyHklmKeyHasDefaultIntegrity(const CString& key_full_name); | |
| 97 | |
| 98 class AppManagerTestBase : public AppTestBaseWithRegistryOverride { | |
| 99 public: | |
| 100 static void SetDisplayName(const CString& name, App* app) { | |
| 101 ASSERT1(app); | |
| 102 app->display_name_ = name; | |
| 103 } | |
| 104 | |
| 105 protected: | |
| 106 // Creates the application registration entries based on the passed in data. | |
| 107 // If passed an application that is uninstalled, the function only creates | |
| 108 // the registration entries in the client state and no information is written | |
| 109 // in the clients. | |
| 110 static void CreateAppRegistryState(const App& app, | |
| 111 bool is_machine, | |
| 112 const CString& previous_version, | |
| 113 bool can_write_clients_key) { | |
| 114 CString clients_key_name = AppendRegKeyPath( | |
| 115 ConfigManager::Instance()->registry_clients(is_machine), | |
| 116 app.app_guid_string()); | |
| 117 CString client_state_key_name = AppendRegKeyPath( | |
| 118 ConfigManager::Instance()->registry_client_state(is_machine), | |
| 119 app.app_guid_string()); | |
| 120 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 121 | |
| 122 RegKey client_key; | |
| 123 if (can_write_clients_key) { | |
| 124 ASSERT_SUCCEEDED(client_key.Create(clients_key_name)); | |
| 125 | |
| 126 CString current_version(app.current_version()->version()); | |
| 127 if (!current_version.IsEmpty()) { | |
| 128 ASSERT_SUCCEEDED(client_key.SetValue(kRegValueProductVersion, | |
| 129 current_version)); | |
| 130 } | |
| 131 | |
| 132 if (!app.display_name_.IsEmpty()) { | |
| 133 ASSERT_SUCCEEDED(client_key.SetValue(kRegValueAppName, | |
| 134 app.display_name_)); | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 RegKey client_state_key; | |
| 139 ASSERT_SUCCEEDED(client_state_key.Create(client_state_key_name)); | |
| 140 | |
| 141 if (!previous_version.IsEmpty()) { | |
| 142 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueProductVersion, | |
| 143 previous_version)); | |
| 144 } | |
| 145 | |
| 146 if (!app.language_.IsEmpty()) { | |
| 147 // TODO(omaha3): This is some interesting logic wrt Clients/ClientState. | |
| 148 // Does it still make sense for Omaha 3? | |
| 149 if (can_write_clients_key) { | |
| 150 ASSERT_SUCCEEDED(client_key.SetValue(kRegValueLanguage, | |
| 151 app.language_)); | |
| 152 } else { | |
| 153 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueLanguage, | |
| 154 app.language_)); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 if (app.did_run_ != ACTIVE_UNKNOWN) { | |
| 159 CString dr = (app.did_run_ == ACTIVE_NOTRUN) ? _T("0") : _T("1"); | |
| 160 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueDidRun, | |
| 161 dr)); | |
| 162 } | |
| 163 | |
| 164 if (!app.ap_.IsEmpty()) { | |
| 165 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueAdditionalParams, | |
| 166 app.ap_)); | |
| 167 } | |
| 168 | |
| 169 if (!app.tt_token_.IsEmpty()) { | |
| 170 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueTTToken, | |
| 171 app.tt_token_)); | |
| 172 } | |
| 173 | |
| 174 if (!::IsEqualGUID(app.iid_, GUID_NULL)) { | |
| 175 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueInstallationId, | |
| 176 GuidToString(app.iid_))); | |
| 177 } | |
| 178 | |
| 179 if (!app.brand_code_.IsEmpty()) { | |
| 180 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueBrandCode, | |
| 181 app.brand_code_)); | |
| 182 } | |
| 183 | |
| 184 if (!app.client_id_.IsEmpty()) { | |
| 185 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueClientId, | |
| 186 app.client_id_)); | |
| 187 } | |
| 188 | |
| 189 if (!app.referral_id_.IsEmpty()) { | |
| 190 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueReferralId, | |
| 191 app.referral_id_)); | |
| 192 } | |
| 193 | |
| 194 if (!app.referral_id_.IsEmpty()) { | |
| 195 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueReferralId, | |
| 196 app.referral_id_)); | |
| 197 } | |
| 198 | |
| 199 if (app.install_time_diff_sec_) { | |
| 200 const DWORD install_time = now - app.install_time_diff_sec_; | |
| 201 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueInstallTimeSec, | |
| 202 install_time)); | |
| 203 } | |
| 204 | |
| 205 if (app.is_eula_accepted_ == TRISTATE_FALSE) { | |
| 206 ASSERT_SUCCEEDED(client_state_key.SetValue(_T("eulaaccepted"), | |
| 207 static_cast<DWORD>(0))); | |
| 208 } | |
| 209 | |
| 210 int days = app.days_since_last_active_ping(); | |
| 211 | |
| 212 if (days != -1) { | |
| 213 EXPECT_GE(days, 0); | |
| 214 ASSERT1(now > static_cast<uint32>(days * kSecondsPerDay)); | |
| 215 uint32 last_active_time = now - days * kSecondsPerDay; | |
| 216 | |
| 217 ASSERT_SUCCEEDED(client_state_key.SetValue( | |
| 218 kRegValueActivePingDayStartSec, | |
| 219 static_cast<DWORD>(last_active_time))); | |
| 220 } | |
| 221 | |
| 222 days = app.days_since_last_roll_call(); | |
| 223 if (days != -1) { | |
| 224 EXPECT_GE(days, 0); | |
| 225 EXPECT_GE(now, static_cast<uint32>(days * kSecondsPerDay)); | |
| 226 | |
| 227 uint32 last_roll_call_time = now - days * kSecondsPerDay; | |
| 228 | |
| 229 ASSERT_SUCCEEDED(client_state_key.SetValue( | |
| 230 kRegValueRollCallDayStartSec, | |
| 231 static_cast<DWORD>(last_roll_call_time))); | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 // App will be cleaned up when bundle is destroyed. | |
| 236 // This is a hack for creating registry data. Would be nice to have a | |
| 237 // different mechanism. | |
| 238 App* CreateAppForRegistryPopulation(const TCHAR* app_id) { | |
| 239 App* app = NULL; | |
| 240 EXPECT_SUCCEEDED( | |
| 241 dummy_app_bundle_for_app_creation_->createApp(CComBSTR(app_id), &app)); | |
| 242 ASSERT1(app); | |
| 243 | |
| 244 // install_time_diff_sec_ is -1 day for new app. After that, the app | |
| 245 // becomes registered and the install age will be 0. So set the time to 0 | |
| 246 // to make the expected value and actual equal. | |
| 247 app->install_time_diff_sec_ = 0; | |
| 248 return app; | |
| 249 } | |
| 250 | |
| 251 static void PopulateExpectedApp1ClientsOnly(App* expected_app) { | |
| 252 ASSERT_TRUE(expected_app); | |
| 253 expected_app->current_version()->set_version(_T("1.1.1.3")); | |
| 254 expected_app->language_ = _T("abc"); | |
| 255 expected_app->display_name_ = _T("My App"); | |
| 256 | |
| 257 // This is the result when Client State does not exist. | |
| 258 expected_app->install_time_diff_sec_ = | |
| 259 static_cast<uint32>(-1 * kSecondsPerDay); | |
| 260 } | |
| 261 | |
| 262 static void PopulateExpectedApp1(App* expected_app) { | |
| 263 ASSERT_TRUE(expected_app); | |
| 264 expected_app->current_version()->set_version(_T("1.1.1.3")); | |
| 265 expected_app->language_ = _T("abc"); | |
| 266 expected_app->display_name_ = _T("My App"); | |
| 267 expected_app->ap_ = _T("Test ap"); | |
| 268 expected_app->tt_token_ = _T("Test TT Token"); | |
| 269 expected_app->iid_ = | |
| 270 StringToGuid(_T("{F723495F-8ACF-4746-8240-643741C797B5}")); | |
| 271 expected_app->brand_code_ = _T("GOOG"); | |
| 272 expected_app->client_id_ = _T("someclient"); | |
| 273 // Do not set referral_id or install_time_diff_sec because these are not | |
| 274 // expected in most cases. | |
| 275 expected_app->did_run_ = ACTIVE_RUN; | |
| 276 expected_app->set_days_since_last_active_ping(3); | |
| 277 expected_app->set_days_since_last_roll_call(1); | |
| 278 } | |
| 279 | |
| 280 static void PopulateExpectedApp2(App* expected_app) { | |
| 281 ASSERT_TRUE(expected_app); | |
| 282 expected_app->current_version()->set_version(_T("1.2.1.3")); | |
| 283 expected_app->language_ = _T("de"); | |
| 284 expected_app->ap_ = _T("beta"); | |
| 285 expected_app->tt_token_ = _T("beta TT Token"); | |
| 286 expected_app->iid_ = | |
| 287 StringToGuid(_T("{431EC961-CFD8-49ea-AB7B-2B99BCA274AD}")); | |
| 288 expected_app->brand_code_ = _T("GooG"); | |
| 289 expected_app->client_id_ = _T("anotherclient"); | |
| 290 expected_app->did_run_ = ACTIVE_NOTRUN; | |
| 291 expected_app->set_days_since_last_active_ping(100); | |
| 292 expected_app->set_days_since_last_roll_call(1); | |
| 293 } | |
| 294 | |
| 295 static void PopulateExpectedUninstalledApp(const CString& uninstalled_version, | |
| 296 App* expected_app) { | |
| 297 ASSERT_TRUE(expected_app); | |
| 298 PopulateExpectedApp2(expected_app); | |
| 299 | |
| 300 expected_app->current_version()->set_version(uninstalled_version); | |
| 301 } | |
| 302 | |
| 303 static void SetAppInstallTimeDiffSec(App* app, | |
| 304 uint32 install_time_diff_sec) { | |
| 305 ASSERT_TRUE(app); | |
| 306 app->install_time_diff_sec_ = install_time_diff_sec; | |
| 307 } | |
| 308 | |
| 309 explicit AppManagerTestBase(bool is_machine) | |
| 310 : AppTestBaseWithRegistryOverride(is_machine, true), | |
| 311 app_manager_(NULL), | |
| 312 app_(NULL), | |
| 313 guid1_(StringToGuid(kGuid1)) {} | |
| 314 | |
| 315 virtual void SetUp() { | |
| 316 AppTestBaseWithRegistryOverride::SetUp(); | |
| 317 | |
| 318 app_manager_ = AppManager::Instance(); | |
| 319 ASSERT_TRUE(app_manager_); | |
| 320 | |
| 321 // Initialize the second bundle. | |
| 322 dummy_app_bundle_for_app_creation_ = model_->CreateAppBundle(is_machine_); | |
| 323 ASSERT_TRUE(dummy_app_bundle_for_app_creation_.get()); | |
| 324 | |
| 325 EXPECT_SUCCEEDED(dummy_app_bundle_for_app_creation_->put_displayName( | |
| 326 CComBSTR(_T("My Bundle")))); | |
| 327 EXPECT_SUCCEEDED(dummy_app_bundle_for_app_creation_->put_displayLanguage( | |
| 328 CComBSTR(_T("en")))); | |
| 329 EXPECT_SUCCEEDED(dummy_app_bundle_for_app_creation_->put_installSource( | |
| 330 CComBSTR(_T("unittest")))); | |
| 331 // TODO(omaha3): Address with the TODO in AppBundleInitializedTest::SetUp(). | |
| 332 if (is_machine_) { | |
| 333 SetAppBundleStateForUnitTest(dummy_app_bundle_for_app_creation_.get(), | |
| 334 new fsm::AppBundleStateInitialized); | |
| 335 } else { | |
| 336 EXPECT_SUCCEEDED(dummy_app_bundle_for_app_creation_->initialize()); | |
| 337 } | |
| 338 | |
| 339 EXPECT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kGuid1), &app_)); | |
| 340 ASSERT_TRUE(app_); | |
| 341 } | |
| 342 | |
| 343 virtual void TearDown() { | |
| 344 app_manager_ = NULL; | |
| 345 | |
| 346 AppTestBaseWithRegistryOverride::TearDown(); | |
| 347 } | |
| 348 | |
| 349 static void UpdateUpdateAvailableStats(const GUID& app_guid, | |
| 350 AppManager* app_manager) { | |
| 351 ASSERT1(app_manager); | |
| 352 app_manager->UpdateUpdateAvailableStats(app_guid); | |
| 353 } | |
| 354 | |
| 355 CString GetClientKeyName(const GUID& app_guid) const { | |
| 356 return app_manager_->GetClientKeyName(app_guid); | |
| 357 } | |
| 358 | |
| 359 static void SetAppGuid(const CString& guid, App* app) { | |
| 360 ASSERT1(app); | |
| 361 app->app_guid_ = StringToGuid(guid); | |
| 362 } | |
| 363 | |
| 364 bool IsClientStateKeyPresent(const App& app) { | |
| 365 CString client_state_key_name = AppendRegKeyPath( | |
| 366 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 367 GuidToString(app.app_guid_)); | |
| 368 | |
| 369 return RegKey::HasKey(client_state_key_name); | |
| 370 } | |
| 371 | |
| 372 // TODO(omaha3): In this test or elsewhere, test the new Omaha 3 behaviors: | |
| 373 // IID is deleted if GUID_NULL and dr is cleared. | |
| 374 // TODO(omaha3): Add checks for values set/not set by | |
| 375 // app_registry_utils::PersistSuccessfulInstall(). | |
| 376 void PersistSuccessfulInstallTest() { | |
| 377 // Create the data the installer would have written. These values should | |
| 378 // not be read below because the caller is responsible for updating these | |
| 379 // values. | |
| 380 CString clients_key_name = AppendRegKeyPath( | |
| 381 ConfigManager::Instance()->registry_clients(is_machine_), | |
| 382 kGuid1); | |
| 383 EXPECT_SUCCEEDED(RegKey::SetValue(clients_key_name, | |
| 384 kRegValueProductVersion, | |
| 385 _T("9.8.7.6"))); | |
| 386 EXPECT_SUCCEEDED( | |
| 387 RegKey::SetValue(clients_key_name, kRegValueLanguage, _T("fr"))); | |
| 388 | |
| 389 // Populate the App structure. For the most part, these values are not | |
| 390 // used. Exceptions are: | |
| 391 // * pv and language are written. | |
| 392 // * iid is written to the registry. | |
| 393 app_->display_name_ = _T("foo"); | |
| 394 app_->next_version()->set_version(_T("4.5.6.7")); | |
| 395 app_->language_ = _T("de"); | |
| 396 app_->ap_ = _T("test ap"); | |
| 397 app_->tt_token_ = _T("test TT Token"); | |
| 398 app_->iid_ = | |
| 399 StringToGuid(_T("{64333341-CA93-490d-9FB7-7FC5728721F4}")); | |
| 400 app_->brand_code_ = _T("g00g"); | |
| 401 app_->client_id_ = _T("myclient"); | |
| 402 app_->referral_id_ = _T("somereferrer"); | |
| 403 app_->set_days_since_last_active_ping(-1); | |
| 404 app_->set_days_since_last_roll_call(-1); | |
| 405 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 406 | |
| 407 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 408 | |
| 409 app_manager_->PersistSuccessfulInstall(*app_); | |
| 410 | |
| 411 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 412 | |
| 413 // Validate the results. | |
| 414 CString client_state_key_name = AppendRegKeyPath( | |
| 415 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 416 kGuid1); | |
| 417 RegKey client_state_key; | |
| 418 EXPECT_SUCCEEDED(client_state_key.Create(client_state_key_name)); | |
| 419 | |
| 420 ValidateClientStateMedium(is_machine_, kGuid1); | |
| 421 | |
| 422 // Check version is based on app_ and not read from Clients key. | |
| 423 CString client_state_version; | |
| 424 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueProductVersion, | |
| 425 &client_state_version)); | |
| 426 EXPECT_STREQ(_T("4.5.6.7"), app_->next_version()->version()); | |
| 427 EXPECT_STREQ(_T("4.5.6.7"), client_state_version); | |
| 428 | |
| 429 // Check language is based on app_ and not read from Clients key. | |
| 430 CString language; | |
| 431 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueLanguage, &language)); | |
| 432 EXPECT_STREQ(_T("de"), app_->language_); | |
| 433 EXPECT_STREQ(_T("de"), language); | |
| 434 | |
| 435 // Check iid is set correctly in ClientState. | |
| 436 CString iid; | |
| 437 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallationId, &iid)); | |
| 438 EXPECT_STREQ(_T("{64333341-CA93-490D-9FB7-7FC5728721F4}"), | |
| 439 GuidToString(app_->iid_)); | |
| 440 EXPECT_STREQ(_T("{64333341-CA93-490D-9FB7-7FC5728721F4}"), iid); | |
| 441 | |
| 442 DWORD last_successful_check(0); | |
| 443 EXPECT_SUCCEEDED( | |
| 444 client_state_key.GetValue(kRegValueLastSuccessfulCheckSec, | |
| 445 &last_successful_check)); | |
| 446 EXPECT_GE(now, last_successful_check); | |
| 447 EXPECT_GE(static_cast<uint32>(200), now - last_successful_check); | |
| 448 | |
| 449 // Check other values were not written. | |
| 450 EXPECT_EQ(4, client_state_key.GetValueCount()); | |
| 451 EXPECT_FALSE(client_state_key.HasValue(kRegValueAdditionalParams)); | |
| 452 EXPECT_FALSE(client_state_key.HasValue(kRegValueBrandCode)); | |
| 453 EXPECT_FALSE(client_state_key.HasValue(kRegValueBrowser)); | |
| 454 EXPECT_FALSE(client_state_key.HasValue(kRegValueClientId)); | |
| 455 EXPECT_FALSE(client_state_key.HasValue(kRegValueDidRun)); | |
| 456 EXPECT_FALSE(client_state_key.HasValue(kRegValueOemInstall)); | |
| 457 EXPECT_FALSE(client_state_key.HasValue(kRegValueReferralId)); | |
| 458 EXPECT_FALSE(client_state_key.HasValue(kRegValueEulaAccepted)); | |
| 459 EXPECT_FALSE(client_state_key.HasValue(kRegValueUsageStats)); | |
| 460 EXPECT_FALSE(client_state_key.HasValue(kRegValueInstallTimeSec)); | |
| 461 EXPECT_FALSE(client_state_key.HasValue(kRegValueLastUpdateTimeSec)); | |
| 462 EXPECT_FALSE(client_state_key.HasValue(kRegValueTTToken)); | |
| 463 EXPECT_FALSE(client_state_key.HasValue(kRegValueActivePingDayStartSec)); | |
| 464 EXPECT_FALSE(client_state_key.HasValue(kRegValueRollCallDayStartSec)); | |
| 465 | |
| 466 EXPECT_TRUE(app_registry_utils::IsAppEulaAccepted(is_machine_, | |
| 467 kGuid1, | |
| 468 false)); | |
| 469 } | |
| 470 | |
| 471 void PersistUpdateCheckSuccessfullySent_AllUpdated() { | |
| 472 const CString client_state_key_name = AppendRegKeyPath( | |
| 473 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 474 kGuid1); | |
| 475 | |
| 476 // Create the test data. | |
| 477 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 478 expected_app->current_version()->set_version(_T("1.0.0.0")); | |
| 479 expected_app->iid_ = StringToGuid(kIid1); | |
| 480 expected_app->did_run_ = ACTIVE_RUN; | |
| 481 // Set non-zero values for activities so that the registry values can | |
| 482 // be updated. | |
| 483 expected_app->set_days_since_last_active_ping(4); | |
| 484 expected_app->set_days_since_last_roll_call(2); | |
| 485 CreateAppRegistryState(*expected_app, is_machine_, _T(""), true); | |
| 486 | |
| 487 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 488 | |
| 489 __mutexBlock(app_->model()->lock()) { | |
| 490 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 491 | |
| 492 // We only want to make sure the timestamps in the registry are updated | |
| 493 // and don't care about time_since_midnight_sec here, so just pass a 0 as | |
| 494 // the first parameter. | |
| 495 EXPECT_SUCCEEDED( | |
| 496 app_manager_->PersistUpdateCheckSuccessfullySent(*app_, 0)); | |
| 497 } | |
| 498 | |
| 499 // Validate the results. | |
| 500 RegKey client_state_key; | |
| 501 EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name)); | |
| 502 | |
| 503 // Check installation id removed. | |
| 504 EXPECT_FALSE(client_state_key.HasValue(kRegValueInstallationId)); | |
| 505 | |
| 506 // Check ping timestamps are updated. | |
| 507 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 508 | |
| 509 DWORD last_active_ping_day_start_sec = 0; | |
| 510 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueActivePingDayStartSec, | |
| 511 &last_active_ping_day_start_sec)); | |
| 512 EXPECT_GE(now, last_active_ping_day_start_sec); | |
| 513 EXPECT_LE(now, last_active_ping_day_start_sec + kMaxTimeSinceMidnightSec); | |
| 514 | |
| 515 DWORD last_roll_call_day_start_sec = 0; | |
| 516 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueRollCallDayStartSec, | |
| 517 &last_roll_call_day_start_sec)); | |
| 518 EXPECT_GE(now, last_roll_call_day_start_sec); | |
| 519 EXPECT_LE(now, last_roll_call_day_start_sec + kMaxTimeSinceMidnightSec); | |
| 520 | |
| 521 // Check did_run is cleared. | |
| 522 CString did_run; | |
| 523 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueDidRun, &did_run)); | |
| 524 EXPECT_STREQ(_T("0"), did_run); | |
| 525 | |
| 526 // Check that members in app_ are not changed. | |
| 527 EXPECT_TRUE(expected_app->iid() == app_->iid()); | |
| 528 EXPECT_EQ(expected_app->days_since_last_active_ping(), | |
| 529 app_->days_since_last_active_ping()); | |
| 530 EXPECT_EQ(expected_app->days_since_last_roll_call(), | |
| 531 app_->days_since_last_roll_call()); | |
| 532 EXPECT_EQ(expected_app->did_run(), app_->did_run()); | |
| 533 } | |
| 534 | |
| 535 void PersistUpdateCheckSuccessfullySent_NotRun() { | |
| 536 const CString client_state_key_name = AppendRegKeyPath( | |
| 537 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 538 kGuid1); | |
| 539 const int kDaysSinceLastActivePing = 2; | |
| 540 | |
| 541 // Create the test data. | |
| 542 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 543 expected_app->current_version()->set_version(_T("1.0.0.0")); | |
| 544 expected_app->iid_ = StringToGuid(kIid1); | |
| 545 expected_app->did_run_ = ACTIVE_NOTRUN; | |
| 546 expected_app->set_days_since_last_active_ping(kDaysSinceLastActivePing); | |
| 547 expected_app->set_days_since_last_roll_call(0); | |
| 548 CreateAppRegistryState(*expected_app, is_machine_, _T(""), true); | |
| 549 | |
| 550 // Choose a time that is close to current time but with some skew so that | |
| 551 // if the registry is rewritten, we won't write the same value again and | |
| 552 // the change would be detected. | |
| 553 const uint32 base_time = Time64ToInt32(GetCurrent100NSTime()) - 2; | |
| 554 | |
| 555 RegKey client_state_key; | |
| 556 EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name)); | |
| 557 uint32 last_active_time = | |
| 558 base_time - kDaysSinceLastActivePing * kSecondsPerDay; | |
| 559 ASSERT_SUCCEEDED(client_state_key.SetValue( | |
| 560 kRegValueActivePingDayStartSec, | |
| 561 static_cast<DWORD>(last_active_time))); | |
| 562 | |
| 563 ASSERT_SUCCEEDED(client_state_key.SetValue( | |
| 564 kRegValueRollCallDayStartSec, | |
| 565 static_cast<DWORD>(base_time))); | |
| 566 | |
| 567 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 568 | |
| 569 __mutexBlock(app_->model()->lock()) { | |
| 570 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 571 | |
| 572 // We only want to make sure the timestamps in the registry are updated | |
| 573 // and don't care about time_since_midnight_sec here, so just pass a 0 as | |
| 574 // the first parameter. | |
| 575 EXPECT_SUCCEEDED( | |
| 576 app_manager_->PersistUpdateCheckSuccessfullySent(*app_, 0)); | |
| 577 } | |
| 578 | |
| 579 // Validate the results. | |
| 580 | |
| 581 // did_run is false so installation id should still exist. | |
| 582 CString iid; | |
| 583 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallationId, &iid)); | |
| 584 EXPECT_STREQ(kIid1, iid); | |
| 585 | |
| 586 // did_run is false so active ping timestamp should not be updated. | |
| 587 DWORD last_active_ping_day_start_sec = 0; | |
| 588 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueActivePingDayStartSec, | |
| 589 &last_active_ping_day_start_sec)); | |
| 590 EXPECT_EQ(last_active_time, last_active_ping_day_start_sec); | |
| 591 | |
| 592 // Previous days_since_last_roll_call is 0 so that timestamp should | |
| 593 // not change. | |
| 594 DWORD last_roll_call_day_start_sec = 0; | |
| 595 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueRollCallDayStartSec, | |
| 596 &last_roll_call_day_start_sec)); | |
| 597 EXPECT_EQ(base_time, last_roll_call_day_start_sec); | |
| 598 | |
| 599 // did_run is still not set. | |
| 600 CString did_run; | |
| 601 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueDidRun, &did_run)); | |
| 602 EXPECT_STREQ(_T("0"), did_run); | |
| 603 | |
| 604 // Checks that members in app_ are not changed. | |
| 605 EXPECT_TRUE(expected_app->iid() == app_->iid()); | |
| 606 EXPECT_EQ(expected_app->days_since_last_active_ping(), | |
| 607 app_->days_since_last_active_ping()); | |
| 608 EXPECT_EQ(expected_app->days_since_last_roll_call(), | |
| 609 app_->days_since_last_roll_call()); | |
| 610 EXPECT_EQ(expected_app->did_run(), app_->did_run()); | |
| 611 } | |
| 612 | |
| 613 void PersistUpdateCheckSuccessfullySent_NoPreviousPing() { | |
| 614 const CString client_state_key_name = AppendRegKeyPath( | |
| 615 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 616 kGuid1); | |
| 617 const int kDaysSinceLastActivePing = 2; | |
| 618 | |
| 619 // Create the test data. | |
| 620 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 621 expected_app->current_version()->set_version(_T("1.0.0.0")); | |
| 622 expected_app->iid_ = StringToGuid(kIid1); | |
| 623 expected_app->did_run_ = ACTIVE_UNKNOWN; | |
| 624 expected_app->set_days_since_last_active_ping(-1); | |
| 625 expected_app->set_days_since_last_roll_call(-1); | |
| 626 CreateAppRegistryState(*expected_app, is_machine_, _T(""), true); | |
| 627 | |
| 628 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 629 | |
| 630 __mutexBlock(app_->model()->lock()) { | |
| 631 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 632 | |
| 633 // We only want to make sure the timestamps in the registry are updated | |
| 634 // and don't care about time_since_midnight_sec here, so just pass a 0 as | |
| 635 // the first parameter. | |
| 636 EXPECT_SUCCEEDED( | |
| 637 app_manager_->PersistUpdateCheckSuccessfullySent(*app_, 0)); | |
| 638 } | |
| 639 | |
| 640 // Validate the results. | |
| 641 RegKey client_state_key; | |
| 642 EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name)); | |
| 643 | |
| 644 // did_run is unknown so installation id should still exist. | |
| 645 CString iid; | |
| 646 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallationId, &iid)); | |
| 647 EXPECT_STREQ(kIid1, iid); | |
| 648 | |
| 649 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 650 | |
| 651 // did_run is unknown so active ping timestamp should not be updated. | |
| 652 EXPECT_FALSE(client_state_key.HasValue(kRegValueActivePingDayStartSec)); | |
| 653 | |
| 654 DWORD last_roll_call_day_start_sec = 0; | |
| 655 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueRollCallDayStartSec, | |
| 656 &last_roll_call_day_start_sec)); | |
| 657 EXPECT_GE(now, last_roll_call_day_start_sec); | |
| 658 EXPECT_LE(now, last_roll_call_day_start_sec + kMaxTimeSinceMidnightSec); | |
| 659 | |
| 660 // did_run is unknown. | |
| 661 CString did_run; | |
| 662 EXPECT_FALSE(client_state_key.HasValue(kRegValueDidRun)); | |
| 663 | |
| 664 // Checks that members in app_ are not changed. | |
| 665 EXPECT_TRUE(expected_app->iid() == app_->iid()); | |
| 666 EXPECT_EQ(expected_app->days_since_last_active_ping(), | |
| 667 app_->days_since_last_active_ping()); | |
| 668 EXPECT_EQ(expected_app->days_since_last_roll_call(), | |
| 669 app_->days_since_last_roll_call()); | |
| 670 EXPECT_EQ(expected_app->did_run(), app_->did_run()); | |
| 671 } | |
| 672 | |
| 673 void SynchronizeClientStateTest(const CString& app_id) { | |
| 674 const CString client_state_key_name = AppendRegKeyPath( | |
| 675 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 676 app_id); | |
| 677 | |
| 678 App* expected_app = CreateAppForRegistryPopulation(app_id); | |
| 679 PopulateExpectedApp1(expected_app); | |
| 680 expected_app->referral_id_ = _T("referrer"); | |
| 681 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_FALSE)); | |
| 682 expected_app->install_time_diff_sec_ = 141516; | |
| 683 CreateAppRegistryState(*expected_app, is_machine_, _T(""), true); | |
| 684 | |
| 685 EXPECT_TRUE(RegKey::HasValue(client_state_key_name, _T("referral"))); | |
| 686 | |
| 687 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 688 | |
| 689 App* app = NULL; | |
| 690 EXPECT_SUCCEEDED(app_bundle_->createApp(CComBSTR(app_id), &app)); | |
| 691 ASSERT_TRUE(app); | |
| 692 | |
| 693 __mutexBlock(app_->model()->lock()) { | |
| 694 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app)); | |
| 695 } | |
| 696 | |
| 697 EXPECT_TRUE(app->referral_id_.IsEmpty()); | |
| 698 | |
| 699 __mutexBlock(app_->model()->lock()) { | |
| 700 EXPECT_SUCCEEDED(app_manager_->SynchronizeClientState(app->app_guid())); | |
| 701 } | |
| 702 | |
| 703 EXPECT_TRUE(app->referral_id_.IsEmpty()); | |
| 704 | |
| 705 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 706 | |
| 707 EXPECT_TRUE(app->referral_id_.IsEmpty()); | |
| 708 | |
| 709 // Validate the results. | |
| 710 RegKey client_state_key; | |
| 711 EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name)); | |
| 712 | |
| 713 // Check version and language have been copied to client state. | |
| 714 EXPECT_STREQ(expected_app->current_version()->version(), | |
| 715 GetSzValue(client_state_key_name, kRegValueProductVersion)); | |
| 716 EXPECT_STREQ(expected_app->language_, | |
| 717 GetSzValue(client_state_key_name, kRegValueLanguage)); | |
| 718 | |
| 719 // Check that ap, brand_code, and client_id, etc. are not changed. | |
| 720 EXPECT_STREQ(expected_app->ap_, | |
| 721 GetSzValue(client_state_key_name, kRegValueAdditionalParams)); | |
| 722 EXPECT_STREQ(expected_app->tt_token_, | |
| 723 GetSzValue(client_state_key_name, kRegValueTTToken)); | |
| 724 EXPECT_STREQ(expected_app->brand_code_, | |
| 725 GetSzValue(client_state_key_name, kRegValueBrandCode)); | |
| 726 EXPECT_STREQ(expected_app->client_id_, | |
| 727 GetSzValue(client_state_key_name, kRegValueClientId)); | |
| 728 | |
| 729 // install_time_diff_sec should be roughly the same as now - installed. | |
| 730 const DWORD install_time = | |
| 731 GetDwordValue(client_state_key_name, kRegValueInstallTimeSec); | |
| 732 const DWORD calculated_install_diff = now - install_time; | |
| 733 EXPECT_GE(calculated_install_diff, expected_app->install_time_diff_sec_); | |
| 734 EXPECT_GE(static_cast<uint32>(500), | |
| 735 calculated_install_diff - expected_app->install_time_diff_sec_); | |
| 736 | |
| 737 EXPECT_EQ(0, GetDwordValue(client_state_key_name, kRegValueEulaAccepted)); | |
| 738 EXPECT_FALSE(expected_app->is_eula_accepted_); | |
| 739 } | |
| 740 | |
| 741 void WritePreInstallDataTest(App* app, bool test_clearing_values) { | |
| 742 ASSERT1(is_machine_ == app->app_bundle()->is_machine()); | |
| 743 const CString clients_key_name = AppendRegKeyPath( | |
| 744 ConfigManager::Instance()->registry_clients(is_machine_), kGuid1); | |
| 745 const CString client_state_key_name = AppendRegKeyPath( | |
| 746 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 747 kGuid1); | |
| 748 | |
| 749 const bool expect_has_client_key = RegKey::HasKey(clients_key_name); | |
| 750 | |
| 751 // Populate the test data. | |
| 752 app->brand_code_ = _T("GGLG"); | |
| 753 app->client_id_ = _T("someclient"); | |
| 754 app->referral_id_ = _T("referrer"); | |
| 755 app->install_time_diff_sec_ = 657812; // Not used. | |
| 756 app->usage_stats_enable_ = TRISTATE_TRUE; | |
| 757 app->browser_type_ = BROWSER_FIREFOX; | |
| 758 app->ap_ = _T("test_ap"); | |
| 759 app->language_ = _T("en"); | |
| 760 | |
| 761 if (test_clearing_values) { | |
| 762 // Set values in registry and clear them in the app. | |
| 763 EXPECT_SUCCEEDED(RegKey::SetValue( | |
| 764 kGuid1ClientsKeyPathUser, | |
| 765 kRegValueBrowser, | |
| 766 static_cast<DWORD>(app->browser_type()))); | |
| 767 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 768 kRegValueAdditionalParams, | |
| 769 app->ap())); | |
| 770 | |
| 771 app->browser_type_ = BROWSER_UNKNOWN; | |
| 772 app->ap_.Empty(); | |
| 773 } | |
| 774 | |
| 775 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 776 | |
| 777 EXPECT_SUCCEEDED(app_manager_->WritePreInstallData(*app)); | |
| 778 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 779 | |
| 780 // Validate the results. | |
| 781 | |
| 782 // WritePreInstallData should never write to client_key, so it shouldn't | |
| 783 // exist if it did not before the function call. | |
| 784 EXPECT_EQ(expect_has_client_key, RegKey::HasKey(clients_key_name)); | |
| 785 | |
| 786 // ClientStateKey should exist. | |
| 787 RegKey client_state_key; | |
| 788 EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name)); | |
| 789 | |
| 790 ValidateClientStateMedium(is_machine_, kGuid1); | |
| 791 | |
| 792 CString brand_code; | |
| 793 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueBrandCode, | |
| 794 &brand_code)); | |
| 795 EXPECT_STREQ(_T("GGLG"), brand_code); | |
| 796 | |
| 797 CString client_id; | |
| 798 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueClientId, &client_id)); | |
| 799 EXPECT_STREQ(_T("someclient"), client_id); | |
| 800 | |
| 801 CString referral_id; | |
| 802 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueReferralId, | |
| 803 &referral_id)); | |
| 804 EXPECT_STREQ(_T("referrer"), referral_id); | |
| 805 | |
| 806 DWORD install_time(0); | |
| 807 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallTimeSec, | |
| 808 &install_time)); | |
| 809 EXPECT_GE(now, install_time); | |
| 810 EXPECT_GE(static_cast<uint32>(200), now - install_time); | |
| 811 | |
| 812 DWORD usage_stats_enable = 0; | |
| 813 EXPECT_SUCCEEDED(client_state_key.GetValue(_T("usagestats"), | |
| 814 &usage_stats_enable)); | |
| 815 EXPECT_EQ(TRISTATE_TRUE, usage_stats_enable); | |
| 816 | |
| 817 if (test_clearing_values) { | |
| 818 EXPECT_FALSE(client_state_key.HasValue(kRegValueBrowser)); | |
| 819 } else { | |
| 820 DWORD browser_type = 0; | |
| 821 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueBrowser, | |
| 822 &browser_type)); | |
| 823 EXPECT_EQ(BROWSER_FIREFOX, browser_type); | |
| 824 } | |
| 825 | |
| 826 if (test_clearing_values) { | |
| 827 EXPECT_FALSE(client_state_key.HasValue(kRegValueAdditionalParams)); | |
| 828 } else { | |
| 829 CString ap; | |
| 830 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueAdditionalParams, | |
| 831 &ap)); | |
| 832 EXPECT_STREQ(_T("test_ap"), ap); | |
| 833 } | |
| 834 | |
| 835 CString lang; | |
| 836 EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueLanguage, &lang)); | |
| 837 EXPECT_STREQ(_T("en"), lang); | |
| 838 | |
| 839 // Version should not be written to clientstate by WritePreInstallData(). | |
| 840 EXPECT_FALSE(RegKey::HasValue(client_state_key_name, | |
| 841 kRegValueProductVersion)); | |
| 842 } | |
| 843 | |
| 844 static void ValidateClientStateMedium(bool is_machine, | |
| 845 const CString& app_guid) { | |
| 846 const CString client_state_medium_key_name = AppendRegKeyPath( | |
| 847 ConfigManager::Instance()->machine_registry_client_state_medium(), | |
| 848 app_guid); | |
| 849 if (is_machine) { | |
| 850 RegKey client_state_medium_key; | |
| 851 ASSERT_SUCCEEDED( | |
| 852 client_state_medium_key.Open(client_state_medium_key_name)); | |
| 853 EXPECT_EQ(0, client_state_medium_key.GetValueCount()); | |
| 854 } else { | |
| 855 EXPECT_FALSE(RegKey::HasKey(client_state_medium_key_name)); | |
| 856 // There is no such thing as a user ClientStateMedium key. | |
| 857 const CString user_client_state_medium_key_name = AppendRegKeyPath( | |
| 858 USER_KEY GOOPDATE_REG_RELATIVE_CLIENT_STATE_MEDIUM, | |
| 859 app_guid); | |
| 860 EXPECT_FALSE(RegKey::HasKey(user_client_state_medium_key_name)); | |
| 861 return; | |
| 862 } | |
| 863 } | |
| 864 | |
| 865 // Uses SetupGoogleUpdate to create the ClientStateMedium key with the | |
| 866 // appropriate permissions. Used to test that the permissions are inherited. | |
| 867 void CreateClientStateMediumKey() { | |
| 868 SetupGoogleUpdate setup_google_update(true); | |
| 869 | |
| 870 // On Windows 7, AddAllowedAce() can fail if the registry is redirected. So | |
| 871 // we ignore errors from this call. | |
| 872 setup_google_update.CreateClientStateMedium(); | |
| 873 } | |
| 874 | |
| 875 AppManager* app_manager_; | |
| 876 App* app_; | |
| 877 // A second bundle is necessary because the same bundle cannot have the same | |
| 878 // app in it more than once and many of these tests create an app to populate | |
| 879 // the registry and another to read it. | |
| 880 shared_ptr<AppBundle> dummy_app_bundle_for_app_creation_; | |
| 881 | |
| 882 const GUID guid1_; | |
| 883 | |
| 884 private: | |
| 885 DISALLOW_IMPLICIT_CONSTRUCTORS(AppManagerTestBase); | |
| 886 }; | |
| 887 | |
| 888 // For most tests, the EULA should be accepted. | |
| 889 class AppManagerMachineTest : public AppManagerTestBase { | |
| 890 protected: | |
| 891 AppManagerMachineTest() : AppManagerTestBase(true) {} | |
| 892 }; | |
| 893 | |
| 894 class AppManagerUserTest : public AppManagerTestBase { | |
| 895 protected: | |
| 896 AppManagerUserTest() : AppManagerTestBase(false) {} | |
| 897 }; | |
| 898 | |
| 899 // These fixtures are also used for ReadUninstalledAppPersistentData tests. | |
| 900 class AppManagerReadAppPersistentDataMachineTest | |
| 901 : public AppManagerMachineTest { | |
| 902 }; | |
| 903 | |
| 904 class AppManagerReadAppPersistentDataUserTest | |
| 905 : public AppManagerUserTest { | |
| 906 }; | |
| 907 | |
| 908 class AppManagerWithBundleTest : public AppManagerTestBase { | |
| 909 public: | |
| 910 explicit AppManagerWithBundleTest(bool is_machine) | |
| 911 : AppManagerTestBase(is_machine) { | |
| 912 // CoCreateInstance for registered hook CLSIDs returns ERROR_FILE_NOT_FOUND | |
| 913 // instead of REGDB_E_CLASSNOTREG without this WMI hack. This has to be done | |
| 914 // before the registry overriding that is done by the base class. | |
| 915 WmiQuery wmi_query; | |
| 916 EXPECT_SUCCEEDED(wmi_query.Connect(_T("root\\SecurityCenter"))); | |
| 917 } | |
| 918 | |
| 919 static void PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 920 bool is_machine, | |
| 921 App* expected_app0, | |
| 922 App* expected_app1, | |
| 923 App* expected_app2, | |
| 924 App* opposite_hive_data1, | |
| 925 App* opposite_hive_data2); | |
| 926 | |
| 927 protected: | |
| 928 | |
| 929 // Wrappers for static functions; simplifies callers using this test fixture. | |
| 930 | |
| 931 void PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 932 bool is_machine, | |
| 933 App** expected_app0, | |
| 934 App** expected_app1, | |
| 935 App** expected_app2) { | |
| 936 *expected_app0 = CreateAppForRegistryPopulation(kGuid1); | |
| 937 *expected_app1 = CreateAppForRegistryPopulation(kGuid2); | |
| 938 *expected_app2 = CreateAppForRegistryPopulation(kGuid3); | |
| 939 App* opposite_hive_data1 = CreateAppForRegistryPopulation(kGuid6); | |
| 940 App* opposite_hive_data2 = CreateAppForRegistryPopulation(kGuid7); | |
| 941 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 942 is_machine, | |
| 943 *expected_app0, | |
| 944 *expected_app1, | |
| 945 *expected_app2, | |
| 946 opposite_hive_data1, | |
| 947 opposite_hive_data2); | |
| 948 } | |
| 949 | |
| 950 void PopulateForRegistrationUpdateHookTests( | |
| 951 bool is_machine, | |
| 952 App** expected_app0, | |
| 953 App** expected_app1, | |
| 954 App** expected_app2, | |
| 955 const CString& clsid_app0) { | |
| 956 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 957 is_machine, | |
| 958 expected_app0, | |
| 959 expected_app1, | |
| 960 expected_app2); | |
| 961 | |
| 962 CString clients_key_name = AppendRegKeyPath( | |
| 963 ConfigManager::Instance()->registry_clients(is_machine), | |
| 964 (*expected_app0)->app_guid_string()); | |
| 965 EXPECT_SUCCEEDED(RegKey::SetValue(clients_key_name, | |
| 966 kRegValueUpdateHookClsid, | |
| 967 clsid_app0)); | |
| 968 } | |
| 969 | |
| 970 private: | |
| 971 DISALLOW_IMPLICIT_CONSTRUCTORS(AppManagerWithBundleTest); | |
| 972 }; | |
| 973 | |
| 974 class AppManagerWithBundleMachineTest : public AppManagerWithBundleTest { | |
| 975 protected: | |
| 976 AppManagerWithBundleMachineTest() : AppManagerWithBundleTest(true) {} | |
| 977 }; | |
| 978 | |
| 979 class AppManagerWithBundleUserTest : public AppManagerWithBundleTest { | |
| 980 protected: | |
| 981 AppManagerWithBundleUserTest() : AppManagerWithBundleTest(false) {} | |
| 982 }; | |
| 983 | |
| 984 class HoldAppManagerLock : public Runnable { | |
| 985 public: | |
| 986 explicit HoldAppManagerLock(bool is_machine, const int period) | |
| 987 : period_(period) { | |
| 988 reset(lock_acquired_event_, ::CreateEvent(NULL, false, false, NULL)); | |
| 989 reset(stop_event_, ::CreateEvent(NULL, false, false, NULL)); | |
| 990 | |
| 991 InitializeAppManagerRegistryLock(is_machine, &lock_); | |
| 992 } | |
| 993 | |
| 994 virtual void Run() { | |
| 995 __mutexScope(lock_); | |
| 996 | |
| 997 EXPECT_TRUE(::SetEvent(get(lock_acquired_event_))); | |
| 998 | |
| 999 // TODO(omaha3): Could just use a sleep if we don't do more tests. | |
| 1000 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(stop_event_), period_)); | |
| 1001 } | |
| 1002 | |
| 1003 void Stop() { | |
| 1004 EXPECT_TRUE(::SetEvent(get(stop_event_))); | |
| 1005 } | |
| 1006 | |
| 1007 void WaitForLockToBeAcquired() { | |
| 1008 EXPECT_EQ(WAIT_OBJECT_0, | |
| 1009 ::WaitForSingleObject(get(lock_acquired_event_), 2000)); | |
| 1010 } | |
| 1011 | |
| 1012 private: | |
| 1013 const int period_; | |
| 1014 GLock lock_; | |
| 1015 scoped_event lock_acquired_event_; | |
| 1016 scoped_event stop_event_; | |
| 1017 | |
| 1018 DISALLOW_IMPLICIT_CONSTRUCTORS(HoldAppManagerLock); | |
| 1019 }; | |
| 1020 | |
| 1021 // Provide access to the member functions for other tests without requiring them | |
| 1022 // to know about the test fixture class. | |
| 1023 | |
| 1024 void PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 1025 bool is_machine, | |
| 1026 App* expected_app0, | |
| 1027 App* expected_app1, | |
| 1028 App* expected_app2, | |
| 1029 App* opposite_hive_data1, | |
| 1030 App* opposite_hive_data2) { | |
| 1031 AppManagerWithBundleTest:: | |
| 1032 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 1033 is_machine, | |
| 1034 expected_app0, | |
| 1035 expected_app1, | |
| 1036 expected_app2, | |
| 1037 opposite_hive_data1, | |
| 1038 opposite_hive_data2); | |
| 1039 } | |
| 1040 | |
| 1041 void SetDisplayName(const CString& name, App* app) { | |
| 1042 AppManagerTestBase::SetDisplayName(name, app); | |
| 1043 } | |
| 1044 | |
| 1045 // TODO(omaha3): Maybe use this to test the similar code in install_apps.cc. | |
| 1046 #if 0 | |
| 1047 TEST_F(AppManagerTest, ConvertCommandLineToProductData_Succeeds) { | |
| 1048 CommandLineAppArgs extra1; | |
| 1049 extra1.app_guid = guid1_; | |
| 1050 extra1.app_name = _T("foo"); | |
| 1051 extra1.needs_admin = false; | |
| 1052 extra1.ap = _T("Test ap"); | |
| 1053 extra1.tt_token = _T("Test TT Token"); | |
| 1054 extra1.encoded_installer_data = _T("%20foobar"); | |
| 1055 extra1.install_data_index = _T("foobar"); | |
| 1056 | |
| 1057 CommandLineAppArgs extra2; | |
| 1058 extra2.app_guid = StringToGuid(kGuid2); | |
| 1059 extra2.app_name = _T("bar"); | |
| 1060 extra2.needs_admin = true; // This gets ignored. | |
| 1061 extra2.ap = _T("beta"); | |
| 1062 extra2.tt_token = _T("beta TT Token"); | |
| 1063 | |
| 1064 CommandLineAppArgs extra3; | |
| 1065 extra3.app_guid = StringToGuid(kGuid3); | |
| 1066 extra3.app_name = _T("bar"); | |
| 1067 extra3.needs_admin = true; // This gets ignored. | |
| 1068 extra3.ap = _T("beta"); | |
| 1069 extra3.tt_token = _T("beta TT Token"); | |
| 1070 | |
| 1071 CommandLineArgs args; | |
| 1072 args.is_interactive_set = true; // Not used. | |
| 1073 args.is_machine_set = true; // Not used. | |
| 1074 args.is_crash_handler_disabled = true; // Not used. | |
| 1075 args.is_eula_required_set = true; | |
| 1076 args.is_eula_required_set = true; // Not used. | |
| 1077 args.webplugin_urldomain = _T("http://nothing.google.com"); // Not used. | |
| 1078 args.webplugin_args = _T("blah"); // Not used. | |
| 1079 args.install_source = _T("one_click"); | |
| 1080 args.code_red_metainstaller_path = _T("foo.exe"); // Not used. | |
| 1081 args.legacy_manifest_path = _T("bar.exe"); // Not used. | |
| 1082 args.crash_filename = _T("foo.dmp"); // Not used. | |
| 1083 args.extra.installation_id = StringToGuid(kIid1); | |
| 1084 args.extra.brand_code = _T("GOOG"); | |
| 1085 args.extra.client_id = _T("someclient"); | |
| 1086 args.extra.experiment = _T("exp1"); | |
| 1087 args.extra.referral_id = _T("referrer1"); | |
| 1088 args.extra.browser_type = BROWSER_IE; | |
| 1089 args.extra.language = _T("abc"); | |
| 1090 args.extra.usage_stats_enable = TRISTATE_TRUE; | |
| 1091 args.extra.apps.push_back(extra1); | |
| 1092 args.extra.apps.push_back(extra2); | |
| 1093 args.extra.apps.push_back(extra3); | |
| 1094 | |
| 1095 AppData* expected_data1 = CreateAppData(); | |
| 1096 PopulateExpectedAppData1(guid1_, false, &expected_data1); | |
| 1097 expected_data1.set_version(_T("")); // Clear value. | |
| 1098 expected_data1.set_previous_version(_T("")); // Clear value. | |
| 1099 expected_data1.set_did_run(ACTIVE_UNKNOWN); // Clear value. | |
| 1100 expected_data1.set_display_name(_T("foo")); | |
| 1101 expected_data1.set_browser_type(BROWSER_IE); | |
| 1102 expected_data1.set_install_source(_T("one_click")); | |
| 1103 expected_data1.set_encoded_installer_data(_T("%20foobar")); | |
| 1104 expected_data1.set_install_data_index(_T("foobar")); | |
| 1105 expected_data1.set_usage_stats_enable(TRISTATE_TRUE); | |
| 1106 expected_data1.set_referral_id(_T("referrer1")); | |
| 1107 expected_data1.set_install_time_diff_sec( | |
| 1108 static_cast<uint32>(-1 * kSecondsPerDay)); // New install. | |
| 1109 expected_data1.set_is_eula_accepted(false); | |
| 1110 expected_data1.set_days_since_last_active_ping(0); | |
| 1111 expected_data1.set_days_since_last_roll_call(0); | |
| 1112 | |
| 1113 AppData* expected_data2 = CreateAppData(); | |
| 1114 | |
| 1115 // Make the first app appear to already be installed but without an | |
| 1116 // InstallTime. This affects install_time_diff_sec. | |
| 1117 expected_data2.set_version(_T("4.5.6.7")); | |
| 1118 CreateAppRegistryState(expected_data2); | |
| 1119 | |
| 1120 PopulateExpectedAppData2(StringToGuid(kGuid2), false, &expected_data2); | |
| 1121 | |
| 1122 expected_data2.set_version(_T("")); // Clear value. | |
| 1123 expected_data2.set_previous_version(_T("")); // Clear value. | |
| 1124 expected_data2.set_did_run(ACTIVE_UNKNOWN); // Clear value. | |
| 1125 expected_data2.set_language(_T("abc")); | |
| 1126 expected_data2.set_display_name(_T("bar")); | |
| 1127 expected_data2.set_browser_type(BROWSER_IE); | |
| 1128 expected_data2.set_install_source(_T("one_click")); | |
| 1129 expected_data2.set_usage_stats_enable(TRISTATE_TRUE); | |
| 1130 // Override unique expected data because the args apply to all apps. | |
| 1131 expected_data2.set_iid(StringToGuid(kIid1)); | |
| 1132 expected_data2.set_brand_code(_T("GOOG")); | |
| 1133 expected_data2.set_client_id(_T("someclient")); | |
| 1134 expected_data2.set_experiment(_T("exp1")); | |
| 1135 expected_data2.set_referral_id(_T("referrer1")); | |
| 1136 expected_data2.set_install_time_diff_sec(0); // InstallTime is unknown. | |
| 1137 expected_data2.set_is_eula_accepted(false); | |
| 1138 expected_data2.set_days_since_last_active_ping(0); | |
| 1139 expected_data2.set_days_since_last_roll_call(0); | |
| 1140 | |
| 1141 AppData expected_data3(StringToGuid(kGuid3), false); | |
| 1142 | |
| 1143 // Make the first app appear to already be installed with a valid InstallTime. | |
| 1144 // This affects install_time_diff_sec. | |
| 1145 expected_data3.set_version(_T("4.5.6.7")); | |
| 1146 expected_data3.set_install_time_diff_sec(123456); // Known original time. | |
| 1147 CreateAppRegistryState(expected_data3); | |
| 1148 | |
| 1149 PopulateExpectedAppData2(&expected_data3); | |
| 1150 expected_data3.set_version(_T("")); // Clear value. | |
| 1151 expected_data3.set_previous_version(_T("")); // Clear value. | |
| 1152 expected_data3.set_did_run(AppData::ACTIVE_UNKNOWN); // Clear value. | |
| 1153 expected_data3.set_language(_T("abc")); | |
| 1154 expected_data3.set_display_name(_T("bar")); | |
| 1155 expected_data3.set_browser_type(BROWSER_IE); | |
| 1156 expected_data3.set_install_source(_T("one_click")); | |
| 1157 expected_data3.set_usage_stats_enable(TRISTATE_TRUE); | |
| 1158 // Override unique expected data because the args apply to all apps. | |
| 1159 expected_data3.set_iid(StringToGuid(kIid1)); | |
| 1160 expected_data3.set_brand_code(_T("GOOG")); | |
| 1161 expected_data3.set_client_id(_T("someclient")); | |
| 1162 expected_data3.set_referral_id(_T("referrer1")); | |
| 1163 expected_data3.set_is_eula_accepted(false); | |
| 1164 expected_data3.set_days_since_last_active_ping(0); | |
| 1165 expected_data3.set_days_since_last_roll_call(0); | |
| 1166 | |
| 1167 ProductDataVector products; | |
| 1168 AppManager app_manager(false); | |
| 1169 app_manager.ConvertCommandLineToProductData(args, &products); | |
| 1170 | |
| 1171 ASSERT_EQ(3, products.size()); | |
| 1172 EXPECT_EQ(0, products[0].num_components()); | |
| 1173 EXPECT_EQ(0, products[1].num_components()); | |
| 1174 EXPECT_EQ(0, products[2].num_components()); | |
| 1175 ValidateExpectedValues(expected_data1, products[0].app_data()); | |
| 1176 ValidateExpectedValues(expected_data2, products[1].app_data()); | |
| 1177 | |
| 1178 // install_time_diff_sec may be off by a second or so. | |
| 1179 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 1180 EXPECT_GE(products[2].app_data().install_time_diff_sec(), | |
| 1181 expected_data3.install_time_diff_sec()); | |
| 1182 EXPECT_GE(static_cast<uint32>(500), | |
| 1183 products[2].app_data().install_time_diff_sec() - | |
| 1184 expected_data3.install_time_diff_sec()); | |
| 1185 // Fix up expected_data3 or it might fail verification. | |
| 1186 expected_data3.set_install_time_diff_sec( | |
| 1187 products[2].app_data().install_time_diff_sec()); | |
| 1188 | |
| 1189 ValidateExpectedValues(expected_data3, products[2].app_data()); | |
| 1190 } | |
| 1191 #endif | |
| 1192 | |
| 1193 TEST_F(AppManagerMachineTest, WritePreInstallData) { | |
| 1194 SetAppGuid(kGuid1, app_); | |
| 1195 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1196 WritePreInstallDataTest(app_, false); | |
| 1197 | |
| 1198 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine, | |
| 1199 _T("oeminstall"))); | |
| 1200 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine, | |
| 1201 _T("eulaaccepted"))); | |
| 1202 } | |
| 1203 | |
| 1204 TEST_F(AppManagerMachineTest, WritePreInstallData_IsOem) { | |
| 1205 const DWORD now = Time64ToInt32(GetCurrent100NSTime()); | |
| 1206 ASSERT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE, | |
| 1207 _T("OemInstallTime"), | |
| 1208 now)); | |
| 1209 if (vista_util::IsVistaOrLater()) { | |
| 1210 ASSERT_SUCCEEDED(RegKey::SetValue( | |
| 1211 _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), | |
| 1212 _T("ImageState"), | |
| 1213 _T("IMAGE_STATE_UNDEPLOYABLE"))); | |
| 1214 } else { | |
| 1215 ASSERT_SUCCEEDED(RegKey::SetValue(_T("HKLM\\System\\Setup"), | |
| 1216 _T("AuditInProgress"), | |
| 1217 static_cast<DWORD>(1))); | |
| 1218 } | |
| 1219 | |
| 1220 SetAppGuid(kGuid1, app_); | |
| 1221 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1222 WritePreInstallDataTest(app_, false); | |
| 1223 | |
| 1224 CString oeminstall; | |
| 1225 EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathMachine, | |
| 1226 _T("oeminstall"), | |
| 1227 &oeminstall)); | |
| 1228 EXPECT_STREQ(_T("1"), oeminstall); | |
| 1229 | |
| 1230 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine, | |
| 1231 _T("eulaaccepted"))); | |
| 1232 } | |
| 1233 | |
| 1234 // Creates the ClientStateMedium key with the appropriate permissions then | |
| 1235 // verifies that the created app subkey inherits those. | |
| 1236 // The Update key must be created first to avoid applying ClientStateMedium's | |
| 1237 // permissions to all its parent keys. | |
| 1238 // This keys in this test need to inherit the HKLM privileges, so put the | |
| 1239 // override root in HKLM. | |
| 1240 TEST_F(AppManagerMachineTest, | |
| 1241 WritePreInstallData_CheckClientStateMediumPermissions) { | |
| 1242 const TCHAR kRegistryHiveOverrideRootInHklm[] = | |
| 1243 _T("HKLM\\Software\\") SHORT_COMPANY_NAME | |
| 1244 _T("\\") PRODUCT_NAME _T("\\UnitTest\\"); | |
| 1245 RestoreRegistryHives(); | |
| 1246 hive_override_key_name_ = kRegistryHiveOverrideRootInHklm; | |
| 1247 RegKey::DeleteKey(hive_override_key_name_); | |
| 1248 OverrideRegistryHives(hive_override_key_name_); | |
| 1249 | |
| 1250 EXPECT_SUCCEEDED(RegKey::CreateKey( | |
| 1251 ConfigManager::Instance()->machine_registry_update())); | |
| 1252 CreateClientStateMediumKey(); | |
| 1253 | |
| 1254 SetAppGuid(kGuid1, app_); | |
| 1255 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1256 WritePreInstallDataTest(app_, false); | |
| 1257 | |
| 1258 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine, | |
| 1259 _T("oeminstall"))); | |
| 1260 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine, | |
| 1261 _T("eulaaccepted"))); | |
| 1262 | |
| 1263 const CString app_client_state_medium_key_name = AppendRegKeyPath( | |
| 1264 _T("HKLM\\Software\\") SHORT_COMPANY_NAME | |
| 1265 _T("\\") PRODUCT_NAME _T("\\ClientStateMedium\\"), | |
| 1266 kGuid1); | |
| 1267 VerifyHklmKeyHasMediumIntegrity(app_client_state_medium_key_name); | |
| 1268 VerifyHklmKeyHasDefaultIntegrity( | |
| 1269 _T("HKLM\\Software\\") SHORT_COMPANY_NAME | |
| 1270 _T("\\") PRODUCT_NAME _T("\\ClientStateMedium\\")); | |
| 1271 } | |
| 1272 | |
| 1273 TEST_F(AppManagerMachineTest, | |
| 1274 WritePreInstallData_ClearClientStateMediumUsageStats) { | |
| 1275 const CString client_state_key_name = | |
| 1276 AppendRegKeyPath(MACHINE_REG_CLIENT_STATE_MEDIUM, kGuid1); | |
| 1277 EXPECT_SUCCEEDED(RegKey::SetValue(client_state_key_name, | |
| 1278 _T("usagestats"), | |
| 1279 static_cast<DWORD>(1))); | |
| 1280 | |
| 1281 SetAppGuid(kGuid1, app_); | |
| 1282 WritePreInstallDataTest(app_, false); | |
| 1283 | |
| 1284 EXPECT_FALSE(RegKey::HasValue(client_state_key_name, _T("usagestats"))); | |
| 1285 } | |
| 1286 | |
| 1287 // Tests the EULA accepted case too. | |
| 1288 TEST_F(AppManagerUserTest, WritePreInstallData) { | |
| 1289 SetAppGuid(kGuid1, app_); | |
| 1290 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1291 WritePreInstallDataTest(app_, false); | |
| 1292 | |
| 1293 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1294 _T("oeminstall"))); | |
| 1295 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1296 _T("eulaaccepted"))); | |
| 1297 } | |
| 1298 | |
| 1299 TEST_F(AppManagerUserTest, | |
| 1300 WritePreInstallData_EulaNotAcceptedAppNotRegistered) { | |
| 1301 SetAppGuid(kGuid1, app_); | |
| 1302 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_FALSE)); | |
| 1303 | |
| 1304 WritePreInstallDataTest(app_, false); | |
| 1305 | |
| 1306 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1307 _T("oeminstall"))); | |
| 1308 | |
| 1309 DWORD eula_accepted = 99; | |
| 1310 EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser, | |
| 1311 _T("eulaaccepted"), | |
| 1312 &eula_accepted)); | |
| 1313 EXPECT_EQ(0, eula_accepted); | |
| 1314 } | |
| 1315 | |
| 1316 TEST_F(AppManagerUserTest, | |
| 1317 WritePreInstallData_EulaNotAcceptedAppAlreadyInstalled) { | |
| 1318 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1319 _T("pv"), | |
| 1320 _T("1.2.3.4"))); | |
| 1321 | |
| 1322 SetAppGuid(kGuid1, app_); | |
| 1323 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_FALSE)); | |
| 1324 | |
| 1325 WritePreInstallDataTest(app_, false); | |
| 1326 | |
| 1327 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1328 _T("oeminstall"))); | |
| 1329 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1330 _T("eulaaccepted"))); | |
| 1331 } | |
| 1332 | |
| 1333 TEST_F(AppManagerUserTest, | |
| 1334 WritePreInstallData_EulaAcceptedAppAlreadyInstalled) { | |
| 1335 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1336 _T("pv"), | |
| 1337 _T("1.2.3.4"))); | |
| 1338 | |
| 1339 SetAppGuid(kGuid1, app_); | |
| 1340 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1341 | |
| 1342 WritePreInstallDataTest(app_, false); | |
| 1343 | |
| 1344 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1345 _T("oeminstall"))); | |
| 1346 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1347 _T("eulaaccepted"))); | |
| 1348 } | |
| 1349 | |
| 1350 TEST_F(AppManagerUserTest, | |
| 1351 WritePreInstallData_EulaAcceptedAppAlreadyInstalledAccepted) { | |
| 1352 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1353 _T("pv"), | |
| 1354 _T("1.2.3.4"))); | |
| 1355 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 1356 _T("eulaaccepted"), | |
| 1357 static_cast<DWORD>(1))); | |
| 1358 | |
| 1359 SetAppGuid(kGuid1, app_); | |
| 1360 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1361 | |
| 1362 WritePreInstallDataTest(app_, false); | |
| 1363 | |
| 1364 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1365 _T("oeminstall"))); | |
| 1366 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1367 _T("eulaaccepted"))); | |
| 1368 } | |
| 1369 | |
| 1370 TEST_F(AppManagerUserTest, | |
| 1371 WritePreInstallData_EulaAcceptedAppAlreadyInstalledNotAccepted) { | |
| 1372 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1373 _T("pv"), | |
| 1374 _T("1.2.3.4"))); | |
| 1375 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 1376 _T("eulaaccepted"), | |
| 1377 static_cast<DWORD>(0))); | |
| 1378 | |
| 1379 SetAppGuid(kGuid1, app_); | |
| 1380 EXPECT_SUCCEEDED(app_->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1381 | |
| 1382 WritePreInstallDataTest(app_, false); | |
| 1383 | |
| 1384 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1385 _T("oeminstall"))); | |
| 1386 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1387 _T("eulaaccepted"))); | |
| 1388 } | |
| 1389 | |
| 1390 TEST_F(AppManagerReadAppPersistentDataMachineTest, NoApp) { | |
| 1391 __mutexScope(app_->model()->lock()); | |
| 1392 EXPECT_FAILED(app_manager_->ReadAppPersistentData(app_)); | |
| 1393 } | |
| 1394 | |
| 1395 // For new app, the install_time_diff_sec_ should be -1 day. | |
| 1396 TEST_F(AppManagerMachineTest, ReadAppInstallTimeDiff_NewApp) { | |
| 1397 __mutexScope(app_->model()->lock()); | |
| 1398 app_manager_->ReadAppInstallTimeDiff(app_); | |
| 1399 EXPECT_EQ(kInitialInstallTimeDiff, app_->install_time_diff_sec()); | |
| 1400 } | |
| 1401 | |
| 1402 TEST_F(AppManagerUserTest, ReadAppInstallTimeDiff_NewApp) { | |
| 1403 __mutexScope(app_->model()->lock()); | |
| 1404 app_manager_->ReadAppInstallTimeDiff(app_); | |
| 1405 EXPECT_EQ(kInitialInstallTimeDiff, app_->install_time_diff_sec()); | |
| 1406 } | |
| 1407 | |
| 1408 // For registered app, the install_time_diff_sec_ should be 0 if InstallTime | |
| 1409 // registry value does not exist. | |
| 1410 TEST_F(AppManagerMachineTest, ReadAppInstallTimeDiff_RegisteredApp) { | |
| 1411 App* new_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1412 PopulateExpectedApp1(new_app); | |
| 1413 CreateAppRegistryState(*new_app, is_machine_, _T("1.0.0.0"), true); | |
| 1414 | |
| 1415 __mutexScope(app_->model()->lock()); | |
| 1416 app_manager_->ReadAppInstallTimeDiff(app_); | |
| 1417 EXPECT_EQ(0, app_->install_time_diff_sec()); | |
| 1418 } | |
| 1419 | |
| 1420 // For over-install app, the app is already registered. So | |
| 1421 // install_time_diff_sec_ will be read from InstallTime registry value if | |
| 1422 // exists. Otherwise it should be 0 as verified by the previous test case. | |
| 1423 TEST_F(AppManagerUserTest, ReadAppInstallTimeDiff_OverInstall) { | |
| 1424 const uint32 kInstallTimeDiffSec = 100000; | |
| 1425 App* over_install_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1426 PopulateExpectedApp1(over_install_app); | |
| 1427 SetAppInstallTimeDiffSec(over_install_app, kInstallTimeDiffSec); | |
| 1428 CreateAppRegistryState(*over_install_app, is_machine_, _T("1.1.1.1"), true); | |
| 1429 | |
| 1430 __mutexScope(app_->model()->lock()); | |
| 1431 app_manager_->ReadAppInstallTimeDiff(app_); | |
| 1432 EXPECT_GE(app_->install_time_diff_sec(), kInstallTimeDiffSec); | |
| 1433 EXPECT_LE(app_->install_time_diff_sec(), kInstallTimeDiffSec + 1); | |
| 1434 } | |
| 1435 | |
| 1436 // For uninstalled app, the install_time_diff_sec_ will be read from registry | |
| 1437 // if InstallTime registry value exists. | |
| 1438 TEST_F(AppManagerMachineTest, ReadAppInstallTimeDiff_UninstalledApp) { | |
| 1439 const uint32 kInstallTimeDiffSec = 123456; | |
| 1440 App* uninstalled_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1441 PopulateExpectedUninstalledApp(_T("1.1.0.0"), uninstalled_app); | |
| 1442 SetAppInstallTimeDiffSec(uninstalled_app, kInstallTimeDiffSec); | |
| 1443 CreateAppRegistryState(*uninstalled_app, is_machine_, _T("1.1.0.0"), false); | |
| 1444 | |
| 1445 __mutexScope(app_->model()->lock()); | |
| 1446 app_manager_->ReadAppInstallTimeDiff(app_); | |
| 1447 EXPECT_GE(app_->install_time_diff_sec(), kInstallTimeDiffSec); | |
| 1448 EXPECT_LE(app_->install_time_diff_sec(), kInstallTimeDiffSec + 1); | |
| 1449 } | |
| 1450 | |
| 1451 // A special case. If pv of the uninstalled app doesn't exist, then it is | |
| 1452 // considered not in uninstalled status. InstallTime should be ignored. | |
| 1453 TEST_F(AppManagerUserTest, ReadAppInstallTimeDiff_UninstalledAppWithoutPv) { | |
| 1454 const uint32 kInstallTimeDiffSec = 112233; | |
| 1455 App* uninstalled_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1456 PopulateExpectedUninstalledApp(_T("1.1.0.0"), uninstalled_app); | |
| 1457 SetAppInstallTimeDiffSec(uninstalled_app, kInstallTimeDiffSec); | |
| 1458 CreateAppRegistryState(*uninstalled_app, is_machine_, _T(""), false); | |
| 1459 | |
| 1460 __mutexScope(app_->model()->lock()); | |
| 1461 app_manager_->ReadAppInstallTimeDiff(app_); | |
| 1462 EXPECT_EQ(kInitialInstallTimeDiff, app_->install_time_diff_sec()); | |
| 1463 } | |
| 1464 | |
| 1465 // Tests clearing of data that is already present when not present in app_. | |
| 1466 TEST_F(AppManagerUserTest, | |
| 1467 WritePreInstallData_AppAlreadyInstalled_ClearExistingData) { | |
| 1468 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1469 _T("pv"), | |
| 1470 _T("1.2.3.4"))); | |
| 1471 | |
| 1472 SetAppGuid(kGuid1, app_); | |
| 1473 | |
| 1474 WritePreInstallDataTest(app_, true); | |
| 1475 | |
| 1476 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1477 kRegValueBrowser)); | |
| 1478 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 1479 kRegValueAdditionalParams)); | |
| 1480 } | |
| 1481 | |
| 1482 // Tests clearing of data that is already present when not present in app_. | |
| 1483 TEST_F(AppManagerUserTest, | |
| 1484 WritePreInstallData_AppAlreadyInstalled_OverwriteExistingData) { | |
| 1485 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1486 _T("pv"), | |
| 1487 _T("1.2.3.4"))); | |
| 1488 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1489 kRegValueBrowser, | |
| 1490 static_cast<DWORD>(BROWSER_CHROME))); | |
| 1491 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1492 kRegValueAdditionalParams, | |
| 1493 _T("existingAP"))); | |
| 1494 | |
| 1495 SetAppGuid(kGuid1, app_); | |
| 1496 | |
| 1497 WritePreInstallDataTest(app_, false); | |
| 1498 | |
| 1499 EXPECT_EQ(BROWSER_FIREFOX, GetDwordValue(kGuid1ClientStateKeyPathUser, | |
| 1500 kRegValueBrowser)); | |
| 1501 EXPECT_EQ(_T("test_ap"), GetSzValue(kGuid1ClientStateKeyPathUser, | |
| 1502 kRegValueAdditionalParams)); | |
| 1503 } | |
| 1504 | |
| 1505 // It is important that previous_version passed to CreateAppRegistryState() be | |
| 1506 // different than the current_version in PopulateExpectedApp1() to ensure the | |
| 1507 // version is populated from Clients and not ClientState. | |
| 1508 TEST_F(AppManagerReadAppPersistentDataUserTest, AppExists) { | |
| 1509 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1510 PopulateExpectedApp1(expected_app); | |
| 1511 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1512 | |
| 1513 __mutexScope(app_->model()->lock()); | |
| 1514 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1515 | |
| 1516 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1517 ValidateExpectedValues(*expected_app, *app_); | |
| 1518 } | |
| 1519 | |
| 1520 TEST_F(AppManagerReadAppPersistentDataMachineTest, AppExists) { | |
| 1521 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1522 PopulateExpectedApp1(expected_app); | |
| 1523 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1524 | |
| 1525 __mutexScope(app_->model()->lock()); | |
| 1526 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1527 | |
| 1528 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1529 ValidateExpectedValues(*expected_app, *app_); | |
| 1530 } | |
| 1531 | |
| 1532 TEST_F(AppManagerReadAppPersistentDataUserTest, AppExists_NoDisplayName) { | |
| 1533 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1534 PopulateExpectedApp1(expected_app); | |
| 1535 SetDisplayName(_T(""), expected_app); | |
| 1536 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1537 | |
| 1538 __mutexScope(app_->model()->lock()); | |
| 1539 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1540 | |
| 1541 SetDisplayName(kDefaultAppName, expected_app); | |
| 1542 | |
| 1543 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1544 ValidateExpectedValues(*expected_app, *app_); | |
| 1545 } | |
| 1546 | |
| 1547 TEST_F(AppManagerReadAppPersistentDataUserTest, AppExists_EmptyDisplayName) { | |
| 1548 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1549 PopulateExpectedApp1(expected_app); | |
| 1550 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1551 EXPECT_SUCCEEDED(RegKey::SetValue(GetClientKeyName(guid1_), | |
| 1552 kRegValueAppName, | |
| 1553 _T(""))); | |
| 1554 | |
| 1555 __mutexScope(app_->model()->lock()); | |
| 1556 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1557 | |
| 1558 SetDisplayName(kDefaultAppName, expected_app); | |
| 1559 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1560 ValidateExpectedValues(*expected_app, *app_); | |
| 1561 } | |
| 1562 | |
| 1563 TEST_F(AppManagerReadAppPersistentDataUserTest, EulaNotAccepted) { | |
| 1564 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1565 PopulateExpectedApp1(expected_app); | |
| 1566 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1567 | |
| 1568 // TODO(omaha): We should be able to eliminate the SetValue calls in | |
| 1569 // AppManagerReadAppPersistentData* by moving put_isEulaAccepted() call above | |
| 1570 // CreateAppRegistryState(). | |
| 1571 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 1572 _T("eulaaccepted"), | |
| 1573 static_cast<DWORD>(0))); | |
| 1574 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_FALSE)); | |
| 1575 | |
| 1576 __mutexScope(app_->model()->lock()); | |
| 1577 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1578 | |
| 1579 ValidateExpectedValues(*expected_app, *app_); | |
| 1580 } | |
| 1581 | |
| 1582 TEST_F(AppManagerReadAppPersistentDataUserTest, EulaAccepted) { | |
| 1583 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1584 PopulateExpectedApp1(expected_app); | |
| 1585 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1586 | |
| 1587 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 1588 _T("eulaaccepted"), | |
| 1589 static_cast<DWORD>(1))); | |
| 1590 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1591 | |
| 1592 __mutexScope(app_->model()->lock()); | |
| 1593 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1594 | |
| 1595 ValidateExpectedValues(*expected_app, *app_); | |
| 1596 } | |
| 1597 | |
| 1598 TEST_F(AppManagerReadAppPersistentDataMachineTest, EulaNotAccepted) { | |
| 1599 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1600 PopulateExpectedApp1(expected_app); | |
| 1601 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1602 | |
| 1603 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathMachine, | |
| 1604 _T("eulaaccepted"), | |
| 1605 static_cast<DWORD>(0))); | |
| 1606 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_FALSE)); | |
| 1607 | |
| 1608 __mutexScope(app_->model()->lock()); | |
| 1609 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1610 | |
| 1611 ValidateExpectedValues(*expected_app, *app_); | |
| 1612 } | |
| 1613 | |
| 1614 TEST_F(AppManagerReadAppPersistentDataMachineTest, EulaAccepted) { | |
| 1615 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1616 PopulateExpectedApp1(expected_app); | |
| 1617 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1618 | |
| 1619 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathMachine, | |
| 1620 _T("eulaaccepted"), | |
| 1621 static_cast<DWORD>(1))); | |
| 1622 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1623 | |
| 1624 __mutexScope(app_->model()->lock()); | |
| 1625 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1626 | |
| 1627 ValidateExpectedValues(*expected_app, *app_); | |
| 1628 } | |
| 1629 | |
| 1630 TEST_F(AppManagerReadAppPersistentDataUserTest, TwoApps) { | |
| 1631 App* app2 = NULL; | |
| 1632 EXPECT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kGuid2), &app2)); | |
| 1633 ASSERT_TRUE(app2); | |
| 1634 | |
| 1635 App* expected_app1 = CreateAppForRegistryPopulation(kGuid1); | |
| 1636 PopulateExpectedApp1(expected_app1); | |
| 1637 CreateAppRegistryState(*expected_app1, is_machine_, _T("1.0.0.0"), true); | |
| 1638 | |
| 1639 App* expected_app2 = CreateAppForRegistryPopulation(kGuid2); | |
| 1640 PopulateExpectedApp1(expected_app2); | |
| 1641 CreateAppRegistryState(*expected_app2, is_machine_, _T("1.0.0.0"), true); | |
| 1642 | |
| 1643 __mutexScope(app_->model()->lock()); | |
| 1644 | |
| 1645 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1646 EXPECT_SUCCEEDED(expected_app1->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1647 ValidateExpectedValues(*expected_app1, *app_); | |
| 1648 | |
| 1649 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app2)); | |
| 1650 EXPECT_SUCCEEDED(expected_app2->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1651 ValidateExpectedValues(*expected_app2, *app2); | |
| 1652 } | |
| 1653 | |
| 1654 TEST_F(AppManagerReadAppPersistentDataUserTest, NoClientState) { | |
| 1655 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1656 PopulateExpectedApp1ClientsOnly(expected_app); | |
| 1657 CreateAppRegistryState(*expected_app, is_machine_, _T("1.0.0.0"), true); | |
| 1658 | |
| 1659 // CreateAppRegistryState always creates the ClientState key, so delete it. | |
| 1660 EXPECT_SUCCEEDED(RegKey::DeleteKey(kGuid1ClientStateKeyPathUser)); | |
| 1661 | |
| 1662 EXPECT_FALSE(IsClientStateKeyPresent(*app_)); | |
| 1663 | |
| 1664 __mutexScope(app_->model()->lock()); | |
| 1665 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1666 | |
| 1667 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1668 ValidateExpectedValues(*expected_app, *app_); | |
| 1669 } | |
| 1670 | |
| 1671 // This is the No Clients key case. | |
| 1672 TEST_F(AppManagerReadAppPersistentDataUserTest, | |
| 1673 ReadUninstalledAppPersistentData_UninstalledApp) { | |
| 1674 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1675 PopulateExpectedUninstalledApp(_T("1.1.0.0"), expected_app); | |
| 1676 CreateAppRegistryState(*expected_app, is_machine_, _T("1.1.0.0"), false); | |
| 1677 | |
| 1678 __mutexScope(app_->model()->lock()); | |
| 1679 EXPECT_SUCCEEDED(app_manager_->ReadUninstalledAppPersistentData(app_)); | |
| 1680 | |
| 1681 SetDisplayName(kDefaultAppName, expected_app); | |
| 1682 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1683 ValidateExpectedValues(*expected_app, *app_); | |
| 1684 | |
| 1685 // Explicitly verify the absence of a Clients key and the version since these | |
| 1686 // are important to this test. | |
| 1687 EXPECT_FALSE(RegKey::HasKey( | |
| 1688 AppendRegKeyPath(ConfigManager::Instance()->registry_clients(is_machine_), | |
| 1689 kGuid1))); | |
| 1690 EXPECT_STREQ(_T("1.1.0.0"), expected_app->current_version()->version()); | |
| 1691 | |
| 1692 // Verify that ReadAppPersistentData does not populate the version. | |
| 1693 app_->current_version()->set_version(_T("")); | |
| 1694 expected_app->current_version()->set_version(_T("")); | |
| 1695 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1696 SetDisplayName(kDefaultAppName, expected_app); | |
| 1697 ValidateExpectedValues(*expected_app, *app_); | |
| 1698 EXPECT_TRUE(expected_app->current_version()->version().IsEmpty()); | |
| 1699 } | |
| 1700 | |
| 1701 TEST_F(AppManagerReadAppPersistentDataMachineTest, | |
| 1702 ReadUninstalledAppPersistentData_UninstalledApp) { | |
| 1703 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1704 PopulateExpectedUninstalledApp(_T("1.1.0.0"), expected_app); | |
| 1705 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1706 CreateAppRegistryState(*expected_app, is_machine_, _T("1.1.0.0"), false); | |
| 1707 | |
| 1708 __mutexScope(app_->model()->lock()); | |
| 1709 EXPECT_SUCCEEDED(app_manager_->ReadUninstalledAppPersistentData(app_)); | |
| 1710 | |
| 1711 SetDisplayName(kDefaultAppName, expected_app); | |
| 1712 ValidateExpectedValues(*expected_app, *app_); | |
| 1713 | |
| 1714 // Explicitly verify the absence of a Clients key and the version since these | |
| 1715 // are important to this test. | |
| 1716 EXPECT_FALSE(RegKey::HasKey( | |
| 1717 AppendRegKeyPath(ConfigManager::Instance()->registry_clients(is_machine_), | |
| 1718 kGuid1))); | |
| 1719 EXPECT_STREQ(_T("1.1.0.0"), expected_app->current_version()->version()); | |
| 1720 | |
| 1721 // Verify that ReadAppPersistentData does not populate the version. | |
| 1722 app_->current_version()->set_version(_T("")); | |
| 1723 expected_app->current_version()->set_version(_T("")); | |
| 1724 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1725 SetDisplayName(kDefaultAppName, expected_app); | |
| 1726 ValidateExpectedValues(*expected_app, *app_); | |
| 1727 EXPECT_TRUE(expected_app->current_version()->version().IsEmpty()); | |
| 1728 } | |
| 1729 | |
| 1730 TEST_F(AppManagerReadAppPersistentDataUserTest, | |
| 1731 ReadUninstalledAppPersistentData_EulaNotAccepted) { | |
| 1732 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1733 PopulateExpectedUninstalledApp(_T("1.1.0.0"), expected_app); | |
| 1734 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_FALSE)); | |
| 1735 CreateAppRegistryState(*expected_app, is_machine_, _T("1.1.0.0"), false); | |
| 1736 | |
| 1737 __mutexScope(app_->model()->lock()); | |
| 1738 EXPECT_SUCCEEDED(app_manager_->ReadUninstalledAppPersistentData(app_)); | |
| 1739 | |
| 1740 SetDisplayName(kDefaultAppName, expected_app); | |
| 1741 ValidateExpectedValues(*expected_app, *app_); | |
| 1742 } | |
| 1743 | |
| 1744 // Tests the case where Omaha has created the Client State key before running | |
| 1745 // the installer. Uses PopulateExpectedUninstalledApp then clears pv before | |
| 1746 // writing the data to the registry. is_uninstalled_ is not set to false until | |
| 1747 // after CreateAppRegistryState to prevent Client key from being created. | |
| 1748 TEST_F(AppManagerReadAppPersistentDataUserTest, | |
| 1749 ClientStateExistsWithoutPvOrClientsKey) { | |
| 1750 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1751 PopulateExpectedUninstalledApp(_T(""), expected_app); | |
| 1752 CreateAppRegistryState(*expected_app, is_machine_, _T(""), false); | |
| 1753 | |
| 1754 // Update expected_app->install_time_diff_sec_ value here since related | |
| 1755 // registry values have been changed. app_ will be created based on the | |
| 1756 // new registry status so to make the objects match, reloading here is | |
| 1757 // necessary. | |
| 1758 app_manager_->ReadAppInstallTimeDiff(expected_app); | |
| 1759 | |
| 1760 __mutexScope(app_->model()->lock()); | |
| 1761 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1762 | |
| 1763 SetDisplayName(kDefaultAppName, expected_app); | |
| 1764 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1765 ValidateExpectedValues(*expected_app, *app_); | |
| 1766 } | |
| 1767 | |
| 1768 TEST_F(AppManagerReadAppPersistentDataMachineTest, | |
| 1769 ClientStateExistsWithoutPvOrClientsKey) { | |
| 1770 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1771 PopulateExpectedUninstalledApp(_T(""), expected_app); | |
| 1772 CreateAppRegistryState(*expected_app, is_machine_, _T(""), false); | |
| 1773 | |
| 1774 // Update expected_app->install_time_diff_sec_ value here since related | |
| 1775 // registry values have been changed. app_ will be created based on the | |
| 1776 // new registry status so to make the objects match, reloading here is | |
| 1777 // necessary. | |
| 1778 app_manager_->ReadAppInstallTimeDiff(expected_app); | |
| 1779 | |
| 1780 __mutexScope(app_->model()->lock()); | |
| 1781 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1782 | |
| 1783 SetDisplayName(kDefaultAppName, expected_app); | |
| 1784 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1785 ValidateExpectedValues(*expected_app, *app_); | |
| 1786 } | |
| 1787 | |
| 1788 // An empty pv value is the same as a populated one for uninstall checks. | |
| 1789 TEST_F(AppManagerReadAppPersistentDataUserTest, | |
| 1790 ClientStateExistsWithEmptyPvNoClientsKey) { | |
| 1791 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 1792 PopulateExpectedUninstalledApp(_T(""), expected_app); | |
| 1793 CreateAppRegistryState(*expected_app, is_machine_, _T(""), false); | |
| 1794 | |
| 1795 // Write the empty pv value. | |
| 1796 CString client_state_key_name = AppendRegKeyPath( | |
| 1797 ConfigManager::Instance()->registry_client_state(false), | |
| 1798 kGuid1); | |
| 1799 EXPECT_SUCCEEDED(RegKey::SetValue(client_state_key_name, | |
| 1800 kRegValueProductVersion, | |
| 1801 _T(""))); | |
| 1802 | |
| 1803 __mutexScope(app_->model()->lock()); | |
| 1804 EXPECT_SUCCEEDED(app_manager_->ReadAppPersistentData(app_)); | |
| 1805 | |
| 1806 SetDisplayName(kDefaultAppName, expected_app); | |
| 1807 EXPECT_SUCCEEDED(expected_app->put_isEulaAccepted(VARIANT_TRUE)); | |
| 1808 ValidateExpectedValues(*expected_app, *app_); | |
| 1809 } | |
| 1810 | |
| 1811 TEST_F(AppManagerUserTest, | |
| 1812 ReadInstallerRegistrationValues_FailsWhenClientsKeyAbsent) { | |
| 1813 __mutexBlock(app_->model()->lock()) { | |
| 1814 EXPECT_EQ(GOOPDATEINSTALL_E_INSTALLER_DID_NOT_WRITE_CLIENTS_KEY, | |
| 1815 app_manager_->ReadInstallerRegistrationValues(app_)); | |
| 1816 } | |
| 1817 | |
| 1818 EXPECT_TRUE(app_->next_version()->version().IsEmpty()); | |
| 1819 EXPECT_TRUE(app_->language().IsEmpty()); | |
| 1820 | |
| 1821 EXPECT_FALSE(RegKey::HasKey(kGuid1ClientsKeyPathUser)); | |
| 1822 EXPECT_FALSE(RegKey::HasKey(kGuid1ClientStateKeyPathUser)); | |
| 1823 } | |
| 1824 | |
| 1825 TEST_F(AppManagerUserTest, | |
| 1826 ReadInstallerRegistrationValues_FailsWhenVersionValueAbsent) { | |
| 1827 ASSERT_SUCCEEDED(RegKey::CreateKey(kGuid1ClientsKeyPathUser)); | |
| 1828 | |
| 1829 __mutexBlock(app_->model()->lock()) { | |
| 1830 EXPECT_EQ(GOOPDATEINSTALL_E_INSTALLER_DID_NOT_WRITE_CLIENTS_KEY, | |
| 1831 app_manager_->ReadInstallerRegistrationValues(app_)); | |
| 1832 } | |
| 1833 | |
| 1834 EXPECT_TRUE(app_->next_version()->version().IsEmpty()); | |
| 1835 EXPECT_TRUE(app_->language().IsEmpty()); | |
| 1836 | |
| 1837 EXPECT_TRUE(RegKey::HasKey(kGuid1ClientsKeyPathUser)); | |
| 1838 EXPECT_FALSE(RegKey::HasKey(kGuid1ClientStateKeyPathUser)); | |
| 1839 } | |
| 1840 | |
| 1841 TEST_F(AppManagerUserTest, | |
| 1842 ReadInstallerRegistrationValues_FailsWhenVersionValueEmpty) { | |
| 1843 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1844 kRegValueProductVersion, | |
| 1845 _T(""))); | |
| 1846 | |
| 1847 __mutexBlock(app_->model()->lock()) { | |
| 1848 EXPECT_EQ(GOOPDATEINSTALL_E_INSTALLER_DID_NOT_WRITE_CLIENTS_KEY, | |
| 1849 app_manager_->ReadInstallerRegistrationValues(app_)); | |
| 1850 } | |
| 1851 | |
| 1852 EXPECT_TRUE(app_->next_version()->version().IsEmpty()); | |
| 1853 EXPECT_TRUE(app_->language().IsEmpty()); | |
| 1854 | |
| 1855 EXPECT_TRUE(RegKey::HasKey(kGuid1ClientsKeyPathUser)); | |
| 1856 EXPECT_FALSE(RegKey::HasKey(kGuid1ClientStateKeyPathUser)); | |
| 1857 } | |
| 1858 | |
| 1859 TEST_F(AppManagerUserTest, | |
| 1860 ReadInstallerRegistrationValues_SucceedsWhenStateKeyAbsent) { | |
| 1861 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1862 kRegValueProductVersion, | |
| 1863 _T("0.9.68.4"))); | |
| 1864 | |
| 1865 __mutexBlock(app_->model()->lock()) { | |
| 1866 EXPECT_SUCCEEDED(app_manager_->ReadInstallerRegistrationValues(app_)); | |
| 1867 } | |
| 1868 | |
| 1869 EXPECT_STREQ(_T("0.9.68.4"), app_->next_version()->version()); | |
| 1870 EXPECT_TRUE(app_->language().IsEmpty()); | |
| 1871 } | |
| 1872 | |
| 1873 TEST_F(AppManagerUserTest, | |
| 1874 ReadInstallerRegistrationValues_SucceedsWithLanguage) { | |
| 1875 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1876 kRegValueProductVersion, | |
| 1877 _T("0.9.68.4"))); | |
| 1878 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 1879 kRegValueLanguage, | |
| 1880 _T("zh-TW"))); | |
| 1881 | |
| 1882 __mutexBlock(app_->model()->lock()) { | |
| 1883 EXPECT_SUCCEEDED(app_manager_->ReadInstallerRegistrationValues(app_)); | |
| 1884 } | |
| 1885 | |
| 1886 EXPECT_STREQ(_T("0.9.68.4"), app_->next_version()->version()); | |
| 1887 EXPECT_STREQ(_T("zh-TW"), app_->language()); | |
| 1888 } | |
| 1889 | |
| 1890 TEST_F(AppManagerMachineTest, | |
| 1891 ReadInstallerRegistrationValues_SucceedsWithLanguage) { | |
| 1892 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathMachine, | |
| 1893 kRegValueProductVersion, | |
| 1894 _T("0.9.68.4"))); | |
| 1895 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathMachine, | |
| 1896 kRegValueLanguage, | |
| 1897 _T("zh-TW"))); | |
| 1898 | |
| 1899 __mutexBlock(app_->model()->lock()) { | |
| 1900 EXPECT_SUCCEEDED(app_manager_->ReadInstallerRegistrationValues(app_)); | |
| 1901 } | |
| 1902 | |
| 1903 EXPECT_STREQ(_T("0.9.68.4"), app_->next_version()->version()); | |
| 1904 EXPECT_STREQ(_T("zh-TW"), app_->language()); | |
| 1905 } | |
| 1906 | |
| 1907 TEST_F(AppManagerUserTest, PersistSuccessfulInstall) { | |
| 1908 PersistSuccessfulInstallTest(); | |
| 1909 } | |
| 1910 | |
| 1911 TEST_F(AppManagerMachineTest, PersistSuccessfulInstall) { | |
| 1912 PersistSuccessfulInstallTest(); | |
| 1913 } | |
| 1914 | |
| 1915 TEST_F(AppManagerUserTest, PersistUpdateCheckSuccessfullySent_AllUpdated) { | |
| 1916 PersistUpdateCheckSuccessfullySent_AllUpdated(); | |
| 1917 } | |
| 1918 | |
| 1919 TEST_F(AppManagerMachineTest, PersistUpdateCheckSuccessfullySent_AllUpdated) { | |
| 1920 PersistUpdateCheckSuccessfullySent_AllUpdated(); | |
| 1921 } | |
| 1922 | |
| 1923 TEST_F(AppManagerUserTest, PersistUpdateCheckSuccessfullySent_NotRun) { | |
| 1924 PersistUpdateCheckSuccessfullySent_NotRun(); | |
| 1925 } | |
| 1926 | |
| 1927 TEST_F(AppManagerMachineTest, PersistUpdateCheckSuccessfullySent_NotRun) { | |
| 1928 PersistUpdateCheckSuccessfullySent_NotRun(); | |
| 1929 } | |
| 1930 | |
| 1931 TEST_F(AppManagerUserTest, PersistUpdateCheckSuccessfullySent_NoPreviousPing) { | |
| 1932 PersistUpdateCheckSuccessfullySent_NoPreviousPing(); | |
| 1933 } | |
| 1934 | |
| 1935 TEST_F(AppManagerMachineTest, | |
| 1936 PersistUpdateCheckSuccessfullySent_NoPreviousPing) { | |
| 1937 PersistUpdateCheckSuccessfullySent_NoPreviousPing(); | |
| 1938 } | |
| 1939 | |
| 1940 TEST_F(AppManagerUserTest, SynchronizeClientStateTest) { | |
| 1941 SynchronizeClientStateTest(kGuid2); // App ID must be different than app_. | |
| 1942 | |
| 1943 ValidateClientStateMedium(is_machine_, kGuid2); | |
| 1944 } | |
| 1945 | |
| 1946 TEST_F(AppManagerMachineTest, SynchronizeClientStateTest) { | |
| 1947 SynchronizeClientStateTest(kGuid2); // App ID must be different than app_. | |
| 1948 | |
| 1949 ValidateClientStateMedium(is_machine_, kGuid2); | |
| 1950 } | |
| 1951 | |
| 1952 // Should not create ClientStateMedium key. | |
| 1953 TEST_F(AppManagerMachineTest, SynchronizeClientState_Omaha) { | |
| 1954 SynchronizeClientStateTest(kGoogleUpdateAppId); | |
| 1955 | |
| 1956 const CString client_state_medium_key_name = AppendRegKeyPath( | |
| 1957 ConfigManager::Instance()->machine_registry_client_state_medium(), | |
| 1958 kGoogleUpdateAppId); | |
| 1959 EXPECT_FALSE(RegKey::HasKey(client_state_medium_key_name)); | |
| 1960 } | |
| 1961 | |
| 1962 TEST_F(AppManagerUserTest, UpdateUpdateAvailableStats_NoExistingStats) { | |
| 1963 const time64 before_time_in_100ns(GetCurrent100NSTime()); | |
| 1964 | |
| 1965 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 1966 UpdateUpdateAvailableStats(guid1_, app_manager_); | |
| 1967 | |
| 1968 const time64 after_time_in_100ns(GetCurrent100NSTime()); | |
| 1969 | |
| 1970 DWORD update_available_count(0); | |
| 1971 EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser, | |
| 1972 _T("UpdateAvailableCount"), | |
| 1973 &update_available_count)); | |
| 1974 EXPECT_EQ(1, update_available_count); | |
| 1975 | |
| 1976 DWORD64 update_available_since_time(0); | |
| 1977 EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser, | |
| 1978 _T("UpdateAvailableSince"), | |
| 1979 &update_available_since_time)); | |
| 1980 EXPECT_LE(before_time_in_100ns, update_available_since_time); | |
| 1981 EXPECT_GE(after_time_in_100ns, update_available_since_time); | |
| 1982 const DWORD64 time_since_first_update_available = | |
| 1983 after_time_in_100ns - update_available_since_time; | |
| 1984 EXPECT_GT(10 * kSecsTo100ns, time_since_first_update_available); | |
| 1985 } | |
| 1986 | |
| 1987 TEST_F(AppManagerUserTest, UpdateUpdateAvailableStats_WithExistingStats) { | |
| 1988 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 1989 _T("UpdateAvailableCount"), | |
| 1990 static_cast<DWORD>(123456))); | |
| 1991 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 1992 _T("UpdateAvailableSince"), | |
| 1993 static_cast<DWORD64>(9876543210))); | |
| 1994 | |
| 1995 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 1996 UpdateUpdateAvailableStats(guid1_, app_manager_); | |
| 1997 | |
| 1998 DWORD update_available_count(0); | |
| 1999 EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser, | |
| 2000 _T("UpdateAvailableCount"), | |
| 2001 &update_available_count)); | |
| 2002 EXPECT_EQ(123457, update_available_count); | |
| 2003 | |
| 2004 DWORD64 update_available_since_time(0); | |
| 2005 EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser, | |
| 2006 _T("UpdateAvailableSince"), | |
| 2007 &update_available_since_time)); | |
| 2008 EXPECT_EQ(9876543210, update_available_since_time); | |
| 2009 } | |
| 2010 | |
| 2011 // TODO(omaha3): Test PersistSuccessfulUpdateCheckResponse(). | |
| 2012 // TODO(omaha): Move these tests to app_registry_utils_unittest.cc. | |
| 2013 #if 0 | |
| 2014 TEST_F(AppManagerUserTest, ClearUpdateAvailableStats_KeyNotPresent) { | |
| 2015 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2016 ClearUpdateAvailableStats(guid1_, app_manager_); | |
| 2017 } | |
| 2018 | |
| 2019 TEST_F(AppManagerUserTest, ClearUpdateAvailableStats_DataPresent) { | |
| 2020 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2021 _T("UpdateAvailableCount"), | |
| 2022 static_cast<DWORD>(123456))); | |
| 2023 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2024 _T("UpdateAvailableSince"), | |
| 2025 static_cast<DWORD64>(9876543210))); | |
| 2026 | |
| 2027 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2028 ClearUpdateAvailableStats(guid1_, app_manager_); | |
| 2029 | |
| 2030 EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser)); | |
| 2031 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2032 _T("UpdateAvailableCount"))); | |
| 2033 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2034 _T("UpdateAvailableSince"))); | |
| 2035 } | |
| 2036 #endif | |
| 2037 | |
| 2038 TEST_F(AppManagerUserTest, ReadUpdateAvailableStats_DataNotPresent) { | |
| 2039 RegKey::CreateKey(kGuid1ClientStateKeyPathUser); | |
| 2040 | |
| 2041 DWORD update_responses(1); | |
| 2042 DWORD64 time_since_first_response_ms(1); | |
| 2043 app_manager_->ReadUpdateAvailableStats(guid1_, | |
| 2044 &update_responses, | |
| 2045 &time_since_first_response_ms); | |
| 2046 | |
| 2047 EXPECT_EQ(0, update_responses); | |
| 2048 EXPECT_EQ(0, time_since_first_response_ms); | |
| 2049 } | |
| 2050 | |
| 2051 TEST_F(AppManagerUserTest, ReadUpdateAvailableStats_DataPresent) { | |
| 2052 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2053 _T("UpdateAvailableCount"), | |
| 2054 static_cast<DWORD>(123456))); | |
| 2055 const DWORD64 kUpdateAvailableSince = | |
| 2056 GetCurrent100NSTime() - 2 * kMillisecsTo100ns; | |
| 2057 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2058 _T("UpdateAvailableSince"), | |
| 2059 kUpdateAvailableSince)); | |
| 2060 | |
| 2061 DWORD update_responses(0); | |
| 2062 DWORD64 time_since_first_response_ms(0); | |
| 2063 app_manager_->ReadUpdateAvailableStats(guid1_, | |
| 2064 &update_responses, | |
| 2065 &time_since_first_response_ms); | |
| 2066 | |
| 2067 EXPECT_EQ(123456, update_responses); | |
| 2068 EXPECT_LE(2, time_since_first_response_ms); | |
| 2069 EXPECT_GT(10 * kMsPerSec, time_since_first_response_ms); | |
| 2070 } | |
| 2071 | |
| 2072 // TODO(omaha): Move these tests to app_registry_utils_unittest.cc. | |
| 2073 #if 0 | |
| 2074 TEST_F(AppManagerUserTest, PersistSuccessfulInstall_Install_Online) { | |
| 2075 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2076 _T("UpdateAvailableCount"), | |
| 2077 static_cast<DWORD>(123456))); | |
| 2078 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2079 _T("UpdateAvailableSince"), | |
| 2080 static_cast<DWORD64>(9876543210))); | |
| 2081 | |
| 2082 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2083 app_manager_->PersistSuccessfulInstall(guid1_, false, false); | |
| 2084 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 2085 | |
| 2086 // Verify ClearUpdateAvailableStats() was called. | |
| 2087 EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser)); | |
| 2088 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2089 _T("UpdateAvailableCount"))); | |
| 2090 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2091 _T("UpdateAvailableSince"))); | |
| 2092 | |
| 2093 // Verify update check value is written but update value is not. | |
| 2094 const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser, | |
| 2095 kRegValueLastSuccessfulCheckSec); | |
| 2096 EXPECT_GE(now, last_check_sec); | |
| 2097 EXPECT_GE(static_cast<uint32>(200), now - last_check_sec); | |
| 2098 | |
| 2099 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2100 kRegValueLastUpdateTimeSec)); | |
| 2101 } | |
| 2102 | |
| 2103 TEST_F(AppManagerUserTest, PersistSuccessfulInstall_Install_Offline) { | |
| 2104 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2105 _T("UpdateAvailableCount"), | |
| 2106 static_cast<DWORD>(123456))); | |
| 2107 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2108 _T("UpdateAvailableSince"), | |
| 2109 static_cast<DWORD64>(9876543210))); | |
| 2110 | |
| 2111 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2112 app_manager_->PersistSuccessfulInstall(guid1_, false, true); | |
| 2113 | |
| 2114 // Verify ClearUpdateAvailableStats() was called. | |
| 2115 EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser)); | |
| 2116 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2117 _T("UpdateAvailableCount"))); | |
| 2118 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2119 _T("UpdateAvailableSince"))); | |
| 2120 | |
| 2121 // Verify update values are not written. | |
| 2122 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2123 kRegValueLastSuccessfulCheckSec)); | |
| 2124 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2125 kRegValueLastUpdateTimeSec)); | |
| 2126 } | |
| 2127 | |
| 2128 TEST_F(AppManagerUserTest, PersistSuccessfulInstall_Update_ExistingTimes) { | |
| 2129 const DWORD kExistingUpdateValues = 0x70123456; | |
| 2130 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2131 _T("UpdateAvailableCount"), | |
| 2132 static_cast<DWORD>(123456))); | |
| 2133 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2134 _T("UpdateAvailableSince"), | |
| 2135 static_cast<DWORD64>(9876543210))); | |
| 2136 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2137 kRegValueLastSuccessfulCheckSec, | |
| 2138 kExistingUpdateValues)); | |
| 2139 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2140 kRegValueLastUpdateTimeSec, | |
| 2141 kExistingUpdateValues)); | |
| 2142 | |
| 2143 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2144 app_manager_->PersistSuccessfulInstall(guid1_, true, false); | |
| 2145 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 2146 | |
| 2147 // Verify ClearUpdateAvailableStats() was called. | |
| 2148 EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser)); | |
| 2149 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2150 _T("UpdateAvailableCount"))); | |
| 2151 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2152 _T("UpdateAvailableSince"))); | |
| 2153 | |
| 2154 // Verify update values updated. | |
| 2155 const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser, | |
| 2156 kRegValueLastSuccessfulCheckSec); | |
| 2157 EXPECT_NE(kExistingUpdateValues, last_check_sec); | |
| 2158 EXPECT_GE(now, last_check_sec); | |
| 2159 EXPECT_GE(static_cast<uint32>(200), now - last_check_sec); | |
| 2160 | |
| 2161 const uint32 last_update_sec = | |
| 2162 GetDwordValue(kGuid1ClientStateKeyPathUser, kRegValueLastUpdateTimeSec); | |
| 2163 EXPECT_NE(kExistingUpdateValues, last_update_sec); | |
| 2164 EXPECT_GE(now, last_update_sec); | |
| 2165 EXPECT_GE(static_cast<uint32>(200), now - last_update_sec); | |
| 2166 } | |
| 2167 | |
| 2168 TEST_F(AppManagerUserTest, | |
| 2169 PersistSuccessfulInstall_Update_StateKeyDoesNotExist) { | |
| 2170 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2171 app_manager_->PersistSuccessfulInstall(guid1_, true, false); | |
| 2172 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 2173 | |
| 2174 // Verify update values updated. | |
| 2175 const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser, | |
| 2176 kRegValueLastSuccessfulCheckSec); | |
| 2177 EXPECT_GE(now, last_check_sec); | |
| 2178 EXPECT_GE(static_cast<uint32>(200), now - last_check_sec); | |
| 2179 | |
| 2180 const uint32 last_update_sec = | |
| 2181 GetDwordValue(kGuid1ClientStateKeyPathUser, kRegValueLastUpdateTimeSec); | |
| 2182 EXPECT_GE(now, last_update_sec); | |
| 2183 EXPECT_GE(static_cast<uint32>(200), now - last_update_sec); | |
| 2184 } | |
| 2185 #endif | |
| 2186 | |
| 2187 // TODO(omaha): Move these tests to app_registry_utils_unittest.cc. | |
| 2188 #if 0 | |
| 2189 TEST_F(AppManagerUserTest, PersistSuccessfulUpdateCheck_ExistingTime) { | |
| 2190 const DWORD kExistingUpdateValue = 0x12345678; | |
| 2191 EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser, | |
| 2192 kRegValueLastSuccessfulCheckSec, | |
| 2193 kExistingUpdateValue)); | |
| 2194 | |
| 2195 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2196 app_manager_->PersistSuccessfulUpdateCheck(guid1_); | |
| 2197 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 2198 | |
| 2199 const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser, | |
| 2200 kRegValueLastSuccessfulCheckSec); | |
| 2201 EXPECT_NE(kExistingUpdateValue, last_check_sec); | |
| 2202 EXPECT_GE(now, last_check_sec); | |
| 2203 EXPECT_GE(static_cast<uint32>(200), now - last_check_sec); | |
| 2204 | |
| 2205 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2206 kRegValueLastUpdateTimeSec)); | |
| 2207 } | |
| 2208 | |
| 2209 TEST_F(AppManagerUserTest, PersistSuccessfulUpdateCheck_StateKeyDoesNotExist) { | |
| 2210 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2211 app_manager_->PersistSuccessfulUpdateCheck(guid1_); | |
| 2212 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
| 2213 | |
| 2214 const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser, | |
| 2215 kRegValueLastSuccessfulCheckSec); | |
| 2216 EXPECT_GE(now, last_check_sec); | |
| 2217 EXPECT_GE(static_cast<uint32>(200), now - last_check_sec); | |
| 2218 | |
| 2219 EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser, | |
| 2220 kRegValueLastUpdateTimeSec)); | |
| 2221 } | |
| 2222 #endif | |
| 2223 | |
| 2224 TEST_F(AppManagerMachineTest, RemoveClientState_Uninstalled) { | |
| 2225 App* expected_app = CreateAppForRegistryPopulation(kGuid1); | |
| 2226 PopulateExpectedUninstalledApp(_T("1.1.0.0"), expected_app); | |
| 2227 CreateAppRegistryState(*expected_app, is_machine_, _T("1.1.0.0"), false); | |
| 2228 | |
| 2229 __mutexScope(AppManager::Instance()->GetRegistryStableStateLock()); | |
| 2230 EXPECT_SUCCEEDED(app_manager_->RemoveClientState(guid1_)); | |
| 2231 EXPECT_FALSE(IsClientStateKeyPresent(*expected_app)); | |
| 2232 } | |
| 2233 | |
| 2234 // TODO(omaha): Move implementation up to class definition. | |
| 2235 // Creates 2 registered app and 1 unregistered app and populates the parameters. | |
| 2236 // Each is written to the registry. | |
| 2237 // Also creates partial Clients and ClientState keys and creates a registered | |
| 2238 // and an unregistered app in the opposite registry hive. | |
| 2239 void AppManagerWithBundleTest:: | |
| 2240 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 2241 bool is_machine, | |
| 2242 App* expected_app0, | |
| 2243 App* expected_app1, | |
| 2244 App* expected_app2, | |
| 2245 App* opposite_hive_data1, | |
| 2246 App* opposite_hive_data2) { | |
| 2247 | |
| 2248 PopulateExpectedApp1(expected_app0); | |
| 2249 CreateAppRegistryState(*expected_app0, is_machine, _T("1.0.0.0"), true); | |
| 2250 | |
| 2251 PopulateExpectedApp2(expected_app1); | |
| 2252 CreateAppRegistryState(*expected_app1, is_machine, _T("1.1.0.0"), true); | |
| 2253 | |
| 2254 PopulateExpectedUninstalledApp(_T("2.3.0.0"), expected_app2); | |
| 2255 CreateAppRegistryState(*expected_app2, is_machine, _T("2.3.0.0"), false); | |
| 2256 | |
| 2257 // | |
| 2258 // Add incomplete Clients and ClientState entries. | |
| 2259 // | |
| 2260 | |
| 2261 // No pv. | |
| 2262 EXPECT_HRESULT_SUCCEEDED(RegKey::SetValue( | |
| 2263 AppendRegKeyPath(is_machine ? MACHINE_REG_CLIENTS : USER_REG_CLIENTS, | |
| 2264 kGuid4), | |
| 2265 _T("name"), | |
| 2266 _T("foo"))); | |
| 2267 | |
| 2268 EXPECT_HRESULT_SUCCEEDED(RegKey::SetValue( | |
| 2269 AppendRegKeyPath(is_machine ? MACHINE_REG_CLIENT_STATE : | |
| 2270 USER_REG_CLIENT_STATE, | |
| 2271 kGuid5), | |
| 2272 kRegValueDidRun, | |
| 2273 _T("1"))); | |
| 2274 | |
| 2275 // Add registered and unregistered app to the opposite registry hive. | |
| 2276 PopulateExpectedApp2(opposite_hive_data1); | |
| 2277 CreateAppRegistryState(*opposite_hive_data1, | |
| 2278 !is_machine, | |
| 2279 _T("1.1.0.0"), | |
| 2280 true); | |
| 2281 | |
| 2282 PopulateExpectedUninstalledApp(_T("1.1.0.0"), opposite_hive_data2); | |
| 2283 CreateAppRegistryState(*opposite_hive_data2, | |
| 2284 !is_machine, | |
| 2285 _T("1.1.0.0"), | |
| 2286 false); | |
| 2287 } | |
| 2288 | |
| 2289 TEST_F(AppManagerWithBundleMachineTest, GetRegisteredApps) { | |
| 2290 App *expected_app0, *expected_app1, *expected_app2; | |
| 2291 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 2292 true, | |
| 2293 &expected_app0, | |
| 2294 &expected_app1, | |
| 2295 &expected_app2); | |
| 2296 | |
| 2297 // An important part of this test is that GetRegisteredApps() continues and | |
| 2298 // returns success even though there is a key for an app that is not properly | |
| 2299 // registered (e.g. it does not have a pv value or has an invalid pv value). | |
| 2300 // Since this is so important, explicitly check registry was set up correctly. | |
| 2301 // Invalid pv value type is checked in a separate test since it causes an | |
| 2302 // assert. | |
| 2303 // Since GetRegisteredApps() does not rely on pv, the app is still returned | |
| 2304 // in the vector. | |
| 2305 // Note that kGuid4 is not upper-cased like the other GUIDs. This is because | |
| 2306 // the other GUIDs are converted to a GUID and back to a string by | |
| 2307 // PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests(). | |
| 2308 const CString incomplete_clients_key = | |
| 2309 AppendRegKeyPath(MACHINE_REG_CLIENTS, kGuid4); | |
| 2310 EXPECT_TRUE(RegKey::HasKey(incomplete_clients_key)); | |
| 2311 EXPECT_FALSE(RegKey::HasValue(incomplete_clients_key, | |
| 2312 kRegValueProductVersion)); | |
| 2313 | |
| 2314 AppIdVector registered_app_ids; | |
| 2315 EXPECT_SUCCEEDED(app_manager_->GetRegisteredApps(®istered_app_ids)); | |
| 2316 EXPECT_EQ(3, registered_app_ids.size()); | |
| 2317 | |
| 2318 EXPECT_STREQ(CString(kGuid1).MakeUpper(), registered_app_ids[0]); | |
| 2319 EXPECT_STREQ(CString(kGuid2).MakeUpper(), registered_app_ids[1]); | |
| 2320 EXPECT_STREQ(kGuid4, registered_app_ids[2]); | |
| 2321 } | |
| 2322 | |
| 2323 TEST_F(AppManagerWithBundleUserTest, GetRegisteredApps) { | |
| 2324 App *expected_app0, *expected_app1, *expected_app2; | |
| 2325 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 2326 false, | |
| 2327 &expected_app0, | |
| 2328 &expected_app1, | |
| 2329 &expected_app2); | |
| 2330 | |
| 2331 // See comment in machine GetRegisteredApps test. | |
| 2332 const CString incomplete_clients_key = | |
| 2333 AppendRegKeyPath(USER_REG_CLIENTS, kGuid4); | |
| 2334 EXPECT_TRUE(RegKey::HasKey(incomplete_clients_key)); | |
| 2335 EXPECT_FALSE(RegKey::HasValue(incomplete_clients_key, | |
| 2336 kRegValueProductVersion)); | |
| 2337 | |
| 2338 AppIdVector registered_app_ids; | |
| 2339 EXPECT_SUCCEEDED(app_manager_->GetRegisteredApps(®istered_app_ids)); | |
| 2340 EXPECT_EQ(3, registered_app_ids.size()); | |
| 2341 | |
| 2342 EXPECT_STREQ(CString(kGuid1).MakeUpper(), registered_app_ids[0]); | |
| 2343 EXPECT_STREQ(CString(kGuid2).MakeUpper(), registered_app_ids[1]); | |
| 2344 EXPECT_STREQ(kGuid4, registered_app_ids[2]); | |
| 2345 } | |
| 2346 | |
| 2347 TEST_F(AppManagerWithBundleUserTest, GetRegisteredApps_InvalidPvValueType) { | |
| 2348 App *expected_app0, *expected_app1, *expected_app2; | |
| 2349 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 2350 false, | |
| 2351 &expected_app0, | |
| 2352 &expected_app1, | |
| 2353 &expected_app2); | |
| 2354 | |
| 2355 // It is important that this value is alphabetically before the other AppIds. | |
| 2356 // This allows us to test that processing continues despite the bad pv. | |
| 2357 const TCHAR* const kInvalidPvTypeAppId = | |
| 2358 _T("{0150B619-867C-4985-B193-ED309A23EE36}"); | |
| 2359 const CString invalid_pv_type_clients_key = | |
| 2360 AppendRegKeyPath(USER_REG_CLIENTS, kInvalidPvTypeAppId); | |
| 2361 | |
| 2362 // Incorrect data type for pv. See comment in machine GetRegisteredApps test. | |
| 2363 EXPECT_HRESULT_SUCCEEDED(RegKey::SetValue(invalid_pv_type_clients_key, | |
| 2364 kRegValueProductVersion, | |
| 2365 static_cast<DWORD>(12345))); | |
| 2366 EXPECT_TRUE(RegKey::HasValue(invalid_pv_type_clients_key, | |
| 2367 kRegValueProductVersion)); | |
| 2368 DWORD value_type = REG_SZ; | |
| 2369 EXPECT_SUCCEEDED(RegKey::GetValueType(invalid_pv_type_clients_key, | |
| 2370 kRegValueProductVersion, | |
| 2371 &value_type)); | |
| 2372 EXPECT_NE(REG_SZ, value_type); | |
| 2373 | |
| 2374 AppIdVector registered_app_ids; | |
| 2375 EXPECT_SUCCEEDED(app_manager_->GetRegisteredApps(®istered_app_ids)); | |
| 2376 | |
| 2377 EXPECT_EQ(4, registered_app_ids.size()); | |
| 2378 | |
| 2379 EXPECT_STREQ(kInvalidPvTypeAppId, registered_app_ids[0]); | |
| 2380 EXPECT_STREQ(CString(kGuid1).MakeUpper(), registered_app_ids[1]); | |
| 2381 EXPECT_STREQ(CString(kGuid2).MakeUpper(), registered_app_ids[2]); | |
| 2382 EXPECT_STREQ(kGuid4, registered_app_ids[3]); | |
| 2383 } | |
| 2384 | |
| 2385 TEST_F(AppManagerWithBundleMachineTest, GetUninstalledApps) { | |
| 2386 App *expected_app0, *expected_app1, *expected_app2; | |
| 2387 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 2388 true, | |
| 2389 &expected_app0, | |
| 2390 &expected_app1, | |
| 2391 &expected_app2); | |
| 2392 | |
| 2393 AppIdVector registered_app_ids; | |
| 2394 EXPECT_SUCCEEDED(app_manager_->GetUninstalledApps(®istered_app_ids)); | |
| 2395 EXPECT_EQ(1, registered_app_ids.size()); | |
| 2396 | |
| 2397 EXPECT_STREQ(CString(kGuid3).MakeUpper(), registered_app_ids[0]); | |
| 2398 } | |
| 2399 | |
| 2400 TEST_F(AppManagerWithBundleUserTest, GetUninstalledApps) { | |
| 2401 App *expected_app0, *expected_app1, *expected_app2; | |
| 2402 PopulateDataAndRegistryForRegisteredAndUnInstalledAppsTests( | |
| 2403 false, | |
| 2404 &expected_app0, | |
| 2405 &expected_app1, | |
| 2406 &expected_app2); | |
| 2407 | |
| 2408 AppIdVector registered_app_ids; | |
| 2409 EXPECT_SUCCEEDED(app_manager_->GetUninstalledApps(®istered_app_ids)); | |
| 2410 EXPECT_EQ(1, registered_app_ids.size()); | |
| 2411 | |
| 2412 EXPECT_STREQ(CString(kGuid3).MakeUpper(), registered_app_ids[0]); | |
| 2413 } | |
| 2414 | |
| 2415 TEST_F(AppManagerWithBundleMachineTest, GetOemInstalledAndEulaAcceptedApps) { | |
| 2416 // Create an OEM installed app. | |
| 2417 App* expected_app1 = CreateAppForRegistryPopulation(kGuid1); | |
| 2418 PopulateExpectedApp1(expected_app1); | |
| 2419 CreateAppRegistryState(*expected_app1, is_machine_, _T("1.0.0.0"), true); | |
| 2420 | |
| 2421 CString client_state_key_name = AppendRegKeyPath( | |
| 2422 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 2423 expected_app1->app_guid_string()); | |
| 2424 RegKey client_state_key; | |
| 2425 ASSERT_SUCCEEDED(client_state_key.Create(client_state_key_name)); | |
| 2426 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueOemInstall, _T("1"))); | |
| 2427 | |
| 2428 // Create a non-OEM installed app. | |
| 2429 App* expected_app2 = CreateAppForRegistryPopulation(kGuid2); | |
| 2430 PopulateExpectedApp2(expected_app2); | |
| 2431 CreateAppRegistryState(*expected_app2, is_machine_, _T("2.0.0.0"), true); | |
| 2432 | |
| 2433 AppIdVector oem_installed_app_ids; | |
| 2434 EXPECT_SUCCEEDED( | |
| 2435 app_manager_->GetOemInstalledAndEulaAcceptedApps(&oem_installed_app_ids)); | |
| 2436 EXPECT_EQ(1, oem_installed_app_ids.size()); | |
| 2437 EXPECT_STREQ(expected_app1->app_guid_string().MakeUpper(), | |
| 2438 oem_installed_app_ids[0]); | |
| 2439 | |
| 2440 app_manager_->ClearOemInstalled(oem_installed_app_ids); | |
| 2441 oem_installed_app_ids.clear(); | |
| 2442 EXPECT_SUCCEEDED( | |
| 2443 app_manager_->GetOemInstalledAndEulaAcceptedApps(&oem_installed_app_ids)); | |
| 2444 EXPECT_EQ(0, oem_installed_app_ids.size()); | |
| 2445 } | |
| 2446 | |
| 2447 TEST_F(AppManagerWithBundleUserTest, GetOemInstalledAndEulaAcceptedApps) { | |
| 2448 // Create an OEM installed app. | |
| 2449 App* expected_app1 = CreateAppForRegistryPopulation(kGuid1); | |
| 2450 PopulateExpectedApp1(expected_app1); | |
| 2451 CreateAppRegistryState(*expected_app1, is_machine_, _T("1.0.0.0"), true); | |
| 2452 | |
| 2453 CString client_state_key_name = AppendRegKeyPath( | |
| 2454 ConfigManager::Instance()->registry_client_state(is_machine_), | |
| 2455 expected_app1->app_guid_string()); | |
| 2456 RegKey client_state_key; | |
| 2457 ASSERT_SUCCEEDED(client_state_key.Create(client_state_key_name)); | |
| 2458 ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueOemInstall, _T("1"))); | |
| 2459 | |
| 2460 // Create a non-OEM installed app. | |
| 2461 App* expected_app2 = CreateAppForRegistryPopulation(kGuid2); | |
| 2462 PopulateExpectedApp2(expected_app2); | |
| 2463 CreateAppRegistryState(*expected_app2, is_machine_, _T("2.0.0.0"), true); | |
| 2464 | |
| 2465 AppIdVector oem_installed_app_ids; | |
| 2466 EXPECT_SUCCEEDED( | |
| 2467 app_manager_->GetOemInstalledAndEulaAcceptedApps(&oem_installed_app_ids)); | |
| 2468 EXPECT_EQ(1, oem_installed_app_ids.size()); | |
| 2469 EXPECT_STREQ(expected_app1->app_guid_string().MakeUpper(), | |
| 2470 oem_installed_app_ids[0]); | |
| 2471 | |
| 2472 app_manager_->ClearOemInstalled(oem_installed_app_ids); | |
| 2473 oem_installed_app_ids.clear(); | |
| 2474 EXPECT_SUCCEEDED( | |
| 2475 app_manager_->GetOemInstalledAndEulaAcceptedApps(&oem_installed_app_ids)); | |
| 2476 EXPECT_EQ(0, oem_installed_app_ids.size()); | |
| 2477 } | |
| 2478 | |
| 2479 // TODO(omaha): Perhaps CoCreate some real hooks and test further for the | |
| 2480 // *UpdateHook* tests. | |
| 2481 TEST_F(AppManagerWithBundleMachineTest, RunRegistrationUpdateHook) { | |
| 2482 App *expected_app0, *expected_app1, *expected_app2; | |
| 2483 PopulateForRegistrationUpdateHookTests( | |
| 2484 true, | |
| 2485 &expected_app0, | |
| 2486 &expected_app1, | |
| 2487 &expected_app2, | |
| 2488 kNonExistentClsid); | |
| 2489 | |
| 2490 EXPECT_EQ(REGDB_E_CLASSNOTREG, | |
| 2491 app_manager_->RunRegistrationUpdateHook(CString(kGuid1))); | |
| 2492 | |
| 2493 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), | |
| 2494 app_manager_->RunRegistrationUpdateHook(CString(kGuid7))); | |
| 2495 } | |
| 2496 | |
| 2497 TEST_F(AppManagerWithBundleUserTest, RunRegistrationUpdateHook) { | |
| 2498 App *expected_app0, *expected_app1, *expected_app2; | |
| 2499 PopulateForRegistrationUpdateHookTests( | |
| 2500 false, | |
| 2501 &expected_app0, | |
| 2502 &expected_app1, | |
| 2503 &expected_app2, | |
| 2504 kNonExistentClsid); | |
| 2505 | |
| 2506 EXPECT_EQ(REGDB_E_CLASSNOTREG, | |
| 2507 app_manager_->RunRegistrationUpdateHook(CString(kGuid1))); | |
| 2508 | |
| 2509 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), | |
| 2510 app_manager_->RunRegistrationUpdateHook(CString(kGuid7))); | |
| 2511 } | |
| 2512 | |
| 2513 // TODO(omaha): The RunAllRegistrationUpdateHooks tests do not actually | |
| 2514 // CoCreate any hook. Need to find a way to test this. | |
| 2515 TEST_F(AppManagerWithBundleMachineTest, RunAllRegistrationUpdateHooks) { | |
| 2516 App *expected_app0, *expected_app1, *expected_app2; | |
| 2517 PopulateForRegistrationUpdateHookTests( | |
| 2518 true, | |
| 2519 &expected_app0, | |
| 2520 &expected_app1, | |
| 2521 &expected_app2, | |
| 2522 GuidToString(GUID_NULL)); | |
| 2523 | |
| 2524 EXPECT_SUCCEEDED(app_manager_->RunAllRegistrationUpdateHooks()); | |
| 2525 } | |
| 2526 | |
| 2527 TEST_F(AppManagerWithBundleUserTest, RunAllRegistrationUpdateHooks) { | |
| 2528 App *expected_app0, *expected_app1, *expected_app2; | |
| 2529 PopulateForRegistrationUpdateHookTests( | |
| 2530 false, | |
| 2531 &expected_app0, | |
| 2532 &expected_app1, | |
| 2533 &expected_app2, | |
| 2534 GuidToString(GUID_NULL)); | |
| 2535 | |
| 2536 EXPECT_SUCCEEDED(app_manager_->RunAllRegistrationUpdateHooks()); | |
| 2537 } | |
| 2538 | |
| 2539 TEST_F(AppManagerMachineTest, AppLockContention) { | |
| 2540 const int kLockHeldTimeMs = 500; | |
| 2541 HoldAppManagerLock hold_lock(is_machine_, kLockHeldTimeMs); | |
| 2542 | |
| 2543 Thread thread; | |
| 2544 thread.Start(&hold_lock); | |
| 2545 hold_lock.WaitForLockToBeAcquired(); | |
| 2546 | |
| 2547 HighresTimer lock_metrics_timer; | |
| 2548 __mutexScope(app_->model()->lock()); | |
| 2549 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), | |
| 2550 app_manager_->ReadAppPersistentData(app_)); | |
| 2551 | |
| 2552 // -20 because this sometimes failed with 48x vs. 500. | |
| 2553 EXPECT_LE(kLockHeldTimeMs - 20, lock_metrics_timer.GetElapsedMs()); | |
| 2554 | |
| 2555 thread.WaitTillExit(1000); | |
| 2556 } | |
| 2557 | |
| 2558 TEST_F(AppManagerUserTest, AppLockContention) { | |
| 2559 const int kLockHeldTimeMs = 500; | |
| 2560 HoldAppManagerLock hold_lock(is_machine_, kLockHeldTimeMs); | |
| 2561 | |
| 2562 Thread thread; | |
| 2563 thread.Start(&hold_lock); | |
| 2564 hold_lock.WaitForLockToBeAcquired(); | |
| 2565 | |
| 2566 HighresTimer lock_metrics_timer; | |
| 2567 __mutexScope(app_->model()->lock()); | |
| 2568 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), | |
| 2569 app_manager_->ReadAppPersistentData(app_)); | |
| 2570 | |
| 2571 // -20 because this sometimes failed with 48x vs. 500. | |
| 2572 EXPECT_LE(kLockHeldTimeMs - 20, lock_metrics_timer.GetElapsedMs()); | |
| 2573 | |
| 2574 thread.WaitTillExit(1000); | |
| 2575 } | |
| 2576 | |
| 2577 TEST_F(AppManagerMachineTest, AppLock_MachineAndUser) { | |
| 2578 GLock app_manager_user_lock; | |
| 2579 InitializeAppManagerRegistryLock(false, &app_manager_user_lock); | |
| 2580 | |
| 2581 __mutexScope(app_manager_user_lock); | |
| 2582 | |
| 2583 HighresTimer lock_metrics_timer; | |
| 2584 __mutexScope(app_->model()->lock()); | |
| 2585 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), | |
| 2586 app_manager_->ReadAppPersistentData(app_)); | |
| 2587 | |
| 2588 EXPECT_GT(40, lock_metrics_timer.GetElapsedMs()) | |
| 2589 << _T("No delay is expected because there should not be a conflict."); | |
| 2590 } | |
| 2591 | |
| 2592 TEST_F(AppManagerUserTest, ReadAppVersionNoLock_NoApp) { | |
| 2593 CString version; | |
| 2594 EXPECT_FAILED(AppManager::ReadAppVersionNoLock(is_machine_, | |
| 2595 StringToGuid(kGuid1), | |
| 2596 &version)); | |
| 2597 } | |
| 2598 | |
| 2599 TEST_F(AppManagerUserTest, ReadAppVersionNoLock_RegisteredApp) { | |
| 2600 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser, | |
| 2601 kRegValueProductVersion, | |
| 2602 _T("0.9.75.4"))); | |
| 2603 | |
| 2604 CString version; | |
| 2605 EXPECT_SUCCEEDED(AppManager::ReadAppVersionNoLock(is_machine_, | |
| 2606 StringToGuid(kGuid1), | |
| 2607 &version)); | |
| 2608 EXPECT_STREQ(_T("0.9.75.4"), version); | |
| 2609 EXPECT_SUCCEEDED(RegKey::DeleteKey(kGuid1ClientsKeyPathUser)); | |
| 2610 } | |
| 2611 | |
| 2612 TEST_F(AppManagerMachineTest, ReadAppVersionNoLock_NoApp) { | |
| 2613 CString version; | |
| 2614 EXPECT_FAILED(AppManager::ReadAppVersionNoLock(is_machine_, | |
| 2615 StringToGuid(kGuid1), | |
| 2616 &version)); | |
| 2617 } | |
| 2618 | |
| 2619 TEST_F(AppManagerMachineTest, ReadAppVersionNoLock_RegisteredApp) { | |
| 2620 ASSERT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathMachine, | |
| 2621 kRegValueProductVersion, | |
| 2622 _T("0.9.80.4"))); | |
| 2623 | |
| 2624 CString version; | |
| 2625 EXPECT_SUCCEEDED(AppManager::ReadAppVersionNoLock(is_machine_, | |
| 2626 StringToGuid(kGuid1), | |
| 2627 &version)); | |
| 2628 EXPECT_STREQ(_T("0.9.80.4"), version); | |
| 2629 EXPECT_SUCCEEDED(RegKey::DeleteKey(kGuid1ClientsKeyPathMachine)); | |
| 2630 } | |
| 2631 | |
| 2632 } // namespace omaha | |
| OLD | NEW |