1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "base/flags.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <optional>
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include "android-base/properties.h"
22*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker namespace art {
26*795d594fSAndroid Build Coastguard Worker
27*795d594fSAndroid Build Coastguard Worker // Tests may be run in parallel so this helper class ensures
28*795d594fSAndroid Build Coastguard Worker // that we generate a unique test flag each time to avoid
29*795d594fSAndroid Build Coastguard Worker // tests stepping on each other
30*795d594fSAndroid Build Coastguard Worker class TestFlag {
31*795d594fSAndroid Build Coastguard Worker public:
32*795d594fSAndroid Build Coastguard Worker // Takes control of the tmp_file pointer.
TestFlag(ScratchFile * tmp_file,FlagType flag_type)33*795d594fSAndroid Build Coastguard Worker TestFlag(ScratchFile* tmp_file, FlagType flag_type) {
34*795d594fSAndroid Build Coastguard Worker tmp_file_.reset(tmp_file);
35*795d594fSAndroid Build Coastguard Worker
36*795d594fSAndroid Build Coastguard Worker std::string tmp_name = tmp_file_->GetFilename();
37*795d594fSAndroid Build Coastguard Worker size_t tmp_last_slash = tmp_name.rfind('/');
38*795d594fSAndroid Build Coastguard Worker tmp_name = tmp_name.substr(tmp_last_slash + 1);
39*795d594fSAndroid Build Coastguard Worker
40*795d594fSAndroid Build Coastguard Worker flag_name_ = "art.gtest." + tmp_name;
41*795d594fSAndroid Build Coastguard Worker system_prop_name_ = "dalvik.vm." + flag_name_;
42*795d594fSAndroid Build Coastguard Worker server_name_ = "persist.device_config.runtime_native." + flag_name_;
43*795d594fSAndroid Build Coastguard Worker cmd_line_name_ = flag_name_;
44*795d594fSAndroid Build Coastguard Worker std::replace(cmd_line_name_.begin(), cmd_line_name_.end(), '.', '-');
45*795d594fSAndroid Build Coastguard Worker
46*795d594fSAndroid Build Coastguard Worker flag_.reset(new Flag<int>(flag_name_, /*default_value=*/ 42, flag_type));
47*795d594fSAndroid Build Coastguard Worker }
48*795d594fSAndroid Build Coastguard Worker
AssertCmdlineValue(bool has_value,int expected)49*795d594fSAndroid Build Coastguard Worker void AssertCmdlineValue(bool has_value, int expected) {
50*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(flag_->from_command_line_.has_value(), has_value);
51*795d594fSAndroid Build Coastguard Worker if (has_value) {
52*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(flag_->from_command_line_.value(), expected);
53*795d594fSAndroid Build Coastguard Worker }
54*795d594fSAndroid Build Coastguard Worker }
55*795d594fSAndroid Build Coastguard Worker
AssertSysPropValue(bool has_value,int expected)56*795d594fSAndroid Build Coastguard Worker void AssertSysPropValue(bool has_value, int expected) {
57*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(flag_->from_system_property_.has_value(), has_value);
58*795d594fSAndroid Build Coastguard Worker if (has_value) {
59*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(flag_->from_system_property_.value(), expected);
60*795d594fSAndroid Build Coastguard Worker }
61*795d594fSAndroid Build Coastguard Worker }
62*795d594fSAndroid Build Coastguard Worker
AssertServerSettingValue(bool has_value,int expected)63*795d594fSAndroid Build Coastguard Worker void AssertServerSettingValue(bool has_value, int expected) {
64*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(flag_->from_server_setting_.has_value(), has_value);
65*795d594fSAndroid Build Coastguard Worker if (has_value) {
66*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(flag_->from_server_setting_.value(), expected);
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker }
69*795d594fSAndroid Build Coastguard Worker
AssertDefaultValue(int expected)70*795d594fSAndroid Build Coastguard Worker void AssertDefaultValue(int expected) {
71*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(flag_->default_, expected);
72*795d594fSAndroid Build Coastguard Worker }
73*795d594fSAndroid Build Coastguard Worker
Value()74*795d594fSAndroid Build Coastguard Worker int Value() {
75*795d594fSAndroid Build Coastguard Worker return (*flag_)();
76*795d594fSAndroid Build Coastguard Worker }
77*795d594fSAndroid Build Coastguard Worker
SystemProperty() const78*795d594fSAndroid Build Coastguard Worker std::string SystemProperty() const {
79*795d594fSAndroid Build Coastguard Worker return system_prop_name_;
80*795d594fSAndroid Build Coastguard Worker }
81*795d594fSAndroid Build Coastguard Worker
ServerSetting() const82*795d594fSAndroid Build Coastguard Worker std::string ServerSetting() const {
83*795d594fSAndroid Build Coastguard Worker return server_name_;
84*795d594fSAndroid Build Coastguard Worker }
85*795d594fSAndroid Build Coastguard Worker
CmdLineName() const86*795d594fSAndroid Build Coastguard Worker std::string CmdLineName() const {
87*795d594fSAndroid Build Coastguard Worker return cmd_line_name_;
88*795d594fSAndroid Build Coastguard Worker }
89*795d594fSAndroid Build Coastguard Worker
90*795d594fSAndroid Build Coastguard Worker private:
91*795d594fSAndroid Build Coastguard Worker std::unique_ptr<ScratchFile> tmp_file_;
92*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Flag<int>> flag_;
93*795d594fSAndroid Build Coastguard Worker std::string flag_name_;
94*795d594fSAndroid Build Coastguard Worker std::string cmd_line_name_;
95*795d594fSAndroid Build Coastguard Worker std::string system_prop_name_;
96*795d594fSAndroid Build Coastguard Worker std::string server_name_;
97*795d594fSAndroid Build Coastguard Worker };
98*795d594fSAndroid Build Coastguard Worker
99*795d594fSAndroid Build Coastguard Worker class FlagsTests : public CommonRuntimeTest {
100*795d594fSAndroid Build Coastguard Worker protected:
FlagsTests()101*795d594fSAndroid Build Coastguard Worker FlagsTests() {
102*795d594fSAndroid Build Coastguard Worker this->use_boot_image_ = true; // Make the Runtime creation cheaper.
103*795d594fSAndroid Build Coastguard Worker }
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker // We need to initialize the flag after the ScratchDir is created
106*795d594fSAndroid Build Coastguard Worker // but before we configure the runtime options (so that we can get
107*795d594fSAndroid Build Coastguard Worker // the right name for the config).
108*795d594fSAndroid Build Coastguard Worker //
109*795d594fSAndroid Build Coastguard Worker // So we do it in SetUpRuntimeOptions.
SetUpRuntimeOptions(RuntimeOptions * options)110*795d594fSAndroid Build Coastguard Worker virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
111*795d594fSAndroid Build Coastguard Worker test_flag_.reset(new TestFlag(new ScratchFile(), FlagType::kDeviceConfig));
112*795d594fSAndroid Build Coastguard Worker CommonRuntimeTest::SetUpRuntimeOptions(options);
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker
TearDown()115*795d594fSAndroid Build Coastguard Worker virtual void TearDown() {
116*795d594fSAndroid Build Coastguard Worker test_flag_ = nullptr;
117*795d594fSAndroid Build Coastguard Worker CommonRuntimeTest::TearDown();
118*795d594fSAndroid Build Coastguard Worker }
119*795d594fSAndroid Build Coastguard Worker
120*795d594fSAndroid Build Coastguard Worker std::unique_ptr<TestFlag> test_flag_;
121*795d594fSAndroid Build Coastguard Worker };
122*795d594fSAndroid Build Coastguard Worker
123*795d594fSAndroid Build Coastguard Worker class FlagsTestsWithCmdLineBase : public FlagsTests {
124*795d594fSAndroid Build Coastguard Worker public:
FlagsTestsWithCmdLineBase(FlagType type)125*795d594fSAndroid Build Coastguard Worker explicit FlagsTestsWithCmdLineBase(FlagType type) : flag_type_(type) {
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker
128*795d594fSAndroid Build Coastguard Worker protected:
TearDown()129*795d594fSAndroid Build Coastguard Worker virtual void TearDown() {
130*795d594fSAndroid Build Coastguard Worker android::base::SetProperty(test_flag_->SystemProperty(), "");
131*795d594fSAndroid Build Coastguard Worker android::base::SetProperty(test_flag_->ServerSetting(), "");
132*795d594fSAndroid Build Coastguard Worker FlagsTests::TearDown();
133*795d594fSAndroid Build Coastguard Worker }
134*795d594fSAndroid Build Coastguard Worker
SetUpRuntimeOptions(RuntimeOptions * options)135*795d594fSAndroid Build Coastguard Worker virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
136*795d594fSAndroid Build Coastguard Worker test_flag_.reset(new TestFlag(new ScratchFile(), flag_type_));
137*795d594fSAndroid Build Coastguard Worker std::string option = "-X" + test_flag_->CmdLineName() + ":1";
138*795d594fSAndroid Build Coastguard Worker options->emplace_back(option.c_str(), nullptr);
139*795d594fSAndroid Build Coastguard Worker }
140*795d594fSAndroid Build Coastguard Worker
141*795d594fSAndroid Build Coastguard Worker FlagType flag_type_;
142*795d594fSAndroid Build Coastguard Worker };
143*795d594fSAndroid Build Coastguard Worker
144*795d594fSAndroid Build Coastguard Worker class FlagsTestsWithCmdLine : public FlagsTestsWithCmdLineBase {
145*795d594fSAndroid Build Coastguard Worker public:
FlagsTestsWithCmdLine()146*795d594fSAndroid Build Coastguard Worker FlagsTestsWithCmdLine() : FlagsTestsWithCmdLineBase(FlagType::kDeviceConfig) {
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker };
149*795d594fSAndroid Build Coastguard Worker
150*795d594fSAndroid Build Coastguard Worker class FlagsTestsCmdLineOnly : public FlagsTestsWithCmdLineBase {
151*795d594fSAndroid Build Coastguard Worker public:
FlagsTestsCmdLineOnly()152*795d594fSAndroid Build Coastguard Worker FlagsTestsCmdLineOnly() : FlagsTestsWithCmdLineBase(FlagType::kCmdlineOnly) {
153*795d594fSAndroid Build Coastguard Worker }
154*795d594fSAndroid Build Coastguard Worker };
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker // Validate that when no flag is set, the default is taken and none of the other
157*795d594fSAndroid Build Coastguard Worker // locations are populated
TEST_F(FlagsTests,ValidateDefaultValue)158*795d594fSAndroid Build Coastguard Worker TEST_F(FlagsTests, ValidateDefaultValue) {
159*795d594fSAndroid Build Coastguard Worker FlagBase::ReloadAllFlags("test");
160*795d594fSAndroid Build Coastguard Worker
161*795d594fSAndroid Build Coastguard Worker test_flag_->AssertCmdlineValue(false, 1);
162*795d594fSAndroid Build Coastguard Worker test_flag_->AssertSysPropValue(false, 2);
163*795d594fSAndroid Build Coastguard Worker test_flag_->AssertServerSettingValue(false, 3);
164*795d594fSAndroid Build Coastguard Worker test_flag_->AssertDefaultValue(42);
165*795d594fSAndroid Build Coastguard Worker
166*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(test_flag_->Value(), 42);
167*795d594fSAndroid Build Coastguard Worker }
168*795d594fSAndroid Build Coastguard Worker
169*795d594fSAndroid Build Coastguard Worker // Validate that the server side config is picked when it is set.
TEST_F(FlagsTestsWithCmdLine,FlagsTestsGetValueServerSetting)170*795d594fSAndroid Build Coastguard Worker TEST_F(FlagsTestsWithCmdLine, FlagsTestsGetValueServerSetting) {
171*795d594fSAndroid Build Coastguard Worker // On older releases (e.g. nougat) the system properties have very strict
172*795d594fSAndroid Build Coastguard Worker // limitations (e.g. for length) and setting the properties will fail.
173*795d594fSAndroid Build Coastguard Worker // On modern platforms this should not be the case, so condition the test
174*795d594fSAndroid Build Coastguard Worker // based on the success of setting the properties.
175*795d594fSAndroid Build Coastguard Worker if (!android::base::SetProperty(test_flag_->SystemProperty(), "2")) {
176*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Release does not support property setting, skipping test: "
177*795d594fSAndroid Build Coastguard Worker << test_flag_->SystemProperty();
178*795d594fSAndroid Build Coastguard Worker return;
179*795d594fSAndroid Build Coastguard Worker }
180*795d594fSAndroid Build Coastguard Worker
181*795d594fSAndroid Build Coastguard Worker if (!android::base::SetProperty(test_flag_->ServerSetting(), "3")) {
182*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Release does not support property setting, skipping test: "
183*795d594fSAndroid Build Coastguard Worker << test_flag_->ServerSetting();
184*795d594fSAndroid Build Coastguard Worker return;
185*795d594fSAndroid Build Coastguard Worker }
186*795d594fSAndroid Build Coastguard Worker
187*795d594fSAndroid Build Coastguard Worker FlagBase::ReloadAllFlags("test");
188*795d594fSAndroid Build Coastguard Worker
189*795d594fSAndroid Build Coastguard Worker test_flag_->AssertCmdlineValue(true, 1);
190*795d594fSAndroid Build Coastguard Worker test_flag_->AssertSysPropValue(true, 2);
191*795d594fSAndroid Build Coastguard Worker test_flag_->AssertServerSettingValue(true, 3);
192*795d594fSAndroid Build Coastguard Worker test_flag_->AssertDefaultValue(42);
193*795d594fSAndroid Build Coastguard Worker
194*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(test_flag_->Value(), 3);
195*795d594fSAndroid Build Coastguard Worker }
196*795d594fSAndroid Build Coastguard Worker
197*795d594fSAndroid Build Coastguard Worker // Validate that the system property value is picked when the server one is not set.
TEST_F(FlagsTestsWithCmdLine,FlagsTestsGetValueSysProperty)198*795d594fSAndroid Build Coastguard Worker TEST_F(FlagsTestsWithCmdLine, FlagsTestsGetValueSysProperty) {
199*795d594fSAndroid Build Coastguard Worker if (!android::base::SetProperty(test_flag_->SystemProperty(), "2")) {
200*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Release does not support property setting, skipping test: "
201*795d594fSAndroid Build Coastguard Worker << test_flag_->SystemProperty();
202*795d594fSAndroid Build Coastguard Worker return;
203*795d594fSAndroid Build Coastguard Worker }
204*795d594fSAndroid Build Coastguard Worker
205*795d594fSAndroid Build Coastguard Worker FlagBase::ReloadAllFlags("test");
206*795d594fSAndroid Build Coastguard Worker
207*795d594fSAndroid Build Coastguard Worker test_flag_->AssertCmdlineValue(true, 1);
208*795d594fSAndroid Build Coastguard Worker test_flag_->AssertSysPropValue(true, 2);
209*795d594fSAndroid Build Coastguard Worker test_flag_->AssertServerSettingValue(false, 3);
210*795d594fSAndroid Build Coastguard Worker test_flag_->AssertDefaultValue(42);
211*795d594fSAndroid Build Coastguard Worker
212*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(test_flag_->Value(), 2);
213*795d594fSAndroid Build Coastguard Worker }
214*795d594fSAndroid Build Coastguard Worker
215*795d594fSAndroid Build Coastguard Worker // Validate that the cmdline value is picked when no properties are set.
TEST_F(FlagsTestsWithCmdLine,FlagsTestsGetValueCmdline)216*795d594fSAndroid Build Coastguard Worker TEST_F(FlagsTestsWithCmdLine, FlagsTestsGetValueCmdline) {
217*795d594fSAndroid Build Coastguard Worker FlagBase::ReloadAllFlags("test");
218*795d594fSAndroid Build Coastguard Worker
219*795d594fSAndroid Build Coastguard Worker test_flag_->AssertCmdlineValue(true, 1);
220*795d594fSAndroid Build Coastguard Worker test_flag_->AssertSysPropValue(false, 2);
221*795d594fSAndroid Build Coastguard Worker test_flag_->AssertServerSettingValue(false, 3);
222*795d594fSAndroid Build Coastguard Worker test_flag_->AssertDefaultValue(42);
223*795d594fSAndroid Build Coastguard Worker
224*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(test_flag_->Value(), 1);
225*795d594fSAndroid Build Coastguard Worker }
226*795d594fSAndroid Build Coastguard Worker
227*795d594fSAndroid Build Coastguard Worker // Validate that cmdline only flags don't read system properties.
TEST_F(FlagsTestsCmdLineOnly,CmdlineOnlyFlags)228*795d594fSAndroid Build Coastguard Worker TEST_F(FlagsTestsCmdLineOnly, CmdlineOnlyFlags) {
229*795d594fSAndroid Build Coastguard Worker if (!android::base::SetProperty(test_flag_->SystemProperty(), "2")) {
230*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Release does not support property setting, skipping test: "
231*795d594fSAndroid Build Coastguard Worker << test_flag_->SystemProperty();
232*795d594fSAndroid Build Coastguard Worker return;
233*795d594fSAndroid Build Coastguard Worker }
234*795d594fSAndroid Build Coastguard Worker
235*795d594fSAndroid Build Coastguard Worker if (!android::base::SetProperty(test_flag_->ServerSetting(), "3")) {
236*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Release does not support property setting, skipping test: "
237*795d594fSAndroid Build Coastguard Worker << test_flag_->ServerSetting();
238*795d594fSAndroid Build Coastguard Worker return;
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker
241*795d594fSAndroid Build Coastguard Worker FlagBase::ReloadAllFlags("test");
242*795d594fSAndroid Build Coastguard Worker
243*795d594fSAndroid Build Coastguard Worker test_flag_->AssertCmdlineValue(true, 1);
244*795d594fSAndroid Build Coastguard Worker test_flag_->AssertSysPropValue(false, 2);
245*795d594fSAndroid Build Coastguard Worker test_flag_->AssertServerSettingValue(false, 3);
246*795d594fSAndroid Build Coastguard Worker test_flag_->AssertDefaultValue(42);
247*795d594fSAndroid Build Coastguard Worker
248*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(test_flag_->Value(), 1);
249*795d594fSAndroid Build Coastguard Worker }
250*795d594fSAndroid Build Coastguard Worker
251*795d594fSAndroid Build Coastguard Worker } // namespace art
252