blob: ebc2c02a6b5e05dfbc68150aacaddd758af4e9c9 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/chrome_cleaner/settings/settings.h"
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/chrome_cleaner/constants/chrome_cleaner_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chrome_cleaner {
// Number high enough that it will never be a valid engine value.
constexpr int kInvalidEngineValue = 3141592;
static_assert(kInvalidEngineValue < Engine::Name_MIN ||
kInvalidEngineValue > Engine::Name_MAX,
"kInvalidEngineValue is not an invalid value");
constexpr char kNonNumericValue[] = "foo";
class SettingsTest : public testing::Test {
protected:
Settings* ReinitializeSettings(const base::CommandLine& command_line) {
Settings* settings = Settings::GetInstance();
settings->Initialize(command_line, GetTargetBinary());
return settings;
}
void TestExecutionMode(const std::string& switch_value,
ExecutionMode expected_execution_mode) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
if (!switch_value.empty())
command_line.AppendSwitchASCII(kExecutionModeSwitch, switch_value);
Settings* settings = ReinitializeSettings(command_line);
EXPECT_EQ(expected_execution_mode, settings->execution_mode());
}
};
TEST_F(SettingsTest, EngineDefaultValue) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
Settings* settings = ReinitializeSettings(command_line);
EXPECT_EQ(Engine::URZA, settings->engine());
}
TEST_F(SettingsTest, ValidEngines) {
for (int index = Engine::Name_MIN; index < Engine::Name_MAX; ++index) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(chrome_cleaner::kEngineSwitch,
base::IntToString(index));
Settings* settings = ReinitializeSettings(command_line);
if (index != Engine::UNKNOWN)
EXPECT_EQ(static_cast<Engine::Name>(index), settings->engine());
else
EXPECT_EQ(Engine::URZA, settings->engine()); // Fallback to default.
}
}
TEST_F(SettingsTest, EngineInvalidNumericValue) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(chrome_cleaner::kEngineSwitch,
base::IntToString(kInvalidEngineValue));
Settings* settings = ReinitializeSettings(command_line);
EXPECT_EQ(Engine::URZA, settings->engine());
}
TEST_F(SettingsTest, EngineNonNumericValue) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(chrome_cleaner::kEngineSwitch,
kNonNumericValue);
Settings* settings = ReinitializeSettings(command_line);
EXPECT_EQ(Engine::URZA, settings->engine());
}
TEST_F(SettingsTest, CleanerRunId_Generated) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
Settings* settings = ReinitializeSettings(command_line);
// A non-empty cleanup id should be generated if switch --cleanup-id is not
// present.
EXPECT_FALSE(settings->cleanup_id().empty());
command_line.AppendSwitchASCII(chrome_cleaner::kCleanupIdSwitch,
std::string());
settings = ReinitializeSettings(command_line);
// A non-empty cleanup id should be generated if switch --cleanup-id is
// present, but the corresponding value is empty.
EXPECT_FALSE(settings->cleanup_id().empty());
}
TEST_F(SettingsTest, CleanerRunId_Propagated) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
const std::string propagated_cleanup_id = "propagated-run-id";
command_line.AppendSwitchASCII(chrome_cleaner::kCleanupIdSwitch,
propagated_cleanup_id);
Settings* settings = ReinitializeSettings(command_line);
EXPECT_EQ(propagated_cleanup_id, settings->cleanup_id());
}
TEST_F(SettingsTest, SBEREnabled) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
EXPECT_FALSE(ReinitializeSettings(command_line)->sber_enabled());
command_line.AppendSwitch(chrome_cleaner::kExtendedSafeBrowsingEnabledSwitch);
EXPECT_TRUE(ReinitializeSettings(command_line)->sber_enabled());
}
TEST_F(SettingsTest, ExecutionMode) {
const struct TestCase {
std::string switch_value;
ExecutionMode expected_execution_mode;
} test_cases[] = {
// Switch not present.
{"", ExecutionMode::kNone},
// Valid values for execution mode.
{base::IntToString(static_cast<int>(ExecutionMode::kScanning)),
ExecutionMode::kScanning},
{base::IntToString(static_cast<int>(ExecutionMode::kCleanup)),
ExecutionMode::kCleanup},
// Unknown values for execution mode.
{base::IntToString(static_cast<int>(ExecutionMode::kNumValues)),
ExecutionMode::kNone},
{base::IntToString(static_cast<int>(ExecutionMode::kNumValues) + 1),
ExecutionMode::kNone},
{base::IntToString(static_cast<int>(ExecutionMode::kNone) - 1),
ExecutionMode::kNone},
{"invalid-value", ExecutionMode::kNone},
};
for (auto t : test_cases) {
TestExecutionMode(t.switch_value, t.expected_execution_mode);
}
}
TEST_F(SettingsTest, Timeouts) {
using OverrideAccessor = bool (Settings::*)() const;
using TimeoutAccessor = base::TimeDelta (Settings::*)() const;
const struct TestCase {
std::string switch_value;
bool expected_timeout_overridden;
base::TimeDelta expected_timeout;
} test_cases[] = {
// Switch not present.
{"", false, base::TimeDelta()},
// Valid number of minutes.
{"100", true, base::TimeDelta::FromMinutes(100)},
// Disabled.
{"0", true, base::TimeDelta()},
// Invalid values.
{"ten", false, base::TimeDelta()},
{"1.5", false, base::TimeDelta()},
{"-3", false, base::TimeDelta()},
};
const struct SwitchesToTest {
std::string switch_name;
OverrideAccessor override_accessor;
TimeoutAccessor timeout_accessor;
} switches_to_test[] = {
{kCleaningTimeoutMinutesSwitch, &Settings::cleaning_timeout_overridden,
&Settings::cleaning_timeout},
{kScanningTimeoutMinutesSwitch, &Settings::scanning_timeout_overridden,
&Settings::scanning_timeout},
};
for (auto s : switches_to_test) {
SCOPED_TRACE(s.switch_name);
for (auto t : test_cases) {
SCOPED_TRACE(t.switch_value);
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
if (!t.switch_value.empty())
command_line.AppendSwitchASCII(s.switch_name, t.switch_value);
Settings* settings = ReinitializeSettings(command_line);
bool timeout_overridden = (settings->*(s.override_accessor))();
base::TimeDelta timeout = (settings->*(s.timeout_accessor))();
EXPECT_EQ(t.expected_timeout_overridden, timeout_overridden);
EXPECT_EQ(t.expected_timeout, timeout);
}
}
}
TEST_F(SettingsTest, NoLocationsToScanSpecified) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
Settings* settings = ReinitializeSettings(command_line);
// All valid scan locations should be specified, but let's not check the exact
// contents and size. It's bigger than 1 location for sure.
EXPECT_LT(1u, settings->locations_to_scan().size());
EXPECT_TRUE(settings->scan_switches_correct());
}
TEST_F(SettingsTest, LimitsToSpecifiedLocations) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(kScanLocationsSwitch, "1,2,3");
std::vector<UwS::TraceLocation> expected_locations = {
UwS::FOUND_IN_STARTUP, UwS::FOUND_IN_MEMORY,
UwS::FOUND_IN_UNINSTALLSTRING,
};
Settings* settings = ReinitializeSettings(command_line);
EXPECT_EQ(expected_locations, settings->locations_to_scan());
EXPECT_TRUE(settings->scan_switches_correct());
}
TEST_F(SettingsTest, UsesOnlyValidSpecifiedLocations) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(kScanLocationsSwitch, "1,100,yada,-3");
std::vector<UwS::TraceLocation> expected_locations = {UwS::FOUND_IN_STARTUP};
Settings* settings = ReinitializeSettings(command_line);
EXPECT_EQ(expected_locations, settings->locations_to_scan());
EXPECT_FALSE(settings->scan_switches_correct());
}
TEST_F(SettingsTest, OnlyInvalidLocationsSpecified) {
const std::string test_cases[] = {
"", // empty flag value
"100,102,-3", // only invalid values specified
};
for (const std::string& switch_value : test_cases) {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(kScanLocationsSwitch, switch_value);
Settings* settings = ReinitializeSettings(command_line);
// All valid scan locations should be specified.
EXPECT_LT(1u, settings->locations_to_scan().size());
EXPECT_FALSE(settings->scan_switches_correct());
}
}
} // namespace chrome_cleaner