blob: 2001015d2e828666da05e688e30dbfae7152664b [file] [log] [blame]
// Copyright 2007-2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
//
// ApplicationManager unit tests
#include <vector>
#include "base/scoped_ptr.h"
#include "omaha/common/utils.h"
#include "omaha/common/time.h"
#include "omaha/common/vistautil.h"
#include "omaha/enterprise/const_group_policy.h"
#include "omaha/goopdate/command_line.h"
#include "omaha/goopdate/config_manager.h"
#include "omaha/goopdate/const_goopdate.h"
#include "omaha/setup/setup_google_update.h"
#include "omaha/testing/unit_test.h"
#include "omaha/worker/application_data.h"
#include "omaha/worker/job.h"
namespace omaha {
namespace {
const TCHAR* const kGuid1 = _T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}");
const TCHAR* const kGuid2 = _T("{A979ACBD-1F55-4b12-A35F-4DBCA5A7CCB8}");
const TCHAR* const kGuid3 = _T("{661045C5-4429-4140-BC48-8CEA241D1DEF}");
const TCHAR* const kGuid4 = _T("{AAFA1CF9-E94F-42e6-A899-4CD27F37D5A7}");
const TCHAR* const kGuid5 = _T("{3B1A3CCA-0525-4418-93E6-A0DB3398EC9B}");
const TCHAR* const kGuid6 = _T("{F3F2CFD4-5F98-4bf0-ABB0-BEEEA46C62B4}");
const TCHAR* const kGuid7 = _T("{6FD2272F-8583-4bbd-895A-E65F8003FC7B}");
const TCHAR* const kIid1 = _T("{F723495F-8ACF-4746-8240-643741C797B5}");
const TCHAR* const kGuid1ClientsKeyPathUser =
_T("HKCU\\Software\\Google\\Update\\Clients\\")
_T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}");
const TCHAR* const kGuid1ClientStateKeyPathUser =
_T("HKCU\\Software\\Google\\Update\\ClientState\\")
_T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}");
const TCHAR* const kGuid1ClientStateKeyPathMachine =
_T("HKLM\\Software\\Google\\Update\\ClientState\\")
_T("{21CD0965-0B0E-47cf-B421-2D191C16C0E2}");
} // namespace
void ValidateExpectedValues(const AppData& expected, const AppData& actual);
void VerifyHklmKeyHasMediumIntegrity(const CString& key_full_name);
void VerifyHklmKeyHasDefaultIntegrity(const CString& key_full_name);
class AppManagerTest : public testing::Test {
public:
// Creates the application registration entries based on the passed in data.
// If passed an application that is uninstalled, the method only creates
// the registration entries in the client state and no information is written
// in the clients.
static void CreateAppRegistryState(const AppData& data) {
bool is_machine = data.is_machine_app();
CString client_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_clients(is_machine),
GuidToString(data.app_guid()));
CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(is_machine),
GuidToString(data.app_guid()));
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
RegKey client_key;
if (!data.is_uninstalled()) {
ASSERT_SUCCEEDED(client_key.Create(client_key_name));
if (!data.version().IsEmpty()) {
ASSERT_SUCCEEDED(client_key.SetValue(kRegValueProductVersion,
data.version()));
}
}
RegKey client_state_key;
ASSERT_SUCCEEDED(client_state_key.Create(client_state_key_name));
if (!data.previous_version().IsEmpty()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueProductVersion,
data.previous_version()));
}
if (!data.language().IsEmpty()) {
if (data.is_uninstalled()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueLanguage,
data.language()));
} else {
ASSERT_SUCCEEDED(client_key.SetValue(kRegValueLanguage,
data.language()));
}
}
if (data.did_run() != AppData::ACTIVE_UNKNOWN) {
CString dr = (data.did_run() == AppData::ACTIVE_NOTRUN) ? _T("0") :
_T("1");
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueDidRun,
dr));
}
if (!data.ap().IsEmpty()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueAdditionalParams,
data.ap()));
}
if (!data.tt_token().IsEmpty()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueTTToken,
data.tt_token()));
}
if (!::IsEqualGUID(data.iid(), GUID_NULL)) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueInstallationId,
GuidToString(data.iid())));
}
if (!data.brand_code().IsEmpty()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueBrandCode,
data.brand_code()));
}
if (!data.client_id().IsEmpty()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueClientId,
data.client_id()));
}
if (!data.referral_id().IsEmpty()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueReferralId,
data.referral_id()));
}
if (!data.referral_id().IsEmpty()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueReferralId,
data.referral_id()));
}
if (data.install_time_diff_sec()) {
const DWORD install_time = now - data.install_time_diff_sec();
ASSERT_SUCCEEDED(client_state_key.SetValue(kRegValueInstallTimeSec,
install_time));
}
if (!data.is_eula_accepted()) {
ASSERT_SUCCEEDED(client_state_key.SetValue(_T("eulaaccepted"),
static_cast<DWORD>(0)));
}
int days = data.days_since_last_active_ping();
if (days != -1) {
EXPECT_GE(days, 0);
ASSERT1(now > static_cast<uint32>(days * kSecondsPerDay));
uint32 last_active_time = now - days * kSecondsPerDay;
ASSERT_SUCCEEDED(client_state_key.SetValue(
kRegValueActivePingDayStartSec,
static_cast<DWORD>(last_active_time)));
}
days = data.days_since_last_roll_call();
if (days != -1) {
EXPECT_GE(days, 0);
EXPECT_GE(now, static_cast<uint32>(days * kSecondsPerDay));
uint32 last_roll_call_time = now - days * kSecondsPerDay;
ASSERT_SUCCEEDED(client_state_key.SetValue(
kRegValueRollCallDayStartSec,
static_cast<DWORD>(last_roll_call_time)));
}
}
static void PopulateExpectedAppData1(AppData* expected_app) {
ASSERT_TRUE(expected_app);
expected_app->set_version(_T("1.1.1.3"));
expected_app->set_previous_version(_T("1.0.0.0"));
expected_app->set_language(_T("abc"));
expected_app->set_ap(_T("Test ap"));
expected_app->set_tt_token(_T("Test TT Token"));
expected_app->set_iid(StringToGuid(kIid1));
expected_app->set_brand_code(_T("GOOG"));
expected_app->set_client_id(_T("someclient"));
// Do not set referral_id or install_time_diff_sec because these are not
// expected in most cases.
// This value must be ACTIVE_RUN for UpdateApplicationStateTest to work.
expected_app->set_did_run(AppData::ACTIVE_RUN);
expected_app->set_days_since_last_active_ping(3);
expected_app->set_days_since_last_roll_call(1);
}
static void PopulateExpectedAppData1InvalidBrand(AppData* expected_app) {
PopulateExpectedAppData1(expected_app);
expected_app->set_brand_code(_T("GOOG1122"));
}
static void PopulateExpectedAppData2(AppData* expected_app) {
ASSERT_TRUE(expected_app);
expected_app->set_version(_T("1.2.1.3"));
expected_app->set_previous_version(_T("1.1.0.0"));
expected_app->set_language(_T("de"));
expected_app->set_ap(_T("beta"));
expected_app->set_tt_token(_T("beta TT Token"));
expected_app->set_iid(
StringToGuid(_T("{431EC961-CFD8-49ea-AB7B-2B99BCA274AD}")));
expected_app->set_brand_code(_T("GooG"));
expected_app->set_client_id(_T("anotherclient"));
expected_app->set_did_run(AppData::ACTIVE_NOTRUN);
expected_app->set_days_since_last_active_ping(100);
expected_app->set_days_since_last_roll_call(1);
}
static void PopulateExpectedUninstalledAppData(AppData* expected_app) {
ASSERT_TRUE(expected_app);
PopulateExpectedAppData2(expected_app);
// Make the AppData represent an uninstall.
expected_app->set_version(_T(""));
expected_app->set_is_uninstalled(true);
}
protected:
AppManagerTest()
: hive_override_key_name_(kRegistryHiveOverrideRoot),
guid1_(StringToGuid(kGuid1)) {}
virtual void SetUp() {
RegKey::DeleteKey(hive_override_key_name_);
OverrideRegistryHives(hive_override_key_name_);
}
virtual void TearDown() {
RestoreRegistryHives();
RegKey::DeleteKey(hive_override_key_name_);
}
void ClearUpdateAvailableStats(const GUID& parent_app_guid,
const GUID& app_guid,
AppManager* app_manager) {
ASSERT_TRUE(app_manager);
app_manager->ClearUpdateAvailableStats(parent_app_guid, app_guid);
}
bool IsClientStateKeyPresent(const AppData& data) {
CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(data.is_machine_app()),
GuidToString(data.app_guid()));
return RegKey::HasKey(client_state_key_name);
}
void InitializeApplicationStateTest(bool is_machine) {
// Create the test data.
AppData expected_data(guid1_, is_machine);
expected_data.set_version(_T("4.5.6.7"));
expected_data.set_language(_T("de"));
expected_data.set_days_since_last_active_ping(-1);
expected_data.set_days_since_last_roll_call(-1);
CreateAppRegistryState(expected_data);
// Create the job that contains the test data.
CommandLineAppArgs extra;
extra.app_guid = guid1_;
extra.app_name = _T("foo");
extra.ap = _T("test ap");
extra.tt_token = _T("test TT Token");
CommandLineArgs args;
args.extra.installation_id =
StringToGuid(_T("{64333341-CA93-490d-9FB7-7FC5728721F4}"));
args.extra.brand_code = _T("g00g");
args.extra.client_id = _T("myclient");
args.extra.referral_id = _T("somereferrer");
args.extra.language = _T("en");
args.extra.apps.push_back(extra);
AppManager app_manager(is_machine);
ProductDataVector products;
app_manager.ConvertCommandLineToProductData(args, &products);
ASSERT_EQ(1, products.size());
AppData product_app_data = products[0].app_data();
EXPECT_TRUE(product_app_data.is_eula_accepted());
// Test the method.
ASSERT_SUCCEEDED(
app_manager.InitializeApplicationState(&product_app_data));
// Validate the results.
CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(is_machine),
kGuid1);
RegKey client_state_key;
ASSERT_SUCCEEDED(client_state_key.Create(client_state_key_name));
ValidateClientStateMedium(is_machine, kGuid1);
// Check version is copied to the client state.
CString previous_version;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueProductVersion,
&previous_version));
EXPECT_STREQ(_T("4.5.6.7"), product_app_data.version());
EXPECT_STREQ(_T("4.5.6.7"), previous_version);
// Check language is copied to the client state.
CString language;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueLanguage, &language));
EXPECT_STREQ(_T("de"), product_app_data.language());
EXPECT_STREQ(_T("de"), language);
// Check iid is set correctly in ClientState.
CString iid;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallationId, &iid));
EXPECT_STREQ(_T("{64333341-CA93-490D-9FB7-7FC5728721F4}"),
GuidToString(product_app_data.iid()));
EXPECT_STREQ(_T("{64333341-CA93-490D-9FB7-7FC5728721F4}"), iid);
// Check other values were not written.
EXPECT_FALSE(client_state_key.HasValue(kRegValueAdditionalParams));
EXPECT_FALSE(client_state_key.HasValue(kRegValueBrandCode));
EXPECT_FALSE(client_state_key.HasValue(kRegValueBrowser));
EXPECT_FALSE(client_state_key.HasValue(kRegValueClientId));
EXPECT_FALSE(client_state_key.HasValue(kRegValueDidRun));
EXPECT_FALSE(client_state_key.HasValue(kRegValueOemInstall));
EXPECT_FALSE(client_state_key.HasValue(kRegValueReferralId));
EXPECT_FALSE(client_state_key.HasValue(kRegValueEulaAccepted));
EXPECT_FALSE(client_state_key.HasValue(kRegValueUsageStats));
EXPECT_FALSE(client_state_key.HasValue(kRegValueInstallTimeSec));
EXPECT_FALSE(client_state_key.HasValue(kRegValueTTToken));
EXPECT_FALSE(client_state_key.HasValue(kRegValueActivePingDayStartSec));
EXPECT_FALSE(client_state_key.HasValue(kRegValueRollCallDayStartSec));
}
void HandleSuccessfulUpdateCheckRequestSendTest_AllUpdated(bool is_machine) {
const CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(is_machine),
kGuid1);
// Create the test data.
AppData expected_data(guid1_, is_machine);
expected_data.set_version(_T("1.0.0.0"));
expected_data.set_iid(StringToGuid(kIid1));
expected_data.set_did_run(AppData::ACTIVE_RUN);
// Set non-zero values for activities so that the registry values can
// be updated.
expected_data.set_days_since_last_active_ping(4);
expected_data.set_days_since_last_roll_call(2);
CreateAppRegistryState(expected_data);
ProductData product_data;
AppManager app_manager(is_machine);
EXPECT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_,
&product_data));
AppData app_data_temp = product_data.app_data();
// We only want to make sure the timestamps in the registry are updated and
// don't care about time_since_midnight_sec here, so just pass a 0 as the
// first parameter.
EXPECT_SUCCEEDED(app_manager.HandleSuccessfulUpdateCheckRequestSend(
0, &app_data_temp));
// Validate the results.
RegKey client_state_key;
EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name));
// Check installation id removed.
EXPECT_FALSE(client_state_key.HasValue(kRegValueInstallationId));
// Check ping timestamps are updated.
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
DWORD last_active_ping_day_start_sec = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueActivePingDayStartSec,
&last_active_ping_day_start_sec));
EXPECT_GE(now, last_active_ping_day_start_sec);
EXPECT_LE(now, last_active_ping_day_start_sec + kMaxTimeSinceMidnightSec);
EXPECT_EQ(0, app_data_temp.days_since_last_active_ping());
DWORD last_roll_call_day_start_sec = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueRollCallDayStartSec,
&last_roll_call_day_start_sec));
EXPECT_GE(now, last_roll_call_day_start_sec);
EXPECT_LE(now, last_roll_call_day_start_sec + kMaxTimeSinceMidnightSec);
EXPECT_EQ(0, app_data_temp.days_since_last_roll_call());
// Check did_run is cleared.
CString did_run;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueDidRun, &did_run));
EXPECT_STREQ(_T("0"), did_run);
}
void HandleSuccessfulUpdateCheckRequestSendTest_NotRun(bool is_machine) {
const CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(is_machine),
kGuid1);
const int kDaysSinceLastActivePing = 2;
// Create the test data.
AppData expected_data(guid1_, is_machine);
expected_data.set_version(_T("1.0.0.0"));
expected_data.set_iid(StringToGuid(kIid1));
expected_data.set_did_run(AppData::ACTIVE_NOTRUN);
expected_data.set_days_since_last_active_ping(kDaysSinceLastActivePing);
expected_data.set_days_since_last_roll_call(0);
CreateAppRegistryState(expected_data);
// Choose a time that is close to current time but with some skew so that
// if the registry is rewritten, we won't write the same value again and
// the change would be detected.
const uint32 base_time = Time64ToInt32(GetCurrent100NSTime()) - 2;
RegKey client_state_key;
EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name));
uint32 last_active_time =
base_time - kDaysSinceLastActivePing * kSecondsPerDay;
ASSERT_SUCCEEDED(client_state_key.SetValue(
kRegValueActivePingDayStartSec,
static_cast<DWORD>(last_active_time)));
ASSERT_SUCCEEDED(client_state_key.SetValue(
kRegValueRollCallDayStartSec,
static_cast<DWORD>(base_time)));
ProductData product_data;
AppManager app_manager(is_machine);
EXPECT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_,
&product_data));
AppData app_data_temp = product_data.app_data();
// We only want to make sure the timestamps in the registry are updated and
// don't care about time_since_midnight_sec here, so just pass a 0 as the
// first parameter.
EXPECT_SUCCEEDED(app_manager.HandleSuccessfulUpdateCheckRequestSend(
0, &app_data_temp));
// Validate the results.
// did_run is false so installation id should still exist.
CString iid;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallationId, &iid));
EXPECT_STREQ(kIid1, iid);
// did_run is false so active ping timestamp should not be updated.
DWORD last_active_ping_day_start_sec = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueActivePingDayStartSec,
&last_active_ping_day_start_sec));
EXPECT_EQ(last_active_time, last_active_ping_day_start_sec);
EXPECT_EQ(kDaysSinceLastActivePing,
app_data_temp.days_since_last_active_ping());
// Previous days_since_last_roll_call is 0 so that timestamp should
// not change.
DWORD last_roll_call_day_start_sec = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueRollCallDayStartSec,
&last_roll_call_day_start_sec));
EXPECT_EQ(base_time, last_roll_call_day_start_sec);
EXPECT_EQ(0, app_data_temp.days_since_last_roll_call());
// did_run is still not set.
CString did_run;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueDidRun, &did_run));
EXPECT_STREQ(_T("0"), did_run);
}
void HandleSuccessfulUpdateCheckRequestSendTest_NoPreviousPing(
bool is_machine) {
const CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(is_machine),
kGuid1);
const int kDaysSinceLastActivePing = 2;
// Create the test data.
AppData expected_data(guid1_, is_machine);
expected_data.set_version(_T("1.0.0.0"));
expected_data.set_iid(StringToGuid(kIid1));
expected_data.set_did_run(AppData::ACTIVE_UNKNOWN);
expected_data.set_days_since_last_active_ping(-1);
expected_data.set_days_since_last_roll_call(-1);
CreateAppRegistryState(expected_data);
ProductData product_data;
AppManager app_manager(is_machine);
EXPECT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_,
&product_data));
AppData app_data_temp = product_data.app_data();
// We only want to make sure the timestamps in the registry are updated and
// don't care about time_since_midnight_sec here, so just pass a 0 as the
// first parameter.
EXPECT_SUCCEEDED(app_manager.HandleSuccessfulUpdateCheckRequestSend(
0, &app_data_temp));
// Validate the results.
RegKey client_state_key;
EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name));
// did_run is unknown so installation id should still exist.
CString iid;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallationId, &iid));
EXPECT_STREQ(kIid1, iid);
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
// did_run is unknown so active ping timestamp should not be updated.
EXPECT_FALSE(client_state_key.HasValue(kRegValueActivePingDayStartSec));
EXPECT_EQ(-1, app_data_temp.days_since_last_active_ping());
DWORD last_roll_call_day_start_sec = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueRollCallDayStartSec,
&last_roll_call_day_start_sec));
EXPECT_GE(now, last_roll_call_day_start_sec);
EXPECT_LE(now, last_roll_call_day_start_sec + kMaxTimeSinceMidnightSec);
EXPECT_EQ(0, app_data_temp.days_since_last_roll_call());
// did_run is unknown.
CString did_run;
EXPECT_FALSE(client_state_key.HasValue(kRegValueDidRun));
}
void UpdateApplicationStateTest(bool is_machine, const CString& app_id) {
const CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(is_machine),
app_id);
// Create the test data.
AppData expected_data(StringToGuid(app_id), is_machine);
PopulateExpectedAppData1(&expected_data);
expected_data.set_referral_id(_T("referrer"));
expected_data.set_is_eula_accepted(false);
expected_data.set_install_time_diff_sec(141516);
CreateAppRegistryState(expected_data);
EXPECT_TRUE(RegKey::HasValue(client_state_key_name, _T("referral")));
// Call the test method.
ProductData product_data;
AppManager app_manager(is_machine);
EXPECT_SUCCEEDED(app_manager.ReadProductDataFromStore(StringToGuid(app_id),
&product_data));
EXPECT_TRUE(product_data.app_data().referral_id().IsEmpty());
AppData app_data_temp = product_data.app_data();
EXPECT_SUCCEEDED(app_manager.UpdateApplicationState(&app_data_temp));
product_data.set_app_data(app_data_temp);
EXPECT_TRUE(app_data_temp.referral_id().IsEmpty());
// Need to call again to refresh the values created/copied by
// UpdateApplicationState().
EXPECT_SUCCEEDED(app_manager.ReadProductDataFromStore(StringToGuid(app_id),
&product_data));
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
EXPECT_TRUE(product_data.app_data().referral_id().IsEmpty());
// Validate the results.
RegKey client_state_key;
EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name));
// Check version and language have been copied to client state.
CString previous_version;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueProductVersion,
&previous_version));
EXPECT_STREQ(expected_data.version(), previous_version);
CString language;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueLanguage,
&language));
EXPECT_STREQ(expected_data.language(), language);
// Check that ap, brand_code, and client_id are not changed.
CString ap;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueAdditionalParams,
&ap));
EXPECT_STREQ(expected_data.ap(), ap);
CString tt_token;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueTTToken,
&tt_token));
EXPECT_STREQ(expected_data.tt_token(), tt_token);
CString brand_code;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueBrandCode,
&brand_code));
EXPECT_STREQ(expected_data.brand_code(), brand_code);
CString client_id;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueClientId,
&client_id));
EXPECT_STREQ(expected_data.client_id(), client_id);
// install_time_diff_sec should be roughly the same as now - installed.
DWORD install_time(0);
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallTimeSec,
&install_time));
const DWORD calculated_install_diff = now - install_time;
EXPECT_GE(calculated_install_diff, expected_data.install_time_diff_sec());
EXPECT_GE(static_cast<uint32>(500),
calculated_install_diff - expected_data.install_time_diff_sec());
DWORD eula_accepted = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(_T("eulaaccepted"),
&eula_accepted));
EXPECT_EQ(0, eula_accepted);
EXPECT_FALSE(expected_data.is_eula_accepted());
}
void WritePreInstallDataTest(const AppData& app_data_in) {
const bool is_machine = app_data_in.is_machine_app();
const CString client_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_clients(is_machine), kGuid1);
const CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(is_machine),
kGuid1);
const bool expect_has_client_key = RegKey::HasKey(client_key_name);
// Populate the test data.
AppData app_data(app_data_in);
app_data.set_brand_code(_T("GGLG"));
app_data.set_client_id(_T("someclient"));
app_data.set_referral_id(_T("referrer"));
app_data.set_install_time_diff_sec(657812); // Not used.
app_data.set_usage_stats_enable(TRISTATE_TRUE);
app_data.set_browser_type(BROWSER_FIREFOX);
app_data.set_ap(_T("test_ap"));
app_data.set_language(_T("en"));
app_data.set_version(_T("1.2.3.4"));
AppManager app_manager(is_machine);
app_manager.WritePreInstallData(app_data);
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
// Validate the results.
// WritePreInstallData should never write to client_key, so it shouldn't
// exist if it did not before the method call.
EXPECT_EQ(expect_has_client_key, RegKey::HasKey(client_key_name));
// ClientStateKey should exist.
RegKey client_state_key;
EXPECT_SUCCEEDED(client_state_key.Open(client_state_key_name));
ValidateClientStateMedium(is_machine, kGuid1);
CString brand_code;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueBrandCode,
&brand_code));
EXPECT_STREQ(_T("GGLG"), brand_code);
CString client_id;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueClientId, &client_id));
EXPECT_STREQ(_T("someclient"), client_id);
CString referral_id;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueReferralId,
&referral_id));
EXPECT_STREQ(_T("referrer"), referral_id);
DWORD install_time(0);
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueInstallTimeSec,
&install_time));
EXPECT_GE(now, install_time);
EXPECT_GE(static_cast<uint32>(200), now - install_time);
DWORD usage_stats_enable = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(_T("usagestats"),
&usage_stats_enable));
EXPECT_EQ(TRISTATE_TRUE, usage_stats_enable);
DWORD browser_type = 0;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueBrowser,
&browser_type));
EXPECT_EQ(BROWSER_FIREFOX, browser_type);
CString ap;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueAdditionalParams, &ap));
EXPECT_STREQ(_T("test_ap"), ap);
CString lang;
EXPECT_SUCCEEDED(client_state_key.GetValue(kRegValueLanguage, &lang));
EXPECT_STREQ(_T("en"), lang);
// Version should not be written to clientstate by WritePreInstallData().
EXPECT_FALSE(RegKey::HasValue(client_state_key_name,
kRegValueProductVersion));
}
void ValidateClientStateMedium(bool is_machine, const CString& app_guid) {
const CString client_state_medium_key_name = AppendRegKeyPath(
ConfigManager::Instance()->machine_registry_client_state_medium(),
app_guid);
if (is_machine) {
RegKey client_state_medium_key;
EXPECT_SUCCEEDED(
client_state_medium_key.Open(client_state_medium_key_name));
EXPECT_EQ(0, client_state_medium_key.GetValueCount());
} else {
EXPECT_FALSE(RegKey::HasKey(client_state_medium_key_name));
// There is no such thing as a user ClientStateMedium key.
const CString user_client_state_medium_key_name = AppendRegKeyPath(
USER_KEY GOOPDATE_REG_RELATIVE_CLIENT_STATE_MEDIUM,
app_guid);
EXPECT_FALSE(RegKey::HasKey(user_client_state_medium_key_name));
return;
}
}
// Uses SetupGoogleUpdate to create the ClientStateMedium key with the
// appropriate permissions. Used to test that the permissions are inherited.
void CreateClientStateMediumKey() {
CommandLineArgs args;
SetupGoogleUpdate setup_google_update(true, &args);
EXPECT_SUCCEEDED(setup_google_update.CreateClientStateMedium());
}
CString hive_override_key_name_;
const GUID guid1_;
};
TEST_F(AppManagerTest, ConvertCommandLineToProductData_Succeeds) {
CommandLineAppArgs extra1;
extra1.app_guid = guid1_;
extra1.app_name = _T("foo");
extra1.needs_admin = false;
extra1.ap = _T("Test ap");
extra1.tt_token = _T("Test TT Token");
extra1.encoded_installer_data = _T("%20foobar");
extra1.install_data_index = _T("foobar");
CommandLineAppArgs extra2;
extra2.app_guid = StringToGuid(kGuid2);
extra2.app_name = _T("bar");
extra2.needs_admin = true; // This gets ignored.
extra2.ap = _T("beta");
extra2.tt_token = _T("beta TT Token");
CommandLineAppArgs extra3;
extra3.app_guid = StringToGuid(kGuid3);
extra3.app_name = _T("bar");
extra3.needs_admin = true; // This gets ignored.
extra3.ap = _T("beta");
extra3.tt_token = _T("beta TT Token");
CommandLineArgs args;
args.is_interactive_set = true; // Not used.
args.is_machine_set = true; // Not used.
args.is_crash_handler_disabled = true; // Not used.
args.is_eula_required_set = true;
args.is_eula_required_set = true; // Not used.
args.webplugin_urldomain = _T("http://nothing.google.com"); // Not used.
args.webplugin_args = _T("blah"); // Not used.
args.install_source = _T("one_click");
args.code_red_metainstaller_path = _T("foo.exe"); // Not used.
args.legacy_manifest_path = _T("bar.exe"); // Not used.
args.crash_filename = _T("foo.dmp"); // Not used.
args.extra.installation_id = StringToGuid(kIid1);
args.extra.brand_code = _T("GOOG");
args.extra.client_id = _T("someclient");
args.extra.referral_id = _T("referrer1");
args.extra.browser_type = BROWSER_IE;
args.extra.language = _T("abc");
args.extra.usage_stats_enable = TRISTATE_TRUE;
args.extra.apps.push_back(extra1);
args.extra.apps.push_back(extra2);
args.extra.apps.push_back(extra3);
AppData expected_data1(guid1_, false);
PopulateExpectedAppData1(&expected_data1);
expected_data1.set_version(_T("")); // Clear value.
expected_data1.set_previous_version(_T("")); // Clear value.
expected_data1.set_did_run(AppData::ACTIVE_UNKNOWN); // Clear value.
expected_data1.set_display_name(_T("foo"));
expected_data1.set_browser_type(BROWSER_IE);
expected_data1.set_install_source(_T("one_click"));
expected_data1.set_encoded_installer_data(_T("%20foobar"));
expected_data1.set_install_data_index(_T("foobar"));
expected_data1.set_usage_stats_enable(TRISTATE_TRUE);
expected_data1.set_referral_id(_T("referrer1"));
expected_data1.set_install_time_diff_sec(
static_cast<uint32>(-1 * kSecondsPerDay)); // New install.
expected_data1.set_is_eula_accepted(false);
expected_data1.set_days_since_last_active_ping(0);
expected_data1.set_days_since_last_roll_call(0);
AppData expected_data2(StringToGuid(kGuid2), false);
// Make the first app appear to already be installed but without an
// InstallTime. This affects install_time_diff_sec.
expected_data2.set_version(_T("4.5.6.7"));
CreateAppRegistryState(expected_data2);
PopulateExpectedAppData2(&expected_data2);
expected_data2.set_version(_T("")); // Clear value.
expected_data2.set_previous_version(_T("")); // Clear value.
expected_data2.set_did_run(AppData::ACTIVE_UNKNOWN); // Clear value.
expected_data2.set_language(_T("abc"));
expected_data2.set_display_name(_T("bar"));
expected_data2.set_browser_type(BROWSER_IE);
expected_data2.set_install_source(_T("one_click"));
expected_data2.set_usage_stats_enable(TRISTATE_TRUE);
// Override unique expected data because the args apply to all apps.
expected_data2.set_iid(StringToGuid(kIid1));
expected_data2.set_brand_code(_T("GOOG"));
expected_data2.set_client_id(_T("someclient"));
expected_data2.set_referral_id(_T("referrer1"));
expected_data2.set_install_time_diff_sec(0); // InstallTime is unknown.
expected_data2.set_is_eula_accepted(false);
expected_data2.set_days_since_last_active_ping(0);
expected_data2.set_days_since_last_roll_call(0);
AppData expected_data3(StringToGuid(kGuid3), false);
// Make the first app appear to already be installed with a valid InstallTime.
// This affects install_time_diff_sec.
expected_data3.set_version(_T("4.5.6.7"));
expected_data3.set_install_time_diff_sec(123456); // Known original time.
CreateAppRegistryState(expected_data3);
PopulateExpectedAppData2(&expected_data3);
expected_data3.set_version(_T("")); // Clear value.
expected_data3.set_previous_version(_T("")); // Clear value.
expected_data3.set_did_run(AppData::ACTIVE_UNKNOWN); // Clear value.
expected_data3.set_language(_T("abc"));
expected_data3.set_display_name(_T("bar"));
expected_data3.set_browser_type(BROWSER_IE);
expected_data3.set_install_source(_T("one_click"));
expected_data3.set_usage_stats_enable(TRISTATE_TRUE);
// Override unique expected data because the args apply to all apps.
expected_data3.set_iid(StringToGuid(kIid1));
expected_data3.set_brand_code(_T("GOOG"));
expected_data3.set_client_id(_T("someclient"));
expected_data3.set_referral_id(_T("referrer1"));
expected_data3.set_is_eula_accepted(false);
expected_data3.set_days_since_last_active_ping(0);
expected_data3.set_days_since_last_roll_call(0);
ProductDataVector products;
AppManager app_manager(false);
app_manager.ConvertCommandLineToProductData(args, &products);
ASSERT_EQ(3, products.size());
EXPECT_EQ(0, products[0].num_components());
EXPECT_EQ(0, products[1].num_components());
EXPECT_EQ(0, products[2].num_components());
ValidateExpectedValues(expected_data1, products[0].app_data());
ValidateExpectedValues(expected_data2, products[1].app_data());
// install_time_diff_sec may be off by a second or so.
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
EXPECT_GE(products[2].app_data().install_time_diff_sec(),
expected_data3.install_time_diff_sec());
EXPECT_GE(static_cast<uint32>(500),
products[2].app_data().install_time_diff_sec() -
expected_data3.install_time_diff_sec());
// Fix up expected_data3 or it might fail verification.
expected_data3.set_install_time_diff_sec(
products[2].app_data().install_time_diff_sec());
ValidateExpectedValues(expected_data3, products[2].app_data());
}
TEST_F(AppManagerTest, WritePreInstallData_Machine) {
AppData app_data(guid1_, true);
ASSERT1(app_data.is_eula_accepted());
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine,
_T("oeminstall")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine,
_T("eulaaccepted")));
}
TEST_F(AppManagerTest, WritePreInstallData_Machine_IsOem) {
const DWORD now = Time64ToInt32(GetCurrent100NSTime());
ASSERT_SUCCEEDED(RegKey::SetValue(MACHINE_REG_UPDATE,
_T("OemInstallTime"),
now));
if (vista_util::IsVistaOrLater()) {
ASSERT_SUCCEEDED(RegKey::SetValue(
_T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"),
_T("ImageState"),
_T("IMAGE_STATE_UNDEPLOYABLE")));
} else {
ASSERT_SUCCEEDED(RegKey::SetValue(_T("HKLM\\System\\Setup"),
_T("AuditInProgress"),
static_cast<DWORD>(1)));
}
AppData app_data(guid1_, true);
ASSERT1(app_data.is_eula_accepted());
WritePreInstallDataTest(app_data);
CString oeminstall;
EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathMachine,
_T("oeminstall"),
&oeminstall));
EXPECT_STREQ(_T("1"), oeminstall);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine,
_T("eulaaccepted")));
}
// Creates the ClientStateMedium key with the appropriate permissions then
// verifies that the created app subkey inherits those.
// The Update key must be created first to avoid applying ClientStateMedium's
// permissions to all its parent keys.
// This keys in this test need to inherit the HKLM privileges, so put the
// override root in HKLM.
TEST_F(AppManagerTest,
WritePreInstallData_Machine_CheckClientStateMediumPermissions) {
const TCHAR kRegistryHiveOverrideRootInHklm[] =
_T("HKLM\\Software\\Google\\Update\\UnitTest\\");
RestoreRegistryHives();
hive_override_key_name_ = kRegistryHiveOverrideRootInHklm;
RegKey::DeleteKey(hive_override_key_name_);
OverrideRegistryHives(hive_override_key_name_);
EXPECT_SUCCEEDED(RegKey::CreateKey(
ConfigManager::Instance()->machine_registry_update()));
CreateClientStateMediumKey();
AppData app_data(guid1_, true);
ASSERT1(app_data.is_eula_accepted());
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine,
_T("oeminstall")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathMachine,
_T("eulaaccepted")));
const CString app_client_state_medium_key_name = AppendRegKeyPath(
_T("HKLM\\Software\\Google\\Update\\ClientStateMedium\\"),
kGuid1);
VerifyHklmKeyHasMediumIntegrity(app_client_state_medium_key_name);
VerifyHklmKeyHasDefaultIntegrity(
_T("HKLM\\Software\\Google\\Update\\ClientStateMedium\\"));
}
TEST_F(AppManagerTest,
WritePreInstallData_Machine_ClearClientStateMediumUsageStats) {
const CString client_state_key_name =
AppendRegKeyPath(MACHINE_REG_CLIENT_STATE_MEDIUM, kGuid1);
EXPECT_SUCCEEDED(RegKey::SetValue(client_state_key_name,
_T("usagestats"),
static_cast<DWORD>(1)));
AppData app_data(guid1_, true);
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(client_state_key_name, _T("usagestats")));
}
// Tests the EULA accepted case too.
TEST_F(AppManagerTest, WritePreInstallData_User) {
AppData app_data(guid1_, false);
ASSERT1(app_data.is_eula_accepted());
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("oeminstall")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted")));
}
TEST_F(AppManagerTest,
WritePreInstallData_User_EulaNotAcceptedAppNotRegistered) {
AppData app_data(guid1_, false);
app_data.set_is_eula_accepted(false);
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("oeminstall")));
DWORD eula_accepted = 99;
EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted"),
&eula_accepted));
EXPECT_EQ(0, eula_accepted);
}
TEST_F(AppManagerTest,
WritePreInstallData_User_EulaNotAcceptedAppAlreadyInstalled) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser,
_T("pv"),
_T("1.2.3.4")));
AppData app_data(guid1_, false);
app_data.set_is_eula_accepted(false);
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("oeminstall")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted")));
}
TEST_F(AppManagerTest,
WritePreInstallData_User_EulaAcceptedAppAlreadyInstalled) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser,
_T("pv"),
_T("1.2.3.4")));
AppData app_data(guid1_, false);
app_data.set_is_eula_accepted(true);
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("oeminstall")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted")));
}
TEST_F(AppManagerTest,
WritePreInstallData_User_EulaAcceptedAppAlreadyInstalledAccepted) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser,
_T("pv"),
_T("1.2.3.4")));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted"),
static_cast<DWORD>(1)));
AppData app_data(guid1_, false);
app_data.set_is_eula_accepted(true);
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("oeminstall")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted")));
}
TEST_F(AppManagerTest,
WritePreInstallData_User_EulaAcceptedAppAlreadyInstalledNotAccepted) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientsKeyPathUser,
_T("pv"),
_T("1.2.3.4")));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted"),
static_cast<DWORD>(0)));
AppData app_data(guid1_, false);
app_data.set_is_eula_accepted(true);
WritePreInstallDataTest(app_data);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("oeminstall")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted")));
}
TEST_F(AppManagerTest, ReadProductDataFromStore_MachineNoAppTest) {
ProductData product_data;
AppManager app_manager(true);
ASSERT_FAILED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
}
TEST_F(AppManagerTest, ReadProductDataFromStore_UserAppTest) {
AppData expected_data(guid1_, false);
PopulateExpectedAppData1(&expected_data);
CreateAppRegistryState(expected_data);
AppManager app_manager(false);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest, ReadProductDataFromStore_MachineAppTest) {
AppData expected_data(guid1_, true);
PopulateExpectedAppData1(&expected_data);
CreateAppRegistryState(expected_data);
AppManager app_manager(true);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest, ReadProductDataFromStore_UserAppTest_EulaNotAccepted) {
AppData expected_data(guid1_, false);
PopulateExpectedAppData1(&expected_data);
CreateAppRegistryState(expected_data);
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted"),
static_cast<DWORD>(0)));
expected_data.set_is_eula_accepted(false);
AppManager app_manager(false);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest, ReadProductDataFromStore_UserAppTest_EulaAccepted) {
AppData expected_data(guid1_, false);
PopulateExpectedAppData1(&expected_data);
CreateAppRegistryState(expected_data);
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("eulaaccepted"),
static_cast<DWORD>(1)));
expected_data.set_is_eula_accepted(true);
AppManager app_manager(false);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest,
ReadProductDataFromStore_MachineAppTest_EulaNotAccepted) {
AppData expected_data(guid1_, true);
PopulateExpectedAppData1(&expected_data);
CreateAppRegistryState(expected_data);
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathMachine,
_T("eulaaccepted"),
static_cast<DWORD>(0)));
expected_data.set_is_eula_accepted(false);
AppManager app_manager(true);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest,
ReadProductDataFromStore_MachineAppTest_EulaAccepted) {
AppData expected_data(guid1_, true);
PopulateExpectedAppData1(&expected_data);
CreateAppRegistryState(expected_data);
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathMachine,
_T("eulaaccepted"),
static_cast<DWORD>(1)));
expected_data.set_is_eula_accepted(true);
AppManager app_manager(true);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest, ReadProductDataFromStore_TwoUserAppTest) {
AppData expected_data1(guid1_, false);
PopulateExpectedAppData1(&expected_data1);
CreateAppRegistryState(expected_data1);
AppData expected_data2(StringToGuid(kGuid2), false);
PopulateExpectedAppData1(&expected_data2);
CreateAppRegistryState(expected_data2);
AppManager app_manager(false);
ProductData data1;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &data1));
ValidateExpectedValues(expected_data1, data1.app_data());
ProductData data2;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(StringToGuid(kGuid2),
&data2));
ValidateExpectedValues(expected_data2, data2.app_data());
}
TEST_F(AppManagerTest, ReadProductDataFromStore_UserAppNoClientStateTest) {
AppData expected_data(guid1_, false);
PopulateExpectedAppData1(&expected_data);
CreateAppRegistryState(expected_data);
AppManager app_manager(false);
ProductData data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &data));
ValidateExpectedValues(expected_data, data.app_data());
}
TEST_F(AppManagerTest, ReadProductDataFromStore_UninstalledUserApp) {
AppData expected_data(guid1_, false);
PopulateExpectedUninstalledAppData(&expected_data);
CreateAppRegistryState(expected_data);
AppManager app_manager(false);
ProductData data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &data));
ValidateExpectedValues(expected_data, data.app_data());
}
TEST_F(AppManagerTest, ReadProductDataFromStore_UninstalledMachineApp) {
AppData expected_data(guid1_, true);
PopulateExpectedUninstalledAppData(&expected_data);
CreateAppRegistryState(expected_data);
AppManager app_manager(true);
ProductData data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &data));
ValidateExpectedValues(expected_data, data.app_data());
}
TEST_F(AppManagerTest,
ReadProductDataFromStore_UninstalledUserApp_EulaNotAccepted) {
AppData expected_data(guid1_, false);
PopulateExpectedUninstalledAppData(&expected_data);
expected_data.set_is_eula_accepted(false);
CreateAppRegistryState(expected_data);
AppManager app_manager(false);
ProductData data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &data));
ValidateExpectedValues(expected_data, data.app_data());
}
// Tests the case where Omaha has created the Client State key before running
// the installer. Uses PopulateExpectedUninstalledAppData then clears pv before
// writing the data to the registry. is_uninstalled_ is not set to false until
// after CreateAppRegistryState to prevent Client key from being created.
TEST_F(AppManagerTest,
ReadProductDataFromStore_UserClientStateExistsWithoutPvOrClientKey) {
AppData expected_data(guid1_, false);
PopulateExpectedUninstalledAppData(&expected_data);
expected_data.set_previous_version(_T(""));
CreateAppRegistryState(expected_data);
AppManager app_manager(false);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
expected_data.set_is_uninstalled(false);
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest,
ReadProductDataFromStore_MachineClientStateExistsWithoutPvOrClientKey) {
AppData expected_data(guid1_, true);
PopulateExpectedUninstalledAppData(&expected_data);
expected_data.set_previous_version(_T(""));
CreateAppRegistryState(expected_data);
AppManager app_manager(true);
ProductData data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &data));
expected_data.set_is_uninstalled(false);
ValidateExpectedValues(expected_data, data.app_data());
}
// An empty pv value is the same as a populated one for uninstall checks.
TEST_F(AppManagerTest,
ReadProductDataFromStore_UserClientStateExistsWithEmptyPvNoClientKey) {
AppData expected_data(guid1_, false);
PopulateExpectedUninstalledAppData(&expected_data);
expected_data.set_previous_version(_T(""));
CreateAppRegistryState(expected_data);
// Write the empty pv value.
CString client_state_key_name = AppendRegKeyPath(
ConfigManager::Instance()->registry_client_state(false),
kGuid1);
ASSERT_SUCCEEDED(RegKey::SetValue(client_state_key_name,
kRegValueProductVersion,
_T("")));
AppManager app_manager(false);
ProductData product_data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &product_data));
expected_data.set_is_uninstalled(true);
ValidateExpectedValues(expected_data, product_data.app_data());
}
TEST_F(AppManagerTest, InitializeApplicationState_UserTest) {
InitializeApplicationStateTest(false);
}
TEST_F(AppManagerTest, InitializeApplicationState_MachineTest) {
InitializeApplicationStateTest(true);
}
TEST_F(AppManagerTest,
HandleSuccessfulUpdateCheckRequestSendTest_AllUpdated_UserTest) {
HandleSuccessfulUpdateCheckRequestSendTest_AllUpdated(false);
}
TEST_F(AppManagerTest,
HandleSuccessfulUpdateCheckRequestSendTest_AllUpdated_MachineTest) {
HandleSuccessfulUpdateCheckRequestSendTest_AllUpdated(true);
}
TEST_F(AppManagerTest,
HandleSuccessfulUpdateCheckRequestSendTest_NotRun_UserTest) {
HandleSuccessfulUpdateCheckRequestSendTest_NotRun(false);
}
TEST_F(AppManagerTest,
HandleSuccessfulUpdateCheckRequestSendTest_NotRun_MachineTest) {
HandleSuccessfulUpdateCheckRequestSendTest_NotRun(true);
}
TEST_F(AppManagerTest,
HandleSuccessfulUpdateCheckRequestSendTest_NoPreviousPing_UserTest) {
HandleSuccessfulUpdateCheckRequestSendTest_NoPreviousPing(false);
}
TEST_F(AppManagerTest,
HandleSuccessfulUpdateCheckRequestSendTest_NoPreviousPing_MachineTest) {
HandleSuccessfulUpdateCheckRequestSendTest_NoPreviousPing(true);
}
TEST_F(AppManagerTest, UpdateApplicationState_UserTest) {
UpdateApplicationStateTest(false, kGuid1);
ValidateClientStateMedium(false, kGuid1);
}
TEST_F(AppManagerTest, UpdateApplicationState_MachineTest) {
UpdateApplicationStateTest(true, kGuid1);
ValidateClientStateMedium(true, kGuid1);
}
// Should not create ClientStateMedium key.
TEST_F(AppManagerTest, UpdateApplicationState_MachineTest_Omaha) {
UpdateApplicationStateTest(true, kGoogleUpdateAppId);
const CString client_state_medium_key_name = AppendRegKeyPath(
ConfigManager::Instance()->machine_registry_client_state_medium(),
kGoogleUpdateAppId);
EXPECT_FALSE(RegKey::HasKey(client_state_medium_key_name));
}
TEST_F(AppManagerTest, UpdateUpdateAvailableStats_NoExistingStats) {
const time64 before_time_in_100ns(GetCurrent100NSTime());
AppManager app_manager(false);
app_manager.UpdateUpdateAvailableStats(GUID_NULL, guid1_);
const time64 after_time_in_100ns(GetCurrent100NSTime());
DWORD update_available_count(0);
EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
&update_available_count));
EXPECT_EQ(1, update_available_count);
DWORD64 update_available_since_time(0);
EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
&update_available_since_time));
EXPECT_LE(before_time_in_100ns, update_available_since_time);
EXPECT_GE(after_time_in_100ns, update_available_since_time);
const DWORD64 time_since_first_update_available =
after_time_in_100ns - update_available_since_time;
EXPECT_GT(10 * kSecsTo100ns, time_since_first_update_available);
}
TEST_F(AppManagerTest, UpdateUpdateAvailableStats_WithExistingStats) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
static_cast<DWORD>(123456)));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
static_cast<DWORD64>(9876543210)));
AppManager app_manager(false);
app_manager.UpdateUpdateAvailableStats(GUID_NULL, guid1_);
DWORD update_available_count(0);
EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
&update_available_count));
EXPECT_EQ(123457, update_available_count);
DWORD64 update_available_since_time(0);
EXPECT_SUCCEEDED(RegKey::GetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
&update_available_since_time));
EXPECT_EQ(9876543210, update_available_since_time);
}
TEST_F(AppManagerTest, ClearUpdateAvailableStats_KeyNotPresent) {
AppManager app_manager(false);
ClearUpdateAvailableStats(GUID_NULL, guid1_, &app_manager);
}
TEST_F(AppManagerTest, ClearUpdateAvailableStats_DataPresent) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
static_cast<DWORD>(123456)));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
static_cast<DWORD64>(9876543210)));
AppManager app_manager(false);
ClearUpdateAvailableStats(GUID_NULL, guid1_, &app_manager);
EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince")));
}
TEST_F(AppManagerTest, ReadUpdateAvailableStats_DataNotPresent) {
RegKey::CreateKey(kGuid1ClientStateKeyPathUser);
DWORD update_responses(1);
DWORD64 time_since_first_response_ms(1);
AppManager app_manager(false);
app_manager.ReadUpdateAvailableStats(GUID_NULL,
guid1_,
&update_responses,
&time_since_first_response_ms);
EXPECT_EQ(0, update_responses);
EXPECT_EQ(0, time_since_first_response_ms);
}
TEST_F(AppManagerTest, ReadUpdateAvailableStats_DataPresent) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
static_cast<DWORD>(123456)));
const DWORD64 kUpdateAvailableSince =
GetCurrent100NSTime() - 2 * kMillisecsTo100ns;
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
kUpdateAvailableSince));
DWORD update_responses(0);
DWORD64 time_since_first_response_ms(0);
AppManager app_manager(false);
app_manager.ReadUpdateAvailableStats(GUID_NULL,
guid1_,
&update_responses,
&time_since_first_response_ms);
EXPECT_EQ(123456, update_responses);
EXPECT_LE(2, time_since_first_response_ms);
EXPECT_GT(10 * kMsPerSec, time_since_first_response_ms);
}
// TODO(omaha): Add *UpdateAvailableStats tests with components when
// component design is finalized and implemented
TEST_F(AppManagerTest, RecordSuccessfulInstall_Install_Online) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
static_cast<DWORD>(123456)));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
static_cast<DWORD64>(9876543210)));
AppManager app_manager(false);
app_manager.RecordSuccessfulInstall(GUID_NULL, guid1_, false, false);
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
// Verify ClearUpdateAvailableStats() was called.
EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince")));
// Verify update check value is written but update value is not.
const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec);
EXPECT_GE(now, last_check_sec);
EXPECT_GE(static_cast<uint32>(200), now - last_check_sec);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
kRegValueLastUpdateTimeSec));
}
TEST_F(AppManagerTest, RecordSuccessfulInstall_Install_Offline) {
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
static_cast<DWORD>(123456)));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
static_cast<DWORD64>(9876543210)));
AppManager app_manager(false);
app_manager.RecordSuccessfulInstall(GUID_NULL, guid1_, false, true);
// Verify ClearUpdateAvailableStats() was called.
EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince")));
// Verify update values are not written.
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
kRegValueLastUpdateTimeSec));
}
TEST_F(AppManagerTest, RecordSuccessfulInstall_Update_ExistingTimes) {
const DWORD kExistingUpdateValues = 0x70123456;
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount"),
static_cast<DWORD>(123456)));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince"),
static_cast<DWORD64>(9876543210)));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec,
kExistingUpdateValues));
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
kRegValueLastUpdateTimeSec,
kExistingUpdateValues));
AppManager app_manager(false);
app_manager.RecordSuccessfulInstall(GUID_NULL, guid1_, true, false);
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
// Verify ClearUpdateAvailableStats() was called.
EXPECT_TRUE(RegKey::HasKey(kGuid1ClientStateKeyPathUser));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableCount")));
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
_T("UpdateAvailableSince")));
// Verify update values updated.
const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec);
EXPECT_NE(kExistingUpdateValues, last_check_sec);
EXPECT_GE(now, last_check_sec);
EXPECT_GE(static_cast<uint32>(200), now - last_check_sec);
const uint32 last_update_sec =
GetDwordValue(kGuid1ClientStateKeyPathUser, kRegValueLastUpdateTimeSec);
EXPECT_NE(kExistingUpdateValues, last_update_sec);
EXPECT_GE(now, last_update_sec);
EXPECT_GE(static_cast<uint32>(200), now - last_update_sec);
}
TEST_F(AppManagerTest, RecordSuccessfulInstall_Update_StateKeyDoesNotExist) {
AppManager app_manager(false);
app_manager.RecordSuccessfulInstall(GUID_NULL, guid1_, true, false);
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
// Verify update values updated.
const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec);
EXPECT_GE(now, last_check_sec);
EXPECT_GE(static_cast<uint32>(200), now - last_check_sec);
const uint32 last_update_sec =
GetDwordValue(kGuid1ClientStateKeyPathUser, kRegValueLastUpdateTimeSec);
EXPECT_GE(now, last_update_sec);
EXPECT_GE(static_cast<uint32>(200), now - last_update_sec);
}
TEST_F(AppManagerTest, RecordSuccessfulUpdateCheck_ExistingTime) {
const DWORD kExistingUpdateValue = 0x12345678;
EXPECT_SUCCEEDED(RegKey::SetValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec,
kExistingUpdateValue));
AppManager app_manager(false);
app_manager.RecordSuccessfulUpdateCheck(GUID_NULL, guid1_);
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec);
EXPECT_NE(kExistingUpdateValue, last_check_sec);
EXPECT_GE(now, last_check_sec);
EXPECT_GE(static_cast<uint32>(200), now - last_check_sec);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
kRegValueLastUpdateTimeSec));
}
TEST_F(AppManagerTest, RecordSuccessfulUpdateCheck_StateKeyDoesNotExist) {
AppManager app_manager(false);
app_manager.RecordSuccessfulUpdateCheck(GUID_NULL, guid1_);
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
const uint32 last_check_sec = GetDwordValue(kGuid1ClientStateKeyPathUser,
kRegValueLastSuccessfulCheckSec);
EXPECT_GE(now, last_check_sec);
EXPECT_GE(static_cast<uint32>(200), now - last_check_sec);
EXPECT_FALSE(RegKey::HasValue(kGuid1ClientStateKeyPathUser,
kRegValueLastUpdateTimeSec));
}
TEST_F(AppManagerTest, RemoveClientState_Uninstalled) {
AppData expected_data(guid1_, true);
PopulateExpectedUninstalledAppData(&expected_data);
CreateAppRegistryState(expected_data);
AppManager app_manager(true);
ProductData data;
ASSERT_SUCCEEDED(app_manager.ReadProductDataFromStore(guid1_, &data));
ASSERT_SUCCEEDED(app_manager.RemoveClientState(data.app_data()));
ASSERT_FALSE(IsClientStateKeyPresent(expected_data));
}
class AppManagerTest2 : public testing::Test {
protected:
AppManagerTest2()
: hive_override_key_name_(kRegistryHiveOverrideRoot) {}
virtual void SetUp() {
RegKey::DeleteKey(hive_override_key_name_);
OverrideRegistryHives(hive_override_key_name_);
}
virtual void TearDown() {
RestoreRegistryHives();
RegKey::DeleteKey(hive_override_key_name_);
}
CString hive_override_key_name_;
};
// Create 2 registered app and 1 unregistered app and populates the parameters.
// Each is written to the registry.
// Also creates partial Clients and ClientState keys and creates an a registered
// and unregistered app in the opposite registry hive.
void PopulateDataAndRegistryForRegisteredAndUnRegisteredApplicationsTests(
bool is_machine,
AppData* expected_data1,
AppData* expected_data2,
AppData* expected_data3) {
expected_data1->set_app_guid(StringToGuid(kGuid1));
expected_data1->set_is_machine_app(is_machine);
AppManagerTest::PopulateExpectedAppData1(expected_data1);
AppManagerTest::CreateAppRegistryState(*expected_data1);
expected_data2->set_app_guid(StringToGuid(kGuid2));
expected_data2->set_is_machine_app(is_machine);
AppManagerTest::PopulateExpectedAppData2(expected_data2);
AppManagerTest::CreateAppRegistryState(*expected_data2);
expected_data3->set_app_guid(StringToGuid(kGuid3));
expected_data3->set_is_machine_app(is_machine);
AppManagerTest::PopulateExpectedUninstalledAppData(expected_data3);
AppManagerTest::CreateAppRegistryState(*expected_data3);
// Add incomplete Clients and ClientState entries.
ASSERT_HRESULT_SUCCEEDED(RegKey::SetValue(
AppendRegKeyPath(is_machine ? MACHINE_REG_CLIENTS : USER_REG_CLIENTS,
kGuid4),
_T("name"),
_T("foo")));
ASSERT_HRESULT_SUCCEEDED(RegKey::SetValue(
AppendRegKeyPath(is_machine ? MACHINE_REG_CLIENT_STATE :
USER_REG_CLIENT_STATE,
kGuid5),
kRegValueDidRun,
_T("1")));
// Add registered and unregistered app to the opposite registry hive.
AppData opposite_hive_data1(StringToGuid(kGuid6), !is_machine);
AppManagerTest::PopulateExpectedAppData2(&opposite_hive_data1);
AppManagerTest::CreateAppRegistryState(opposite_hive_data1);
AppData opposite_hive_data2(StringToGuid(kGuid7), !is_machine);
AppManagerTest::PopulateExpectedUninstalledAppData(&opposite_hive_data2);
AppManagerTest::CreateAppRegistryState(opposite_hive_data2);
}
TEST_F(AppManagerTest2, GetRegisteredApplications_machine) {
AppData expected_data1, expected_data2, expected_data3;
PopulateDataAndRegistryForRegisteredAndUnRegisteredApplicationsTests(
true,
&expected_data1,
&expected_data2,
&expected_data3);
AppManager app_manager(true);
ProductDataVector products;
ASSERT_HRESULT_SUCCEEDED(app_manager.GetRegisteredProducts(&products));
ASSERT_EQ(2, products.size());
ASSERT_TRUE(::IsEqualGUID(products[0].app_data().app_guid(),
StringToGuid(kGuid1)));
ValidateExpectedValues(expected_data1, products[0].app_data());
ASSERT_TRUE(::IsEqualGUID(products[1].app_data().app_guid(),
StringToGuid(kGuid2)));
ValidateExpectedValues(expected_data2, products[1].app_data());
}
TEST_F(AppManagerTest2, GetRegisteredApplications_user) {
AppData expected_data1, expected_data2, expected_data3;
PopulateDataAndRegistryForRegisteredAndUnRegisteredApplicationsTests(
false,
&expected_data1,
&expected_data2,
&expected_data3);
AppManager app_manager(false);
ProductDataVector products;
ASSERT_HRESULT_SUCCEEDED(app_manager.GetRegisteredProducts(&products));
ASSERT_EQ(2, products.size());
ASSERT_TRUE(::IsEqualGUID(products[0].app_data().app_guid(),
StringToGuid(kGuid1)));
ValidateExpectedValues(expected_data1, products[0].app_data());
ASSERT_TRUE(::IsEqualGUID(products[1].app_data().app_guid(),
StringToGuid(kGuid2)));
ValidateExpectedValues(expected_data2, products[1].app_data());
}
TEST_F(AppManagerTest2, GetUnRegisteredApplications_machine) {
AppData expected_data1, expected_data2, expected_data3;
PopulateDataAndRegistryForRegisteredAndUnRegisteredApplicationsTests(
true,
&expected_data1,
&expected_data2,
&expected_data3);
AppManager app_manager(true);
ProductDataVector unreg_products;
ASSERT_HRESULT_SUCCEEDED(
app_manager.GetUnRegisteredProducts(&unreg_products));
ASSERT_EQ(1, unreg_products.size());
ValidateExpectedValues(expected_data3, unreg_products[0].app_data());
}
TEST_F(AppManagerTest2, GetUnRegisteredApplications_user) {
AppData expected_data1, expected_data2, expected_data3;
PopulateDataAndRegistryForRegisteredAndUnRegisteredApplicationsTests(
false,
&expected_data1,
&expected_data2,
&expected_data3);
AppManager app_manager(false);
ProductDataVector unreg_products;
ASSERT_HRESULT_SUCCEEDED(
app_manager.GetUnRegisteredProducts(&unreg_products));
ASSERT_EQ(1, unreg_products.size());
ValidateExpectedValues(expected_data3, unreg_products[0].app_data());
}
TEST_F(AppManagerTest2, UpdateLastChecked) {
AppManager app_manager(false);
EXPECT_SUCCEEDED(app_manager.UpdateLastChecked());
EXPECT_FALSE(app_manager.ShouldCheckForUpdates());
ConfigManager::Instance()->SetLastCheckedTime(false, 0);
EXPECT_TRUE(app_manager.ShouldCheckForUpdates());
}
TEST_F(AppManagerTest, ShouldCheckForUpdates_NoLastCheckedPresent) {
AppManager app_manager(false);
EXPECT_TRUE(app_manager.ShouldCheckForUpdates());
}
TEST_F(AppManagerTest, ShouldCheckForUpdates_LastCheckedPresent) {
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
AppManager app_manager(false);
ConfigManager::Instance()->SetLastCheckedTime(false, now - 10);
EXPECT_FALSE(app_manager.ShouldCheckForUpdates());
ConfigManager::Instance()->SetLastCheckedTime(false,
now - kLastCheckPeriodSec - 1);
EXPECT_TRUE(app_manager.ShouldCheckForUpdates());
}
TEST_F(AppManagerTest, ShouldCheckForUpdates_LastCheckedInFuture) {
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
AppManager app_manager(false);
// The absolute difference is within the check period.
ConfigManager::Instance()->SetLastCheckedTime(false, now + 600);
EXPECT_FALSE(app_manager.ShouldCheckForUpdates());
// The absolute difference is greater than the check period.
ConfigManager::Instance()->SetLastCheckedTime(false,
now + kLastCheckPeriodSec + 1);
EXPECT_TRUE(app_manager.ShouldCheckForUpdates());
}
TEST_F(AppManagerTest, ShouldCheckForUpdates_PeriodZero) {
EXPECT_SUCCEEDED(
RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
kRegValueAutoUpdateCheckPeriodOverrideMinutes,
static_cast<DWORD>(0)));
AppManager app_manager(false);
EXPECT_FALSE(app_manager.ShouldCheckForUpdates());
}
TEST_F(AppManagerTest, ShouldCheckForUpdates_PeriodOverride) {
const DWORD kOverrideMinutes = 10;
const DWORD kOverrideSeconds = kOverrideMinutes * 60;
const uint32 now = Time64ToInt32(GetCurrent100NSTime());
AppManager app_manager(false);
EXPECT_SUCCEEDED(
RegKey::SetValue(kRegKeyGoopdateGroupPolicy,
kRegValueAutoUpdateCheckPeriodOverrideMinutes,
kOverrideMinutes));
ConfigManager::Instance()->SetLastCheckedTime(false, now - 10);
EXPECT_FALSE(app_manager.ShouldCheckForUpdates());
ConfigManager::Instance()->SetLastCheckedTime(false,
now - kOverrideSeconds - 1);
EXPECT_TRUE(app_manager.ShouldCheckForUpdates());
}
} // namespace omaha