xref: /aosp_15_r20/art/cmdline/cmdline_parser_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 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 "cmdline_parser.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <numeric>
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include "base/utils.h"
24*795d594fSAndroid Build Coastguard Worker #include "jdwp_provider.h"
25*795d594fSAndroid Build Coastguard Worker #include "experimental_flags.h"
26*795d594fSAndroid Build Coastguard Worker #include "parsed_options.h"
27*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
28*795d594fSAndroid Build Coastguard Worker #include "runtime_options.h"
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker #define EXPECT_NULL(expected) EXPECT_EQ(reinterpret_cast<const void*>(expected), \
31*795d594fSAndroid Build Coastguard Worker                                         reinterpret_cast<void*>(nullptr));
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker namespace art {
34*795d594fSAndroid Build Coastguard Worker   bool UsuallyEquals(double expected, double actual);
35*795d594fSAndroid Build Coastguard Worker 
36*795d594fSAndroid Build Coastguard Worker   // This has a gtest dependency, which is why it's in the gtest only.
operator ==(const ProfileSaverOptions & lhs,const ProfileSaverOptions & rhs)37*795d594fSAndroid Build Coastguard Worker   bool operator==(const ProfileSaverOptions& lhs, const ProfileSaverOptions& rhs) {
38*795d594fSAndroid Build Coastguard Worker     return lhs.enabled_ == rhs.enabled_ &&
39*795d594fSAndroid Build Coastguard Worker            lhs.min_save_period_ms_ == rhs.min_save_period_ms_ &&
40*795d594fSAndroid Build Coastguard Worker            lhs.min_methods_to_save_ == rhs.min_methods_to_save_ &&
41*795d594fSAndroid Build Coastguard Worker            lhs.min_classes_to_save_ == rhs.min_classes_to_save_ &&
42*795d594fSAndroid Build Coastguard Worker            lhs.min_notification_before_wake_ == rhs.min_notification_before_wake_ &&
43*795d594fSAndroid Build Coastguard Worker            lhs.max_notification_before_wake_ == rhs.max_notification_before_wake_;
44*795d594fSAndroid Build Coastguard Worker   }
45*795d594fSAndroid Build Coastguard Worker 
UsuallyEquals(double expected,double actual)46*795d594fSAndroid Build Coastguard Worker   bool UsuallyEquals(double expected, double actual) {
47*795d594fSAndroid Build Coastguard Worker     using FloatingPoint = ::testing::internal::FloatingPoint<double>;
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker     FloatingPoint exp(expected);
50*795d594fSAndroid Build Coastguard Worker     FloatingPoint act(actual);
51*795d594fSAndroid Build Coastguard Worker 
52*795d594fSAndroid Build Coastguard Worker     // Compare with ULPs instead of comparing with ==
53*795d594fSAndroid Build Coastguard Worker     return exp.AlmostEquals(act);
54*795d594fSAndroid Build Coastguard Worker   }
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker   template <typename T>
UsuallyEquals(const T & expected,const T & actual,typename std::enable_if<detail::SupportsEqualityOperator<T>::value>::type * =nullptr)57*795d594fSAndroid Build Coastguard Worker   bool UsuallyEquals(const T& expected, const T& actual,
58*795d594fSAndroid Build Coastguard Worker                      typename std::enable_if<
59*795d594fSAndroid Build Coastguard Worker                          detail::SupportsEqualityOperator<T>::value>::type* = nullptr) {
60*795d594fSAndroid Build Coastguard Worker     return expected == actual;
61*795d594fSAndroid Build Coastguard Worker   }
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker   template <char Separator>
UsuallyEquals(const std::vector<std::string> & expected,const ParseStringList<Separator> & actual)64*795d594fSAndroid Build Coastguard Worker   bool UsuallyEquals(const std::vector<std::string>& expected,
65*795d594fSAndroid Build Coastguard Worker                      const ParseStringList<Separator>& actual) {
66*795d594fSAndroid Build Coastguard Worker     return expected == static_cast<std::vector<std::string>>(actual);
67*795d594fSAndroid Build Coastguard Worker   }
68*795d594fSAndroid Build Coastguard Worker 
69*795d594fSAndroid Build Coastguard Worker   // Try to use memcmp to compare simple plain-old-data structs.
70*795d594fSAndroid Build Coastguard Worker   //
71*795d594fSAndroid Build Coastguard Worker   // This should *not* generate false positives, but it can generate false negatives.
72*795d594fSAndroid Build Coastguard Worker   // This will mostly work except for fields like float which can have different bit patterns
73*795d594fSAndroid Build Coastguard Worker   // that are nevertheless equal.
74*795d594fSAndroid Build Coastguard Worker   // If a test is failing because the structs aren't "equal" when they really are
75*795d594fSAndroid Build Coastguard Worker   // then it's recommended to implement operator== for it instead.
76*795d594fSAndroid Build Coastguard Worker   template <typename T, typename... Ignore>
UsuallyEquals(const T & expected,const T & actual,const Ignore &...more,typename std::enable_if<std::is_pod<T>::value>::type * =nullptr,typename std::enable_if<!detail::SupportsEqualityOperator<T>::value>::type * =nullptr)77*795d594fSAndroid Build Coastguard Worker   bool UsuallyEquals(
78*795d594fSAndroid Build Coastguard Worker       const T& expected,
79*795d594fSAndroid Build Coastguard Worker       const T& actual,
80*795d594fSAndroid Build Coastguard Worker       [[maybe_unused]] const Ignore&... more,
81*795d594fSAndroid Build Coastguard Worker       typename std::enable_if<std::is_pod<T>::value>::type* = nullptr,
82*795d594fSAndroid Build Coastguard Worker       typename std::enable_if<!detail::SupportsEqualityOperator<T>::value>::type* = nullptr) {
83*795d594fSAndroid Build Coastguard Worker     return memcmp(std::addressof(expected), std::addressof(actual), sizeof(T)) == 0;
84*795d594fSAndroid Build Coastguard Worker   }
85*795d594fSAndroid Build Coastguard Worker 
UsuallyEquals(const XGcOption & expected,const XGcOption & actual)86*795d594fSAndroid Build Coastguard Worker   bool UsuallyEquals(const XGcOption& expected, const XGcOption& actual) {
87*795d594fSAndroid Build Coastguard Worker     return memcmp(std::addressof(expected), std::addressof(actual), sizeof(expected)) == 0;
88*795d594fSAndroid Build Coastguard Worker   }
89*795d594fSAndroid Build Coastguard Worker 
UsuallyEquals(const char * expected,const std::string & actual)90*795d594fSAndroid Build Coastguard Worker   bool UsuallyEquals(const char* expected, const std::string& actual) {
91*795d594fSAndroid Build Coastguard Worker     return std::string(expected) == actual;
92*795d594fSAndroid Build Coastguard Worker   }
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker   template <typename TMap, typename TKey, typename T>
IsExpectedKeyValue(const T & expected,const TMap & map,const TKey & key)95*795d594fSAndroid Build Coastguard Worker   ::testing::AssertionResult IsExpectedKeyValue(const T& expected,
96*795d594fSAndroid Build Coastguard Worker                                                 const TMap& map,
97*795d594fSAndroid Build Coastguard Worker                                                 const TKey& key) {
98*795d594fSAndroid Build Coastguard Worker     auto* actual = map.Get(key);
99*795d594fSAndroid Build Coastguard Worker     if (actual != nullptr) {
100*795d594fSAndroid Build Coastguard Worker       if (!UsuallyEquals(expected, *actual)) {
101*795d594fSAndroid Build Coastguard Worker         return ::testing::AssertionFailure()
102*795d594fSAndroid Build Coastguard Worker           << "expected " << detail::ToStringAny(expected) << " but got "
103*795d594fSAndroid Build Coastguard Worker           << detail::ToStringAny(*actual);
104*795d594fSAndroid Build Coastguard Worker       }
105*795d594fSAndroid Build Coastguard Worker       return ::testing::AssertionSuccess();
106*795d594fSAndroid Build Coastguard Worker     }
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker     return ::testing::AssertionFailure() << "key was not in the map";
109*795d594fSAndroid Build Coastguard Worker   }
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker   template <typename TMap, typename TKey, typename T>
IsExpectedDefaultKeyValue(const T & expected,const TMap & map,const TKey & key)112*795d594fSAndroid Build Coastguard Worker   ::testing::AssertionResult IsExpectedDefaultKeyValue(const T& expected,
113*795d594fSAndroid Build Coastguard Worker                                                        const TMap& map,
114*795d594fSAndroid Build Coastguard Worker                                                        const TKey& key) {
115*795d594fSAndroid Build Coastguard Worker     const T& actual = map.GetOrDefault(key);
116*795d594fSAndroid Build Coastguard Worker     if (!UsuallyEquals(expected, actual)) {
117*795d594fSAndroid Build Coastguard Worker       return ::testing::AssertionFailure()
118*795d594fSAndroid Build Coastguard Worker           << "expected " << detail::ToStringAny(expected) << " but got "
119*795d594fSAndroid Build Coastguard Worker           << detail::ToStringAny(actual);
120*795d594fSAndroid Build Coastguard Worker      }
121*795d594fSAndroid Build Coastguard Worker     return ::testing::AssertionSuccess();
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker class CmdlineParserTest : public ::testing::Test {
125*795d594fSAndroid Build Coastguard Worker  public:
126*795d594fSAndroid Build Coastguard Worker   CmdlineParserTest() = default;
127*795d594fSAndroid Build Coastguard Worker   ~CmdlineParserTest() = default;
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker  protected:
130*795d594fSAndroid Build Coastguard Worker   using M = RuntimeArgumentMap;
131*795d594fSAndroid Build Coastguard Worker   using RuntimeParser = ParsedOptions::RuntimeParser;
132*795d594fSAndroid Build Coastguard Worker 
SetUpTestCase()133*795d594fSAndroid Build Coastguard Worker   static void SetUpTestCase() {
134*795d594fSAndroid Build Coastguard Worker     art::Locks::Init();
135*795d594fSAndroid Build Coastguard Worker     art::InitLogging(nullptr, art::Runtime::Abort);  // argv = null
136*795d594fSAndroid Build Coastguard Worker   }
137*795d594fSAndroid Build Coastguard Worker 
SetUp()138*795d594fSAndroid Build Coastguard Worker   void SetUp() override {
139*795d594fSAndroid Build Coastguard Worker     parser_ = ParsedOptions::MakeParser(false);  // do not ignore unrecognized options
140*795d594fSAndroid Build Coastguard Worker   }
141*795d594fSAndroid Build Coastguard Worker 
IsResultSuccessful(const CmdlineResult & result)142*795d594fSAndroid Build Coastguard Worker   static ::testing::AssertionResult IsResultSuccessful(const CmdlineResult& result) {
143*795d594fSAndroid Build Coastguard Worker     if (result.IsSuccess()) {
144*795d594fSAndroid Build Coastguard Worker       return ::testing::AssertionSuccess();
145*795d594fSAndroid Build Coastguard Worker     } else {
146*795d594fSAndroid Build Coastguard Worker       return ::testing::AssertionFailure()
147*795d594fSAndroid Build Coastguard Worker         << result.GetStatus() << " with: " << result.GetMessage();
148*795d594fSAndroid Build Coastguard Worker     }
149*795d594fSAndroid Build Coastguard Worker   }
150*795d594fSAndroid Build Coastguard Worker 
IsResultFailure(const CmdlineResult & result,CmdlineResult::Status failure_status)151*795d594fSAndroid Build Coastguard Worker   static ::testing::AssertionResult IsResultFailure(const CmdlineResult& result,
152*795d594fSAndroid Build Coastguard Worker                                                     CmdlineResult::Status failure_status) {
153*795d594fSAndroid Build Coastguard Worker     if (result.IsSuccess()) {
154*795d594fSAndroid Build Coastguard Worker       return ::testing::AssertionFailure() << " got success but expected failure: "
155*795d594fSAndroid Build Coastguard Worker           << failure_status;
156*795d594fSAndroid Build Coastguard Worker     } else if (result.GetStatus() == failure_status) {
157*795d594fSAndroid Build Coastguard Worker       return ::testing::AssertionSuccess();
158*795d594fSAndroid Build Coastguard Worker     }
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker     return ::testing::AssertionFailure() << " expected failure " << failure_status
161*795d594fSAndroid Build Coastguard Worker         << " but got " << result.GetStatus();
162*795d594fSAndroid Build Coastguard Worker   }
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<RuntimeParser> parser_;
165*795d594fSAndroid Build Coastguard Worker };
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker #define EXPECT_KEY_EXISTS(map, key) EXPECT_TRUE((map).Exists(key))
168*795d594fSAndroid Build Coastguard Worker #define EXPECT_KEY_VALUE(map, key, expected) EXPECT_TRUE(IsExpectedKeyValue(expected, map, key))
169*795d594fSAndroid Build Coastguard Worker #define EXPECT_DEFAULT_KEY_VALUE(map, key, expected) EXPECT_TRUE(IsExpectedDefaultKeyValue(expected, map, key))
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker #define _EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv)              \
172*795d594fSAndroid Build Coastguard Worker   do {                                                        \
173*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsResultSuccessful(parser_->Parse(argv)));    \
174*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(0u, parser_->GetArgumentsMap().Size());         \
175*795d594fSAndroid Build Coastguard Worker 
176*795d594fSAndroid Build Coastguard Worker #define EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv)               \
177*795d594fSAndroid Build Coastguard Worker   _EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv);                   \
178*795d594fSAndroid Build Coastguard Worker   } while (false)
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker #define EXPECT_SINGLE_PARSE_DEFAULT_VALUE(expected, argv, key)\
181*795d594fSAndroid Build Coastguard Worker   _EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv);                   \
182*795d594fSAndroid Build Coastguard Worker     RuntimeArgumentMap args = parser_->ReleaseArgumentsMap(); \
183*795d594fSAndroid Build Coastguard Worker     EXPECT_DEFAULT_KEY_VALUE(args, key, expected);            \
184*795d594fSAndroid Build Coastguard Worker   } while (false)                                             // NOLINT [readability/namespace] [5]
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker #define _EXPECT_SINGLE_PARSE_EXISTS(argv, key)                \
187*795d594fSAndroid Build Coastguard Worker   do {                                                        \
188*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsResultSuccessful(parser_->Parse(argv)));    \
189*795d594fSAndroid Build Coastguard Worker     RuntimeArgumentMap args = parser_->ReleaseArgumentsMap(); \
190*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(1u, args.Size());                               \
191*795d594fSAndroid Build Coastguard Worker     EXPECT_KEY_EXISTS(args, key);                             \
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker #define EXPECT_SINGLE_PARSE_EXISTS(argv, key)                 \
194*795d594fSAndroid Build Coastguard Worker     _EXPECT_SINGLE_PARSE_EXISTS(argv, key);                   \
195*795d594fSAndroid Build Coastguard Worker   } while (false)
196*795d594fSAndroid Build Coastguard Worker 
197*795d594fSAndroid Build Coastguard Worker #define EXPECT_SINGLE_PARSE_VALUE(expected, argv, key)        \
198*795d594fSAndroid Build Coastguard Worker     _EXPECT_SINGLE_PARSE_EXISTS(argv, key);                   \
199*795d594fSAndroid Build Coastguard Worker     EXPECT_KEY_VALUE(args, key, expected);                    \
200*795d594fSAndroid Build Coastguard Worker   } while (false)
201*795d594fSAndroid Build Coastguard Worker 
202*795d594fSAndroid Build Coastguard Worker #define EXPECT_SINGLE_PARSE_VALUE_STR(expected, argv, key)    \
203*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(std::string(expected), argv, key)
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker #define EXPECT_SINGLE_PARSE_FAIL(argv, failure_status)         \
206*795d594fSAndroid Build Coastguard Worker     do {                                                       \
207*795d594fSAndroid Build Coastguard Worker       EXPECT_TRUE(IsResultFailure(parser_->Parse(argv), failure_status));\
208*795d594fSAndroid Build Coastguard Worker       RuntimeArgumentMap args = parser_->ReleaseArgumentsMap();\
209*795d594fSAndroid Build Coastguard Worker       EXPECT_EQ(0u, args.Size());                              \
210*795d594fSAndroid Build Coastguard Worker     } while (false)
211*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestSimpleSuccesses)212*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestSimpleSuccesses) {
213*795d594fSAndroid Build Coastguard Worker   auto& parser = *parser_;
214*795d594fSAndroid Build Coastguard Worker 
215*795d594fSAndroid Build Coastguard Worker   EXPECT_LT(0u, parser.CountDefinedArguments());
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker   {
218*795d594fSAndroid Build Coastguard Worker     // Test case 1: No command line arguments
219*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(IsResultSuccessful(parser.Parse("")));
220*795d594fSAndroid Build Coastguard Worker     RuntimeArgumentMap args = parser.ReleaseArgumentsMap();
221*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(0u, args.Size());
222*795d594fSAndroid Build Coastguard Worker   }
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_EXISTS("-Xzygote", M::Zygote);
225*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(std::vector<std::string>({"/hello/world"}),
226*795d594fSAndroid Build Coastguard Worker                             "-Xbootclasspath:/hello/world",
227*795d594fSAndroid Build Coastguard Worker                             M::BootClassPath);
228*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(std::vector<std::string>({"/hello", "/world"}),
229*795d594fSAndroid Build Coastguard Worker                             "-Xbootclasspath:/hello:/world",
230*795d594fSAndroid Build Coastguard Worker                             M::BootClassPath);
231*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE_STR("/hello/world", "-classpath /hello/world", M::ClassPath);
232*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(Memory<1>(234), "-Xss234", M::StackSize);
233*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(MemoryKiB(1234*MB), "-Xms1234m", M::MemoryInitialSize);
234*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(true, "-XX:EnableHSpaceCompactForOOM", M::EnableHSpaceCompactForOOM);
235*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(false, "-XX:DisableHSpaceCompactForOOM", M::EnableHSpaceCompactForOOM);
236*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(0.5, "-XX:HeapTargetUtilization=0.5", M::HeapTargetUtilization);
237*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(5u, "-XX:ParallelGCThreads=5", M::ParallelGCThreads);
238*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(10u,
239*795d594fSAndroid Build Coastguard Worker                             "-XX:ParallelGCThreads=5 -XX:ParallelGCThreads=10",
240*795d594fSAndroid Build Coastguard Worker                             M::ParallelGCThreads);
241*795d594fSAndroid Build Coastguard Worker }  // TEST_F
242*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestSimpleFailures)243*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestSimpleFailures) {
244*795d594fSAndroid Build Coastguard Worker   // Test argument is unknown to the parser
245*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("abcdefg^%@#*(@#", CmdlineResult::kUnknown);
246*795d594fSAndroid Build Coastguard Worker   // Test value map substitution fails
247*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-Xverify:whatever", CmdlineResult::kFailure);
248*795d594fSAndroid Build Coastguard Worker   // Test value type parsing failures
249*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-Xsswhatever", CmdlineResult::kFailure);  // invalid memory value
250*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-Xms123", CmdlineResult::kFailure);       // memory value too small
251*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-XX:HeapTargetUtilization=0.0", CmdlineResult::kOutOfRange);  // toosmal
252*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-XX:HeapTargetUtilization=2.0", CmdlineResult::kOutOfRange);  // toolarg
253*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-XX:ParallelGCThreads=-5", CmdlineResult::kOutOfRange);  // too small
254*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-Xgc:blablabla", CmdlineResult::kUsage);  // not a valid suboption
255*795d594fSAndroid Build Coastguard Worker }  // TEST_F
256*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestLogVerbosity)257*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestLogVerbosity) {
258*795d594fSAndroid Build Coastguard Worker   {
259*795d594fSAndroid Build Coastguard Worker     const char* log_args = "-verbose:"
260*795d594fSAndroid Build Coastguard Worker         "class,compiler,gc,heap,interpreter,jdwp,jni,monitor,profiler,signals,simulator,startup,"
261*795d594fSAndroid Build Coastguard Worker         "third-party-jni,threads,verifier,verifier-debug";
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker     LogVerbosity log_verbosity = LogVerbosity();
264*795d594fSAndroid Build Coastguard Worker     log_verbosity.class_linker = true;
265*795d594fSAndroid Build Coastguard Worker     log_verbosity.compiler = true;
266*795d594fSAndroid Build Coastguard Worker     log_verbosity.gc = true;
267*795d594fSAndroid Build Coastguard Worker     log_verbosity.heap = true;
268*795d594fSAndroid Build Coastguard Worker     log_verbosity.interpreter = true;
269*795d594fSAndroid Build Coastguard Worker     log_verbosity.jdwp = true;
270*795d594fSAndroid Build Coastguard Worker     log_verbosity.jni = true;
271*795d594fSAndroid Build Coastguard Worker     log_verbosity.monitor = true;
272*795d594fSAndroid Build Coastguard Worker     log_verbosity.profiler = true;
273*795d594fSAndroid Build Coastguard Worker     log_verbosity.signals = true;
274*795d594fSAndroid Build Coastguard Worker     log_verbosity.simulator = true;
275*795d594fSAndroid Build Coastguard Worker     log_verbosity.startup = true;
276*795d594fSAndroid Build Coastguard Worker     log_verbosity.third_party_jni = true;
277*795d594fSAndroid Build Coastguard Worker     log_verbosity.threads = true;
278*795d594fSAndroid Build Coastguard Worker     log_verbosity.verifier = true;
279*795d594fSAndroid Build Coastguard Worker     log_verbosity.verifier_debug = true;
280*795d594fSAndroid Build Coastguard Worker 
281*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
282*795d594fSAndroid Build Coastguard Worker   }
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker   {
285*795d594fSAndroid Build Coastguard Worker     const char* log_args = "-verbose:"
286*795d594fSAndroid Build Coastguard Worker         "class,compiler,gc,heap,jdwp,jni,monitor";
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker     LogVerbosity log_verbosity = LogVerbosity();
289*795d594fSAndroid Build Coastguard Worker     log_verbosity.class_linker = true;
290*795d594fSAndroid Build Coastguard Worker     log_verbosity.compiler = true;
291*795d594fSAndroid Build Coastguard Worker     log_verbosity.gc = true;
292*795d594fSAndroid Build Coastguard Worker     log_verbosity.heap = true;
293*795d594fSAndroid Build Coastguard Worker     log_verbosity.jdwp = true;
294*795d594fSAndroid Build Coastguard Worker     log_verbosity.jni = true;
295*795d594fSAndroid Build Coastguard Worker     log_verbosity.monitor = true;
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
298*795d594fSAndroid Build Coastguard Worker   }
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-verbose:blablabla", CmdlineResult::kUsage);  // invalid verbose opt
301*795d594fSAndroid Build Coastguard Worker 
302*795d594fSAndroid Build Coastguard Worker   {
303*795d594fSAndroid Build Coastguard Worker     const char* log_args = "-verbose:deopt";
304*795d594fSAndroid Build Coastguard Worker     LogVerbosity log_verbosity = LogVerbosity();
305*795d594fSAndroid Build Coastguard Worker     log_verbosity.deopt = true;
306*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
307*795d594fSAndroid Build Coastguard Worker   }
308*795d594fSAndroid Build Coastguard Worker 
309*795d594fSAndroid Build Coastguard Worker   {
310*795d594fSAndroid Build Coastguard Worker     const char* log_args = "-verbose:collector";
311*795d594fSAndroid Build Coastguard Worker     LogVerbosity log_verbosity = LogVerbosity();
312*795d594fSAndroid Build Coastguard Worker     log_verbosity.collector = true;
313*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
314*795d594fSAndroid Build Coastguard Worker   }
315*795d594fSAndroid Build Coastguard Worker 
316*795d594fSAndroid Build Coastguard Worker   {
317*795d594fSAndroid Build Coastguard Worker     const char* log_args = "-verbose:oat";
318*795d594fSAndroid Build Coastguard Worker     LogVerbosity log_verbosity = LogVerbosity();
319*795d594fSAndroid Build Coastguard Worker     log_verbosity.oat = true;
320*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
321*795d594fSAndroid Build Coastguard Worker   }
322*795d594fSAndroid Build Coastguard Worker 
323*795d594fSAndroid Build Coastguard Worker   {
324*795d594fSAndroid Build Coastguard Worker     const char* log_args = "-verbose:dex";
325*795d594fSAndroid Build Coastguard Worker     LogVerbosity log_verbosity = LogVerbosity();
326*795d594fSAndroid Build Coastguard Worker     log_verbosity.dex = true;
327*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
328*795d594fSAndroid Build Coastguard Worker   }
329*795d594fSAndroid Build Coastguard Worker }  // TEST_F
330*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestXGcOption)331*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestXGcOption) {
332*795d594fSAndroid Build Coastguard Worker   /*
333*795d594fSAndroid Build Coastguard Worker    * Test success
334*795d594fSAndroid Build Coastguard Worker    */
335*795d594fSAndroid Build Coastguard Worker   {
336*795d594fSAndroid Build Coastguard Worker     XGcOption option_all_true{};
337*795d594fSAndroid Build Coastguard Worker     option_all_true.collector_type_ = gc::CollectorType::kCollectorTypeCMS;
338*795d594fSAndroid Build Coastguard Worker     option_all_true.verify_pre_gc_heap_ = true;
339*795d594fSAndroid Build Coastguard Worker     option_all_true.verify_pre_sweeping_heap_ = true;
340*795d594fSAndroid Build Coastguard Worker     option_all_true.verify_post_gc_heap_ = true;
341*795d594fSAndroid Build Coastguard Worker     option_all_true.verify_pre_gc_rosalloc_ = true;
342*795d594fSAndroid Build Coastguard Worker     option_all_true.verify_pre_sweeping_rosalloc_ = true;
343*795d594fSAndroid Build Coastguard Worker     option_all_true.verify_post_gc_rosalloc_ = true;
344*795d594fSAndroid Build Coastguard Worker 
345*795d594fSAndroid Build Coastguard Worker     const char * xgc_args_all_true = "-Xgc:concurrent,"
346*795d594fSAndroid Build Coastguard Worker         "preverify,presweepingverify,postverify,"
347*795d594fSAndroid Build Coastguard Worker         "preverify_rosalloc,presweepingverify_rosalloc,"
348*795d594fSAndroid Build Coastguard Worker         "postverify_rosalloc,precise,"
349*795d594fSAndroid Build Coastguard Worker         "verifycardtable";
350*795d594fSAndroid Build Coastguard Worker 
351*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(option_all_true, xgc_args_all_true, M::GcOption);
352*795d594fSAndroid Build Coastguard Worker 
353*795d594fSAndroid Build Coastguard Worker     XGcOption option_all_false{};
354*795d594fSAndroid Build Coastguard Worker     option_all_false.collector_type_ = gc::CollectorType::kCollectorTypeMS;
355*795d594fSAndroid Build Coastguard Worker     option_all_false.verify_pre_gc_heap_ = false;
356*795d594fSAndroid Build Coastguard Worker     option_all_false.verify_pre_sweeping_heap_ = false;
357*795d594fSAndroid Build Coastguard Worker     option_all_false.verify_post_gc_heap_ = false;
358*795d594fSAndroid Build Coastguard Worker     option_all_false.verify_pre_gc_rosalloc_ = false;
359*795d594fSAndroid Build Coastguard Worker     option_all_false.verify_pre_sweeping_rosalloc_ = false;
360*795d594fSAndroid Build Coastguard Worker     option_all_false.verify_post_gc_rosalloc_ = false;
361*795d594fSAndroid Build Coastguard Worker 
362*795d594fSAndroid Build Coastguard Worker     const char* xgc_args_all_false = "-Xgc:nonconcurrent,"
363*795d594fSAndroid Build Coastguard Worker         "nopreverify,nopresweepingverify,nopostverify,nopreverify_rosalloc,"
364*795d594fSAndroid Build Coastguard Worker         "nopresweepingverify_rosalloc,nopostverify_rosalloc,noprecise,noverifycardtable";
365*795d594fSAndroid Build Coastguard Worker 
366*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(option_all_false, xgc_args_all_false, M::GcOption);
367*795d594fSAndroid Build Coastguard Worker 
368*795d594fSAndroid Build Coastguard Worker     XGcOption option_all_default{};
369*795d594fSAndroid Build Coastguard Worker 
370*795d594fSAndroid Build Coastguard Worker     const char* xgc_args_blank = "-Xgc:";
371*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(option_all_default, xgc_args_blank, M::GcOption);
372*795d594fSAndroid Build Coastguard Worker   }
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker   /*
375*795d594fSAndroid Build Coastguard Worker    * Test failures
376*795d594fSAndroid Build Coastguard Worker    */
377*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-Xgc:blablabla", CmdlineResult::kUsage);  // invalid Xgc opt
378*795d594fSAndroid Build Coastguard Worker }  // TEST_F
379*795d594fSAndroid Build Coastguard Worker 
380*795d594fSAndroid Build Coastguard Worker /*
381*795d594fSAndroid Build Coastguard Worker  * { "-XjdwpProvider:_" }
382*795d594fSAndroid Build Coastguard Worker  */
TEST_F(CmdlineParserTest,TestJdwpProviderEmpty)383*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestJdwpProviderEmpty) {
384*795d594fSAndroid Build Coastguard Worker   {
385*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_DEFAULT_VALUE(JdwpProvider::kUnset, "", M::JdwpProvider);
386*795d594fSAndroid Build Coastguard Worker   }
387*795d594fSAndroid Build Coastguard Worker }  // TEST_F
388*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestJdwpProviderDefault)389*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestJdwpProviderDefault) {
390*795d594fSAndroid Build Coastguard Worker   const char* opt_args = "-XjdwpProvider:default";
391*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(JdwpProvider::kDefaultJdwpProvider, opt_args, M::JdwpProvider);
392*795d594fSAndroid Build Coastguard Worker }  // TEST_F
393*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestJdwpProviderNone)394*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestJdwpProviderNone) {
395*795d594fSAndroid Build Coastguard Worker   const char* opt_args = "-XjdwpProvider:none";
396*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(JdwpProvider::kNone, opt_args, M::JdwpProvider);
397*795d594fSAndroid Build Coastguard Worker }  // TEST_F
398*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestJdwpProviderAdbconnection)399*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestJdwpProviderAdbconnection) {
400*795d594fSAndroid Build Coastguard Worker   const char* opt_args = "-XjdwpProvider:adbconnection";
401*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(JdwpProvider::kAdbConnection, opt_args, M::JdwpProvider);
402*795d594fSAndroid Build Coastguard Worker }  // TEST_F
403*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestJdwpProviderHelp)404*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestJdwpProviderHelp) {
405*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-XjdwpProvider:help", CmdlineResult::kUsage);
406*795d594fSAndroid Build Coastguard Worker }  // TEST_F
407*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestJdwpProviderFail)408*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestJdwpProviderFail) {
409*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_FAIL("-XjdwpProvider:blablabla", CmdlineResult::kFailure);
410*795d594fSAndroid Build Coastguard Worker }  // TEST_F
411*795d594fSAndroid Build Coastguard Worker 
412*795d594fSAndroid Build Coastguard Worker /*
413*795d594fSAndroid Build Coastguard Worker  * -D_ -D_ -D_ ...
414*795d594fSAndroid Build Coastguard Worker  */
TEST_F(CmdlineParserTest,TestPropertiesList)415*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestPropertiesList) {
416*795d594fSAndroid Build Coastguard Worker   /*
417*795d594fSAndroid Build Coastguard Worker    * Test successes
418*795d594fSAndroid Build Coastguard Worker    */
419*795d594fSAndroid Build Coastguard Worker   {
420*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> opt = {"hello"};
421*795d594fSAndroid Build Coastguard Worker 
422*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(opt, "-Dhello", M::PropertiesList);
423*795d594fSAndroid Build Coastguard Worker   }
424*795d594fSAndroid Build Coastguard Worker 
425*795d594fSAndroid Build Coastguard Worker   {
426*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> opt = {"hello", "world"};
427*795d594fSAndroid Build Coastguard Worker 
428*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(opt, "-Dhello -Dworld", M::PropertiesList);
429*795d594fSAndroid Build Coastguard Worker   }
430*795d594fSAndroid Build Coastguard Worker 
431*795d594fSAndroid Build Coastguard Worker   {
432*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> opt = {"one", "two", "three"};
433*795d594fSAndroid Build Coastguard Worker 
434*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(opt, "-Done -Dtwo -Dthree", M::PropertiesList);
435*795d594fSAndroid Build Coastguard Worker   }
436*795d594fSAndroid Build Coastguard Worker }  // TEST_F
437*795d594fSAndroid Build Coastguard Worker 
438*795d594fSAndroid Build Coastguard Worker /*
439*795d594fSAndroid Build Coastguard Worker * -Xcompiler-option foo -Xcompiler-option bar ...
440*795d594fSAndroid Build Coastguard Worker */
TEST_F(CmdlineParserTest,TestCompilerOption)441*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestCompilerOption) {
442*795d594fSAndroid Build Coastguard Worker  /*
443*795d594fSAndroid Build Coastguard Worker   * Test successes
444*795d594fSAndroid Build Coastguard Worker   */
445*795d594fSAndroid Build Coastguard Worker   {
446*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> opt = {"hello"};
447*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(opt, "-Xcompiler-option hello", M::CompilerOptions);
448*795d594fSAndroid Build Coastguard Worker   }
449*795d594fSAndroid Build Coastguard Worker 
450*795d594fSAndroid Build Coastguard Worker   {
451*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> opt = {"hello", "world"};
452*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(opt,
453*795d594fSAndroid Build Coastguard Worker                               "-Xcompiler-option hello -Xcompiler-option world",
454*795d594fSAndroid Build Coastguard Worker                               M::CompilerOptions);
455*795d594fSAndroid Build Coastguard Worker   }
456*795d594fSAndroid Build Coastguard Worker 
457*795d594fSAndroid Build Coastguard Worker   {
458*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> opt = {"one", "two", "three"};
459*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(opt,
460*795d594fSAndroid Build Coastguard Worker                               "-Xcompiler-option one -Xcompiler-option two -Xcompiler-option three",
461*795d594fSAndroid Build Coastguard Worker                               M::CompilerOptions);
462*795d594fSAndroid Build Coastguard Worker   }
463*795d594fSAndroid Build Coastguard Worker }  // TEST_F
464*795d594fSAndroid Build Coastguard Worker 
465*795d594fSAndroid Build Coastguard Worker /*
466*795d594fSAndroid Build Coastguard Worker * -Xjit, -Xnojit, -Xjitcodecachesize, Xjitcompilethreshold
467*795d594fSAndroid Build Coastguard Worker */
TEST_F(CmdlineParserTest,TestJitOptions)468*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestJitOptions) {
469*795d594fSAndroid Build Coastguard Worker  /*
470*795d594fSAndroid Build Coastguard Worker   * Test successes
471*795d594fSAndroid Build Coastguard Worker   */
472*795d594fSAndroid Build Coastguard Worker   {
473*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(true, "-Xusejit:true", M::UseJitCompilation);
474*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(false, "-Xusejit:false", M::UseJitCompilation);
475*795d594fSAndroid Build Coastguard Worker   }
476*795d594fSAndroid Build Coastguard Worker   {
477*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(
478*795d594fSAndroid Build Coastguard Worker         MemoryKiB(16 * KB), "-Xjitinitialsize:16K", M::JITCodeCacheInitialCapacity);
479*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(
480*795d594fSAndroid Build Coastguard Worker         MemoryKiB(16 * MB), "-Xjitmaxsize:16M", M::JITCodeCacheMaxCapacity);
481*795d594fSAndroid Build Coastguard Worker   }
482*795d594fSAndroid Build Coastguard Worker   {
483*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_VALUE(12345u, "-Xjitthreshold:12345", M::JITOptimizeThreshold);
484*795d594fSAndroid Build Coastguard Worker   }
485*795d594fSAndroid Build Coastguard Worker }  // TEST_F
486*795d594fSAndroid Build Coastguard Worker 
487*795d594fSAndroid Build Coastguard Worker /*
488*795d594fSAndroid Build Coastguard Worker * -Xps-*
489*795d594fSAndroid Build Coastguard Worker */
TEST_F(CmdlineParserTest,ProfileSaverOptions)490*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, ProfileSaverOptions) {
491*795d594fSAndroid Build Coastguard Worker   ProfileSaverOptions opt = ProfileSaverOptions(true, 1, 2, 3, 4, 5, 6, 7, "abc", true);
492*795d594fSAndroid Build Coastguard Worker 
493*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(opt,
494*795d594fSAndroid Build Coastguard Worker                             "-Xjitsaveprofilinginfo "
495*795d594fSAndroid Build Coastguard Worker                             "-Xps-min-save-period-ms:1 "
496*795d594fSAndroid Build Coastguard Worker                             "-Xps-min-first-save-ms:2 "
497*795d594fSAndroid Build Coastguard Worker                             "-Xps-min-methods-to-save:3 "
498*795d594fSAndroid Build Coastguard Worker                             "-Xps-min-classes-to-save:4 "
499*795d594fSAndroid Build Coastguard Worker                             "-Xps-min-notification-before-wake:5 "
500*795d594fSAndroid Build Coastguard Worker                             "-Xps-max-notification-before-wake:6 "
501*795d594fSAndroid Build Coastguard Worker                             "-Xps-inline-cache-threshold:7 "
502*795d594fSAndroid Build Coastguard Worker                             "-Xps-profile-path:abc "
503*795d594fSAndroid Build Coastguard Worker                             "-Xps-profile-boot-class-path",
504*795d594fSAndroid Build Coastguard Worker                             M::ProfileSaverOpts);
505*795d594fSAndroid Build Coastguard Worker }  // TEST_F
506*795d594fSAndroid Build Coastguard Worker 
507*795d594fSAndroid Build Coastguard Worker /* -Xexperimental:_ */
TEST_F(CmdlineParserTest,TestExperimentalFlags)508*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestExperimentalFlags) {
509*795d594fSAndroid Build Coastguard Worker   // Default
510*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_DEFAULT_VALUE(ExperimentalFlags::kNone,
511*795d594fSAndroid Build Coastguard Worker                                     "",
512*795d594fSAndroid Build Coastguard Worker                                     M::Experimental);
513*795d594fSAndroid Build Coastguard Worker 
514*795d594fSAndroid Build Coastguard Worker   // Disabled explicitly
515*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(ExperimentalFlags::kNone,
516*795d594fSAndroid Build Coastguard Worker                             "-Xexperimental:none",
517*795d594fSAndroid Build Coastguard Worker                             M::Experimental);
518*795d594fSAndroid Build Coastguard Worker }
519*795d594fSAndroid Build Coastguard Worker 
520*795d594fSAndroid Build Coastguard Worker // -Xverify:_
TEST_F(CmdlineParserTest,TestVerify)521*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestVerify) {
522*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kNone,     "-Xverify:none",     M::Verify);
523*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kEnable,   "-Xverify:remote",   M::Verify);
524*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kEnable,   "-Xverify:all",      M::Verify);
525*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_VALUE(verifier::VerifyMode::kSoftFail, "-Xverify:softfail", M::Verify);
526*795d594fSAndroid Build Coastguard Worker }
527*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestIgnoreUnrecognized)528*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestIgnoreUnrecognized) {
529*795d594fSAndroid Build Coastguard Worker   RuntimeParser::Builder parserBuilder;
530*795d594fSAndroid Build Coastguard Worker 
531*795d594fSAndroid Build Coastguard Worker   // clang-format off
532*795d594fSAndroid Build Coastguard Worker   parserBuilder
533*795d594fSAndroid Build Coastguard Worker       .Define("-help")
534*795d594fSAndroid Build Coastguard Worker           .IntoKey(M::Help)
535*795d594fSAndroid Build Coastguard Worker       .IgnoreUnrecognized(true);
536*795d594fSAndroid Build Coastguard Worker   // clang-format on
537*795d594fSAndroid Build Coastguard Worker 
538*795d594fSAndroid Build Coastguard Worker   parser_.reset(new RuntimeParser(parserBuilder.Build()));
539*795d594fSAndroid Build Coastguard Worker 
540*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_EMPTY_SUCCESS("-non-existent-option");
541*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_EMPTY_SUCCESS("-non-existent-option1 --non-existent-option-2");
542*795d594fSAndroid Build Coastguard Worker }  //  TEST_F
543*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TestIgnoredArguments)544*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TestIgnoredArguments) {
545*795d594fSAndroid Build Coastguard Worker   std::initializer_list<const char*> ignored_args = {
546*795d594fSAndroid Build Coastguard Worker       "-ea", "-da", "-enableassertions", "-disableassertions", "--runtime-arg", "-esa",
547*795d594fSAndroid Build Coastguard Worker       "-dsa", "-enablesystemassertions", "-disablesystemassertions", "-Xrs", "-Xint:abdef",
548*795d594fSAndroid Build Coastguard Worker       "-Xdexopt:foobar", "-Xnoquithandler", "-Xjnigreflimit:ixnay", "-Xgenregmap", "-Xnogenregmap",
549*795d594fSAndroid Build Coastguard Worker       "-Xverifyopt:never", "-Xcheckdexsum", "-Xincludeselectedop", "-Xjitop:noop",
550*795d594fSAndroid Build Coastguard Worker       "-Xincludeselectedmethod", "-Xjitblocking", "-Xjitmethod:_", "-Xjitclass:nosuchluck",
551*795d594fSAndroid Build Coastguard Worker       "-Xjitoffset:none", "-Xjitconfig:yes", "-Xjitcheckcg", "-Xjitverbose", "-Xjitprofile",
552*795d594fSAndroid Build Coastguard Worker       "-Xjitdisableopt", "-Xjitsuspendpoll", "-XX:mainThreadStackSize=1337"
553*795d594fSAndroid Build Coastguard Worker   };
554*795d594fSAndroid Build Coastguard Worker 
555*795d594fSAndroid Build Coastguard Worker   // Check they are ignored when parsed one at a time
556*795d594fSAndroid Build Coastguard Worker   for (auto&& arg : ignored_args) {
557*795d594fSAndroid Build Coastguard Worker     SCOPED_TRACE(arg);
558*795d594fSAndroid Build Coastguard Worker     EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(arg);
559*795d594fSAndroid Build Coastguard Worker   }
560*795d594fSAndroid Build Coastguard Worker 
561*795d594fSAndroid Build Coastguard Worker   // Check they are ignored when we pass it all together at once
562*795d594fSAndroid Build Coastguard Worker   std::vector<const char*> argv = ignored_args;
563*795d594fSAndroid Build Coastguard Worker   EXPECT_SINGLE_PARSE_EMPTY_SUCCESS(argv);
564*795d594fSAndroid Build Coastguard Worker }  //  TEST_F
565*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,MultipleArguments)566*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, MultipleArguments) {
567*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(IsResultSuccessful(parser_->Parse(
568*795d594fSAndroid Build Coastguard Worker       "-help -XX:ForegroundHeapGrowthMultiplier=0.5 "
569*795d594fSAndroid Build Coastguard Worker       "-Xmethod-trace -XX:LargeObjectSpace=map")));
570*795d594fSAndroid Build Coastguard Worker 
571*795d594fSAndroid Build Coastguard Worker   auto&& map = parser_->ReleaseArgumentsMap();
572*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(4u, map.Size());
573*795d594fSAndroid Build Coastguard Worker   EXPECT_KEY_VALUE(map, M::Help, Unit{});
574*795d594fSAndroid Build Coastguard Worker   EXPECT_KEY_VALUE(map, M::ForegroundHeapGrowthMultiplier, 0.5);
575*795d594fSAndroid Build Coastguard Worker   EXPECT_KEY_VALUE(map, M::MethodTrace, Unit{});
576*795d594fSAndroid Build Coastguard Worker   EXPECT_KEY_VALUE(map, M::LargeObjectSpace, gc::space::LargeObjectSpaceType::kMap);
577*795d594fSAndroid Build Coastguard Worker }  //  TEST_F
578*795d594fSAndroid Build Coastguard Worker 
TEST_F(CmdlineParserTest,TypesNotInRuntime)579*795d594fSAndroid Build Coastguard Worker TEST_F(CmdlineParserTest, TypesNotInRuntime) {
580*795d594fSAndroid Build Coastguard Worker   using ParseCommaSeparatedIntList = ParseIntList<','>;
581*795d594fSAndroid Build Coastguard Worker   CmdlineType<ParseCommaSeparatedIntList> ct;
582*795d594fSAndroid Build Coastguard Worker   auto success0 =
583*795d594fSAndroid Build Coastguard Worker       CmdlineParseResult<ParseCommaSeparatedIntList>::Success(ParseCommaSeparatedIntList({1, 2, 3, 4}));
584*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(success0, ct.Parse("1,2,3,4"));
585*795d594fSAndroid Build Coastguard Worker   auto success1 =
586*795d594fSAndroid Build Coastguard Worker       CmdlineParseResult<ParseCommaSeparatedIntList>::Success(ParseCommaSeparatedIntList({0}));
587*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(success1, ct.Parse("1"));
588*795d594fSAndroid Build Coastguard Worker 
589*795d594fSAndroid Build Coastguard Worker   EXPECT_FALSE(ct.Parse("").IsSuccess());
590*795d594fSAndroid Build Coastguard Worker   EXPECT_FALSE(ct.Parse(",").IsSuccess());
591*795d594fSAndroid Build Coastguard Worker   EXPECT_FALSE(ct.Parse("1,").IsSuccess());
592*795d594fSAndroid Build Coastguard Worker   EXPECT_FALSE(ct.Parse(",1").IsSuccess());
593*795d594fSAndroid Build Coastguard Worker   EXPECT_FALSE(ct.Parse("1a2").IsSuccess());
594*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(CmdlineResult::kOutOfRange, ct.Parse("1,10000000000000").GetStatus());
595*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(CmdlineResult::kOutOfRange, ct.Parse("-10000000000000,123").GetStatus());
596*795d594fSAndroid Build Coastguard Worker }  // TEST_F
597*795d594fSAndroid Build Coastguard Worker }  // namespace art
598