16 #include "absl/flags/flag.h"
28 #include "gtest/gtest.h"
29 #include "absl/base/attributes.h"
30 #include "absl/base/macros.h"
31 #include "absl/flags/config.h"
32 #include "absl/flags/declare.h"
33 #include "absl/flags/internal/flag.h"
34 #include "absl/flags/marshalling.h"
35 #include "absl/flags/reflection.h"
36 #include "absl/flags/usage_config.h"
37 #include "absl/strings/match.h"
38 #include "absl/strings/numbers.h"
39 #include "absl/strings/str_cat.h"
40 #include "absl/strings/str_split.h"
41 #include "absl/strings/string_view.h"
42 #include "absl/time/time.h"
51 std::string TestHelpMsg() {
return "dynamic help"; }
52 #if defined(_MSC_VER) && !defined(__clang__)
53 std::string TestLiteralHelpMsg() {
return "literal help"; }
56 void TestMakeDflt(
void*
dst) {
59 void TestCallback() {}
63 UDT(
const UDT&) =
default;
82 std::replace(normalized.begin(), normalized.end(),
'\\',
'/');
92 S1(
const S1&) =
default;
99 S2(
const S2&) =
default;
104 TEST_F(FlagTest, Traits) {
106 flags::FlagValueStorageKind::kValueAndInitBit);
108 flags::FlagValueStorageKind::kValueAndInitBit);
110 flags::FlagValueStorageKind::kOneWordAtomic);
112 flags::FlagValueStorageKind::kOneWordAtomic);
115 flags::FlagValueStorageKind::kSequenceLocked);
117 flags::FlagValueStorageKind::kSequenceLocked);
122 EXPECT_EQ(flags::StorageKind<absl::Duration>(),
123 flags::FlagValueStorageKind::kSequenceLocked);
126 EXPECT_EQ(flags::StorageKind<std::string>(),
127 flags::FlagValueStorageKind::kAlignedBuffer);
129 flags::FlagValueStorageKind::kAlignedBuffer);
135 flags::FlagHelpKind::kLiteral};
139 #if !defined(_MSC_VER) || defined(__clang__)
140 #define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind) \
141 constexpr flags::FlagDefaultArg f1default##T{ \
142 flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind}; \
143 constexpr absl::Flag<T> f1##T{"f1", "file", help_arg, f1default##T}; \
144 ABSL_CONST_INIT absl::Flag<T> f2##T { \
146 {flags::FlagHelpMsg(&TestHelpMsg), flags::FlagHelpKind::kGenFunc}, \
147 flags::FlagDefaultArg { \
148 flags::FlagDefaultSrc(&TestMakeDflt<T>), \
149 flags::FlagDefaultKind::kGenFunc \
153 #define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind) \
154 constexpr flags::FlagDefaultArg f1default##T{ \
155 flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind}; \
156 constexpr absl::Flag<T> f1##T{"f1", "file", &TestLiteralHelpMsg, \
158 ABSL_CONST_INIT absl::Flag<T> f2##T { \
159 "f2", "file", &TestHelpMsg, &TestMakeDflt<T> \
175 template <
typename T>
191 #define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T);
193 TEST_F(FlagTest, TestConstruction) {
226 #if !ABSL_FLAGS_STRIP_NAMES
228 TEST_F(FlagTest, TestFlagDeclaration) {
255 #endif // !ABSL_FLAGS_STRIP_NAMES
261 ABSL_FLAG(
bool, test_flag_01,
true,
"test flag 01");
262 ABSL_FLAG(
int, test_flag_02, 1234,
"test flag 02");
269 ABSL_FLAG(
double, test_flag_09, -9.876e-50,
"test flag 09");
270 ABSL_FLAG(
float, test_flag_10, 1.234e12f,
"test flag 10");
276 #if !ABSL_FLAGS_STRIP_NAMES
277 TEST_F(FlagTest, TestFlagDefinition) {
388 #endif // !ABSL_FLAGS_STRIP_NAMES
392 TEST_F(FlagTest, TestDefault) {
459 struct NonTriviallyCopyableAggregate {
460 NonTriviallyCopyableAggregate() =
default;
461 NonTriviallyCopyableAggregate(
const NonTriviallyCopyableAggregate& rhs)
463 NonTriviallyCopyableAggregate& operator=(
464 const NonTriviallyCopyableAggregate& rhs) {
479 bool operator==(
const NonTriviallyCopyableAggregate& ntc1,
480 const NonTriviallyCopyableAggregate& ntc2) {
481 return ntc1.value == ntc2.value;
486 ABSL_FLAG(
bool, test_flag_eb_01, {},
"");
489 ABSL_FLAG(
double, test_flag_eb_04, {},
"");
491 ABSL_FLAG(NonTriviallyCopyableAggregate, test_flag_eb_06, {},
"");
495 TEST_F(FlagTest, TestEmptyBracesDefault) {
515 NonTriviallyCopyableAggregate{});
520 TEST_F(FlagTest, TestGetSet) {
560 TEST_F(FlagTest, TestGetViaReflection) {
589 TEST_F(FlagTest, ConcurrentSetAndGet) {
599 std::atomic<bool>
stop{
false};
600 std::vector<std::thread>
threads;
604 while (!
stop.load(std::memory_order_relaxed)) {
607 absl::Duration v = absl::GetFlag(FLAGS_test_flag_12);
608 EXPECT_TRUE(v == kValidDurations[0] || v == kValidDurations[1]);
609 v = *handle->TryGet<absl::Duration>();
610 EXPECT_TRUE(v == kValidDurations[0] || v == kValidDurations[1]);
620 stop.store(
true, std::memory_order_relaxed);
626 int GetDflt1() {
return 1; }
630 ABSL_FLAG(
int, test_int_flag_with_non_const_default, GetDflt1(),
631 "test int flag non const default");
633 absl::StrCat(
"AAA",
"BBB"),
"test string flag non const default");
637 TEST_F(FlagTest, TestNonConstexprDefault) {
647 ABSL_FLAG(
bool, test_flag_with_non_const_help,
true,
652 #if !ABSL_FLAGS_STRIP_HELP
653 TEST_F(FlagTest, TestNonConstexprHelp) {
656 "test flag non const help");
662 int cb_test_value = -1;
667 ABSL_FLAG(
int, test_flag_with_cb, 100,
"").OnUpdate(TestFlagCB);
669 ABSL_FLAG(
int, test_flag_with_lambda_cb, 200,
"").OnUpdate([]() {
670 cb_test_value =
absl::GetFlag(FLAGS_test_flag_with_lambda_cb) +
676 void TestFlagCB() { cb_test_value =
absl::GetFlag(FLAGS_test_flag_with_cb); }
679 TEST_F(FlagTest, CallbackInvocation) {
694 CustomUDT() :
a(1),
b(1) {}
697 friend bool operator==(
const CustomUDT&
f1,
const CustomUDT&
f2) {
698 return f1.a ==
f2.a &&
f1.b ==
f2.b;
705 std::vector<absl::string_view> parts =
708 if (parts.size() != 2)
return false;
722 ABSL_FLAG(CustomUDT, test_flag_custom_udt, CustomUDT(),
"test flag custom UDT");
726 TEST_F(FlagTest, TestCustomUDT) {
727 EXPECT_EQ(flags::StorageKind<CustomUDT>(),
728 flags::FlagValueStorageKind::kOneWordAtomic);
736 #if !defined(_WIN32) && GTEST_HAS_DEATH_TEST
738 using FlagDeathTest = FlagTest;
740 TEST_F(FlagDeathTest, TestTypeMismatchValidations) {
744 "Flag 'mistyped_int_flag' is defined as one type and declared "
747 static_cast<void>(
absl::GetFlag(FLAGS_mistyped_string_flag)),
748 "Flag 'mistyped_string_flag' is defined as one type and "
749 "declared as another");
754 "Flag 'mistyped_int_flag' is defined as one type and declared "
757 absl::SetFlag(&FLAGS_mistyped_string_flag, std::vector<std::string>{}),
758 "Flag 'mistyped_string_flag' is defined as one type and declared as "
768 struct ConversionTestVal {
769 ConversionTestVal() =
default;
770 explicit ConversionTestVal(
int a_in) :
a(a_in) {}
772 enum class ViaImplicitConv { kTen = 10, kEleven };
774 ConversionTestVal(ViaImplicitConv
from) :
a(static_cast<
int>(
from)) {}
794 ABSL_FLAG(ConversionTestVal, test_flag_implicit_conv,
795 ConversionTestVal::ViaImplicitConv::kTen,
796 "test flag init via implicit conversion");
800 TEST_F(FlagTest, CanSetViaImplicitConversion) {
803 ConversionTestVal::ViaImplicitConv::kEleven);
809 struct NonDfltConstructible {
812 NonDfltConstructible(
int i) :
value(
i) {}
816 explicit NonDfltConstructible(
char c) :
value(100 + static_cast<
int>(
c)) {}
831 ABSL_FLAG(NonDfltConstructible, ndc_flag1, NonDfltConstructible(
'1'),
832 "Flag with non default constructible type");
833 ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0,
834 "Flag with non default constructible type");
838 TEST_F(FlagTest, TestNonDefaultConstructibleType) {
864 if (handle1 !=
nullptr && handle2 !=
nullptr) {
865 return handle1->Name() == handle2->Name();
870 TEST_F(FlagTest, TestRetiredFlagRegistration) {
889 struct SmallAlignUDT {
890 SmallAlignUDT() :
c(
'A'),
s(12) {}
902 struct NonTriviallyCopyableUDT {
903 NonTriviallyCopyableUDT() :
c(
'A') {}
904 NonTriviallyCopyableUDT(
const NonTriviallyCopyableUDT& rhs) :
c(rhs.
c) {}
905 NonTriviallyCopyableUDT& operator=(
const NonTriviallyCopyableUDT& rhs) {
920 ABSL_FLAG(SmallAlignUDT, test_flag_sa_udt, {},
"help");
921 ABSL_FLAG(NonTriviallyCopyableUDT, test_flag_ntc_udt, {},
"help");
925 TEST_F(FlagTest, TestSmallAlignUDT) {
938 TEST_F(FlagTest, TestNonTriviallyCopyableUDT) {
954 enum TestE {
A = 1, B = 2,
C = 3 };
957 EnumWrapper() :
e(
A) {}
969 ABSL_FLAG(EnumWrapper, test_enum_wrapper_flag, {},
"help");
983 #define FLAG_NAME_MACRO(name) prefix_ ## name
986 "Testing macro expansion within ABSL_FLAG");
996 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
997 #define ABSL_SKIP_OPTIONAL_BOOL_TEST_DUE_TO_GCC_BUG
1000 #ifndef ABSL_SKIP_OPTIONAL_BOOL_TEST_DUE_TO_GCC_BUG
1009 absl::nullopt,
"help");
1010 #if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
1011 ABSL_FLAG(std::optional<int64_t>, std_optional_int64, std::nullopt,
"help");
1016 #ifndef ABSL_SKIP_OPTIONAL_BOOL_TEST_DUE_TO_GCC_BUG
1017 TEST_F(FlagTest, TestOptionalBool) {
1037 TEST_F(FlagTest, TestOptionalInt) {
1056 TEST_F(FlagTest, TestOptionalDouble) {
1075 TEST_F(FlagTest, TestOptionalString) {
1096 TEST_F(FlagTest, TestOptionalDuration) {
1115 TEST_F(FlagTest, TestOptionalOptional) {
1143 #if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
1145 TEST_F(FlagTest, TestStdOptional) {