Home | History | Annotate | Download | only in brillo
      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:
     19   FlagHelperTest() {}
     20   ~FlagHelperTest() override { brillo::FlagHelper::ResetForTesting(); }
     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.
     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
     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
    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.
    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
    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.
    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.
    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.
    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.
    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.
    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.
    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