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 <cmath>
22 #include <new>
23 #include <string>
24 #include <thread>  // NOLINT
25 #include <vector>
26 
27 #include "gtest/gtest.h"
28 #include "absl/base/attributes.h"
29 #include "absl/flags/config.h"
30 #include "absl/flags/declare.h"
31 #include "absl/flags/internal/flag.h"
32 #include "absl/flags/marshalling.h"
33 #include "absl/flags/reflection.h"
34 #include "absl/flags/usage_config.h"
35 #include "absl/strings/match.h"
36 #include "absl/strings/numbers.h"
37 #include "absl/strings/str_cat.h"
38 #include "absl/strings/str_split.h"
39 #include "absl/strings/string_view.h"
40 #include "absl/time/time.h"
41 
42 ABSL_DECLARE_FLAG(int64_t, mistyped_int_flag);
43 ABSL_DECLARE_FLAG(std::vector<std::string>, mistyped_string_flag);
44 
45 namespace {
46 
47 namespace flags = absl::flags_internal;
48 
TestHelpMsg()49 std::string TestHelpMsg() { return "dynamic help"; }
50 #if defined(_MSC_VER) && !defined(__clang__)
TestLiteralHelpMsg()51 std::string TestLiteralHelpMsg() { return "literal help"; }
52 #endif
53 template <typename T>
TestMakeDflt(void * dst)54 void TestMakeDflt(void* dst) {
55   new (dst) T{};
56 }
TestCallback()57 void TestCallback() {}
58 
59 struct UDT {
60   UDT() = default;
61   UDT(const UDT&) = default;
62 };
AbslParseFlag(absl::string_view,UDT *,std::string *)63 bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
AbslUnparseFlag(const UDT &)64 std::string AbslUnparseFlag(const UDT&) { return ""; }
65 
66 class FlagTest : public testing::Test {
67  protected:
SetUpTestSuite()68   static void SetUpTestSuite() {
69     // Install a function to normalize filenames before this test is run.
70     absl::FlagsUsageConfig default_config;
71     default_config.normalize_filename = &FlagTest::NormalizeFileName;
72     absl::SetFlagsUsageConfig(default_config);
73   }
74 
75  private:
NormalizeFileName(absl::string_view fname)76   static std::string NormalizeFileName(absl::string_view fname) {
77 #ifdef _WIN32
78     std::string normalized(fname);
79     std::replace(normalized.begin(), normalized.end(), '\\', '/');
80     fname = normalized;
81 #endif
82     return std::string(fname);
83   }
84   absl::FlagSaver flag_saver_;
85 };
86 
87 struct S1 {
88   S1() = default;
89   S1(const S1&) = default;
90   int32_t f1;
91   int64_t f2;
92 };
93 
94 struct S2 {
95   S2() = default;
96   S2(const S2&) = default;
97   int64_t f1;
98   double f2;
99 };
100 
TEST_F(FlagTest,Traits)101 TEST_F(FlagTest, Traits) {
102   EXPECT_EQ(flags::StorageKind<int>(),
103             flags::FlagValueStorageKind::kOneWordAtomic);
104   EXPECT_EQ(flags::StorageKind<bool>(),
105             flags::FlagValueStorageKind::kOneWordAtomic);
106   EXPECT_EQ(flags::StorageKind<double>(),
107             flags::FlagValueStorageKind::kOneWordAtomic);
108   EXPECT_EQ(flags::StorageKind<int64_t>(),
109             flags::FlagValueStorageKind::kOneWordAtomic);
110 
111 #if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD)
112   EXPECT_EQ(flags::StorageKind<S1>(),
113             flags::FlagValueStorageKind::kTwoWordsAtomic);
114   EXPECT_EQ(flags::StorageKind<S2>(),
115             flags::FlagValueStorageKind::kTwoWordsAtomic);
116 #else
117   EXPECT_EQ(flags::StorageKind<S1>(),
118             flags::FlagValueStorageKind::kAlignedBuffer);
119   EXPECT_EQ(flags::StorageKind<S2>(),
120             flags::FlagValueStorageKind::kAlignedBuffer);
121 #endif
122 
123   EXPECT_EQ(flags::StorageKind<std::string>(),
124             flags::FlagValueStorageKind::kAlignedBuffer);
125   EXPECT_EQ(flags::StorageKind<std::vector<std::string>>(),
126             flags::FlagValueStorageKind::kAlignedBuffer);
127 }
128 
129 // --------------------------------------------------------------------
130 
131 constexpr flags::FlagHelpArg help_arg{flags::FlagHelpMsg("literal help"),
132                                       flags::FlagHelpKind::kLiteral};
133 
134 using String = std::string;
135 
136 #if !defined(_MSC_VER) || defined(__clang__)
137 #define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind)                        \
138   constexpr flags::FlagDefaultArg f1default##T{                            \
139       flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind};     \
140   constexpr absl::Flag<T> f1##T{"f1", "file", help_arg, f1default##T};     \
141   ABSL_CONST_INIT absl::Flag<T> f2##T {                                    \
142     "f2", "file",                                                          \
143         {flags::FlagHelpMsg(&TestHelpMsg), flags::FlagHelpKind::kGenFunc}, \
144         flags::FlagDefaultArg {                                            \
145       flags::FlagDefaultSrc(&TestMakeDflt<T>),                             \
146           flags::FlagDefaultKind::kGenFunc                                 \
147     }                                                                      \
148   }
149 #else
150 #define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind)                    \
151   constexpr flags::FlagDefaultArg f1default##T{                        \
152       flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind}; \
153   constexpr absl::Flag<T> f1##T{"f1", "file", &TestLiteralHelpMsg,     \
154                                 &TestMakeDflt<T>};                     \
155   ABSL_CONST_INIT absl::Flag<T> f2##T {                                \
156     "f2", "file", &TestHelpMsg, &TestMakeDflt<T>                       \
157   }
158 #endif
159 
160 DEFINE_CONSTRUCTED_FLAG(bool, true, kOneWord);
161 DEFINE_CONSTRUCTED_FLAG(int16_t, 1, kOneWord);
162 DEFINE_CONSTRUCTED_FLAG(uint16_t, 2, kOneWord);
163 DEFINE_CONSTRUCTED_FLAG(int32_t, 3, kOneWord);
164 DEFINE_CONSTRUCTED_FLAG(uint32_t, 4, kOneWord);
165 DEFINE_CONSTRUCTED_FLAG(int64_t, 5, kOneWord);
166 DEFINE_CONSTRUCTED_FLAG(uint64_t, 6, kOneWord);
167 DEFINE_CONSTRUCTED_FLAG(float, 7.8, kOneWord);
168 DEFINE_CONSTRUCTED_FLAG(double, 9.10, kOneWord);
169 DEFINE_CONSTRUCTED_FLAG(String, &TestMakeDflt<String>, kGenFunc);
170 DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt<UDT>, kGenFunc);
171 
172 template <typename T>
TestConstructionFor(const absl::Flag<T> & f1,absl::Flag<T> & f2)173 bool TestConstructionFor(const absl::Flag<T>& f1, absl::Flag<T>& f2) {
174   EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Name(), "f1");
175   EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help");
176   EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Filename(), "file");
177 
178   flags::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(f2))
179       .OnUpdate(TestCallback);
180 
181   EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Name(), "f2");
182   EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Help(), "dynamic help");
183   EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Filename(), "file");
184 
185   return true;
186 }
187 
188 #define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T);
189 
TEST_F(FlagTest,TestConstruction)190 TEST_F(FlagTest, TestConstruction) {
191   TEST_CONSTRUCTED_FLAG(bool);
192   TEST_CONSTRUCTED_FLAG(int16_t);
193   TEST_CONSTRUCTED_FLAG(uint16_t);
194   TEST_CONSTRUCTED_FLAG(int32_t);
195   TEST_CONSTRUCTED_FLAG(uint32_t);
196   TEST_CONSTRUCTED_FLAG(int64_t);
197   TEST_CONSTRUCTED_FLAG(uint64_t);
198   TEST_CONSTRUCTED_FLAG(float);
199   TEST_CONSTRUCTED_FLAG(double);
200   TEST_CONSTRUCTED_FLAG(String);
201   TEST_CONSTRUCTED_FLAG(UDT);
202 }
203 
204 // --------------------------------------------------------------------
205 
206 }  // namespace
207 
208 ABSL_DECLARE_FLAG(bool, test_flag_01);
209 ABSL_DECLARE_FLAG(int, test_flag_02);
210 ABSL_DECLARE_FLAG(int16_t, test_flag_03);
211 ABSL_DECLARE_FLAG(uint16_t, test_flag_04);
212 ABSL_DECLARE_FLAG(int32_t, test_flag_05);
213 ABSL_DECLARE_FLAG(uint32_t, test_flag_06);
214 ABSL_DECLARE_FLAG(int64_t, test_flag_07);
215 ABSL_DECLARE_FLAG(uint64_t, test_flag_08);
216 ABSL_DECLARE_FLAG(double, test_flag_09);
217 ABSL_DECLARE_FLAG(float, test_flag_10);
218 ABSL_DECLARE_FLAG(std::string, test_flag_11);
219 ABSL_DECLARE_FLAG(absl::Duration, test_flag_12);
220 
221 namespace {
222 
223 #if !ABSL_FLAGS_STRIP_NAMES
224 
TEST_F(FlagTest,TestFlagDeclaration)225 TEST_F(FlagTest, TestFlagDeclaration) {
226   // test that we can access flag objects.
227   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(),
228             "test_flag_01");
229   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(),
230             "test_flag_02");
231   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(),
232             "test_flag_03");
233   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(),
234             "test_flag_04");
235   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(),
236             "test_flag_05");
237   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(),
238             "test_flag_06");
239   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(),
240             "test_flag_07");
241   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(),
242             "test_flag_08");
243   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(),
244             "test_flag_09");
245   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(),
246             "test_flag_10");
247   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(),
248             "test_flag_11");
249   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(),
250             "test_flag_12");
251 }
252 #endif  // !ABSL_FLAGS_STRIP_NAMES
253 
254 // --------------------------------------------------------------------
255 
256 }  // namespace
257 
258 ABSL_FLAG(bool, test_flag_01, true, "test flag 01");
259 ABSL_FLAG(int, test_flag_02, 1234, "test flag 02");
260 ABSL_FLAG(int16_t, test_flag_03, -34, "test flag 03");
261 ABSL_FLAG(uint16_t, test_flag_04, 189, "test flag 04");
262 ABSL_FLAG(int32_t, test_flag_05, 10765, "test flag 05");
263 ABSL_FLAG(uint32_t, test_flag_06, 40000, "test flag 06");
264 ABSL_FLAG(int64_t, test_flag_07, -1234567, "test flag 07");
265 ABSL_FLAG(uint64_t, test_flag_08, 9876543, "test flag 08");
266 ABSL_FLAG(double, test_flag_09, -9.876e-50, "test flag 09");
267 ABSL_FLAG(float, test_flag_10, 1.234e12f, "test flag 10");
268 ABSL_FLAG(std::string, test_flag_11, "", "test flag 11");
269 ABSL_FLAG(absl::Duration, test_flag_12, absl::Minutes(10), "test flag 12");
270 
271 namespace {
272 
273 #if !ABSL_FLAGS_STRIP_NAMES
TEST_F(FlagTest,TestFlagDefinition)274 TEST_F(FlagTest, TestFlagDefinition) {
275   absl::string_view expected_file_name = "absl/flags/flag_test.cc";
276 
277   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(),
278             "test_flag_01");
279   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Help(),
280             "test flag 01");
281   EXPECT_TRUE(absl::EndsWith(
282       absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename(),
283       expected_file_name))
284       << absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename();
285 
286   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(),
287             "test_flag_02");
288   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Help(),
289             "test flag 02");
290   EXPECT_TRUE(absl::EndsWith(
291       absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename(),
292       expected_file_name))
293       << absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename();
294 
295   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(),
296             "test_flag_03");
297   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Help(),
298             "test flag 03");
299   EXPECT_TRUE(absl::EndsWith(
300       absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename(),
301       expected_file_name))
302       << absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename();
303 
304   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(),
305             "test_flag_04");
306   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Help(),
307             "test flag 04");
308   EXPECT_TRUE(absl::EndsWith(
309       absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename(),
310       expected_file_name))
311       << absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename();
312 
313   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(),
314             "test_flag_05");
315   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Help(),
316             "test flag 05");
317   EXPECT_TRUE(absl::EndsWith(
318       absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename(),
319       expected_file_name))
320       << absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename();
321 
322   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(),
323             "test_flag_06");
324   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Help(),
325             "test flag 06");
326   EXPECT_TRUE(absl::EndsWith(
327       absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename(),
328       expected_file_name))
329       << absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename();
330 
331   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(),
332             "test_flag_07");
333   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Help(),
334             "test flag 07");
335   EXPECT_TRUE(absl::EndsWith(
336       absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename(),
337       expected_file_name))
338       << absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename();
339 
340   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(),
341             "test_flag_08");
342   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Help(),
343             "test flag 08");
344   EXPECT_TRUE(absl::EndsWith(
345       absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename(),
346       expected_file_name))
347       << absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename();
348 
349   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(),
350             "test_flag_09");
351   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Help(),
352             "test flag 09");
353   EXPECT_TRUE(absl::EndsWith(
354       absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename(),
355       expected_file_name))
356       << absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename();
357 
358   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(),
359             "test_flag_10");
360   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Help(),
361             "test flag 10");
362   EXPECT_TRUE(absl::EndsWith(
363       absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename(),
364       expected_file_name))
365       << absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename();
366 
367   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(),
368             "test_flag_11");
369   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Help(),
370             "test flag 11");
371   EXPECT_TRUE(absl::EndsWith(
372       absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename(),
373       expected_file_name))
374       << absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename();
375 
376   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(),
377             "test_flag_12");
378   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Help(),
379             "test flag 12");
380   EXPECT_TRUE(absl::EndsWith(
381       absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename(),
382       expected_file_name))
383       << absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename();
384 }
385 #endif  // !ABSL_FLAGS_STRIP_NAMES
386 
387 // --------------------------------------------------------------------
388 
TEST_F(FlagTest,TestDefault)389 TEST_F(FlagTest, TestDefault) {
390   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).DefaultValue(),
391             "true");
392   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).DefaultValue(),
393             "1234");
394   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).DefaultValue(),
395             "-34");
396   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).DefaultValue(),
397             "189");
398   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).DefaultValue(),
399             "10765");
400   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).DefaultValue(),
401             "40000");
402   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).DefaultValue(),
403             "-1234567");
404   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).DefaultValue(),
405             "9876543");
406   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).DefaultValue(),
407             "-9.876e-50");
408   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).DefaultValue(),
409             "1.234e+12");
410   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).DefaultValue(),
411             "");
412   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).DefaultValue(),
413             "10m");
414 
415   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).CurrentValue(),
416             "true");
417   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).CurrentValue(),
418             "1234");
419   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).CurrentValue(),
420             "-34");
421   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).CurrentValue(),
422             "189");
423   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).CurrentValue(),
424             "10765");
425   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).CurrentValue(),
426             "40000");
427   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).CurrentValue(),
428             "-1234567");
429   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).CurrentValue(),
430             "9876543");
431   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).CurrentValue(),
432             "-9.876e-50");
433   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).CurrentValue(),
434             "1.234e+12");
435   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).CurrentValue(),
436             "");
437   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).CurrentValue(),
438             "10m");
439 
440   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true);
441   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234);
442   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34);
443   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 189);
444   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), 10765);
445   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 40000);
446   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -1234567);
447   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 9876543);
448   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), -9.876e-50, 1e-55);
449   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), 1.234e12f, 1e5f);
450   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "");
451   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Minutes(10));
452 }
453 
454 // --------------------------------------------------------------------
455 
456 struct NonTriviallyCopyableAggregate {
457   NonTriviallyCopyableAggregate() = default;
NonTriviallyCopyableAggregate__anon682a291b0311::NonTriviallyCopyableAggregate458   NonTriviallyCopyableAggregate(const NonTriviallyCopyableAggregate& rhs)
459       : value(rhs.value) {}
operator =__anon682a291b0311::NonTriviallyCopyableAggregate460   NonTriviallyCopyableAggregate& operator=(
461       const NonTriviallyCopyableAggregate& rhs) {
462     value = rhs.value;
463     return *this;
464   }
465 
466   int value;
467 };
AbslParseFlag(absl::string_view src,NonTriviallyCopyableAggregate * f,std::string * e)468 bool AbslParseFlag(absl::string_view src, NonTriviallyCopyableAggregate* f,
469                    std::string* e) {
470   return absl::ParseFlag(src, &f->value, e);
471 }
AbslUnparseFlag(const NonTriviallyCopyableAggregate & ntc)472 std::string AbslUnparseFlag(const NonTriviallyCopyableAggregate& ntc) {
473   return absl::StrCat(ntc.value);
474 }
475 
operator ==(const NonTriviallyCopyableAggregate & ntc1,const NonTriviallyCopyableAggregate & ntc2)476 bool operator==(const NonTriviallyCopyableAggregate& ntc1,
477                 const NonTriviallyCopyableAggregate& ntc2) {
478   return ntc1.value == ntc2.value;
479 }
480 
481 }  // namespace
482 
483 ABSL_FLAG(bool, test_flag_eb_01, {}, "");
484 ABSL_FLAG(int32_t, test_flag_eb_02, {}, "");
485 ABSL_FLAG(int64_t, test_flag_eb_03, {}, "");
486 ABSL_FLAG(double, test_flag_eb_04, {}, "");
487 ABSL_FLAG(std::string, test_flag_eb_05, {}, "");
488 ABSL_FLAG(NonTriviallyCopyableAggregate, test_flag_eb_06, {}, "");
489 
490 namespace {
491 
TEST_F(FlagTest,TestEmptyBracesDefault)492 TEST_F(FlagTest, TestEmptyBracesDefault) {
493   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_01).DefaultValue(),
494             "false");
495   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_02).DefaultValue(),
496             "0");
497   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_03).DefaultValue(),
498             "0");
499   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_04).DefaultValue(),
500             "0");
501   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_05).DefaultValue(),
502             "");
503   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_06).DefaultValue(),
504             "0");
505 
506   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_01), false);
507   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_02), 0);
508   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_03), 0);
509   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_04), 0.0);
510   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_05), "");
511   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_06),
512             NonTriviallyCopyableAggregate{});
513 }
514 
515 // --------------------------------------------------------------------
516 
TEST_F(FlagTest,TestGetSet)517 TEST_F(FlagTest, TestGetSet) {
518   absl::SetFlag(&FLAGS_test_flag_01, false);
519   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false);
520 
521   absl::SetFlag(&FLAGS_test_flag_02, 321);
522   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 321);
523 
524   absl::SetFlag(&FLAGS_test_flag_03, 67);
525   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), 67);
526 
527   absl::SetFlag(&FLAGS_test_flag_04, 1);
528   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 1);
529 
530   absl::SetFlag(&FLAGS_test_flag_05, -908);
531   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), -908);
532 
533   absl::SetFlag(&FLAGS_test_flag_06, 4001);
534   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 4001);
535 
536   absl::SetFlag(&FLAGS_test_flag_07, -23456);
537   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -23456);
538 
539   absl::SetFlag(&FLAGS_test_flag_08, 975310);
540   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 975310);
541 
542   absl::SetFlag(&FLAGS_test_flag_09, 1.00001);
543   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), 1.00001, 1e-10);
544 
545   absl::SetFlag(&FLAGS_test_flag_10, -3.54f);
546   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), -3.54f, 1e-6f);
547 
548   absl::SetFlag(&FLAGS_test_flag_11, "asdf");
549   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "asdf");
550 
551   absl::SetFlag(&FLAGS_test_flag_12, absl::Seconds(110));
552   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Seconds(110));
553 }
554 
555 // --------------------------------------------------------------------
556 
TEST_F(FlagTest,TestGetViaReflection)557 TEST_F(FlagTest, TestGetViaReflection) {
558   auto* handle = absl::FindCommandLineFlag("test_flag_01");
559   EXPECT_EQ(*handle->TryGet<bool>(), true);
560   handle = absl::FindCommandLineFlag("test_flag_02");
561   EXPECT_EQ(*handle->TryGet<int>(), 1234);
562   handle = absl::FindCommandLineFlag("test_flag_03");
563   EXPECT_EQ(*handle->TryGet<int16_t>(), -34);
564   handle = absl::FindCommandLineFlag("test_flag_04");
565   EXPECT_EQ(*handle->TryGet<uint16_t>(), 189);
566   handle = absl::FindCommandLineFlag("test_flag_05");
567   EXPECT_EQ(*handle->TryGet<int32_t>(), 10765);
568   handle = absl::FindCommandLineFlag("test_flag_06");
569   EXPECT_EQ(*handle->TryGet<uint32_t>(), 40000);
570   handle = absl::FindCommandLineFlag("test_flag_07");
571   EXPECT_EQ(*handle->TryGet<int64_t>(), -1234567);
572   handle = absl::FindCommandLineFlag("test_flag_08");
573   EXPECT_EQ(*handle->TryGet<uint64_t>(), 9876543);
574   handle = absl::FindCommandLineFlag("test_flag_09");
575   EXPECT_NEAR(*handle->TryGet<double>(), -9.876e-50, 1e-55);
576   handle = absl::FindCommandLineFlag("test_flag_10");
577   EXPECT_NEAR(*handle->TryGet<float>(), 1.234e12f, 1e5f);
578   handle = absl::FindCommandLineFlag("test_flag_11");
579   EXPECT_EQ(*handle->TryGet<std::string>(), "");
580   handle = absl::FindCommandLineFlag("test_flag_12");
581   EXPECT_EQ(*handle->TryGet<absl::Duration>(), absl::Minutes(10));
582 }
583 
584 // --------------------------------------------------------------------
585 
GetDflt1()586 int GetDflt1() { return 1; }
587 
588 }  // namespace
589 
590 ABSL_FLAG(int, test_int_flag_with_non_const_default, GetDflt1(),
591           "test int flag non const default");
592 ABSL_FLAG(std::string, test_string_flag_with_non_const_default,
593           absl::StrCat("AAA", "BBB"), "test string flag non const default");
594 
595 namespace {
596 
TEST_F(FlagTest,TestNonConstexprDefault)597 TEST_F(FlagTest, TestNonConstexprDefault) {
598   EXPECT_EQ(absl::GetFlag(FLAGS_test_int_flag_with_non_const_default), 1);
599   EXPECT_EQ(absl::GetFlag(FLAGS_test_string_flag_with_non_const_default),
600             "AAABBB");
601 }
602 
603 // --------------------------------------------------------------------
604 
605 }  // namespace
606 
607 ABSL_FLAG(bool, test_flag_with_non_const_help, true,
608           absl::StrCat("test ", "flag ", "non const help"));
609 
610 namespace {
611 
612 #if !ABSL_FLAGS_STRIP_HELP
TEST_F(FlagTest,TestNonConstexprHelp)613 TEST_F(FlagTest, TestNonConstexprHelp) {
614   EXPECT_EQ(
615       absl::GetFlagReflectionHandle(FLAGS_test_flag_with_non_const_help).Help(),
616       "test flag non const help");
617 }
618 #endif  //! ABSL_FLAGS_STRIP_HELP
619 
620 // --------------------------------------------------------------------
621 
622 int cb_test_value = -1;
623 void TestFlagCB();
624 
625 }  // namespace
626 
627 ABSL_FLAG(int, test_flag_with_cb, 100, "").OnUpdate(TestFlagCB);
628 
__anon682a291b0702() 629 ABSL_FLAG(int, test_flag_with_lambda_cb, 200, "").OnUpdate([]() {
630   cb_test_value = absl::GetFlag(FLAGS_test_flag_with_lambda_cb) +
631                   absl::GetFlag(FLAGS_test_flag_with_cb);
632 });
633 
634 namespace {
635 
TestFlagCB()636 void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); }
637 
638 // Tests side-effects of callback invocation.
TEST_F(FlagTest,CallbackInvocation)639 TEST_F(FlagTest, CallbackInvocation) {
640   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100);
641   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200);
642   EXPECT_EQ(cb_test_value, 300);
643 
644   absl::SetFlag(&FLAGS_test_flag_with_cb, 1);
645   EXPECT_EQ(cb_test_value, 1);
646 
647   absl::SetFlag(&FLAGS_test_flag_with_lambda_cb, 3);
648   EXPECT_EQ(cb_test_value, 4);
649 }
650 
651 // --------------------------------------------------------------------
652 
653 struct CustomUDT {
CustomUDT__anon682a291b0811::CustomUDT654   CustomUDT() : a(1), b(1) {}
CustomUDT__anon682a291b0811::CustomUDT655   CustomUDT(int a_, int b_) : a(a_), b(b_) {}
656 
operator ==(const CustomUDT & f1,const CustomUDT & f2)657   friend bool operator==(const CustomUDT& f1, const CustomUDT& f2) {
658     return f1.a == f2.a && f1.b == f2.b;
659   }
660 
661   int a;
662   int b;
663 };
AbslParseFlag(absl::string_view in,CustomUDT * f,std::string *)664 bool AbslParseFlag(absl::string_view in, CustomUDT* f, std::string*) {
665   std::vector<absl::string_view> parts =
666       absl::StrSplit(in, ':', absl::SkipWhitespace());
667 
668   if (parts.size() != 2) return false;
669 
670   if (!absl::SimpleAtoi(parts[0], &f->a)) return false;
671 
672   if (!absl::SimpleAtoi(parts[1], &f->b)) return false;
673 
674   return true;
675 }
AbslUnparseFlag(const CustomUDT & f)676 std::string AbslUnparseFlag(const CustomUDT& f) {
677   return absl::StrCat(f.a, ":", f.b);
678 }
679 
680 }  // namespace
681 
682 ABSL_FLAG(CustomUDT, test_flag_custom_udt, CustomUDT(), "test flag custom UDT");
683 
684 namespace {
685 
TEST_F(FlagTest,TestCustomUDT)686 TEST_F(FlagTest, TestCustomUDT) {
687   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(1, 1));
688   absl::SetFlag(&FLAGS_test_flag_custom_udt, CustomUDT(2, 3));
689   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(2, 3));
690 }
691 
692 // MSVC produces link error on the type mismatch.
693 // Linux does not have build errors and validations work as expected.
694 #if !defined(_WIN32) && GTEST_HAS_DEATH_TEST
695 
696 using FlagDeathTest = FlagTest;
697 
TEST_F(FlagDeathTest,TestTypeMismatchValidations)698 TEST_F(FlagDeathTest, TestTypeMismatchValidations) {
699 #if !defined(NDEBUG)
700   EXPECT_DEATH_IF_SUPPORTED(
701       static_cast<void>(absl::GetFlag(FLAGS_mistyped_int_flag)),
702       "Flag 'mistyped_int_flag' is defined as one type and declared "
703       "as another");
704   EXPECT_DEATH_IF_SUPPORTED(
705       static_cast<void>(absl::GetFlag(FLAGS_mistyped_string_flag)),
706       "Flag 'mistyped_string_flag' is defined as one type and "
707       "declared as another");
708 #endif
709 
710   EXPECT_DEATH_IF_SUPPORTED(
711       absl::SetFlag(&FLAGS_mistyped_int_flag, 1),
712       "Flag 'mistyped_int_flag' is defined as one type and declared "
713       "as another");
714   EXPECT_DEATH_IF_SUPPORTED(
715       absl::SetFlag(&FLAGS_mistyped_string_flag, std::vector<std::string>{}),
716       "Flag 'mistyped_string_flag' is defined as one type and declared as "
717       "another");
718 }
719 
720 #endif
721 
722 // --------------------------------------------------------------------
723 
724 // A contrived type that offers implicit and explicit conversion from specific
725 // source types.
726 struct ConversionTestVal {
727   ConversionTestVal() = default;
ConversionTestVal__anon682a291b0911::ConversionTestVal728   explicit ConversionTestVal(int a_in) : a(a_in) {}
729 
730   enum class ViaImplicitConv { kTen = 10, kEleven };
731   // NOLINTNEXTLINE
ConversionTestVal__anon682a291b0911::ConversionTestVal732   ConversionTestVal(ViaImplicitConv from) : a(static_cast<int>(from)) {}
733 
734   int a;
735 };
736 
AbslParseFlag(absl::string_view in,ConversionTestVal * val_out,std::string *)737 bool AbslParseFlag(absl::string_view in, ConversionTestVal* val_out,
738                    std::string*) {
739   if (!absl::SimpleAtoi(in, &val_out->a)) {
740     return false;
741   }
742   return true;
743 }
AbslUnparseFlag(const ConversionTestVal & val)744 std::string AbslUnparseFlag(const ConversionTestVal& val) {
745   return absl::StrCat(val.a);
746 }
747 
748 }  // namespace
749 
750 // Flag default values can be specified with a value that converts to the flag
751 // value type implicitly.
752 ABSL_FLAG(ConversionTestVal, test_flag_implicit_conv,
753           ConversionTestVal::ViaImplicitConv::kTen,
754           "test flag init via implicit conversion");
755 
756 namespace {
757 
TEST_F(FlagTest,CanSetViaImplicitConversion)758 TEST_F(FlagTest, CanSetViaImplicitConversion) {
759   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).a, 10);
760   absl::SetFlag(&FLAGS_test_flag_implicit_conv,
761                 ConversionTestVal::ViaImplicitConv::kEleven);
762   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).a, 11);
763 }
764 
765 // --------------------------------------------------------------------
766 
767 struct NonDfltConstructible {
768  public:
769   // This constructor tests that we can initialize the flag with int value
NonDfltConstructible__anon682a291b0a11::NonDfltConstructible770   NonDfltConstructible(int i) : value(i) {}  // NOLINT
771 
772   // This constructor tests that we can't initialize the flag with char value
773   // but can with explicitly constructed NonDfltConstructible.
NonDfltConstructible__anon682a291b0a11::NonDfltConstructible774   explicit NonDfltConstructible(char c) : value(100 + static_cast<int>(c)) {}
775 
776   int value;
777 };
778 
AbslParseFlag(absl::string_view in,NonDfltConstructible * ndc_out,std::string *)779 bool AbslParseFlag(absl::string_view in, NonDfltConstructible* ndc_out,
780                    std::string*) {
781   return absl::SimpleAtoi(in, &ndc_out->value);
782 }
AbslUnparseFlag(const NonDfltConstructible & ndc)783 std::string AbslUnparseFlag(const NonDfltConstructible& ndc) {
784   return absl::StrCat(ndc.value);
785 }
786 
787 }  // namespace
788 
789 ABSL_FLAG(NonDfltConstructible, ndc_flag1, NonDfltConstructible('1'),
790           "Flag with non default constructible type");
791 ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0,
792           "Flag with non default constructible type");
793 
794 namespace {
795 
TEST_F(FlagTest,TestNonDefaultConstructibleType)796 TEST_F(FlagTest, TestNonDefaultConstructibleType) {
797   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100);
798   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0);
799 
800   absl::SetFlag(&FLAGS_ndc_flag1, NonDfltConstructible('A'));
801   absl::SetFlag(&FLAGS_ndc_flag2, 25);
802 
803   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, 'A' + 100);
804   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 25);
805 }
806 
807 }  // namespace
808 
809 // --------------------------------------------------------------------
810 
811 ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr");
812 ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr");
813 ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
814 
__anon682a291b0c02null815 bool initializaion_order_fiasco_test = [] {
816   // Iterate over all the flags during static initialization.
817   // This should not trigger ASan's initialization-order-fiasco.
818   auto* handle1 = absl::FindCommandLineFlag("flag_on_separate_file");
819   auto* handle2 = absl::FindCommandLineFlag("retired_flag_on_separate_file");
820   if (handle1 != nullptr && handle2 != nullptr) {
821     return handle1->Name() == handle2->Name();
822   }
823   return true;
824 }();
825 
826 namespace {
827 
TEST_F(FlagTest,TestRetiredFlagRegistration)828 TEST_F(FlagTest, TestRetiredFlagRegistration) {
829   auto* handle = absl::FindCommandLineFlag("old_bool_flag");
830   EXPECT_TRUE(handle->IsOfType<bool>());
831   EXPECT_TRUE(handle->IsRetired());
832   handle = absl::FindCommandLineFlag("old_int_flag");
833   EXPECT_TRUE(handle->IsOfType<int>());
834   EXPECT_TRUE(handle->IsRetired());
835   handle = absl::FindCommandLineFlag("old_str_flag");
836   EXPECT_TRUE(handle->IsOfType<std::string>());
837   EXPECT_TRUE(handle->IsRetired());
838 }
839 
840 }  // namespace
841 
842 // --------------------------------------------------------------------
843 
844 namespace {
845 
846 // User-defined type with small alignment, but size exceeding 16.
847 struct SmallAlignUDT {
SmallAlignUDT__anon682a291b0e11::SmallAlignUDT848   SmallAlignUDT() : c('A'), s(12) {}
849   char c;
850   int16_t s;
851   char bytes[14];
852 };
853 
AbslParseFlag(absl::string_view,SmallAlignUDT *,std::string *)854 bool AbslParseFlag(absl::string_view, SmallAlignUDT*, std::string*) {
855   return true;
856 }
AbslUnparseFlag(const SmallAlignUDT &)857 std::string AbslUnparseFlag(const SmallAlignUDT&) { return ""; }
858 
859 // User-defined type with small size, but not trivially copyable.
860 struct NonTriviallyCopyableUDT {
NonTriviallyCopyableUDT__anon682a291b0e11::NonTriviallyCopyableUDT861   NonTriviallyCopyableUDT() : c('A') {}
NonTriviallyCopyableUDT__anon682a291b0e11::NonTriviallyCopyableUDT862   NonTriviallyCopyableUDT(const NonTriviallyCopyableUDT& rhs) : c(rhs.c) {}
operator =__anon682a291b0e11::NonTriviallyCopyableUDT863   NonTriviallyCopyableUDT& operator=(const NonTriviallyCopyableUDT& rhs) {
864     c = rhs.c;
865     return *this;
866   }
867 
868   char c;
869 };
870 
AbslParseFlag(absl::string_view,NonTriviallyCopyableUDT *,std::string *)871 bool AbslParseFlag(absl::string_view, NonTriviallyCopyableUDT*, std::string*) {
872   return true;
873 }
AbslUnparseFlag(const NonTriviallyCopyableUDT &)874 std::string AbslUnparseFlag(const NonTriviallyCopyableUDT&) { return ""; }
875 
876 }  // namespace
877 
878 ABSL_FLAG(SmallAlignUDT, test_flag_sa_udt, {}, "help");
879 ABSL_FLAG(NonTriviallyCopyableUDT, test_flag_ntc_udt, {}, "help");
880 
881 namespace {
882 
TEST_F(FlagTest,TestSmallAlignUDT)883 TEST_F(FlagTest, TestSmallAlignUDT) {
884   SmallAlignUDT value = absl::GetFlag(FLAGS_test_flag_sa_udt);
885   EXPECT_EQ(value.c, 'A');
886   EXPECT_EQ(value.s, 12);
887 
888   value.c = 'B';
889   value.s = 45;
890   absl::SetFlag(&FLAGS_test_flag_sa_udt, value);
891   value = absl::GetFlag(FLAGS_test_flag_sa_udt);
892   EXPECT_EQ(value.c, 'B');
893   EXPECT_EQ(value.s, 45);
894 }
895 
TEST_F(FlagTest,TestNonTriviallyCopyableUDT)896 TEST_F(FlagTest, TestNonTriviallyCopyableUDT) {
897   NonTriviallyCopyableUDT value = absl::GetFlag(FLAGS_test_flag_ntc_udt);
898   EXPECT_EQ(value.c, 'A');
899 
900   value.c = 'B';
901   absl::SetFlag(&FLAGS_test_flag_ntc_udt, value);
902   value = absl::GetFlag(FLAGS_test_flag_ntc_udt);
903   EXPECT_EQ(value.c, 'B');
904 }
905 
906 }  // namespace
907