• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <cstdint>
6 #include <cstdio>
7 #include <sysexits.h>
8 
9 #include <base/command_line.h>
10 #include <base/macros.h>
11 #include <brillo/flag_helper.h>
12 
13 #include <gtest/gtest.h>
14 
15 namespace brillo {
16 
17 class FlagHelperTest : public ::testing::Test {
18  public:
FlagHelperTest()19   FlagHelperTest() {}
~FlagHelperTest()20   ~FlagHelperTest() override { brillo::FlagHelper::ResetForTesting(); }
SetUpTestCase()21   static void SetUpTestCase() { base::CommandLine::Init(0, nullptr); }
22 };
23 
24 // Test that the DEFINE_xxxx macros can create the respective variables
25 // correctly with the default value.
TEST_F(FlagHelperTest,Defaults)26 TEST_F(FlagHelperTest, Defaults) {
27   DEFINE_bool(bool1, true, "Test bool flag");
28   DEFINE_bool(bool2, false, "Test bool flag");
29   DEFINE_int32(int32_1, INT32_MIN, "Test int32 flag");
30   DEFINE_int32(int32_2, 0, "Test int32 flag");
31   DEFINE_int32(int32_3, INT32_MAX, "Test int32 flag");
32   DEFINE_int64(int64_1, INT64_MIN, "Test int64 flag");
33   DEFINE_int64(int64_2, 0, "Test int64 flag");
34   DEFINE_int64(int64_3, INT64_MAX, "Test int64 flag");
35   DEFINE_uint64(uint64_1, 0, "Test uint64 flag");
36   DEFINE_uint64(uint64_2, UINT_LEAST64_MAX, "Test uint64 flag");
37   DEFINE_double(double_1, -100.5, "Test double flag");
38   DEFINE_double(double_2, 0, "Test double flag");
39   DEFINE_double(double_3, 100.5, "Test double flag");
40   DEFINE_string(string_1, "", "Test string flag");
41   DEFINE_string(string_2, "value", "Test string flag");
42 
43   const char* argv[] = {"test_program"};
44   base::CommandLine command_line(arraysize(argv), argv);
45 
46   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
47       &command_line);
48   brillo::FlagHelper::Init(arraysize(argv), argv, "TestDefaultTrue");
49 
50   EXPECT_TRUE(FLAGS_bool1);
51   EXPECT_FALSE(FLAGS_bool2);
52   EXPECT_EQ(FLAGS_int32_1, INT32_MIN);
53   EXPECT_EQ(FLAGS_int32_2, 0);
54   EXPECT_EQ(FLAGS_int32_3, INT32_MAX);
55   EXPECT_EQ(FLAGS_int64_1, INT64_MIN);
56   EXPECT_EQ(FLAGS_int64_2, 0);
57   EXPECT_EQ(FLAGS_int64_3, INT64_MAX);
58   EXPECT_EQ(FLAGS_uint64_1, 0);
59   EXPECT_EQ(FLAGS_uint64_2, UINT_LEAST64_MAX);
60   EXPECT_DOUBLE_EQ(FLAGS_double_1, -100.5);
61   EXPECT_DOUBLE_EQ(FLAGS_double_2, 0);
62   EXPECT_DOUBLE_EQ(FLAGS_double_3, 100.5);
63   EXPECT_STREQ(FLAGS_string_1.c_str(), "");
64   EXPECT_STREQ(FLAGS_string_2.c_str(), "value");
65 }
66 
67 // Test that command line flag values are parsed and update the flag
68 // variable values correctly when using double '--' flags
TEST_F(FlagHelperTest,SetValueDoubleDash)69 TEST_F(FlagHelperTest, SetValueDoubleDash) {
70   DEFINE_bool(bool1, false, "Test bool flag");
71   DEFINE_bool(bool2, true, "Test bool flag");
72   DEFINE_bool(bool3, false, "Test bool flag");
73   DEFINE_bool(bool4, true, "Test bool flag");
74   DEFINE_int32(int32_1, 1, "Test int32 flag");
75   DEFINE_int32(int32_2, 1, "Test int32 flag");
76   DEFINE_int32(int32_3, 1, "Test int32 flag");
77   DEFINE_int64(int64_1, 1, "Test int64 flag");
78   DEFINE_int64(int64_2, 1, "Test int64 flag");
79   DEFINE_int64(int64_3, 1, "Test int64 flag");
80   DEFINE_uint64(uint64_1, 1, "Test uint64 flag");
81   DEFINE_uint64(uint64_2, 1, "Test uint64 flag");
82   DEFINE_double(double_1, 1, "Test double flag");
83   DEFINE_double(double_2, 1, "Test double flag");
84   DEFINE_double(double_3, 1, "Test double flag");
85   DEFINE_string(string_1, "default", "Test string flag");
86   DEFINE_string(string_2, "default", "Test string flag");
87 
88   const char* argv[] = {"test_program",
89                         "--bool1",
90                         "--nobool2",
91                         "--bool3=true",
92                         "--bool4=false",
93                         "--int32_1=-2147483648",
94                         "--int32_2=0",
95                         "--int32_3=2147483647",
96                         "--int64_1=-9223372036854775808",
97                         "--int64_2=0",
98                         "--int64_3=9223372036854775807",
99                         "--uint64_1=0",
100                         "--uint64_2=18446744073709551615",
101                         "--double_1=-100.5",
102                         "--double_2=0",
103                         "--double_3=100.5",
104                         "--string_1=",
105                         "--string_2=value"};
106   base::CommandLine command_line(arraysize(argv), argv);
107 
108   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
109       &command_line);
110   brillo::FlagHelper::Init(arraysize(argv), argv, "TestDefaultTrue");
111 
112   EXPECT_TRUE(FLAGS_bool1);
113   EXPECT_FALSE(FLAGS_bool2);
114   EXPECT_TRUE(FLAGS_bool3);
115   EXPECT_FALSE(FLAGS_bool4);
116   EXPECT_EQ(FLAGS_int32_1, INT32_MIN);
117   EXPECT_EQ(FLAGS_int32_2, 0);
118   EXPECT_EQ(FLAGS_int32_3, INT32_MAX);
119   EXPECT_EQ(FLAGS_int64_1, INT64_MIN);
120   EXPECT_EQ(FLAGS_int64_2, 0);
121   EXPECT_EQ(FLAGS_int64_3, INT64_MAX);
122   EXPECT_EQ(FLAGS_uint64_1, 0);
123   EXPECT_EQ(FLAGS_uint64_2, UINT_LEAST64_MAX);
124   EXPECT_DOUBLE_EQ(FLAGS_double_1, -100.5);
125   EXPECT_DOUBLE_EQ(FLAGS_double_2, 0);
126   EXPECT_DOUBLE_EQ(FLAGS_double_3, 100.5);
127   EXPECT_STREQ(FLAGS_string_1.c_str(), "");
128   EXPECT_STREQ(FLAGS_string_2.c_str(), "value");
129 }
130 
131 // Test that command line flag values are parsed and update the flag
132 // variable values correctly when using single '-' flags
TEST_F(FlagHelperTest,SetValueSingleDash)133 TEST_F(FlagHelperTest, SetValueSingleDash) {
134   DEFINE_bool(bool1, false, "Test bool flag");
135   DEFINE_bool(bool2, true, "Test bool flag");
136   DEFINE_int32(int32_1, 1, "Test int32 flag");
137   DEFINE_int32(int32_2, 1, "Test int32 flag");
138   DEFINE_int32(int32_3, 1, "Test int32 flag");
139   DEFINE_int64(int64_1, 1, "Test int64 flag");
140   DEFINE_int64(int64_2, 1, "Test int64 flag");
141   DEFINE_int64(int64_3, 1, "Test int64 flag");
142   DEFINE_uint64(uint64_1, 1, "Test uint64 flag");
143   DEFINE_uint64(uint64_2, 1, "Test uint64 flag");
144   DEFINE_double(double_1, 1, "Test double flag");
145   DEFINE_double(double_2, 1, "Test double flag");
146   DEFINE_double(double_3, 1, "Test double flag");
147   DEFINE_string(string_1, "default", "Test string flag");
148   DEFINE_string(string_2, "default", "Test string flag");
149 
150   const char* argv[] = {"test_program",
151                         "-bool1",
152                         "-nobool2",
153                         "-int32_1=-2147483648",
154                         "-int32_2=0",
155                         "-int32_3=2147483647",
156                         "-int64_1=-9223372036854775808",
157                         "-int64_2=0",
158                         "-int64_3=9223372036854775807",
159                         "-uint64_1=0",
160                         "-uint64_2=18446744073709551615",
161                         "-double_1=-100.5",
162                         "-double_2=0",
163                         "-double_3=100.5",
164                         "-string_1=",
165                         "-string_2=value"};
166   base::CommandLine command_line(arraysize(argv), argv);
167 
168   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
169       &command_line);
170   brillo::FlagHelper::Init(arraysize(argv), argv, "TestDefaultTrue");
171 
172   EXPECT_TRUE(FLAGS_bool1);
173   EXPECT_FALSE(FLAGS_bool2);
174   EXPECT_EQ(FLAGS_int32_1, INT32_MIN);
175   EXPECT_EQ(FLAGS_int32_2, 0);
176   EXPECT_EQ(FLAGS_int32_3, INT32_MAX);
177   EXPECT_EQ(FLAGS_int64_1, INT64_MIN);
178   EXPECT_EQ(FLAGS_int64_2, 0);
179   EXPECT_EQ(FLAGS_int64_3, INT64_MAX);
180   EXPECT_EQ(FLAGS_uint64_1, 0);
181   EXPECT_EQ(FLAGS_uint64_2, UINT_LEAST64_MAX);
182   EXPECT_DOUBLE_EQ(FLAGS_double_1, -100.5);
183   EXPECT_DOUBLE_EQ(FLAGS_double_2, 0);
184   EXPECT_DOUBLE_EQ(FLAGS_double_3, 100.5);
185   EXPECT_STREQ(FLAGS_string_1.c_str(), "");
186   EXPECT_STREQ(FLAGS_string_2.c_str(), "value");
187 }
188 
189 // Test that a duplicated flag on the command line picks up the last
190 // value set.
TEST_F(FlagHelperTest,DuplicateSetValue)191 TEST_F(FlagHelperTest, DuplicateSetValue) {
192   DEFINE_int32(int32_1, 0, "Test in32 flag");
193 
194   const char* argv[] = {"test_program", "--int32_1=5", "--int32_1=10"};
195   base::CommandLine command_line(arraysize(argv), argv);
196 
197   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
198       &command_line);
199   brillo::FlagHelper::Init(arraysize(argv), argv, "TestDuplicateSetvalue");
200 
201   EXPECT_EQ(FLAGS_int32_1, 10);
202 }
203 
204 // Test that flags set after the -- marker are not parsed as command line flags
TEST_F(FlagHelperTest,FlagTerminator)205 TEST_F(FlagHelperTest, FlagTerminator) {
206   DEFINE_int32(int32_1, 0, "Test int32 flag");
207 
208   const char* argv[] = {"test_program", "--int32_1=5", "--", "--int32_1=10"};
209   base::CommandLine command_line(arraysize(argv), argv);
210 
211   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
212       &command_line);
213   brillo::FlagHelper::Init(arraysize(argv), argv, "TestFlagTerminator");
214 
215   EXPECT_EQ(FLAGS_int32_1, 5);
216 }
217 
218 // Test that help messages are generated correctly when the --help flag
219 // is passed to the program.
TEST_F(FlagHelperTest,HelpMessage)220 TEST_F(FlagHelperTest, HelpMessage) {
221   DEFINE_bool(bool_1, true, "Test bool flag");
222   DEFINE_int32(int_1, 0, "Test int flag");
223   DEFINE_int64(int64_1, 0, "Test int64 flag");
224   DEFINE_uint64(uint64_1, 0, "Test uint64 flag");
225   DEFINE_double(double_1, 0, "Test double flag");
226   DEFINE_string(string_1, "", "Test string flag");
227 
228   const char* argv[] = {"test_program", "--int_1=value", "--help"};
229   base::CommandLine command_line(arraysize(argv), argv);
230 
231   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
232       &command_line);
233 
234   FILE* orig = stdout;
235   stdout = stderr;
236 
237   ASSERT_EXIT(
238       brillo::FlagHelper::Init(arraysize(argv), argv, "TestHelpMessage"),
239       ::testing::ExitedWithCode(EX_OK),
240       "TestHelpMessage\n\n"
241       "  --bool_1  \\(Test bool flag\\)  type: bool  default: true\n"
242       "  --double_1  \\(Test double flag\\)  type: double  default: 0\n"
243       "  --help  \\(Show this help message\\)  type: bool  default: false\n"
244       "  --int64_1  \\(Test int64 flag\\)  type: int64  default: 0\n"
245       "  --int_1  \\(Test int flag\\)  type: int  default: 0\n"
246       "  --string_1  \\(Test string flag\\)  type: string  default: \"\"\n"
247       "  --uint64_1  \\(Test uint64 flag\\)  type: uint64  default: 0\n");
248 
249   stdout = orig;
250 }
251 
252 // Test that passing in unknown command line flags causes the program
253 // to exit with EX_USAGE error code and corresponding error message.
TEST_F(FlagHelperTest,UnknownFlag)254 TEST_F(FlagHelperTest, UnknownFlag) {
255   const char* argv[] = {"test_program", "--flag=value"};
256   base::CommandLine command_line(arraysize(argv), argv);
257 
258   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
259       &command_line);
260 
261   FILE* orig = stdout;
262   stdout = stderr;
263 
264   ASSERT_EXIT(brillo::FlagHelper::Init(arraysize(argv), argv, "TestIntExit"),
265               ::testing::ExitedWithCode(EX_USAGE),
266               "ERROR: unknown command line flag 'flag'");
267 
268   stdout = orig;
269 }
270 
271 // Test that when passing an incorrect/unparsable type to a command line flag,
272 // the program exits with code EX_DATAERR and outputs a corresponding message.
TEST_F(FlagHelperTest,BoolParseError)273 TEST_F(FlagHelperTest, BoolParseError) {
274   DEFINE_bool(bool_1, 0, "Test bool flag");
275 
276   const char* argv[] = {"test_program", "--bool_1=value"};
277   base::CommandLine command_line(arraysize(argv), argv);
278 
279   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
280       &command_line);
281 
282   FILE* orig = stdout;
283   stdout = stderr;
284 
285   ASSERT_EXIT(
286       brillo::FlagHelper::Init(arraysize(argv), argv, "TestBoolParseError"),
287       ::testing::ExitedWithCode(EX_DATAERR),
288       "ERROR: illegal value 'value' specified for bool flag 'bool_1'");
289 
290   stdout = orig;
291 }
292 
293 // Test that when passing an incorrect/unparsable type to a command line flag,
294 // the program exits with code EX_DATAERR and outputs a corresponding message.
TEST_F(FlagHelperTest,Int32ParseError)295 TEST_F(FlagHelperTest, Int32ParseError) {
296   DEFINE_int32(int_1, 0, "Test int flag");
297 
298   const char* argv[] = {"test_program", "--int_1=value"};
299   base::CommandLine command_line(arraysize(argv), argv);
300 
301   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
302       &command_line);
303 
304   FILE* orig = stdout;
305   stdout = stderr;
306 
307   ASSERT_EXIT(brillo::FlagHelper::Init(arraysize(argv),
308                                        argv,
309                                        "TestInt32ParseError"),
310               ::testing::ExitedWithCode(EX_DATAERR),
311               "ERROR: illegal value 'value' specified for int flag 'int_1'");
312 
313   stdout = orig;
314 }
315 
316 // Test that when passing an incorrect/unparsable type to a command line flag,
317 // the program exits with code EX_DATAERR and outputs a corresponding message.
TEST_F(FlagHelperTest,Int64ParseError)318 TEST_F(FlagHelperTest, Int64ParseError) {
319   DEFINE_int64(int64_1, 0, "Test int64 flag");
320 
321   const char* argv[] = {"test_program", "--int64_1=value"};
322   base::CommandLine command_line(arraysize(argv), argv);
323 
324   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
325       &command_line);
326 
327   FILE* orig = stdout;
328   stdout = stderr;
329 
330   ASSERT_EXIT(
331       brillo::FlagHelper::Init(arraysize(argv), argv, "TestInt64ParseError"),
332       ::testing::ExitedWithCode(EX_DATAERR),
333       "ERROR: illegal value 'value' specified for int64 flag "
334       "'int64_1'");
335 
336   stdout = orig;
337 }
338 
339 // Test that when passing an incorrect/unparsable type to a command line flag,
340 // the program exits with code EX_DATAERR and outputs a corresponding message.
TEST_F(FlagHelperTest,UInt64ParseError)341 TEST_F(FlagHelperTest, UInt64ParseError) {
342   DEFINE_uint64(uint64_1, 0, "Test uint64 flag");
343 
344   const char* argv[] = {"test_program", "--uint64_1=value"};
345   base::CommandLine command_line(arraysize(argv), argv);
346 
347   brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
348       &command_line);
349 
350   FILE* orig = stdout;
351   stdout = stderr;
352 
353   ASSERT_EXIT(
354       brillo::FlagHelper::Init(arraysize(argv), argv, "TestUInt64ParseError"),
355       ::testing::ExitedWithCode(EX_DATAERR),
356       "ERROR: illegal value 'value' specified for uint64 flag "
357       "'uint64_1'");
358 
359   stdout = orig;
360 }
361 
362 }  // namespace brillo
363