flag_test.cc (50239B)
1 // 2 // Copyright 2019 The Abseil Authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // https://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #include "absl/flags/flag.h" 17 18 #include <stddef.h> 19 #include <stdint.h> 20 21 #include <atomic> 22 #include <string> 23 #include <thread> // NOLINT 24 #include <vector> 25 26 #include "gtest/gtest.h" 27 #include "absl/base/attributes.h" 28 #include "absl/base/internal/raw_logging.h" 29 #include "absl/base/macros.h" 30 #include "absl/flags/config.h" 31 #include "absl/flags/declare.h" 32 #include "absl/flags/internal/flag.h" 33 #include "absl/flags/marshalling.h" 34 #include "absl/flags/parse.h" 35 #include "absl/flags/reflection.h" 36 #include "absl/flags/usage_config.h" 37 #include "absl/numeric/int128.h" 38 #include "absl/strings/match.h" 39 #include "absl/strings/numbers.h" 40 #include "absl/strings/str_cat.h" 41 #include "absl/strings/str_split.h" 42 #include "absl/strings/string_view.h" 43 #include "absl/time/clock.h" 44 #include "absl/time/time.h" 45 #include "absl/types/optional.h" 46 47 ABSL_DECLARE_FLAG(int64_t, mistyped_int_flag); 48 ABSL_DECLARE_FLAG(std::vector<std::string>, mistyped_string_flag); 49 50 namespace { 51 52 namespace flags = absl::flags_internal; 53 54 std::string TestHelpMsg() { return "dynamic help"; } 55 #if defined(_MSC_VER) && !defined(__clang__) 56 std::string TestLiteralHelpMsg() { return "literal help"; } 57 #endif 58 template <typename T> 59 void TestMakeDflt(void* dst) { 60 new (dst) T{}; 61 } 62 void TestCallback() {} 63 64 struct UDT { 65 UDT() = default; 66 UDT(const UDT&) = default; 67 UDT& operator=(const UDT&) = default; 68 }; 69 bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; } 70 std::string AbslUnparseFlag(const UDT&) { return ""; } 71 72 class FlagTest : public testing::Test { 73 protected: 74 static void SetUpTestSuite() { 75 // Install a function to normalize filenames before this test is run. 76 absl::FlagsUsageConfig default_config; 77 default_config.normalize_filename = &FlagTest::NormalizeFileName; 78 absl::SetFlagsUsageConfig(default_config); 79 } 80 81 private: 82 static std::string NormalizeFileName(absl::string_view fname) { 83 #ifdef _WIN32 84 std::string normalized(fname); 85 std::replace(normalized.begin(), normalized.end(), '\\', '/'); 86 fname = normalized; 87 #endif 88 return std::string(fname); 89 } 90 absl::FlagSaver flag_saver_; 91 }; 92 93 struct S1 { 94 S1() = default; 95 S1(const S1&) = default; 96 int32_t f1; 97 int64_t f2; 98 }; 99 100 struct S2 { 101 S2() = default; 102 S2(const S2&) = default; 103 int64_t f1; 104 double f2; 105 }; 106 107 TEST_F(FlagTest, Traits) { 108 EXPECT_EQ(flags::StorageKind<int>(), 109 flags::FlagValueStorageKind::kValueAndInitBit); 110 EXPECT_EQ(flags::StorageKind<bool>(), 111 flags::FlagValueStorageKind::kValueAndInitBit); 112 EXPECT_EQ(flags::StorageKind<double>(), 113 flags::FlagValueStorageKind::kOneWordAtomic); 114 EXPECT_EQ(flags::StorageKind<int64_t>(), 115 flags::FlagValueStorageKind::kOneWordAtomic); 116 117 EXPECT_EQ(flags::StorageKind<S1>(), 118 flags::FlagValueStorageKind::kSequenceLocked); 119 EXPECT_EQ(flags::StorageKind<S2>(), 120 flags::FlagValueStorageKind::kSequenceLocked); 121 // Make sure absl::Duration uses the sequence-locked code path. MSVC 2015 122 // doesn't consider absl::Duration to be trivially-copyable so we just 123 // restrict this to clang as it seems to be a well-behaved compiler. 124 #ifdef __clang__ 125 EXPECT_EQ(flags::StorageKind<absl::Duration>(), 126 flags::FlagValueStorageKind::kSequenceLocked); 127 #endif 128 129 EXPECT_EQ(flags::StorageKind<std::string>(), 130 flags::FlagValueStorageKind::kHeapAllocated); 131 EXPECT_EQ(flags::StorageKind<std::vector<std::string>>(), 132 flags::FlagValueStorageKind::kHeapAllocated); 133 134 EXPECT_EQ(flags::StorageKind<absl::int128>(), 135 flags::FlagValueStorageKind::kSequenceLocked); 136 EXPECT_EQ(flags::StorageKind<absl::uint128>(), 137 flags::FlagValueStorageKind::kSequenceLocked); 138 } 139 140 // -------------------------------------------------------------------- 141 142 constexpr flags::FlagHelpArg help_arg{flags::FlagHelpMsg("literal help"), 143 flags::FlagHelpKind::kLiteral}; 144 145 using String = std::string; 146 using int128 = absl::int128; 147 using uint128 = absl::uint128; 148 149 #define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind) \ 150 constexpr flags::FlagDefaultArg f1default##T{ \ 151 flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind}; \ 152 constexpr absl::Flag<T> f1##T{"f1", #T, "file", help_arg, f1default##T}; \ 153 ABSL_CONST_INIT absl::Flag<T> f2##T { \ 154 "f2", #T, "file", \ 155 {flags::FlagHelpMsg(&TestHelpMsg), flags::FlagHelpKind::kGenFunc}, \ 156 flags::FlagDefaultArg { \ 157 flags::FlagDefaultSrc(&TestMakeDflt<T>), \ 158 flags::FlagDefaultKind::kGenFunc \ 159 } \ 160 } 161 162 DEFINE_CONSTRUCTED_FLAG(bool, true, kOneWord); 163 DEFINE_CONSTRUCTED_FLAG(int16_t, 1, kOneWord); 164 DEFINE_CONSTRUCTED_FLAG(uint16_t, 2, kOneWord); 165 DEFINE_CONSTRUCTED_FLAG(int32_t, 3, kOneWord); 166 DEFINE_CONSTRUCTED_FLAG(uint32_t, 4, kOneWord); 167 DEFINE_CONSTRUCTED_FLAG(int64_t, 5, kOneWord); 168 DEFINE_CONSTRUCTED_FLAG(uint64_t, 6, kOneWord); 169 DEFINE_CONSTRUCTED_FLAG(float, 7.8, kOneWord); 170 DEFINE_CONSTRUCTED_FLAG(double, 9.10, kOneWord); 171 DEFINE_CONSTRUCTED_FLAG(String, &TestMakeDflt<String>, kGenFunc); 172 DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt<UDT>, kGenFunc); 173 DEFINE_CONSTRUCTED_FLAG(int128, 13, kGenFunc); 174 DEFINE_CONSTRUCTED_FLAG(uint128, 14, kGenFunc); 175 176 template <typename T> 177 bool TestConstructionFor(const absl::Flag<T>& f1, absl::Flag<T>& f2) { 178 EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Name(), "f1"); 179 EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help"); 180 EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Filename(), "file"); 181 182 flags::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(f2), nullptr) 183 .OnUpdate(TestCallback); 184 185 EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Name(), "f2"); 186 EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Help(), "dynamic help"); 187 EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Filename(), "file"); 188 189 return true; 190 } 191 192 #define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T); 193 194 TEST_F(FlagTest, TestConstruction) { 195 TEST_CONSTRUCTED_FLAG(bool); 196 TEST_CONSTRUCTED_FLAG(int16_t); 197 TEST_CONSTRUCTED_FLAG(uint16_t); 198 TEST_CONSTRUCTED_FLAG(int32_t); 199 TEST_CONSTRUCTED_FLAG(uint32_t); 200 TEST_CONSTRUCTED_FLAG(int64_t); 201 TEST_CONSTRUCTED_FLAG(uint64_t); 202 TEST_CONSTRUCTED_FLAG(float); 203 TEST_CONSTRUCTED_FLAG(double); 204 TEST_CONSTRUCTED_FLAG(String); 205 TEST_CONSTRUCTED_FLAG(UDT); 206 TEST_CONSTRUCTED_FLAG(int128); 207 TEST_CONSTRUCTED_FLAG(uint128); 208 } 209 210 // -------------------------------------------------------------------- 211 212 } // namespace 213 214 ABSL_DECLARE_FLAG(bool, test_flag_01); 215 ABSL_DECLARE_FLAG(int, test_flag_02); 216 ABSL_DECLARE_FLAG(int16_t, test_flag_03); 217 ABSL_DECLARE_FLAG(uint16_t, test_flag_04); 218 ABSL_DECLARE_FLAG(int32_t, test_flag_05); 219 ABSL_DECLARE_FLAG(uint32_t, test_flag_06); 220 ABSL_DECLARE_FLAG(int64_t, test_flag_07); 221 ABSL_DECLARE_FLAG(uint64_t, test_flag_08); 222 ABSL_DECLARE_FLAG(double, test_flag_09); 223 ABSL_DECLARE_FLAG(float, test_flag_10); 224 ABSL_DECLARE_FLAG(std::string, test_flag_11); 225 ABSL_DECLARE_FLAG(absl::Duration, test_flag_12); 226 ABSL_DECLARE_FLAG(absl::int128, test_flag_13); 227 ABSL_DECLARE_FLAG(absl::uint128, test_flag_14); 228 229 namespace { 230 231 TEST_F(FlagTest, TestFlagDeclaration) { 232 #if ABSL_FLAGS_STRIP_NAMES 233 GTEST_SKIP() << "This test requires flag names to be present"; 234 #endif 235 // test that we can access flag objects. 236 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(), 237 "test_flag_01"); 238 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(), 239 "test_flag_02"); 240 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(), 241 "test_flag_03"); 242 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(), 243 "test_flag_04"); 244 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(), 245 "test_flag_05"); 246 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(), 247 "test_flag_06"); 248 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(), 249 "test_flag_07"); 250 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(), 251 "test_flag_08"); 252 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(), 253 "test_flag_09"); 254 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(), 255 "test_flag_10"); 256 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(), 257 "test_flag_11"); 258 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(), 259 "test_flag_12"); 260 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Name(), 261 "test_flag_13"); 262 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Name(), 263 "test_flag_14"); 264 } 265 266 } // namespace 267 268 #if ABSL_FLAGS_STRIP_NAMES 269 // The intent of this helper struct and an expression below is to make sure that 270 // in the configuration where ABSL_FLAGS_STRIP_NAMES=1 registrar construction 271 // (in cases of no Tail calls like OnUpdate) is constexpr and thus can and 272 // should be completely optimized away, thus avoiding the cost/overhead of 273 // static initializers. 274 struct VerifyConsteval { 275 friend consteval flags::FlagRegistrarEmpty operator+( 276 flags::FlagRegistrarEmpty, VerifyConsteval) { 277 return {}; 278 } 279 }; 280 281 ABSL_FLAG(int, test_registrar_const_init, 0, "") + VerifyConsteval(); 282 #endif 283 284 // -------------------------------------------------------------------- 285 286 ABSL_FLAG(bool, test_flag_01, true, "test flag 01"); 287 ABSL_FLAG(int, test_flag_02, 1234, "test flag 02"); 288 ABSL_FLAG(int16_t, test_flag_03, -34, "test flag 03"); 289 ABSL_FLAG(uint16_t, test_flag_04, 189, "test flag 04"); 290 ABSL_FLAG(int32_t, test_flag_05, 10765, "test flag 05"); 291 ABSL_FLAG(uint32_t, test_flag_06, 40000, "test flag 06"); 292 ABSL_FLAG(int64_t, test_flag_07, -1234567, "test flag 07"); 293 ABSL_FLAG(uint64_t, test_flag_08, 9876543, "test flag 08"); 294 ABSL_FLAG(double, test_flag_09, -9.876e-50, "test flag 09"); 295 ABSL_FLAG(float, test_flag_10, 1.234e12f, "test flag 10"); 296 ABSL_FLAG(std::string, test_flag_11, "", "test flag 11"); 297 ABSL_FLAG(absl::Duration, test_flag_12, absl::Minutes(10), "test flag 12"); 298 ABSL_FLAG(absl::int128, test_flag_13, absl::MakeInt128(-1, 0), "test flag 13"); 299 ABSL_FLAG(absl::uint128, test_flag_14, absl::MakeUint128(0, 0xFFFAAABBBCCCDDD), 300 "test flag 14"); 301 302 namespace { 303 304 TEST_F(FlagTest, TestFlagDefinition) { 305 #if ABSL_FLAGS_STRIP_NAMES 306 GTEST_SKIP() << "This test requires flag names to be present"; 307 #endif 308 absl::string_view expected_file_name = "absl/flags/flag_test.cc"; 309 310 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(), 311 "test_flag_01"); 312 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Help(), 313 "test flag 01"); 314 EXPECT_TRUE(absl::EndsWith( 315 absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename(), 316 expected_file_name)) 317 << absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename(); 318 319 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(), 320 "test_flag_02"); 321 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Help(), 322 "test flag 02"); 323 EXPECT_TRUE(absl::EndsWith( 324 absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename(), 325 expected_file_name)) 326 << absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename(); 327 328 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(), 329 "test_flag_03"); 330 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Help(), 331 "test flag 03"); 332 EXPECT_TRUE(absl::EndsWith( 333 absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename(), 334 expected_file_name)) 335 << absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename(); 336 337 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(), 338 "test_flag_04"); 339 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Help(), 340 "test flag 04"); 341 EXPECT_TRUE(absl::EndsWith( 342 absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename(), 343 expected_file_name)) 344 << absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename(); 345 346 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(), 347 "test_flag_05"); 348 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Help(), 349 "test flag 05"); 350 EXPECT_TRUE(absl::EndsWith( 351 absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename(), 352 expected_file_name)) 353 << absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename(); 354 355 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(), 356 "test_flag_06"); 357 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Help(), 358 "test flag 06"); 359 EXPECT_TRUE(absl::EndsWith( 360 absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename(), 361 expected_file_name)) 362 << absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename(); 363 364 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(), 365 "test_flag_07"); 366 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Help(), 367 "test flag 07"); 368 EXPECT_TRUE(absl::EndsWith( 369 absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename(), 370 expected_file_name)) 371 << absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename(); 372 373 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(), 374 "test_flag_08"); 375 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Help(), 376 "test flag 08"); 377 EXPECT_TRUE(absl::EndsWith( 378 absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename(), 379 expected_file_name)) 380 << absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename(); 381 382 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(), 383 "test_flag_09"); 384 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Help(), 385 "test flag 09"); 386 EXPECT_TRUE(absl::EndsWith( 387 absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename(), 388 expected_file_name)) 389 << absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename(); 390 391 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(), 392 "test_flag_10"); 393 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Help(), 394 "test flag 10"); 395 EXPECT_TRUE(absl::EndsWith( 396 absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename(), 397 expected_file_name)) 398 << absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename(); 399 400 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(), 401 "test_flag_11"); 402 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Help(), 403 "test flag 11"); 404 EXPECT_TRUE(absl::EndsWith( 405 absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename(), 406 expected_file_name)) 407 << absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename(); 408 409 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(), 410 "test_flag_12"); 411 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Help(), 412 "test flag 12"); 413 EXPECT_TRUE(absl::EndsWith( 414 absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename(), 415 expected_file_name)) 416 << absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename(); 417 418 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Name(), 419 "test_flag_13"); 420 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Help(), 421 "test flag 13"); 422 EXPECT_TRUE(absl::EndsWith( 423 absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Filename(), 424 expected_file_name)) 425 << absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Filename(); 426 427 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Name(), 428 "test_flag_14"); 429 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Help(), 430 "test flag 14"); 431 EXPECT_TRUE(absl::EndsWith( 432 absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Filename(), 433 expected_file_name)) 434 << absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Filename(); 435 } 436 437 // -------------------------------------------------------------------- 438 439 TEST_F(FlagTest, TestDefault) { 440 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).DefaultValue(), 441 "true"); 442 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).DefaultValue(), 443 "1234"); 444 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).DefaultValue(), 445 "-34"); 446 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).DefaultValue(), 447 "189"); 448 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).DefaultValue(), 449 "10765"); 450 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).DefaultValue(), 451 "40000"); 452 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).DefaultValue(), 453 "-1234567"); 454 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).DefaultValue(), 455 "9876543"); 456 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).DefaultValue(), 457 "-9.876e-50"); 458 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).DefaultValue(), 459 "1.234e+12"); 460 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).DefaultValue(), 461 ""); 462 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).DefaultValue(), 463 "10m"); 464 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).DefaultValue(), 465 "-18446744073709551616"); 466 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).DefaultValue(), 467 "1152827684197027293"); 468 469 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).CurrentValue(), 470 "true"); 471 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).CurrentValue(), 472 "1234"); 473 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).CurrentValue(), 474 "-34"); 475 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).CurrentValue(), 476 "189"); 477 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).CurrentValue(), 478 "10765"); 479 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).CurrentValue(), 480 "40000"); 481 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).CurrentValue(), 482 "-1234567"); 483 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).CurrentValue(), 484 "9876543"); 485 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).CurrentValue(), 486 "-9.876e-50"); 487 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).CurrentValue(), 488 "1.234e+12"); 489 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).CurrentValue(), 490 ""); 491 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).CurrentValue(), 492 "10m"); 493 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).CurrentValue(), 494 "-18446744073709551616"); 495 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).CurrentValue(), 496 "1152827684197027293"); 497 498 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true); 499 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234); 500 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34); 501 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 189); 502 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), 10765); 503 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 40000); 504 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -1234567); 505 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 9876543); 506 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), -9.876e-50, 1e-55); 507 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), 1.234e12f, 1e5f); 508 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), ""); 509 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Minutes(10)); 510 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), absl::MakeInt128(-1, 0)); 511 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_14), 512 absl::MakeUint128(0, 0xFFFAAABBBCCCDDD)); 513 } 514 515 // -------------------------------------------------------------------- 516 517 struct NonTriviallyCopyableAggregate { 518 NonTriviallyCopyableAggregate() = default; 519 // NOLINTNEXTLINE 520 NonTriviallyCopyableAggregate(const NonTriviallyCopyableAggregate& rhs) 521 : value(rhs.value) {} 522 // NOLINTNEXTLINE 523 NonTriviallyCopyableAggregate& operator=( 524 const NonTriviallyCopyableAggregate& rhs) { 525 value = rhs.value; 526 return *this; 527 } 528 529 int value; 530 }; 531 bool AbslParseFlag(absl::string_view src, NonTriviallyCopyableAggregate* f, 532 std::string* e) { 533 return absl::ParseFlag(src, &f->value, e); 534 } 535 std::string AbslUnparseFlag(const NonTriviallyCopyableAggregate& ntc) { 536 return absl::StrCat(ntc.value); 537 } 538 539 bool operator==(const NonTriviallyCopyableAggregate& ntc1, 540 const NonTriviallyCopyableAggregate& ntc2) { 541 return ntc1.value == ntc2.value; 542 } 543 544 } // namespace 545 546 ABSL_FLAG(bool, test_flag_eb_01, {}, ""); 547 ABSL_FLAG(int32_t, test_flag_eb_02, {}, ""); 548 ABSL_FLAG(int64_t, test_flag_eb_03, {}, ""); 549 ABSL_FLAG(double, test_flag_eb_04, {}, ""); 550 ABSL_FLAG(std::string, test_flag_eb_05, {}, ""); 551 ABSL_FLAG(NonTriviallyCopyableAggregate, test_flag_eb_06, {}, ""); 552 553 namespace { 554 555 TEST_F(FlagTest, TestEmptyBracesDefault) { 556 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_01).DefaultValue(), 557 "false"); 558 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_02).DefaultValue(), 559 "0"); 560 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_03).DefaultValue(), 561 "0"); 562 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_04).DefaultValue(), 563 "0"); 564 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_05).DefaultValue(), 565 ""); 566 EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_06).DefaultValue(), 567 "0"); 568 569 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_01), false); 570 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_02), 0); 571 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_03), 0); 572 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_04), 0.0); 573 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_05), ""); 574 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_06), 575 NonTriviallyCopyableAggregate{}); 576 } 577 578 // -------------------------------------------------------------------- 579 580 TEST_F(FlagTest, TestGetSet) { 581 absl::SetFlag(&FLAGS_test_flag_01, false); 582 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false); 583 584 absl::SetFlag(&FLAGS_test_flag_02, 321); 585 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 321); 586 587 absl::SetFlag(&FLAGS_test_flag_03, 67); 588 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), 67); 589 590 absl::SetFlag(&FLAGS_test_flag_04, 1); 591 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 1); 592 593 absl::SetFlag(&FLAGS_test_flag_05, -908); 594 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), -908); 595 596 absl::SetFlag(&FLAGS_test_flag_06, 4001); 597 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 4001); 598 599 absl::SetFlag(&FLAGS_test_flag_07, -23456); 600 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -23456); 601 602 absl::SetFlag(&FLAGS_test_flag_08, 975310); 603 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 975310); 604 605 absl::SetFlag(&FLAGS_test_flag_09, 1.00001); 606 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), 1.00001, 1e-10); 607 608 absl::SetFlag(&FLAGS_test_flag_10, -3.54f); 609 EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), -3.54f, 1e-6f); 610 611 absl::SetFlag(&FLAGS_test_flag_11, "asdf"); 612 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "asdf"); 613 614 absl::SetFlag(&FLAGS_test_flag_12, absl::Seconds(110)); 615 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Seconds(110)); 616 617 absl::SetFlag(&FLAGS_test_flag_13, absl::MakeInt128(-1, 0)); 618 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), absl::MakeInt128(-1, 0)); 619 620 absl::SetFlag(&FLAGS_test_flag_14, absl::MakeUint128(0, 0xFFFAAABBBCCCDDD)); 621 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_14), 622 absl::MakeUint128(0, 0xFFFAAABBBCCCDDD)); 623 } 624 625 // -------------------------------------------------------------------- 626 627 TEST_F(FlagTest, TestGetViaReflection) { 628 #if ABSL_FLAGS_STRIP_NAMES 629 GTEST_SKIP() << "This test requires flag names to be present"; 630 #endif 631 auto* handle = absl::FindCommandLineFlag("test_flag_01"); 632 EXPECT_EQ(*handle->TryGet<bool>(), true); 633 handle = absl::FindCommandLineFlag("test_flag_02"); 634 EXPECT_EQ(*handle->TryGet<int>(), 1234); 635 handle = absl::FindCommandLineFlag("test_flag_03"); 636 EXPECT_EQ(*handle->TryGet<int16_t>(), -34); 637 handle = absl::FindCommandLineFlag("test_flag_04"); 638 EXPECT_EQ(*handle->TryGet<uint16_t>(), 189); 639 handle = absl::FindCommandLineFlag("test_flag_05"); 640 EXPECT_EQ(*handle->TryGet<int32_t>(), 10765); 641 handle = absl::FindCommandLineFlag("test_flag_06"); 642 EXPECT_EQ(*handle->TryGet<uint32_t>(), 40000); 643 handle = absl::FindCommandLineFlag("test_flag_07"); 644 EXPECT_EQ(*handle->TryGet<int64_t>(), -1234567); 645 handle = absl::FindCommandLineFlag("test_flag_08"); 646 EXPECT_EQ(*handle->TryGet<uint64_t>(), 9876543); 647 handle = absl::FindCommandLineFlag("test_flag_09"); 648 EXPECT_NEAR(*handle->TryGet<double>(), -9.876e-50, 1e-55); 649 handle = absl::FindCommandLineFlag("test_flag_10"); 650 EXPECT_NEAR(*handle->TryGet<float>(), 1.234e12f, 1e5f); 651 handle = absl::FindCommandLineFlag("test_flag_11"); 652 EXPECT_EQ(*handle->TryGet<std::string>(), ""); 653 handle = absl::FindCommandLineFlag("test_flag_12"); 654 EXPECT_EQ(*handle->TryGet<absl::Duration>(), absl::Minutes(10)); 655 handle = absl::FindCommandLineFlag("test_flag_13"); 656 EXPECT_EQ(*handle->TryGet<absl::int128>(), absl::MakeInt128(-1, 0)); 657 handle = absl::FindCommandLineFlag("test_flag_14"); 658 EXPECT_EQ(*handle->TryGet<absl::uint128>(), 659 absl::MakeUint128(0, 0xFFFAAABBBCCCDDD)); 660 } 661 662 // -------------------------------------------------------------------- 663 664 TEST_F(FlagTest, ConcurrentSetAndGet) { 665 #if ABSL_FLAGS_STRIP_NAMES 666 GTEST_SKIP() << "This test requires flag names to be present"; 667 #endif 668 static constexpr int kNumThreads = 8; 669 // Two arbitrary durations. One thread will concurrently flip the flag 670 // between these two values, while the other threads read it and verify 671 // that no other value is seen. 672 static const absl::Duration kValidDurations[] = { 673 absl::Seconds(int64_t{0x6cebf47a9b68c802}) + absl::Nanoseconds(229702057), 674 absl::Seconds(int64_t{0x23fec0307e4e9d3}) + absl::Nanoseconds(44555374)}; 675 absl::SetFlag(&FLAGS_test_flag_12, kValidDurations[0]); 676 677 std::atomic<bool> stop{false}; 678 std::vector<std::thread> threads; 679 auto* handle = absl::FindCommandLineFlag("test_flag_12"); 680 for (int i = 0; i < kNumThreads; i++) { 681 threads.emplace_back([&]() { 682 while (!stop.load(std::memory_order_relaxed)) { 683 // Try loading the flag both directly and via a reflection 684 // handle. 685 absl::Duration v = absl::GetFlag(FLAGS_test_flag_12); 686 EXPECT_TRUE(v == kValidDurations[0] || v == kValidDurations[1]); 687 v = *handle->TryGet<absl::Duration>(); 688 EXPECT_TRUE(v == kValidDurations[0] || v == kValidDurations[1]); 689 } 690 }); 691 } 692 absl::Time end_time = absl::Now() + absl::Seconds(1); 693 int i = 0; 694 while (absl::Now() < end_time) { 695 absl::SetFlag(&FLAGS_test_flag_12, 696 kValidDurations[i++ % ABSL_ARRAYSIZE(kValidDurations)]); 697 } 698 stop.store(true, std::memory_order_relaxed); 699 for (auto& t : threads) t.join(); 700 } 701 702 // -------------------------------------------------------------------- 703 704 int GetDflt1() { return 1; } 705 706 } // namespace 707 708 ABSL_FLAG(int, test_int_flag_with_non_const_default, GetDflt1(), 709 "test int flag non const default"); 710 ABSL_FLAG(std::string, test_string_flag_with_non_const_default, 711 absl::StrCat("AAA", "BBB"), "test string flag non const default"); 712 713 namespace { 714 715 TEST_F(FlagTest, TestNonConstexprDefault) { 716 EXPECT_EQ(absl::GetFlag(FLAGS_test_int_flag_with_non_const_default), 1); 717 EXPECT_EQ(absl::GetFlag(FLAGS_test_string_flag_with_non_const_default), 718 "AAABBB"); 719 } 720 721 // -------------------------------------------------------------------- 722 723 } // namespace 724 725 ABSL_FLAG(bool, test_flag_with_non_const_help, true, 726 absl::StrCat("test ", "flag ", "non const help")); 727 728 namespace { 729 730 #if !ABSL_FLAGS_STRIP_HELP 731 TEST_F(FlagTest, TestNonConstexprHelp) { 732 EXPECT_EQ( 733 absl::GetFlagReflectionHandle(FLAGS_test_flag_with_non_const_help).Help(), 734 "test flag non const help"); 735 } 736 #endif //! ABSL_FLAGS_STRIP_HELP 737 738 // -------------------------------------------------------------------- 739 740 int cb_test_value = -1; 741 void TestFlagCB(); 742 743 } // namespace 744 745 ABSL_FLAG(int, test_flag_with_cb, 100, "").OnUpdate(TestFlagCB); 746 747 ABSL_FLAG(int, test_flag_with_lambda_cb, 200, "").OnUpdate([]() { 748 cb_test_value = absl::GetFlag(FLAGS_test_flag_with_lambda_cb) + 749 absl::GetFlag(FLAGS_test_flag_with_cb); 750 }); 751 752 namespace { 753 754 void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); } 755 756 // Tests side-effects of callback invocation. 757 TEST_F(FlagTest, CallbackInvocation) { 758 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100); 759 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200); 760 EXPECT_EQ(cb_test_value, 300); 761 762 absl::SetFlag(&FLAGS_test_flag_with_cb, 1); 763 EXPECT_EQ(cb_test_value, 1); 764 765 absl::SetFlag(&FLAGS_test_flag_with_lambda_cb, 3); 766 EXPECT_EQ(cb_test_value, 4); 767 } 768 769 // -------------------------------------------------------------------- 770 771 struct CustomUDT { 772 CustomUDT() : a(1), b(1) {} 773 CustomUDT(int a_, int b_) : a(a_), b(b_) {} 774 775 friend bool operator==(const CustomUDT& f1, const CustomUDT& f2) { 776 return f1.a == f2.a && f1.b == f2.b; 777 } 778 779 int a; 780 int b; 781 }; 782 bool AbslParseFlag(absl::string_view in, CustomUDT* f, std::string*) { 783 std::vector<absl::string_view> parts = 784 absl::StrSplit(in, ':', absl::SkipWhitespace()); 785 786 if (parts.size() != 2) return false; 787 788 if (!absl::SimpleAtoi(parts[0], &f->a)) return false; 789 790 if (!absl::SimpleAtoi(parts[1], &f->b)) return false; 791 792 return true; 793 } 794 std::string AbslUnparseFlag(const CustomUDT& f) { 795 return absl::StrCat(f.a, ":", f.b); 796 } 797 798 } // namespace 799 800 ABSL_FLAG(CustomUDT, test_flag_custom_udt, CustomUDT(), "test flag custom UDT"); 801 802 namespace { 803 804 TEST_F(FlagTest, TestCustomUDT) { 805 EXPECT_EQ(flags::StorageKind<CustomUDT>(), 806 flags::FlagValueStorageKind::kOneWordAtomic); 807 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(1, 1)); 808 absl::SetFlag(&FLAGS_test_flag_custom_udt, CustomUDT(2, 3)); 809 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(2, 3)); 810 } 811 812 // MSVC produces link error on the type mismatch. 813 // Linux does not have build errors and validations work as expected. 814 #if !defined(_WIN32) && GTEST_HAS_DEATH_TEST 815 using FlagDeathTest = FlagTest; 816 817 TEST_F(FlagDeathTest, TestTypeMismatchValidations) { 818 #if ABSL_FLAGS_STRIP_NAMES 819 GTEST_SKIP() << "This test requires flag names to be present"; 820 #endif 821 #if !defined(NDEBUG) 822 EXPECT_DEATH_IF_SUPPORTED( 823 static_cast<void>(absl::GetFlag(FLAGS_mistyped_int_flag)), 824 "Flag 'mistyped_int_flag' is defined as one type and declared " 825 "as another"); 826 EXPECT_DEATH_IF_SUPPORTED( 827 static_cast<void>(absl::GetFlag(FLAGS_mistyped_string_flag)), 828 "Flag 'mistyped_string_flag' is defined as one type and " 829 "declared as another"); 830 #endif 831 832 EXPECT_DEATH_IF_SUPPORTED( 833 absl::SetFlag(&FLAGS_mistyped_int_flag, 1), 834 "Flag 'mistyped_int_flag' is defined as one type and declared " 835 "as another"); 836 EXPECT_DEATH_IF_SUPPORTED( 837 absl::SetFlag(&FLAGS_mistyped_string_flag, std::vector<std::string>{}), 838 "Flag 'mistyped_string_flag' is defined as one type and declared as " 839 "another"); 840 } 841 842 #endif 843 844 // -------------------------------------------------------------------- 845 846 // A contrived type that offers implicit and explicit conversion from specific 847 // source types. 848 struct ConversionTestVal { 849 ConversionTestVal() = default; 850 explicit ConversionTestVal(int a_in) : a(a_in) {} 851 852 enum class ViaImplicitConv { kTen = 10, kEleven }; 853 // NOLINTNEXTLINE 854 ConversionTestVal(ViaImplicitConv from) : a(static_cast<int>(from)) {} 855 856 int a; 857 }; 858 859 bool AbslParseFlag(absl::string_view in, ConversionTestVal* val_out, 860 std::string*) { 861 if (!absl::SimpleAtoi(in, &val_out->a)) { 862 return false; 863 } 864 return true; 865 } 866 std::string AbslUnparseFlag(const ConversionTestVal& val) { 867 return absl::StrCat(val.a); 868 } 869 870 } // namespace 871 872 // Flag default values can be specified with a value that converts to the flag 873 // value type implicitly. 874 ABSL_FLAG(ConversionTestVal, test_flag_implicit_conv, 875 ConversionTestVal::ViaImplicitConv::kTen, 876 "test flag init via implicit conversion"); 877 878 namespace { 879 880 TEST_F(FlagTest, CanSetViaImplicitConversion) { 881 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).a, 10); 882 absl::SetFlag(&FLAGS_test_flag_implicit_conv, 883 ConversionTestVal::ViaImplicitConv::kEleven); 884 EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).a, 11); 885 } 886 887 // -------------------------------------------------------------------- 888 889 struct NonDfltConstructible { 890 public: 891 // This constructor tests that we can initialize the flag with int value 892 NonDfltConstructible(int i) : value(i) {} // NOLINT 893 894 // This constructor tests that we can't initialize the flag with char value 895 // but can with explicitly constructed NonDfltConstructible. 896 explicit NonDfltConstructible(char c) : value(100 + static_cast<int>(c)) {} 897 898 int value; 899 }; 900 901 bool AbslParseFlag(absl::string_view in, NonDfltConstructible* ndc_out, 902 std::string*) { 903 return absl::SimpleAtoi(in, &ndc_out->value); 904 } 905 std::string AbslUnparseFlag(const NonDfltConstructible& ndc) { 906 return absl::StrCat(ndc.value); 907 } 908 909 } // namespace 910 911 ABSL_FLAG(NonDfltConstructible, ndc_flag1, NonDfltConstructible('1'), 912 "Flag with non default constructible type"); 913 ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0, 914 "Flag with non default constructible type"); 915 916 namespace { 917 918 TEST_F(FlagTest, TestNonDefaultConstructibleType) { 919 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100); 920 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0); 921 922 absl::SetFlag(&FLAGS_ndc_flag1, NonDfltConstructible('A')); 923 absl::SetFlag(&FLAGS_ndc_flag2, 25); 924 925 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, 'A' + 100); 926 EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 25); 927 } 928 929 } // namespace 930 931 // -------------------------------------------------------------------- 932 933 ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr"); 934 ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr"); 935 ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr")); 936 937 namespace { 938 939 bool initialization_order_fiasco_test ABSL_ATTRIBUTE_UNUSED = [] { 940 // Iterate over all the flags during static initialization. 941 // This should not trigger ASan's initialization-order-fiasco. 942 auto* handle1 = absl::FindCommandLineFlag("flag_on_separate_file"); 943 auto* handle2 = absl::FindCommandLineFlag("retired_flag_on_separate_file"); 944 if (handle1 != nullptr && handle2 != nullptr) { 945 return handle1->Name() == handle2->Name(); 946 } 947 return true; 948 }(); 949 950 TEST_F(FlagTest, TestRetiredFlagRegistration) { 951 auto* handle = absl::FindCommandLineFlag("old_bool_flag"); 952 EXPECT_TRUE(handle->IsOfType<bool>()); 953 EXPECT_TRUE(handle->IsRetired()); 954 handle = absl::FindCommandLineFlag("old_int_flag"); 955 EXPECT_TRUE(handle->IsOfType<int>()); 956 EXPECT_TRUE(handle->IsRetired()); 957 handle = absl::FindCommandLineFlag("old_str_flag"); 958 EXPECT_TRUE(handle->IsOfType<std::string>()); 959 EXPECT_TRUE(handle->IsRetired()); 960 } 961 962 } // namespace 963 964 // -------------------------------------------------------------------- 965 966 namespace { 967 968 // User-defined type with small alignment, but size exceeding 16. 969 struct SmallAlignUDT { 970 SmallAlignUDT() : c('A'), s(12) {} 971 char c; 972 int16_t s; 973 char bytes[14]; 974 }; 975 976 bool AbslParseFlag(absl::string_view, SmallAlignUDT*, std::string*) { 977 return true; 978 } 979 std::string AbslUnparseFlag(const SmallAlignUDT&) { return ""; } 980 981 } // namespace 982 983 ABSL_FLAG(SmallAlignUDT, test_flag_sa_udt, {}, "help"); 984 985 namespace { 986 987 TEST_F(FlagTest, TestSmallAlignUDT) { 988 EXPECT_EQ(flags::StorageKind<SmallAlignUDT>(), 989 flags::FlagValueStorageKind::kSequenceLocked); 990 SmallAlignUDT value = absl::GetFlag(FLAGS_test_flag_sa_udt); 991 EXPECT_EQ(value.c, 'A'); 992 EXPECT_EQ(value.s, 12); 993 994 value.c = 'B'; 995 value.s = 45; 996 absl::SetFlag(&FLAGS_test_flag_sa_udt, value); 997 value = absl::GetFlag(FLAGS_test_flag_sa_udt); 998 EXPECT_EQ(value.c, 'B'); 999 EXPECT_EQ(value.s, 45); 1000 } 1001 } // namespace 1002 1003 // -------------------------------------------------------------------- 1004 1005 namespace { 1006 1007 // User-defined not trivially copyable type. 1008 template <int id> 1009 struct NonTriviallyCopyableUDT { 1010 NonTriviallyCopyableUDT() : c('A') { s_num_instance++; } 1011 NonTriviallyCopyableUDT(const NonTriviallyCopyableUDT& rhs) : c(rhs.c) { 1012 s_num_instance++; 1013 } 1014 NonTriviallyCopyableUDT& operator=(const NonTriviallyCopyableUDT& rhs) { 1015 c = rhs.c; 1016 return *this; 1017 } 1018 ~NonTriviallyCopyableUDT() { s_num_instance--; } 1019 1020 static uint64_t s_num_instance; 1021 char c; 1022 }; 1023 1024 template <int id> 1025 uint64_t NonTriviallyCopyableUDT<id>::s_num_instance = 0; 1026 1027 template <int id> 1028 bool AbslParseFlag(absl::string_view txt, NonTriviallyCopyableUDT<id>* f, 1029 std::string*) { 1030 f->c = txt.empty() ? '\0' : txt[0]; 1031 return true; 1032 } 1033 template <int id> 1034 std::string AbslUnparseFlag(const NonTriviallyCopyableUDT<id>&) { 1035 return ""; 1036 } 1037 1038 template <int id, typename F> 1039 void TestExpectedLeaks( 1040 F&& f, uint64_t num_leaks, 1041 absl::optional<uint64_t> num_new_instances = absl::nullopt) { 1042 if (!num_new_instances.has_value()) num_new_instances = num_leaks; 1043 1044 auto num_leaked_before = flags::NumLeakedFlagValues(); 1045 auto num_instances_before = NonTriviallyCopyableUDT<id>::s_num_instance; 1046 f(); 1047 EXPECT_EQ(num_leaked_before + num_leaks, flags::NumLeakedFlagValues()); 1048 EXPECT_EQ(num_instances_before + num_new_instances.value(), 1049 NonTriviallyCopyableUDT<id>::s_num_instance); 1050 } 1051 } // namespace 1052 1053 ABSL_FLAG(NonTriviallyCopyableUDT<1>, test_flag_ntc_udt1, {}, "help"); 1054 ABSL_FLAG(NonTriviallyCopyableUDT<2>, test_flag_ntc_udt2, {}, "help"); 1055 ABSL_FLAG(NonTriviallyCopyableUDT<3>, test_flag_ntc_udt3, {}, "help"); 1056 ABSL_FLAG(NonTriviallyCopyableUDT<4>, test_flag_ntc_udt4, {}, "help"); 1057 ABSL_FLAG(NonTriviallyCopyableUDT<5>, test_flag_ntc_udt5, {}, "help"); 1058 1059 namespace { 1060 1061 TEST_F(FlagTest, TestNonTriviallyCopyableGetSetSet) { 1062 EXPECT_EQ(flags::StorageKind<NonTriviallyCopyableUDT<1>>(), 1063 flags::FlagValueStorageKind::kHeapAllocated); 1064 1065 TestExpectedLeaks<1>( 1066 [&] { 1067 NonTriviallyCopyableUDT<1> value = 1068 absl::GetFlag(FLAGS_test_flag_ntc_udt1); 1069 EXPECT_EQ(value.c, 'A'); 1070 }, 1071 0); 1072 1073 TestExpectedLeaks<1>( 1074 [&] { 1075 NonTriviallyCopyableUDT<1> value; 1076 value.c = 'B'; 1077 absl::SetFlag(&FLAGS_test_flag_ntc_udt1, value); 1078 EXPECT_EQ(value.c, 'B'); 1079 }, 1080 1); 1081 1082 TestExpectedLeaks<1>( 1083 [&] { 1084 NonTriviallyCopyableUDT<1> value; 1085 value.c = 'C'; 1086 absl::SetFlag(&FLAGS_test_flag_ntc_udt1, value); 1087 }, 1088 0); 1089 } 1090 1091 TEST_F(FlagTest, TestNonTriviallyCopyableParseSet) { 1092 TestExpectedLeaks<2>( 1093 [&] { 1094 const char* in_argv[] = {"testbin", "--test_flag_ntc_udt2=A"}; 1095 absl::ParseCommandLine(2, const_cast<char**>(in_argv)); 1096 }, 1097 0); 1098 1099 TestExpectedLeaks<2>( 1100 [&] { 1101 NonTriviallyCopyableUDT<2> value; 1102 value.c = 'B'; 1103 absl::SetFlag(&FLAGS_test_flag_ntc_udt2, value); 1104 EXPECT_EQ(value.c, 'B'); 1105 }, 1106 0); 1107 } 1108 1109 TEST_F(FlagTest, TestNonTriviallyCopyableSet) { 1110 TestExpectedLeaks<3>( 1111 [&] { 1112 NonTriviallyCopyableUDT<3> value; 1113 value.c = 'B'; 1114 absl::SetFlag(&FLAGS_test_flag_ntc_udt3, value); 1115 EXPECT_EQ(value.c, 'B'); 1116 }, 1117 0); 1118 } 1119 1120 // One new instance created during initialization and stored in the flag. 1121 auto premain_utd4_get = 1122 (TestExpectedLeaks<4>([] { (void)absl::GetFlag(FLAGS_test_flag_ntc_udt4); }, 1123 0, 1), 1124 false); 1125 1126 TEST_F(FlagTest, TestNonTriviallyCopyableGetBeforeMainParseGet) { 1127 TestExpectedLeaks<4>( 1128 [&] { 1129 const char* in_argv[] = {"testbin", "--test_flag_ntc_udt4=C"}; 1130 absl::ParseCommandLine(2, const_cast<char**>(in_argv)); 1131 }, 1132 1); 1133 1134 TestExpectedLeaks<4>( 1135 [&] { 1136 NonTriviallyCopyableUDT<4> value = 1137 absl::GetFlag(FLAGS_test_flag_ntc_udt4); 1138 EXPECT_EQ(value.c, 'C'); 1139 }, 1140 0); 1141 } 1142 1143 // One new instance created during initialization, which is reused since it was 1144 // never read. 1145 auto premain_utd5_set = (TestExpectedLeaks<5>( 1146 [] { 1147 NonTriviallyCopyableUDT<5> value; 1148 value.c = 'B'; 1149 absl::SetFlag(&FLAGS_test_flag_ntc_udt5, value); 1150 }, 1151 0, 1), 1152 false); 1153 1154 TEST_F(FlagTest, TestNonTriviallyCopyableSetParseGet) { 1155 TestExpectedLeaks<5>( 1156 [&] { 1157 const char* in_argv[] = {"testbin", "--test_flag_ntc_udt5=C"}; 1158 absl::ParseCommandLine(2, const_cast<char**>(in_argv)); 1159 }, 1160 0); 1161 1162 TestExpectedLeaks<5>( 1163 [&] { 1164 NonTriviallyCopyableUDT<5> value = 1165 absl::GetFlag(FLAGS_test_flag_ntc_udt5); 1166 EXPECT_EQ(value.c, 'C'); 1167 }, 1168 0); 1169 } 1170 1171 } // namespace 1172 1173 // -------------------------------------------------------------------- 1174 1175 namespace { 1176 1177 enum TestE { A = 1, B = 2, C = 3 }; 1178 1179 struct EnumWrapper { 1180 EnumWrapper() : e(A) {} 1181 1182 TestE e; 1183 }; 1184 1185 bool AbslParseFlag(absl::string_view, EnumWrapper*, std::string*) { 1186 return true; 1187 } 1188 std::string AbslUnparseFlag(const EnumWrapper&) { return ""; } 1189 1190 } // namespace 1191 1192 ABSL_FLAG(EnumWrapper, test_enum_wrapper_flag, {}, "help"); 1193 1194 TEST_F(FlagTest, TesTypeWrappingEnum) { 1195 EnumWrapper value = absl::GetFlag(FLAGS_test_enum_wrapper_flag); 1196 EXPECT_EQ(value.e, A); 1197 1198 value.e = B; 1199 absl::SetFlag(&FLAGS_test_enum_wrapper_flag, value); 1200 value = absl::GetFlag(FLAGS_test_enum_wrapper_flag); 1201 EXPECT_EQ(value.e, B); 1202 } 1203 1204 // This is a compile test to ensure macros are expanded within ABSL_FLAG and 1205 // ABSL_DECLARE_FLAG. 1206 #define FLAG_NAME_MACRO(name) prefix_##name 1207 ABSL_DECLARE_FLAG(int, FLAG_NAME_MACRO(test_macro_named_flag)); 1208 ABSL_FLAG(int, FLAG_NAME_MACRO(test_macro_named_flag), 0, 1209 "Testing macro expansion within ABSL_FLAG"); 1210 1211 TEST_F(FlagTest, MacroWithinAbslFlag) { 1212 EXPECT_EQ(absl::GetFlag(FLAGS_prefix_test_macro_named_flag), 0); 1213 absl::SetFlag(&FLAGS_prefix_test_macro_named_flag, 1); 1214 EXPECT_EQ(absl::GetFlag(FLAGS_prefix_test_macro_named_flag), 1); 1215 } 1216 1217 // -------------------------------------------------------------------- 1218 1219 ABSL_FLAG(absl::optional<bool>, optional_bool, absl::nullopt, "help"); 1220 ABSL_FLAG(absl::optional<int>, optional_int, {}, "help"); 1221 ABSL_FLAG(absl::optional<double>, optional_double, 9.3, "help"); 1222 ABSL_FLAG(absl::optional<std::string>, optional_string, absl::nullopt, "help"); 1223 ABSL_FLAG(absl::optional<absl::Duration>, optional_duration, absl::nullopt, 1224 "help"); 1225 ABSL_FLAG(absl::optional<absl::optional<int>>, optional_optional_int, 1226 absl::nullopt, "help"); 1227 #if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL) 1228 ABSL_FLAG(std::optional<int64_t>, std_optional_int64, std::nullopt, "help"); 1229 #endif 1230 1231 namespace { 1232 1233 TEST_F(FlagTest, TestOptionalBool) { 1234 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_bool).has_value()); 1235 EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), absl::nullopt); 1236 1237 absl::SetFlag(&FLAGS_optional_bool, false); 1238 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_bool).has_value()); 1239 EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), false); 1240 1241 absl::SetFlag(&FLAGS_optional_bool, true); 1242 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_bool).has_value()); 1243 EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), true); 1244 1245 absl::SetFlag(&FLAGS_optional_bool, absl::nullopt); 1246 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_bool).has_value()); 1247 EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), absl::nullopt); 1248 } 1249 1250 // -------------------------------------------------------------------- 1251 1252 TEST_F(FlagTest, TestOptionalInt) { 1253 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_int).has_value()); 1254 EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), absl::nullopt); 1255 1256 absl::SetFlag(&FLAGS_optional_int, 0); 1257 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_int).has_value()); 1258 EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), 0); 1259 1260 absl::SetFlag(&FLAGS_optional_int, 10); 1261 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_int).has_value()); 1262 EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), 10); 1263 1264 absl::SetFlag(&FLAGS_optional_int, absl::nullopt); 1265 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_int).has_value()); 1266 EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), absl::nullopt); 1267 } 1268 1269 // -------------------------------------------------------------------- 1270 1271 TEST_F(FlagTest, TestOptionalDouble) { 1272 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value()); 1273 EXPECT_DOUBLE_EQ(*absl::GetFlag(FLAGS_optional_double), 9.3); 1274 1275 absl::SetFlag(&FLAGS_optional_double, 0.0); 1276 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value()); 1277 EXPECT_EQ(absl::GetFlag(FLAGS_optional_double), 0.0); 1278 1279 absl::SetFlag(&FLAGS_optional_double, 1.234); 1280 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value()); 1281 EXPECT_DOUBLE_EQ(*absl::GetFlag(FLAGS_optional_double), 1.234); 1282 1283 absl::SetFlag(&FLAGS_optional_double, absl::nullopt); 1284 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_double).has_value()); 1285 EXPECT_EQ(absl::GetFlag(FLAGS_optional_double), absl::nullopt); 1286 } 1287 1288 // -------------------------------------------------------------------- 1289 1290 TEST_F(FlagTest, TestOptionalString) { 1291 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_string).has_value()); 1292 EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), absl::nullopt); 1293 1294 // Setting optional string to "" leads to undefined behavior. 1295 1296 absl::SetFlag(&FLAGS_optional_string, " "); 1297 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_string).has_value()); 1298 EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), " "); 1299 1300 absl::SetFlag(&FLAGS_optional_string, "QWERTY"); 1301 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_string).has_value()); 1302 EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), "QWERTY"); 1303 1304 absl::SetFlag(&FLAGS_optional_string, absl::nullopt); 1305 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_string).has_value()); 1306 EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), absl::nullopt); 1307 } 1308 1309 // -------------------------------------------------------------------- 1310 1311 TEST_F(FlagTest, TestOptionalDuration) { 1312 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_duration).has_value()); 1313 EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::nullopt); 1314 1315 absl::SetFlag(&FLAGS_optional_duration, absl::ZeroDuration()); 1316 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_duration).has_value()); 1317 EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::Seconds(0)); 1318 1319 absl::SetFlag(&FLAGS_optional_duration, absl::Hours(3)); 1320 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_duration).has_value()); 1321 EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::Hours(3)); 1322 1323 absl::SetFlag(&FLAGS_optional_duration, absl::nullopt); 1324 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_duration).has_value()); 1325 EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::nullopt); 1326 } 1327 1328 // -------------------------------------------------------------------- 1329 1330 TEST_F(FlagTest, TestOptionalOptional) { 1331 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_optional_int).has_value()); 1332 EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::nullopt); 1333 1334 absl::optional<int> nullint{absl::nullopt}; 1335 1336 absl::SetFlag(&FLAGS_optional_optional_int, nullint); 1337 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value()); 1338 EXPECT_NE(absl::GetFlag(FLAGS_optional_optional_int), nullint); 1339 EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), 1340 absl::optional<absl::optional<int>>{nullint}); 1341 1342 absl::SetFlag(&FLAGS_optional_optional_int, 0); 1343 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value()); 1344 EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), 0); 1345 1346 absl::SetFlag(&FLAGS_optional_optional_int, absl::optional<int>{0}); 1347 EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value()); 1348 EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), 0); 1349 EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::optional<int>{0}); 1350 1351 absl::SetFlag(&FLAGS_optional_optional_int, absl::nullopt); 1352 EXPECT_FALSE(absl::GetFlag(FLAGS_optional_optional_int).has_value()); 1353 EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::nullopt); 1354 } 1355 1356 // -------------------------------------------------------------------- 1357 1358 #if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL) 1359 1360 TEST_F(FlagTest, TestStdOptional) { 1361 EXPECT_FALSE(absl::GetFlag(FLAGS_std_optional_int64).has_value()); 1362 EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), std::nullopt); 1363 1364 absl::SetFlag(&FLAGS_std_optional_int64, 0); 1365 EXPECT_TRUE(absl::GetFlag(FLAGS_std_optional_int64).has_value()); 1366 EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), 0); 1367 1368 absl::SetFlag(&FLAGS_std_optional_int64, 0xFFFFFFFFFF16); 1369 EXPECT_TRUE(absl::GetFlag(FLAGS_std_optional_int64).has_value()); 1370 EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), 0xFFFFFFFFFF16); 1371 1372 absl::SetFlag(&FLAGS_std_optional_int64, std::nullopt); 1373 EXPECT_FALSE(absl::GetFlag(FLAGS_std_optional_int64).has_value()); 1374 EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), std::nullopt); 1375 } 1376 1377 // -------------------------------------------------------------------- 1378 1379 #endif 1380 1381 } // namespace