xref: /aosp_15_r20/art/libartbase/base/flags_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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