blob: 80f7398a059067a7f8fe1280069a67c7ab543be2 [file] [log] [blame]
Austin Schuh1eb16d12015-09-06 17:21:56 -07001// Copyright (c) 2005, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// ---
31//
32// For now, this unit test does not cover all features of
33// gflags.cc
34
35#include "config_for_unittests.h"
36#include <gflags/gflags.h>
37
38#include <math.h> // for isinf() and isnan()
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#ifdef HAVE_UNISTD_H
43# include <unistd.h> // for unlink()
44#endif
45#include <vector>
46#include <string>
47#include "util.h"
48TEST_INIT
49EXPECT_DEATH_INIT
50
51// I don't actually use this header file, but #include it under the
52// old location to make sure that the include-header-forwarding
53// works. But don't bother on windows; the windows port is so new
54// it never had the old location-names.
55#ifndef _MSC_VER
56#include <gflags/gflags_completions.h>
57void (*unused_fn)() = &GFLAGS_NAMESPACE::HandleCommandLineCompletions;
58#endif
59
60using std::string;
61using std::vector;
62using GFLAGS_NAMESPACE::int32;
63using GFLAGS_NAMESPACE::FlagRegisterer;
64using GFLAGS_NAMESPACE::StringFromEnv;
65using GFLAGS_NAMESPACE::RegisterFlagValidator;
66using GFLAGS_NAMESPACE::CommandLineFlagInfo;
67using GFLAGS_NAMESPACE::GetAllFlags;
68
69DEFINE_string(test_tmpdir, "", "Dir we use for temp files");
70DEFINE_string(srcdir, StringFromEnv("SRCDIR", "."), "Source-dir root, needed to find gflags_unittest_flagfile");
71
72DECLARE_string(tryfromenv); // in gflags.cc
73
74DEFINE_bool(test_bool, false, "tests bool-ness");
75DEFINE_int32(test_int32, -1, "");
76DEFINE_int64(test_int64, -2, "");
77DEFINE_uint64(test_uint64, 2, "");
78DEFINE_double(test_double, -1.0, "");
79DEFINE_string(test_string, "initial", "");
80
81//
82// The below ugliness gets some additional code coverage in the -helpxml
83// and -helpmatch test cases having to do with string lengths and formatting
84//
85DEFINE_bool(test_bool_with_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_quite_long_name,
86 false,
87 "extremely_extremely_extremely_extremely_extremely_extremely_extremely_extremely_long_meaning");
88
89DEFINE_string(test_str1, "initial", "");
90DEFINE_string(test_str2, "initial", "");
91DEFINE_string(test_str3, "initial", "");
92
93// This is used to test setting tryfromenv manually
94DEFINE_string(test_tryfromenv, "initial", "");
95
96// Don't try this at home!
97static int changeable_var = 12;
98DEFINE_int32(changeable_var, ++changeable_var, "");
99
100static int changeable_bool_var = 8008;
101DEFINE_bool(changeable_bool_var, ++changeable_bool_var == 8009, "");
102
103static int changeable_string_var = 0;
104static string ChangeableString() {
105 char r[] = {static_cast<char>('0' + ++changeable_string_var), '\0'};
106 return r;
107}
108DEFINE_string(changeable_string_var, ChangeableString(), "");
109
110// These are never used in this unittest, but can be used by
111// gflags_unittest.sh when it needs to specify flags
112// that are legal for gflags_unittest but don't need to
113// be a particular value.
114DEFINE_bool(unused_bool, true, "unused bool-ness");
115DEFINE_int32(unused_int32, -1001, "");
116DEFINE_int64(unused_int64, -2001, "");
117DEFINE_uint64(unused_uint64, 2000, "");
118DEFINE_double(unused_double, -1000.0, "");
119DEFINE_string(unused_string, "unused", "");
120
121// These flags are used by gflags_unittest.sh
122DEFINE_bool(changed_bool1, false, "changed");
123DEFINE_bool(changed_bool2, false, "changed");
124DEFINE_bool(long_helpstring, false,
125 "This helpstring goes on forever and ever and ever and ever and "
126 "ever and ever and ever and ever and ever and ever and ever and "
127 "ever and ever and ever and ever and ever and ever and ever and "
128 "ever and ever and ever and ever and ever and ever and ever and "
129 "ever and ever and ever and ever and ever and ever and ever and "
130 "ever and ever and ever and ever and ever and ever and ever and "
131 "ever and ever and ever and ever and ever and ever and ever and "
132 "ever and ever and ever and ever and ever and ever and ever and "
133 "ever and ever and ever and ever and ever and ever and ever and "
134 "ever and ever and ever and ever and ever and ever and ever and "
135 "ever. This is the end of a long helpstring");
136
137
138static bool AlwaysFail(const char* flag, bool value) { return value == false; }
139DEFINE_bool(always_fail, false, "will fail to validate when you set it");
140DEFINE_validator(always_fail, AlwaysFail);
141
142// See the comment by GetAllFlags in gflags.h
143static bool DeadlockIfCantLockInValidators(const char* flag, bool value) {
144 if (!value) {
145 return true;
146 }
147 vector<CommandLineFlagInfo> dummy;
148 GetAllFlags(&dummy);
149 return true;
150}
151DEFINE_bool(deadlock_if_cant_lock,
152 false,
153 "will deadlock if set to true and "
154 "if locking of registry in validators fails.");
155DEFINE_validator(deadlock_if_cant_lock, DeadlockIfCantLockInValidators);
156
157#define MAKEFLAG(x) DEFINE_int32(test_flag_num##x, x, "Test flag")
158
159// Define 10 flags
160#define MAKEFLAG10(x) \
161 MAKEFLAG(x##0); \
162 MAKEFLAG(x##1); \
163 MAKEFLAG(x##2); \
164 MAKEFLAG(x##3); \
165 MAKEFLAG(x##4); \
166 MAKEFLAG(x##5); \
167 MAKEFLAG(x##6); \
168 MAKEFLAG(x##7); \
169 MAKEFLAG(x##8); \
170 MAKEFLAG(x##9)
171
172// Define 100 flags
173#define MAKEFLAG100(x) \
174 MAKEFLAG10(x##0); \
175 MAKEFLAG10(x##1); \
176 MAKEFLAG10(x##2); \
177 MAKEFLAG10(x##3); \
178 MAKEFLAG10(x##4); \
179 MAKEFLAG10(x##5); \
180 MAKEFLAG10(x##6); \
181 MAKEFLAG10(x##7); \
182 MAKEFLAG10(x##8); \
183 MAKEFLAG10(x##9)
184
185// Define a bunch of command-line flags. Each occurrence of the MAKEFLAG100
186// macro defines 100 integer flags. This lets us test the effect of having
187// many flags on startup time.
188MAKEFLAG100(1);
189MAKEFLAG100(2);
190MAKEFLAG100(3);
191MAKEFLAG100(4);
192MAKEFLAG100(5);
193MAKEFLAG100(6);
194MAKEFLAG100(7);
195MAKEFLAG100(8);
196MAKEFLAG100(9);
197MAKEFLAG100(10);
198MAKEFLAG100(11);
199MAKEFLAG100(12);
200MAKEFLAG100(13);
201MAKEFLAG100(14);
202MAKEFLAG100(15);
203
204#undef MAKEFLAG100
205#undef MAKEFLAG10
206#undef MAKEFLAG
207
208// This is a pseudo-flag -- we want to register a flag with a filename
209// at the top level, but there is no way to do this except by faking
210// the filename.
211namespace fLI {
212 static const int32 FLAGS_nonotldflag1 = 12;
213 int32 FLAGS_tldflag1 = FLAGS_nonotldflag1;
214 int32 FLAGS_notldflag1 = FLAGS_nonotldflag1;
215 static FlagRegisterer o_tldflag1(
216 "tldflag1", "int32",
217 "should show up in --helpshort", "gflags_unittest.cc",
218 &FLAGS_tldflag1, &FLAGS_notldflag1);
219}
220using fLI::FLAGS_tldflag1;
221
222namespace fLI {
223 static const int32 FLAGS_nonotldflag2 = 23;
224 int32 FLAGS_tldflag2 = FLAGS_nonotldflag2;
225 int32 FLAGS_notldflag2 = FLAGS_nonotldflag2;
226 static FlagRegisterer o_tldflag2(
227 "tldflag2", "int32",
228 "should show up in --helpshort", "gflags_unittest.",
229 &FLAGS_tldflag2, &FLAGS_notldflag2);
230}
231using fLI::FLAGS_tldflag2;
232
233namespace GFLAGS_NAMESPACE {
234
235namespace {
236
237
238static string TmpFile(const string& basename) {
239#ifdef _MSC_VER
240 return FLAGS_test_tmpdir + "\\" + basename;
241#else
242 return FLAGS_test_tmpdir + "/" + basename;
243#endif
244}
245
246// Returns the definition of the --flagfile flag to be used in the tests.
247// Must be called after ParseCommandLineFlags().
248static const char* GetFlagFileFlag() {
249#ifdef _MSC_VER
250 static const string flagfile = FLAGS_srcdir + "\\gflags_unittest_flagfile";
251#else
252 static const string flagfile = FLAGS_srcdir + "/gflags_unittest_flagfile";
253#endif
254 static const string flagfile_flag = string("--flagfile=") + flagfile;
255 return flagfile_flag.c_str();
256}
257
258
259// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
260// compiler error iff T1 and T2 are different types.
261template <typename T1, typename T2>
262struct CompileAssertTypesEqual;
263
264template <typename T>
265struct CompileAssertTypesEqual<T, T> {
266};
267
268
269template <typename Expected, typename Actual>
270void AssertIsType(Actual& x) {
271 CompileAssertTypesEqual<Expected, Actual>();
272}
273
274// Verify all the flags are the right type.
275TEST(FlagTypes, FlagTypes) {
276 AssertIsType<bool>(FLAGS_test_bool);
277 AssertIsType<int32>(FLAGS_test_int32);
278 AssertIsType<int64>(FLAGS_test_int64);
279 AssertIsType<uint64>(FLAGS_test_uint64);
280 AssertIsType<double>(FLAGS_test_double);
281 AssertIsType<string>(FLAGS_test_string);
282}
283
284#ifdef GTEST_HAS_DEATH_TEST
285// Death tests for "help" options.
286//
287// The help system automatically calls gflags_exitfunc(1) when you specify any of
288// the help-related flags ("-helpmatch", "-helpxml") so we can't test
289// those mainline.
290
291// Tests that "-helpmatch" causes the process to die.
292TEST(ReadFlagsFromStringDeathTest, HelpMatch) {
293 EXPECT_DEATH(ReadFlagsFromString("-helpmatch=base", GetArgv0(), true),
294 "");
295}
296
297
298// Tests that "-helpxml" causes the process to die.
299TEST(ReadFlagsFromStringDeathTest, HelpXml) {
300 EXPECT_DEATH(ReadFlagsFromString("-helpxml", GetArgv0(), true),
301 "");
302}
303#endif
304
305
306// A subroutine needed for testing reading flags from a string.
307void TestFlagString(const string& flags,
308 const string& expected_string,
309 bool expected_bool,
310 int32 expected_int32,
311 double expected_double) {
312 EXPECT_TRUE(ReadFlagsFromString(flags,
313 GetArgv0(),
314 // errors are fatal
315 true));
316
317 EXPECT_EQ(expected_string, FLAGS_test_string);
318 EXPECT_EQ(expected_bool, FLAGS_test_bool);
319 EXPECT_EQ(expected_int32, FLAGS_test_int32);
320 EXPECT_DOUBLE_EQ(expected_double, FLAGS_test_double);
321}
322
323
324// Tests reading flags from a string.
325TEST(FlagFileTest, ReadFlagsFromString) {
326 TestFlagString(
327 // Flag string
328 "-test_string=continued\n"
329 "# some comments are in order\n"
330 "# some\n"
331 " # comments\n"
332 "#are\n"
333 " #trickier\n"
334 "# than others\n"
335 "-test_bool=true\n"
336 " -test_int32=1\n"
337 "-test_double=0.0\n",
338 // Expected values
339 "continued",
340 true,
341 1,
342 0.0);
343
344 TestFlagString(
345 // Flag string
346 "# let's make sure it can update values\n"
347 "-test_string=initial\n"
348 "-test_bool=false\n"
349 "-test_int32=123\n"
350 "-test_double=123.0\n",
351 // Expected values
352 "initial",
353 false,
354 123,
355 123.0);
356}
357
358// Tests the filename part of the flagfile
359TEST(FlagFileTest, FilenamesOurfileLast) {
360 FLAGS_test_string = "initial";
361 FLAGS_test_bool = false;
362 FLAGS_test_int32 = -1;
363 FLAGS_test_double = -1.0;
364 TestFlagString(
365 // Flag string
366 "-test_string=continued\n"
367 "# some comments are in order\n"
368 "# some\n"
369 " # comments\n"
370 "#are\n"
371 " #trickier\n"
372 "# than others\n"
373 "not_our_filename\n"
374 "-test_bool=true\n"
375 " -test_int32=1\n"
376 "gflags_unittest\n"
377 "-test_double=1000.0\n",
378 // Expected values
379 "continued",
380 false,
381 -1,
382 1000.0);
383}
384
385TEST(FlagFileTest, FilenamesOurfileFirst) {
386 FLAGS_test_string = "initial";
387 FLAGS_test_bool = false;
388 FLAGS_test_int32 = -1;
389 FLAGS_test_double = -1.0;
390 TestFlagString(
391 // Flag string
392 "-test_string=continued\n"
393 "# some comments are in order\n"
394 "# some\n"
395 " # comments\n"
396 "#are\n"
397 " #trickier\n"
398 "# than others\n"
399 "gflags_unittest\n"
400 "-test_bool=true\n"
401 " -test_int32=1\n"
402 "not_our_filename\n"
403 "-test_double=1000.0\n",
404 // Expected values
405 "continued",
406 true,
407 1,
408 -1.0);
409}
410
411#if defined(HAVE_FNMATCH_H) || defined(HAVE_SHLWAPI_H) // otherwise glob isn't supported
412TEST(FlagFileTest, FilenamesOurfileGlob) {
413 FLAGS_test_string = "initial";
414 FLAGS_test_bool = false;
415 FLAGS_test_int32 = -1;
416 FLAGS_test_double = -1.0;
417 TestFlagString(
418 // Flag string
419 "-test_string=continued\n"
420 "# some comments are in order\n"
421 "# some\n"
422 " # comments\n"
423 "#are\n"
424 " #trickier\n"
425 "# than others\n"
426 "*flags*\n"
427 "-test_bool=true\n"
428 " -test_int32=1\n"
429 "flags\n"
430 "-test_double=1000.0\n",
431 // Expected values
432 "continued",
433 true,
434 1,
435 -1.0);
436}
437
438TEST(FlagFileTest, FilenamesOurfileInBigList) {
439 FLAGS_test_string = "initial";
440 FLAGS_test_bool = false;
441 FLAGS_test_int32 = -1;
442 FLAGS_test_double = -1.0;
443 TestFlagString(
444 // Flag string
445 "-test_string=continued\n"
446 "# some comments are in order\n"
447 "# some\n"
448 " # comments\n"
449 "#are\n"
450 " #trickier\n"
451 "# than others\n"
452 "*first* *flags* *third*\n"
453 "-test_bool=true\n"
454 " -test_int32=1\n"
455 "flags\n"
456 "-test_double=1000.0\n",
457 // Expected values
458 "continued",
459 true,
460 1,
461 -1.0);
462}
463#endif // defined(HAVE_FNMATCH_H) || defined(HAVE_SHLWAPI_H)
464
465// Tests that a failed flag-from-string read keeps flags at default values
466TEST(FlagFileTest, FailReadFlagsFromString) {
467 FLAGS_test_int32 = 119;
468 string flags("# let's make sure it can update values\n"
469 "-test_string=non_initial\n"
470 "-test_bool=false\n"
471 "-test_int32=123\n"
472 "-test_double=illegal\n");
473
474 EXPECT_FALSE(ReadFlagsFromString(flags,
475 GetArgv0(),
476 // errors are fatal
477 false));
478
479 EXPECT_EQ(119, FLAGS_test_int32);
480 EXPECT_EQ("initial", FLAGS_test_string);
481}
482
483// Tests that flags can be set to ordinary values.
484TEST(SetFlagValueTest, OrdinaryValues) {
485 EXPECT_EQ("initial", FLAGS_test_str1);
486
487 SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
488 EXPECT_EQ("second", FLAGS_test_str1); // set; was default
489
490 SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
491 EXPECT_EQ("second", FLAGS_test_str1); // already set once
492
493 FLAGS_test_str1 = "initial";
494 SetCommandLineOptionWithMode("test_str1", "third", SET_FLAG_IF_DEFAULT);
495 EXPECT_EQ("initial", FLAGS_test_str1); // still already set before
496
497 SetCommandLineOptionWithMode("test_str1", "third", SET_FLAGS_VALUE);
498 EXPECT_EQ("third", FLAGS_test_str1); // changed value
499
500 SetCommandLineOptionWithMode("test_str1", "fourth", SET_FLAGS_DEFAULT);
501 EXPECT_EQ("third", FLAGS_test_str1);
502 // value not changed (already set before)
503
504 EXPECT_EQ("initial", FLAGS_test_str2);
505
506 SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_DEFAULT);
507 EXPECT_EQ("second", FLAGS_test_str2); // changed (was default)
508
509 FLAGS_test_str2 = "extra";
510 EXPECT_EQ("extra", FLAGS_test_str2);
511
512 FLAGS_test_str2 = "second";
513 SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
514 EXPECT_EQ("third", FLAGS_test_str2); // still changed (was equal to default)
515
516 SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
517 EXPECT_EQ("fourth", FLAGS_test_str2); // changed (was default)
518
519 EXPECT_EQ("initial", FLAGS_test_str3);
520
521 SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
522 EXPECT_EQ("second", FLAGS_test_str3); // changed
523
524 FLAGS_test_str3 = "third";
525 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_DEFAULT);
526 EXPECT_EQ("third", FLAGS_test_str3); // not changed (was set)
527
528 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
529 EXPECT_EQ("third", FLAGS_test_str3); // not changed (was set)
530
531 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAGS_VALUE);
532 EXPECT_EQ("fourth", FLAGS_test_str3); // changed value
533}
534
535
536// Tests that flags can be set to exceptional values.
537// Note: apparently MINGW doesn't parse inf and nan correctly:
538// http://www.mail-archive.com/bug-gnulib@gnu.org/msg09573.html
539// This url says FreeBSD also has a problem, but I didn't see that.
540TEST(SetFlagValueTest, ExceptionalValues) {
541#if defined(isinf) && !defined(__MINGW32__)
542 EXPECT_EQ("test_double set to inf\n",
543 SetCommandLineOption("test_double", "inf"));
544 EXPECT_INF(FLAGS_test_double);
545
546 EXPECT_EQ("test_double set to inf\n",
547 SetCommandLineOption("test_double", "INF"));
548 EXPECT_INF(FLAGS_test_double);
549#endif
550
551 // set some bad values
552 EXPECT_EQ("",
553 SetCommandLineOption("test_double", "0.1xxx"));
554 EXPECT_EQ("",
555 SetCommandLineOption("test_double", " "));
556 EXPECT_EQ("",
557 SetCommandLineOption("test_double", ""));
558#if defined(isinf) && !defined(__MINGW32__)
559 EXPECT_EQ("test_double set to -inf\n",
560 SetCommandLineOption("test_double", "-inf"));
561 EXPECT_INF(FLAGS_test_double);
562 EXPECT_GT(0, FLAGS_test_double);
563#endif
564
565#if defined(isnan) && !defined(__MINGW32__)
566 EXPECT_EQ("test_double set to nan\n",
567 SetCommandLineOption("test_double", "NaN"));
568 EXPECT_NAN(FLAGS_test_double);
569#endif
570}
571
572// Tests that integer flags can be specified in many ways
573TEST(SetFlagValueTest, DifferentRadices) {
574 EXPECT_EQ("test_int32 set to 12\n",
575 SetCommandLineOption("test_int32", "12"));
576
577 EXPECT_EQ("test_int32 set to 16\n",
578 SetCommandLineOption("test_int32", "0x10"));
579
580 EXPECT_EQ("test_int32 set to 34\n",
581 SetCommandLineOption("test_int32", "0X22"));
582
583 // Leading 0 is *not* octal; it's still decimal
584 EXPECT_EQ("test_int32 set to 10\n",
585 SetCommandLineOption("test_int32", "010"));
586}
587
588// Tests what happens when you try to set a flag to an illegal value
589TEST(SetFlagValueTest, IllegalValues) {
590 FLAGS_test_bool = true;
591 FLAGS_test_int32 = 119;
592 FLAGS_test_int64 = 1191;
593 FLAGS_test_uint64 = 11911;
594
595 EXPECT_EQ("",
596 SetCommandLineOption("test_bool", "12"));
597
598 EXPECT_EQ("",
599 SetCommandLineOption("test_int32", "7000000000000"));
600
601 EXPECT_EQ("",
602 SetCommandLineOption("test_uint64", "-1"));
603
604 EXPECT_EQ("",
605 SetCommandLineOption("test_int64", "not a number!"));
606
607 // Test the empty string with each type of input
608 EXPECT_EQ("", SetCommandLineOption("test_bool", ""));
609 EXPECT_EQ("", SetCommandLineOption("test_int32", ""));
610 EXPECT_EQ("", SetCommandLineOption("test_int64", ""));
611 EXPECT_EQ("", SetCommandLineOption("test_uint64", ""));
612 EXPECT_EQ("", SetCommandLineOption("test_double", ""));
613 EXPECT_EQ("test_string set to \n", SetCommandLineOption("test_string", ""));
614
615 EXPECT_TRUE(FLAGS_test_bool);
616 EXPECT_EQ(119, FLAGS_test_int32);
617 EXPECT_EQ(1191, FLAGS_test_int64);
618 EXPECT_EQ(11911, FLAGS_test_uint64);
619}
620
621
622// Tests that we only evaluate macro args once
623TEST(MacroArgs, EvaluateOnce) {
624 EXPECT_EQ(13, FLAGS_changeable_var);
625 // Make sure we don't ++ the value somehow, when evaluating the flag.
626 EXPECT_EQ(13, FLAGS_changeable_var);
627 // Make sure the macro only evaluated this var once.
628 EXPECT_EQ(13, changeable_var);
629 // Make sure the actual value and default value are the same
630 SetCommandLineOptionWithMode("changeable_var", "21", SET_FLAG_IF_DEFAULT);
631 EXPECT_EQ(21, FLAGS_changeable_var);
632}
633
634TEST(MacroArgs, EvaluateOnceBool) {
635 EXPECT_TRUE(FLAGS_changeable_bool_var);
636 EXPECT_TRUE(FLAGS_changeable_bool_var);
637 EXPECT_EQ(8009, changeable_bool_var);
638 SetCommandLineOptionWithMode("changeable_bool_var", "false",
639 SET_FLAG_IF_DEFAULT);
640 EXPECT_FALSE(FLAGS_changeable_bool_var);
641}
642
643TEST(MacroArgs, EvaluateOnceStrings) {
644 EXPECT_EQ("1", FLAGS_changeable_string_var);
645 EXPECT_EQ("1", FLAGS_changeable_string_var);
646 EXPECT_EQ(1, changeable_string_var);
647 SetCommandLineOptionWithMode("changeable_string_var", "different",
648 SET_FLAG_IF_DEFAULT);
649 EXPECT_EQ("different", FLAGS_changeable_string_var);
650}
651
652// Tests that the FooFromEnv does the right thing
653TEST(FromEnvTest, LegalValues) {
654 setenv("BOOL_VAL1", "true", 1);
655 setenv("BOOL_VAL2", "false", 1);
656 setenv("BOOL_VAL3", "1", 1);
657 setenv("BOOL_VAL4", "F", 1);
658 EXPECT_TRUE(BoolFromEnv("BOOL_VAL1", false));
659 EXPECT_FALSE(BoolFromEnv("BOOL_VAL2", true));
660 EXPECT_TRUE(BoolFromEnv("BOOL_VAL3", false));
661 EXPECT_FALSE(BoolFromEnv("BOOL_VAL4", true));
662 EXPECT_TRUE(BoolFromEnv("BOOL_VAL_UNKNOWN", true));
663 EXPECT_FALSE(BoolFromEnv("BOOL_VAL_UNKNOWN", false));
664
665 setenv("INT_VAL1", "1", 1);
666 setenv("INT_VAL2", "-1", 1);
667 EXPECT_EQ(1, Int32FromEnv("INT_VAL1", 10));
668 EXPECT_EQ(-1, Int32FromEnv("INT_VAL2", 10));
669 EXPECT_EQ(10, Int32FromEnv("INT_VAL_UNKNOWN", 10));
670
671 setenv("INT_VAL3", "1099511627776", 1);
672 EXPECT_EQ(1, Int64FromEnv("INT_VAL1", 20));
673 EXPECT_EQ(-1, Int64FromEnv("INT_VAL2", 20));
674 EXPECT_EQ(1099511627776LL, Int64FromEnv("INT_VAL3", 20));
675 EXPECT_EQ(20, Int64FromEnv("INT_VAL_UNKNOWN", 20));
676
677 EXPECT_EQ(1, Uint64FromEnv("INT_VAL1", 30));
678 EXPECT_EQ(1099511627776ULL, Uint64FromEnv("INT_VAL3", 30));
679 EXPECT_EQ(30, Uint64FromEnv("INT_VAL_UNKNOWN", 30));
680
681 // I pick values here that can be easily represented exactly in floating-point
682 setenv("DOUBLE_VAL1", "0.0", 1);
683 setenv("DOUBLE_VAL2", "1.0", 1);
684 setenv("DOUBLE_VAL3", "-1.0", 1);
685 EXPECT_EQ(0.0, DoubleFromEnv("DOUBLE_VAL1", 40.0));
686 EXPECT_EQ(1.0, DoubleFromEnv("DOUBLE_VAL2", 40.0));
687 EXPECT_EQ(-1.0, DoubleFromEnv("DOUBLE_VAL3", 40.0));
688 EXPECT_EQ(40.0, DoubleFromEnv("DOUBLE_VAL_UNKNOWN", 40.0));
689
690 setenv("STRING_VAL1", "", 1);
691 setenv("STRING_VAL2", "my happy string!", 1);
692 EXPECT_STREQ("", StringFromEnv("STRING_VAL1", "unknown"));
693 EXPECT_STREQ("my happy string!", StringFromEnv("STRING_VAL2", "unknown"));
694 EXPECT_STREQ("unknown", StringFromEnv("STRING_VAL_UNKNOWN", "unknown"));
695}
696
697#ifdef GTEST_HAS_DEATH_TEST
698// Tests that the FooFromEnv dies on parse-error
699TEST(FromEnvDeathTest, IllegalValues) {
700 setenv("BOOL_BAD1", "so true!", 1);
701 setenv("BOOL_BAD2", "", 1);
702 EXPECT_DEATH(BoolFromEnv("BOOL_BAD1", false), "error parsing env variable");
703 EXPECT_DEATH(BoolFromEnv("BOOL_BAD2", true), "error parsing env variable");
704
705 setenv("INT_BAD1", "one", 1);
706 setenv("INT_BAD2", "100000000000000000", 1);
707 setenv("INT_BAD3", "0xx10", 1);
708 setenv("INT_BAD4", "", 1);
709 EXPECT_DEATH(Int32FromEnv("INT_BAD1", 10), "error parsing env variable");
710 EXPECT_DEATH(Int32FromEnv("INT_BAD2", 10), "error parsing env variable");
711 EXPECT_DEATH(Int32FromEnv("INT_BAD3", 10), "error parsing env variable");
712 EXPECT_DEATH(Int32FromEnv("INT_BAD4", 10), "error parsing env variable");
713
714 setenv("BIGINT_BAD1", "18446744073709551616000", 1);
715 EXPECT_DEATH(Int64FromEnv("INT_BAD1", 20), "error parsing env variable");
716 EXPECT_DEATH(Int64FromEnv("INT_BAD3", 20), "error parsing env variable");
717 EXPECT_DEATH(Int64FromEnv("INT_BAD4", 20), "error parsing env variable");
718 EXPECT_DEATH(Int64FromEnv("BIGINT_BAD1", 200), "error parsing env variable");
719
720 setenv("BIGINT_BAD2", "-1", 1);
721 EXPECT_DEATH(Uint64FromEnv("INT_BAD1", 30), "error parsing env variable");
722 EXPECT_DEATH(Uint64FromEnv("INT_BAD3", 30), "error parsing env variable");
723 EXPECT_DEATH(Uint64FromEnv("INT_BAD4", 30), "error parsing env variable");
724 EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD1", 30), "error parsing env variable");
725 // TODO(csilvers): uncomment this when we disallow negative numbers for uint64
726#if 0
727 EXPECT_DEATH(Uint64FromEnv("BIGINT_BAD2", 30), "error parsing env variable");
728#endif
729
730 setenv("DOUBLE_BAD1", "0.0.0", 1);
731 setenv("DOUBLE_BAD2", "", 1);
732 EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD1", 40.0), "error parsing env variable");
733 EXPECT_DEATH(DoubleFromEnv("DOUBLE_BAD2", 40.0), "error parsing env variable");
734}
735#endif
736
737
738// Tests that FlagSaver can save the states of string flags.
739TEST(FlagSaverTest, CanSaveStringFlagStates) {
740 // 1. Initializes the flags.
741
742 // State of flag test_str1:
743 // default value - "initial"
744 // current value - "initial"
745 // not set - true
746
747 SetCommandLineOptionWithMode("test_str2", "second", SET_FLAGS_VALUE);
748 // State of flag test_str2:
749 // default value - "initial"
750 // current value - "second"
751 // not set - false
752
753 SetCommandLineOptionWithMode("test_str3", "second", SET_FLAGS_DEFAULT);
754 // State of flag test_str3:
755 // default value - "second"
756 // current value - "second"
757 // not set - true
758
759 // 2. Saves the flag states.
760
761 {
762 FlagSaver fs;
763
764 // 3. Modifies the flag states.
765
766 SetCommandLineOptionWithMode("test_str1", "second", SET_FLAGS_VALUE);
767 EXPECT_EQ("second", FLAGS_test_str1);
768 // State of flag test_str1:
769 // default value - "second"
770 // current value - "second"
771 // not set - true
772
773 SetCommandLineOptionWithMode("test_str2", "third", SET_FLAGS_DEFAULT);
774 EXPECT_EQ("second", FLAGS_test_str2);
775 // State of flag test_str2:
776 // default value - "third"
777 // current value - "second"
778 // not set - false
779
780 SetCommandLineOptionWithMode("test_str3", "third", SET_FLAGS_VALUE);
781 EXPECT_EQ("third", FLAGS_test_str3);
782 // State of flag test_str1:
783 // default value - "second"
784 // current value - "third"
785 // not set - false
786
787 // 4. Restores the flag states.
788 }
789
790 // 5. Verifies that the states were restored.
791
792 // Verifies that the value of test_str1 was restored.
793 EXPECT_EQ("initial", FLAGS_test_str1);
794 // Verifies that the "not set" attribute of test_str1 was restored to true.
795 SetCommandLineOptionWithMode("test_str1", "second", SET_FLAG_IF_DEFAULT);
796 EXPECT_EQ("second", FLAGS_test_str1);
797
798 // Verifies that the value of test_str2 was restored.
799 EXPECT_EQ("second", FLAGS_test_str2);
800 // Verifies that the "not set" attribute of test_str2 was restored to false.
801 SetCommandLineOptionWithMode("test_str2", "fourth", SET_FLAG_IF_DEFAULT);
802 EXPECT_EQ("second", FLAGS_test_str2);
803
804 // Verifies that the value of test_str3 was restored.
805 EXPECT_EQ("second", FLAGS_test_str3);
806 // Verifies that the "not set" attribute of test_str3 was restored to true.
807 SetCommandLineOptionWithMode("test_str3", "fourth", SET_FLAG_IF_DEFAULT);
808 EXPECT_EQ("fourth", FLAGS_test_str3);
809}
810
811
812// Tests that FlagSaver can save the values of various-typed flags.
813TEST(FlagSaverTest, CanSaveVariousTypedFlagValues) {
814 // Initializes the flags.
815 FLAGS_test_bool = false;
816 FLAGS_test_int32 = -1;
817 FLAGS_test_int64 = -2;
818 FLAGS_test_uint64 = 3;
819 FLAGS_test_double = 4.0;
820 FLAGS_test_string = "good";
821
822 // Saves the flag states.
823 {
824 FlagSaver fs;
825
826 // Modifies the flags.
827 FLAGS_test_bool = true;
828 FLAGS_test_int32 = -5;
829 FLAGS_test_int64 = -6;
830 FLAGS_test_uint64 = 7;
831 FLAGS_test_double = 8.0;
832 FLAGS_test_string = "bad";
833
834 // Restores the flag states.
835 }
836
837 // Verifies the flag values were restored.
838 EXPECT_FALSE(FLAGS_test_bool);
839 EXPECT_EQ(-1, FLAGS_test_int32);
840 EXPECT_EQ(-2, FLAGS_test_int64);
841 EXPECT_EQ(3, FLAGS_test_uint64);
842 EXPECT_DOUBLE_EQ(4.0, FLAGS_test_double);
843 EXPECT_EQ("good", FLAGS_test_string);
844}
845
846TEST(GetAllFlagsTest, BaseTest) {
847 vector<CommandLineFlagInfo> flags;
848 GetAllFlags(&flags);
849 bool found_test_bool = false;
850 vector<CommandLineFlagInfo>::const_iterator i;
851 for (i = flags.begin(); i != flags.end(); ++i) {
852 if (i->name == "test_bool") {
853 found_test_bool = true;
854 EXPECT_EQ(i->type, "bool");
855 EXPECT_EQ(i->default_value, "false");
856 EXPECT_EQ(i->flag_ptr, &FLAGS_test_bool);
857 break;
858 }
859 }
860 EXPECT_TRUE(found_test_bool);
861}
862
863TEST(ShowUsageWithFlagsTest, BaseTest) {
864 // TODO(csilvers): test this by allowing output other than to stdout.
865 // Not urgent since this functionality is tested via
866 // gflags_unittest.sh, though only through use of --help.
867}
868
869TEST(ShowUsageWithFlagsRestrictTest, BaseTest) {
870 // TODO(csilvers): test this by allowing output other than to stdout.
871 // Not urgent since this functionality is tested via
872 // gflags_unittest.sh, though only through use of --helpmatch.
873}
874
875// Note: all these argv-based tests depend on SetArgv being called
876// before ParseCommandLineFlags() in main(), below.
877TEST(GetArgvsTest, BaseTest) {
878 vector<string> argvs = GetArgvs();
879 EXPECT_EQ(4, argvs.size());
880 EXPECT_EQ("/test/argv/for/gflags_unittest", argvs[0]);
881 EXPECT_EQ("argv 2", argvs[1]);
882 EXPECT_EQ("3rd argv", argvs[2]);
883 EXPECT_EQ("argv #4", argvs[3]);
884}
885
886TEST(GetArgvTest, BaseTest) {
887 EXPECT_STREQ("/test/argv/for/gflags_unittest "
888 "argv 2 3rd argv argv #4", GetArgv());
889}
890
891TEST(GetArgv0Test, BaseTest) {
892 EXPECT_STREQ("/test/argv/for/gflags_unittest", GetArgv0());
893}
894
895TEST(GetArgvSumTest, BaseTest) {
896 // This number is just the sum of the ASCII values of all the chars
897 // in GetArgv().
898 EXPECT_EQ(4904, GetArgvSum());
899}
900
901TEST(ProgramInvocationNameTest, BaseTest) {
902 EXPECT_STREQ("/test/argv/for/gflags_unittest",
903 ProgramInvocationName());
904}
905
906TEST(ProgramInvocationShortNameTest, BaseTest) {
907 EXPECT_STREQ("gflags_unittest", ProgramInvocationShortName());
908}
909
910TEST(ProgramUsageTest, BaseTest) { // Depends on 1st arg to ParseCommandLineFlags()
911 EXPECT_STREQ("/test/argv/for/gflags_unittest: "
912 "<useless flag> [...]\nDoes something useless.\n",
913 ProgramUsage());
914}
915
916TEST(GetCommandLineOptionTest, NameExistsAndIsDefault) {
917 string value("will be changed");
918 bool r = GetCommandLineOption("test_bool", &value);
919 EXPECT_TRUE(r);
920 EXPECT_EQ("false", value);
921
922 r = GetCommandLineOption("test_int32", &value);
923 EXPECT_TRUE(r);
924 EXPECT_EQ("-1", value);
925}
926
927TEST(GetCommandLineOptionTest, NameExistsAndWasAssigned) {
928 FLAGS_test_int32 = 400;
929 string value("will be changed");
930 const bool r = GetCommandLineOption("test_int32", &value);
931 EXPECT_TRUE(r);
932 EXPECT_EQ("400", value);
933}
934
935TEST(GetCommandLineOptionTest, NameExistsAndWasSet) {
936 SetCommandLineOption("test_int32", "700");
937 string value("will be changed");
938 const bool r = GetCommandLineOption("test_int32", &value);
939 EXPECT_TRUE(r);
940 EXPECT_EQ("700", value);
941}
942
943TEST(GetCommandLineOptionTest, NameExistsAndWasNotSet) {
944 // This doesn't set the flag's value, but rather its default value.
945 // is_default is still true, but the 'default' value returned has changed!
946 SetCommandLineOptionWithMode("test_int32", "800", SET_FLAGS_DEFAULT);
947 string value("will be changed");
948 const bool r = GetCommandLineOption("test_int32", &value);
949 EXPECT_TRUE(r);
950 EXPECT_EQ("800", value);
951 EXPECT_TRUE(GetCommandLineFlagInfoOrDie("test_int32").is_default);
952}
953
954TEST(GetCommandLineOptionTest, NameExistsAndWasConditionallySet) {
955 SetCommandLineOptionWithMode("test_int32", "900", SET_FLAG_IF_DEFAULT);
956 string value("will be changed");
957 const bool r = GetCommandLineOption("test_int32", &value);
958 EXPECT_TRUE(r);
959 EXPECT_EQ("900", value);
960}
961
962TEST(GetCommandLineOptionTest, NameDoesNotExist) {
963 string value("will not be changed");
964 const bool r = GetCommandLineOption("test_int3210", &value);
965 EXPECT_FALSE(r);
966 EXPECT_EQ("will not be changed", value);
967}
968
969TEST(GetCommandLineFlagInfoTest, FlagExists) {
970 CommandLineFlagInfo info;
971 bool r = GetCommandLineFlagInfo("test_int32", &info);
972 EXPECT_TRUE(r);
973 EXPECT_EQ("test_int32", info.name);
974 EXPECT_EQ("int32", info.type);
975 EXPECT_EQ("", info.description);
976 EXPECT_EQ("-1", info.current_value);
977 EXPECT_EQ("-1", info.default_value);
978 EXPECT_TRUE(info.is_default);
979 EXPECT_FALSE(info.has_validator_fn);
980 EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
981
982 FLAGS_test_bool = true;
983 r = GetCommandLineFlagInfo("test_bool", &info);
984 EXPECT_TRUE(r);
985 EXPECT_EQ("test_bool", info.name);
986 EXPECT_EQ("bool", info.type);
987 EXPECT_EQ("tests bool-ness", info.description);
988 EXPECT_EQ("true", info.current_value);
989 EXPECT_EQ("false", info.default_value);
990 EXPECT_FALSE(info.is_default);
991 EXPECT_FALSE(info.has_validator_fn);
992 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
993
994 FLAGS_test_bool = false;
995 r = GetCommandLineFlagInfo("test_bool", &info);
996 EXPECT_TRUE(r);
997 EXPECT_EQ("test_bool", info.name);
998 EXPECT_EQ("bool", info.type);
999 EXPECT_EQ("tests bool-ness", info.description);
1000 EXPECT_EQ("false", info.current_value);
1001 EXPECT_EQ("false", info.default_value);
1002 EXPECT_FALSE(info.is_default); // value is same, but flag *was* modified
1003 EXPECT_FALSE(info.has_validator_fn);
1004 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
1005}
1006
1007TEST(GetCommandLineFlagInfoTest, FlagDoesNotExist) {
1008 CommandLineFlagInfo info;
1009 // Set to some random values that GetCommandLineFlagInfo should not change
1010 info.name = "name";
1011 info.type = "type";
1012 info.current_value = "curr";
1013 info.default_value = "def";
1014 info.filename = "/";
1015 info.is_default = false;
1016 info.has_validator_fn = true;
1017 info.flag_ptr = NULL;
1018 bool r = GetCommandLineFlagInfo("test_int3210", &info);
1019 EXPECT_FALSE(r);
1020 EXPECT_EQ("name", info.name);
1021 EXPECT_EQ("type", info.type);
1022 EXPECT_EQ("", info.description);
1023 EXPECT_EQ("curr", info.current_value);
1024 EXPECT_EQ("def", info.default_value);
1025 EXPECT_EQ("/", info.filename);
1026 EXPECT_FALSE(info.is_default);
1027 EXPECT_TRUE(info.has_validator_fn);
1028 EXPECT_EQ(NULL, info.flag_ptr);
1029}
1030
1031TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndIsDefault) {
1032 CommandLineFlagInfo info;
1033 info = GetCommandLineFlagInfoOrDie("test_int32");
1034 EXPECT_EQ("test_int32", info.name);
1035 EXPECT_EQ("int32", info.type);
1036 EXPECT_EQ("", info.description);
1037 EXPECT_EQ("-1", info.current_value);
1038 EXPECT_EQ("-1", info.default_value);
1039 EXPECT_TRUE(info.is_default);
1040 EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
1041 info = GetCommandLineFlagInfoOrDie("test_bool");
1042 EXPECT_EQ("test_bool", info.name);
1043 EXPECT_EQ("bool", info.type);
1044 EXPECT_EQ("tests bool-ness", info.description);
1045 EXPECT_EQ("false", info.current_value);
1046 EXPECT_EQ("false", info.default_value);
1047 EXPECT_TRUE(info.is_default);
1048 EXPECT_FALSE(info.has_validator_fn);
1049 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
1050}
1051
1052TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndWasAssigned) {
1053 FLAGS_test_int32 = 400;
1054 CommandLineFlagInfo info;
1055 info = GetCommandLineFlagInfoOrDie("test_int32");
1056 EXPECT_EQ("test_int32", info.name);
1057 EXPECT_EQ("int32", info.type);
1058 EXPECT_EQ("", info.description);
1059 EXPECT_EQ("400", info.current_value);
1060 EXPECT_EQ("-1", info.default_value);
1061 EXPECT_FALSE(info.is_default);
1062 EXPECT_EQ(&FLAGS_test_int32, info.flag_ptr);
1063 FLAGS_test_bool = true;
1064 info = GetCommandLineFlagInfoOrDie("test_bool");
1065 EXPECT_EQ("test_bool", info.name);
1066 EXPECT_EQ("bool", info.type);
1067 EXPECT_EQ("tests bool-ness", info.description);
1068 EXPECT_EQ("true", info.current_value);
1069 EXPECT_EQ("false", info.default_value);
1070 EXPECT_FALSE(info.is_default);
1071 EXPECT_FALSE(info.has_validator_fn);
1072 EXPECT_EQ(&FLAGS_test_bool, info.flag_ptr);
1073}
1074
1075#ifdef GTEST_HAS_DEATH_TEST
1076TEST(GetCommandLineFlagInfoOrDieDeathTest, FlagDoesNotExist) {
1077 EXPECT_DEATH(GetCommandLineFlagInfoOrDie("test_int3210"),
1078 ".*: flag test_int3210 does not exist");
1079}
1080#endif
1081
1082
1083// These are lightly tested because they're deprecated. Basically,
1084// the tests are meant to cover how existing users use these functions,
1085// but not necessarily how new users could use them.
1086TEST(DeprecatedFunctionsTest, CommandlineFlagsIntoString) {
1087 string s = CommandlineFlagsIntoString();
1088 EXPECT_NE(string::npos, s.find("--test_bool="));
1089}
1090
1091TEST(DeprecatedFunctionsTest, AppendFlagsIntoFile) {
1092 FLAGS_test_int32 = 10; // just to make the test more interesting
1093 string filename(TmpFile("flagfile"));
1094 unlink(filename.c_str()); // just to be safe
1095 const bool r = AppendFlagsIntoFile(filename, "not the real argv0");
1096 EXPECT_TRUE(r);
1097
1098 FILE* fp;
1099 EXPECT_EQ(0, SafeFOpen(&fp, filename.c_str(), "r"));
1100 EXPECT_TRUE(fp != NULL);
1101 char line[8192];
1102 EXPECT_TRUE(fgets(line, sizeof(line)-1, fp) != NULL); // get the first line
1103 // First line should be progname.
1104 EXPECT_STREQ("not the real argv0\n", line);
1105
1106 bool found_bool = false, found_int32 = false;
1107 while (fgets(line, sizeof(line)-1, fp)) {
1108 line[sizeof(line)-1] = '\0'; // just to be safe
1109 if (strcmp(line, "--test_bool=false\n") == 0)
1110 found_bool = true;
1111 if (strcmp(line, "--test_int32=10\n") == 0)
1112 found_int32 = true;
1113 }
1114 EXPECT_TRUE(found_int32);
1115 EXPECT_TRUE(found_bool);
1116 fclose(fp);
1117}
1118
1119TEST(DeprecatedFunctionsTest, ReadFromFlagsFile) {
1120 FLAGS_test_int32 = -10; // just to make the test more interesting
1121 string filename(TmpFile("flagfile2"));
1122 unlink(filename.c_str()); // just to be safe
1123 bool r = AppendFlagsIntoFile(filename, GetArgv0());
1124 EXPECT_TRUE(r);
1125
1126 FLAGS_test_int32 = -11;
1127 r = ReadFromFlagsFile(filename, GetArgv0(), true);
1128 EXPECT_TRUE(r);
1129 EXPECT_EQ(-10, FLAGS_test_int32);
1130} // unnamed namespace
1131
1132TEST(DeprecatedFunctionsTest, ReadFromFlagsFileFailure) {
1133 FLAGS_test_int32 = -20;
1134 string filename(TmpFile("flagfile3"));
1135 FILE* fp;
1136 EXPECT_EQ(0, SafeFOpen(&fp, filename.c_str(), "w"));
1137 EXPECT_TRUE(fp != NULL);
1138 // Note the error in the bool assignment below...
1139 fprintf(fp, "%s\n--test_int32=-21\n--test_bool=not_a_bool!\n", GetArgv0());
1140 fclose(fp);
1141
1142 FLAGS_test_int32 = -22;
1143 const bool r = ReadFromFlagsFile(filename, GetArgv0(), false);
1144 EXPECT_FALSE(r);
1145 EXPECT_EQ(-22, FLAGS_test_int32); // the -21 from the flagsfile didn't take
1146}
1147
1148TEST(FlagsSetBeforeInitTest, TryFromEnv) {
1149 EXPECT_EQ("pre-set", FLAGS_test_tryfromenv);
1150}
1151
1152// The following test case verifies that ParseCommandLineFlags() and
1153// ParseCommandLineNonHelpFlags() uses the last definition of a flag
1154// in case it's defined more than once.
1155
1156DEFINE_int32(test_flag, -1, "used for testing gflags.cc");
1157
1158// Parses and returns the --test_flag flag.
1159// If with_help is true, calls ParseCommandLineFlags; otherwise calls
1160// ParseCommandLineNonHelpFlags.
1161int32 ParseTestFlag(bool with_help, int argc, const char** const_argv) {
1162 FlagSaver fs; // Restores the flags before returning.
1163
1164 // Makes a copy of the input array s.t. it can be reused
1165 // (ParseCommandLineFlags() will alter the array).
1166 char** const argv_save = new char*[argc + 1];
1167 char** argv = argv_save;
1168 memcpy(argv, const_argv, sizeof(*argv)*(argc + 1));
1169
1170 if (with_help) {
1171 ParseCommandLineFlags(&argc, &argv, true);
1172 } else {
1173 ParseCommandLineNonHelpFlags(&argc, &argv, true);
1174 }
1175
1176 delete[] argv_save;
1177 return FLAGS_test_flag;
1178}
1179
1180TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1181 WhenFlagIsDefinedTwiceOnCommandLine) {
1182 const char* argv[] = {
1183 "my_test",
1184 "--test_flag=1",
1185 "--test_flag=2",
1186 NULL,
1187 };
1188
1189 EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
1190 EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
1191}
1192
1193TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1194 WhenFlagIsDefinedTwiceInFlagFile) {
1195 const char* argv[] = {
1196 "my_test",
1197 GetFlagFileFlag(),
1198 NULL,
1199 };
1200
1201 EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
1202 EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
1203}
1204
1205TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1206 WhenFlagIsDefinedInCommandLineAndThenFlagFile) {
1207 const char* argv[] = {
1208 "my_test",
1209 "--test_flag=0",
1210 GetFlagFileFlag(),
1211 NULL,
1212 };
1213
1214 EXPECT_EQ(2, ParseTestFlag(true, arraysize(argv) - 1, argv));
1215 EXPECT_EQ(2, ParseTestFlag(false, arraysize(argv) - 1, argv));
1216}
1217
1218TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1219 WhenFlagIsDefinedInFlagFileAndThenCommandLine) {
1220 const char* argv[] = {
1221 "my_test",
1222 GetFlagFileFlag(),
1223 "--test_flag=3",
1224 NULL,
1225 };
1226
1227 EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
1228 EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
1229}
1230
1231TEST(ParseCommandLineFlagsUsesLastDefinitionTest,
1232 WhenFlagIsDefinedInCommandLineAndFlagFileAndThenCommandLine) {
1233 const char* argv[] = {
1234 "my_test",
1235 "--test_flag=0",
1236 GetFlagFileFlag(),
1237 "--test_flag=3",
1238 NULL,
1239 };
1240
1241 EXPECT_EQ(3, ParseTestFlag(true, arraysize(argv) - 1, argv));
1242 EXPECT_EQ(3, ParseTestFlag(false, arraysize(argv) - 1, argv));
1243}
1244
1245TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgFirst) {
1246 const char* argv[] = {
1247 "my_test",
1248 "--",
1249 "--test_flag=0",
1250 NULL,
1251 };
1252
1253 EXPECT_EQ(-1, ParseTestFlag(true, arraysize(argv) - 1, argv));
1254 EXPECT_EQ(-1, ParseTestFlag(false, arraysize(argv) - 1, argv));
1255}
1256
1257TEST(ParseCommandLineFlagsAndDashArgs, TwoDashArgMiddle) {
1258 const char* argv[] = {
1259 "my_test",
1260 "--test_flag=7",
1261 "--",
1262 "--test_flag=0",
1263 NULL,
1264 };
1265
1266 EXPECT_EQ(7, ParseTestFlag(true, arraysize(argv) - 1, argv));
1267 EXPECT_EQ(7, ParseTestFlag(false, arraysize(argv) - 1, argv));
1268}
1269
1270TEST(ParseCommandLineFlagsAndDashArgs, OneDashArg) {
1271 const char* argv[] = {
1272 "my_test",
1273 "-",
1274 "--test_flag=0",
1275 NULL,
1276 };
1277
1278 EXPECT_EQ(0, ParseTestFlag(true, arraysize(argv) - 1, argv));
1279 EXPECT_EQ(0, ParseTestFlag(false, arraysize(argv) - 1, argv));
1280}
1281
1282#ifdef GTEST_HAS_DEATH_TEST
1283TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
1284 FlagIsCompletelyUnknown) {
1285 const char* argv[] = {
1286 "my_test",
1287 "--this_flag_does_not_exist",
1288 NULL,
1289 };
1290
1291 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
1292 "unknown command line flag.*");
1293 EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
1294 "unknown command line flag.*");
1295}
1296
1297TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
1298 BoolFlagIsCompletelyUnknown) {
1299 const char* argv[] = {
1300 "my_test",
1301 "--nothis_flag_does_not_exist",
1302 NULL,
1303 };
1304
1305 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
1306 "unknown command line flag.*");
1307 EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
1308 "unknown command line flag.*");
1309}
1310
1311TEST(ParseCommandLineFlagsUnknownFlagDeathTest,
1312 FlagIsNotABool) {
1313 const char* argv[] = {
1314 "my_test",
1315 "--notest_string",
1316 NULL,
1317 };
1318
1319 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
1320 "boolean value .* specified for .* command line flag");
1321 EXPECT_DEATH(ParseTestFlag(false, arraysize(argv) - 1, argv),
1322 "boolean value .* specified for .* command line flag");
1323}
1324#endif
1325
1326TEST(ParseCommandLineFlagsWrongFields,
1327 DescriptionIsInvalid) {
1328 // These must not be automatic variables, since command line flags
1329 // aren't unregistered and gUnit uses FlagSaver to save and restore
1330 // command line flags' values. If these are on the stack, then when
1331 // later tests attempt to save and restore their values, the stack
1332 // addresses of these variables will be overwritten... Stack smash!
1333 static bool current_storage;
1334 static bool defvalue_storage;
1335 FlagRegisterer fr("flag_name", "bool", 0, "filename",
1336 &current_storage, &defvalue_storage);
1337 CommandLineFlagInfo fi;
1338 EXPECT_TRUE(GetCommandLineFlagInfo("flag_name", &fi));
1339 EXPECT_EQ("", fi.description);
1340 EXPECT_EQ(&current_storage, fi.flag_ptr);
1341}
1342
1343static bool ValidateTestFlagIs5(const char* flagname, int32 flagval) {
1344 if (flagval == 5)
1345 return true;
1346 printf("%s isn't 5!\n", flagname);
1347 return false;
1348}
1349
1350static bool ValidateTestFlagIs10(const char* flagname, int32 flagval) {
1351 return flagval == 10;
1352}
1353
1354
1355TEST(FlagsValidator, ValidFlagViaArgv) {
1356 const char* argv[] = {
1357 "my_test",
1358 "--test_flag=5",
1359 NULL,
1360 };
1361 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1362 EXPECT_EQ(5, ParseTestFlag(true, arraysize(argv) - 1, argv));
1363 // Undo the flag validator setting
1364 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1365}
1366
1367TEST(FlagsValidator, ValidFlagViaSetDefault) {
1368 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1369 // SetCommandLineOptionWithMode returns the empty string on error.
1370 EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
1371 SET_FLAG_IF_DEFAULT));
1372 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1373}
1374
1375TEST(FlagsValidator, ValidFlagViaSetValue) {
1376 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1377 FLAGS_test_flag = 100; // doesn't trigger the validator
1378 // SetCommandLineOptionWithMode returns the empty string on error.
1379 EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
1380 SET_FLAGS_VALUE));
1381 EXPECT_NE("", SetCommandLineOptionWithMode("test_flag", "5",
1382 SET_FLAGS_DEFAULT));
1383 EXPECT_NE("", SetCommandLineOption("test_flag", "5"));
1384 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1385}
1386
1387#ifdef GTEST_HAS_DEATH_TEST
1388TEST(FlagsValidatorDeathTest, InvalidFlagViaArgv) {
1389 const char* argv[] = {
1390 "my_test",
1391 "--test_flag=50",
1392 NULL,
1393 };
1394 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1395 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
1396 "ERROR: failed validation of new value '50' for flag 'test_flag'");
1397 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1398}
1399#endif
1400
1401TEST(FlagsValidator, InvalidFlagViaSetDefault) {
1402 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1403 // SetCommandLineOptionWithMode returns the empty string on error.
1404 EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
1405 SET_FLAG_IF_DEFAULT));
1406 EXPECT_EQ(-1, FLAGS_test_flag); // the setting-to-50 should have failed
1407 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1408}
1409
1410TEST(FlagsValidator, InvalidFlagViaSetValue) {
1411 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1412 FLAGS_test_flag = 100; // doesn't trigger the validator
1413 // SetCommandLineOptionWithMode returns the empty string on error.
1414 EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
1415 SET_FLAGS_VALUE));
1416 EXPECT_EQ("", SetCommandLineOptionWithMode("test_flag", "50",
1417 SET_FLAGS_DEFAULT));
1418 EXPECT_EQ("", SetCommandLineOption("test_flag", "50"));
1419 EXPECT_EQ(100, FLAGS_test_flag); // the setting-to-50 should have failed
1420 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1421}
1422
1423#ifdef GTEST_HAS_DEATH_TEST
1424TEST(FlagsValidatorDeathTest, InvalidFlagNeverSet) {
1425 // If a flag keeps its default value, and that default value is
1426 // invalid, we should die at argv-parse time.
1427 const char* argv[] = {
1428 "my_test",
1429 NULL,
1430 };
1431 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1432 EXPECT_DEATH(ParseTestFlag(true, arraysize(argv) - 1, argv),
1433 "ERROR: --test_flag must be set on the commandline");
1434}
1435#endif
1436
1437TEST(FlagsValidator, InvalidFlagPtr) {
1438 int32 dummy;
1439 EXPECT_FALSE(RegisterFlagValidator(NULL, &ValidateTestFlagIs5));
1440 EXPECT_FALSE(RegisterFlagValidator(&dummy, &ValidateTestFlagIs5));
1441}
1442
1443TEST(FlagsValidator, RegisterValidatorTwice) {
1444 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1445 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1446 EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
1447 EXPECT_FALSE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
1448 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1449 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1450 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs10));
1451 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1452}
1453
1454TEST(FlagsValidator, CommandLineFlagInfo) {
1455 CommandLineFlagInfo info;
1456 info = GetCommandLineFlagInfoOrDie("test_flag");
1457 EXPECT_FALSE(info.has_validator_fn);
1458
1459 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1460 info = GetCommandLineFlagInfoOrDie("test_flag");
1461 EXPECT_TRUE(info.has_validator_fn);
1462
1463 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1464 info = GetCommandLineFlagInfoOrDie("test_flag");
1465 EXPECT_FALSE(info.has_validator_fn);
1466}
1467
1468TEST(FlagsValidator, FlagSaver) {
1469 {
1470 FlagSaver fs;
1471 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1472 EXPECT_EQ("", SetCommandLineOption("test_flag", "50")); // fails validation
1473 }
1474 EXPECT_NE("", SetCommandLineOption("test_flag", "50")); // validator is gone
1475
1476 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, &ValidateTestFlagIs5));
1477 {
1478 FlagSaver fs;
1479 EXPECT_TRUE(RegisterFlagValidator(&FLAGS_test_flag, NULL));
1480 EXPECT_NE("", SetCommandLineOption("test_flag", "50")); // no validator
1481 }
1482 EXPECT_EQ("", SetCommandLineOption("test_flag", "50")); // validator is back
1483}
1484
1485
1486} // unnamed namespace
1487
1488int main(int argc, char **argv) {
1489
1490 // Run unit tests only if called without arguments, otherwise this program
1491 // is used by an "external" usage test
1492 const bool run_tests = (argc == 1);
1493
1494 // We need to call SetArgv before parsing flags, so our "test" argv will
1495 // win out over this executable's real argv. That makes running this
1496 // test with a real --help flag kinda annoying, unfortunately.
1497 const char* test_argv[] = { "/test/argv/for/gflags_unittest",
1498 "argv 2", "3rd argv", "argv #4" };
1499 SetArgv(arraysize(test_argv), test_argv);
1500
1501 // The first arg is the usage message, also important for testing.
1502 string usage_message = (string(GetArgv0()) +
1503 ": <useless flag> [...]\nDoes something useless.\n");
1504
1505 // We test setting tryfromenv manually, and making sure
1506 // ParseCommandLineFlags still evaluates it.
1507 FLAGS_tryfromenv = "test_tryfromenv";
1508 setenv("FLAGS_test_tryfromenv", "pre-set", 1);
1509
1510 // Modify flag values from declared default value in two ways.
1511 // The recommended way:
1512 SetCommandLineOptionWithMode("changed_bool1", "true", SET_FLAGS_DEFAULT);
1513
1514 // The non-recommended way:
1515 FLAGS_changed_bool2 = true;
1516
1517 SetUsageMessage(usage_message.c_str());
1518 SetVersionString("test_version");
1519 ParseCommandLineFlags(&argc, &argv, true);
1520 MakeTmpdir(&FLAGS_test_tmpdir);
1521
1522 int exit_status = 0;
1523 if (run_tests) {
1524 fprintf(stdout, "Running the unit tests now...\n\n"); fflush(stdout);
1525 exit_status = RUN_ALL_TESTS();
1526 } else fprintf(stderr, "\n\nPASS\n");
1527 ShutDownCommandLineFlags();
1528 return exit_status;
1529}
1530
1531} // GFLAGS_NAMESPACE
1532
1533int main(int argc, char** argv) {
1534 return GFLAGS_NAMESPACE::main(argc, argv);
1535}
1536