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