You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
7.5 KiB
248 lines
7.5 KiB
/*
|
|
* Copyright (C) 2011 The Android Open Source Project
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include "base/flags.h"
|
|
|
|
#include <optional>
|
|
|
|
#include "android-base/properties.h"
|
|
#include "common_runtime_test.h"
|
|
|
|
|
|
namespace art {
|
|
|
|
// Tests may be run in parallel so this helper class ensures
|
|
// that we generate a unique test flag each time to avoid
|
|
// tests stepping on each other
|
|
class TestFlag {
|
|
public:
|
|
// Takes control of the tmp_file pointer.
|
|
TestFlag(ScratchFile* tmp_file, FlagType flag_type) {
|
|
tmp_file_.reset(tmp_file);
|
|
|
|
std::string tmp_name = tmp_file_->GetFilename();
|
|
size_t tmp_last_slash = tmp_name.rfind('/');
|
|
tmp_name = tmp_name.substr(tmp_last_slash + 1);
|
|
|
|
flag_name_ = "art.gtest." + tmp_name;
|
|
system_prop_name_ = "dalvik.vm." + flag_name_;
|
|
server_name_ = "persist.device_config.runtime_native." + flag_name_;
|
|
cmd_line_name_ = flag_name_;
|
|
std::replace(cmd_line_name_.begin(), cmd_line_name_.end(), '.', '-');
|
|
|
|
flag_.reset(new Flag<int>(flag_name_, /*default_value=*/ 42, flag_type));
|
|
}
|
|
|
|
void AssertCmdlineValue(bool has_value, int expected) {
|
|
ASSERT_EQ(flag_->from_command_line_.has_value(), has_value);
|
|
if (has_value) {
|
|
ASSERT_EQ(flag_->from_command_line_.value(), expected);
|
|
}
|
|
}
|
|
|
|
void AssertSysPropValue(bool has_value, int expected) {
|
|
ASSERT_EQ(flag_->from_system_property_.has_value(), has_value);
|
|
if (has_value) {
|
|
ASSERT_EQ(flag_->from_system_property_.value(), expected);
|
|
}
|
|
}
|
|
|
|
void AssertServerSettingValue(bool has_value, int expected) {
|
|
ASSERT_EQ(flag_->from_server_setting_.has_value(), has_value);
|
|
if (has_value) {
|
|
ASSERT_EQ(flag_->from_server_setting_.value(), expected);
|
|
}
|
|
}
|
|
|
|
void AssertDefaultValue(int expected) {
|
|
ASSERT_EQ(flag_->default_, expected);
|
|
}
|
|
|
|
int Value() {
|
|
return (*flag_)();
|
|
}
|
|
|
|
std::string SystemProperty() const {
|
|
return system_prop_name_;
|
|
}
|
|
|
|
std::string ServerSetting() const {
|
|
return server_name_;
|
|
}
|
|
|
|
std::string CmdLineName() const {
|
|
return cmd_line_name_;
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<ScratchFile> tmp_file_;
|
|
std::unique_ptr<Flag<int>> flag_;
|
|
std::string flag_name_;
|
|
std::string cmd_line_name_;
|
|
std::string system_prop_name_;
|
|
std::string server_name_;
|
|
};
|
|
|
|
class FlagsTests : public CommonRuntimeTest {
|
|
protected:
|
|
// We need to initialize the flag after the ScratchDir is created
|
|
// but before we configure the runtime options (so that we can get
|
|
// the right name for the config).
|
|
//
|
|
// So we do it in SetUpRuntimeOptions.
|
|
virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
|
|
test_flag_.reset(new TestFlag(new ScratchFile(), FlagType::kDeviceConfig));
|
|
CommonRuntimeTest::SetUpRuntimeOptions(options);
|
|
}
|
|
|
|
virtual void TearDown() {
|
|
test_flag_ = nullptr;
|
|
CommonRuntimeTest::TearDown();
|
|
}
|
|
|
|
std::unique_ptr<TestFlag> test_flag_;
|
|
};
|
|
|
|
class FlagsTestsWithCmdLineBase : public FlagsTests {
|
|
public:
|
|
explicit FlagsTestsWithCmdLineBase(FlagType type) : flag_type_(type) {
|
|
}
|
|
|
|
protected:
|
|
virtual void TearDown() {
|
|
android::base::SetProperty(test_flag_->SystemProperty(), "");
|
|
android::base::SetProperty(test_flag_->ServerSetting(), "");
|
|
FlagsTests::TearDown();
|
|
}
|
|
|
|
virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
|
|
test_flag_.reset(new TestFlag(new ScratchFile(), flag_type_));
|
|
std::string option = "-X" + test_flag_->CmdLineName() + ":1";
|
|
options->emplace_back(option.c_str(), nullptr);
|
|
}
|
|
|
|
FlagType flag_type_;
|
|
};
|
|
|
|
class FlagsTestsWithCmdLine : public FlagsTestsWithCmdLineBase {
|
|
public:
|
|
FlagsTestsWithCmdLine() : FlagsTestsWithCmdLineBase(FlagType::kDeviceConfig) {
|
|
}
|
|
};
|
|
|
|
class FlagsTestsCmdLineOnly : public FlagsTestsWithCmdLineBase {
|
|
public:
|
|
FlagsTestsCmdLineOnly() : FlagsTestsWithCmdLineBase(FlagType::kCmdlineOnly) {
|
|
}
|
|
};
|
|
|
|
// Validate that when no flag is set, the default is taken and none of the other
|
|
// locations are populated
|
|
TEST_F(FlagsTests, ValidateDefaultValue) {
|
|
FlagBase::ReloadAllFlags("test");
|
|
|
|
test_flag_->AssertCmdlineValue(false, 1);
|
|
test_flag_->AssertSysPropValue(false, 2);
|
|
test_flag_->AssertServerSettingValue(false, 3);
|
|
test_flag_->AssertDefaultValue(42);
|
|
|
|
ASSERT_EQ(test_flag_->Value(), 42);
|
|
}
|
|
|
|
// Validate that the server side config is picked when it is set.
|
|
TEST_F(FlagsTestsWithCmdLine, FlagsTestsGetValueServerSetting) {
|
|
// On older releases (e.g. nougat) the system properties have very strict
|
|
// limitations (e.g. for length) and setting the properties will fail.
|
|
// On modern platforms this should not be the case, so condition the test
|
|
// based on the success of setting the properties.
|
|
if (!android::base::SetProperty(test_flag_->SystemProperty(), "2")) {
|
|
LOG(ERROR) << "Release does not support property setting, skipping test: "
|
|
<< test_flag_->SystemProperty();
|
|
return;
|
|
}
|
|
|
|
if (android::base::SetProperty(test_flag_->ServerSetting(), "3")) {
|
|
LOG(ERROR) << "Release does not support property setting, skipping test: "
|
|
<< test_flag_->ServerSetting();
|
|
return;
|
|
}
|
|
|
|
FlagBase::ReloadAllFlags("test");
|
|
|
|
test_flag_->AssertCmdlineValue(true, 1);
|
|
test_flag_->AssertSysPropValue(true, 2);
|
|
test_flag_->AssertServerSettingValue(true, 3);
|
|
test_flag_->AssertDefaultValue(42);
|
|
|
|
ASSERT_EQ(test_flag_->Value(), 3);
|
|
}
|
|
|
|
// Validate that the system property value is picked when the server one is not set.
|
|
TEST_F(FlagsTestsWithCmdLine, FlagsTestsGetValueSysProperty) {
|
|
if (!android::base::SetProperty(test_flag_->SystemProperty(), "2")) {
|
|
LOG(ERROR) << "Release does not support property setting, skipping test: "
|
|
<< test_flag_->SystemProperty();
|
|
return;
|
|
}
|
|
|
|
FlagBase::ReloadAllFlags("test");
|
|
|
|
test_flag_->AssertCmdlineValue(true, 1);
|
|
test_flag_->AssertSysPropValue(true, 2);
|
|
test_flag_->AssertServerSettingValue(false, 3);
|
|
test_flag_->AssertDefaultValue(42);
|
|
|
|
ASSERT_EQ(test_flag_->Value(), 2);
|
|
}
|
|
|
|
// Validate that the cmdline value is picked when no properties are set.
|
|
TEST_F(FlagsTestsWithCmdLine, FlagsTestsGetValueCmdline) {
|
|
FlagBase::ReloadAllFlags("test");
|
|
|
|
test_flag_->AssertCmdlineValue(true, 1);
|
|
test_flag_->AssertSysPropValue(false, 2);
|
|
test_flag_->AssertServerSettingValue(false, 3);
|
|
test_flag_->AssertDefaultValue(42);
|
|
|
|
ASSERT_EQ(test_flag_->Value(), 1);
|
|
}
|
|
|
|
// Validate that cmdline only flags don't read system properties.
|
|
TEST_F(FlagsTestsCmdLineOnly, CmdlineOnlyFlags) {
|
|
if (!android::base::SetProperty(test_flag_->SystemProperty(), "2")) {
|
|
LOG(ERROR) << "Release does not support property setting, skipping test: "
|
|
<< test_flag_->SystemProperty();
|
|
return;
|
|
}
|
|
|
|
if (android::base::SetProperty(test_flag_->ServerSetting(), "3")) {
|
|
LOG(ERROR) << "Release does not support property setting, skipping test: "
|
|
<< test_flag_->ServerSetting();
|
|
return;
|
|
}
|
|
|
|
FlagBase::ReloadAllFlags("test");
|
|
|
|
test_flag_->AssertCmdlineValue(true, 1);
|
|
test_flag_->AssertSysPropValue(false, 2);
|
|
test_flag_->AssertServerSettingValue(false, 3);
|
|
test_flag_->AssertDefaultValue(42);
|
|
|
|
ASSERT_EQ(test_flag_->Value(), 1);
|
|
}
|
|
|
|
} // namespace art
|