1 //===-- flags_test.cpp ------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "tests/scudo_unit_test.h"
12 #include "flags_parser.h"
16 static const char FlagName
[] = "flag_name";
17 static const char FlagDesc
[] = "flag description";
20 static void testFlag(scudo::FlagType Type
, T StartValue
, const char *Env
,
22 scudo::FlagParser Parser
;
24 Parser
.registerFlag(FlagName
, FlagDesc
, Type
, &Flag
);
25 Parser
.parseString(Env
);
26 EXPECT_EQ(FinalValue
, Flag
);
27 // Reporting unrecognized flags is needed to reset them.
28 scudo::reportUnrecognizedFlags();
31 TEST(ScudoFlagsTest
, BooleanFlags
) {
32 testFlag(scudo::FlagType::FT_bool
, false, "flag_name=1", true);
33 testFlag(scudo::FlagType::FT_bool
, false, "flag_name=yes", true);
34 testFlag(scudo::FlagType::FT_bool
, false, "flag_name='yes'", true);
35 testFlag(scudo::FlagType::FT_bool
, false, "flag_name=true", true);
36 testFlag(scudo::FlagType::FT_bool
, true, "flag_name=0", false);
37 testFlag(scudo::FlagType::FT_bool
, true, "flag_name=\"0\"", false);
38 testFlag(scudo::FlagType::FT_bool
, true, "flag_name=no", false);
39 testFlag(scudo::FlagType::FT_bool
, true, "flag_name=false", false);
40 testFlag(scudo::FlagType::FT_bool
, true, "flag_name='false'", false);
43 TEST(ScudoFlagsDeathTest
, BooleanFlags
) {
44 EXPECT_DEATH(testFlag(scudo::FlagType::FT_bool
, false, "flag_name", true),
46 EXPECT_DEATH(testFlag(scudo::FlagType::FT_bool
, false, "flag_name=", true),
47 "invalid value for bool option: ''");
48 EXPECT_DEATH(testFlag(scudo::FlagType::FT_bool
, false, "flag_name=2", true),
49 "invalid value for bool option: '2'");
50 EXPECT_DEATH(testFlag(scudo::FlagType::FT_bool
, false, "flag_name=-1", true),
51 "invalid value for bool option: '-1'");
52 EXPECT_DEATH(testFlag(scudo::FlagType::FT_bool
, false, "flag_name=on", true),
53 "invalid value for bool option: 'on'");
56 TEST(ScudoFlagsTest
, IntFlags
) {
57 testFlag(scudo::FlagType::FT_int
, -11, nullptr, -11);
58 testFlag(scudo::FlagType::FT_int
, -11, "flag_name=0", 0);
59 testFlag(scudo::FlagType::FT_int
, -11, "flag_name='0'", 0);
60 testFlag(scudo::FlagType::FT_int
, -11, "flag_name=42", 42);
61 testFlag(scudo::FlagType::FT_int
, -11, "flag_name=-42", -42);
62 testFlag(scudo::FlagType::FT_int
, -11, "flag_name=\"-42\"", -42);
64 // Unrecognized flags are ignored.
65 testFlag(scudo::FlagType::FT_int
, -11, "--flag_name=42", -11);
66 testFlag(scudo::FlagType::FT_int
, -11, "zzzzzzz=42", -11);
69 TEST(ScudoFlagsDeathTest
, IntFlags
) {
70 EXPECT_DEATH(testFlag(scudo::FlagType::FT_int
, -11, "flag_name", 0),
72 EXPECT_DEATH(testFlag(scudo::FlagType::FT_int
, -11, "flag_name=42U", 0),
73 "invalid value for int option");
76 static void testTwoFlags(const char *Env
, bool ExpectedFlag1
,
77 const int ExpectedFlag2
, const char *Name1
= "flag1",
78 const char *Name2
= "flag2") {
79 scudo::FlagParser Parser
;
80 bool Flag1
= !ExpectedFlag1
;
82 Parser
.registerFlag(Name1
, FlagDesc
, scudo::FlagType::FT_bool
, &Flag1
);
83 Parser
.registerFlag(Name2
, FlagDesc
, scudo::FlagType::FT_int
, &Flag2
);
84 Parser
.parseString(Env
);
85 EXPECT_EQ(ExpectedFlag1
, Flag1
);
86 EXPECT_EQ(Flag2
, ExpectedFlag2
);
87 // Reporting unrecognized flags is needed to reset them.
88 scudo::reportUnrecognizedFlags();
91 TEST(ScudoFlagsTest
, MultipleFlags
) {
92 testTwoFlags("flag1=1 flag2=42", true, 42);
93 testTwoFlags("flag2=-1 flag1=0", false, -1);
94 testTwoFlags("flag1=false:flag2=1337", false, 1337);
95 testTwoFlags("flag2=42:flag1=yes", true, 42);
96 testTwoFlags("flag2=42\nflag1=yes", true, 42);
97 testTwoFlags("flag2=42\r\nflag1=yes", true, 42);
98 testTwoFlags("flag2=42\tflag1=yes", true, 42);
101 TEST(ScudoFlagsTest
, CommonSuffixFlags
) {
102 testTwoFlags("flag=1 other_flag=42", true, 42, "flag", "other_flag");
103 testTwoFlags("other_flag=42 flag=1", true, 42, "flag", "other_flag");
106 TEST(ScudoFlagsTest
, AllocatorFlags
) {
107 scudo::FlagParser Parser
;
109 scudo::registerFlags(&Parser
, &Flags
);
111 Flags
.dealloc_type_mismatch
= false;
112 Flags
.delete_size_mismatch
= false;
113 Flags
.quarantine_max_chunk_size
= 1024;
114 Parser
.parseString("dealloc_type_mismatch=true:delete_size_mismatch=true:"
115 "quarantine_max_chunk_size=2048");
116 EXPECT_TRUE(Flags
.dealloc_type_mismatch
);
117 EXPECT_TRUE(Flags
.delete_size_mismatch
);
118 EXPECT_EQ(2048, Flags
.quarantine_max_chunk_size
);
121 #ifdef GWP_ASAN_HOOKS
122 TEST(ScudoFlagsTest
, GWPASanFlags
) {
123 scudo::FlagParser Parser
;
125 scudo::registerFlags(&Parser
, &Flags
);
127 Flags
.GWP_ASAN_Enabled
= false;
128 Parser
.parseString("GWP_ASAN_Enabled=true:GWP_ASAN_SampleRate=1:"
129 "GWP_ASAN_InstallSignalHandlers=false");
130 EXPECT_TRUE(Flags
.GWP_ASAN_Enabled
);
131 EXPECT_FALSE(Flags
.GWP_ASAN_InstallSignalHandlers
);
132 EXPECT_EQ(1, Flags
.GWP_ASAN_SampleRate
);
134 #endif // GWP_ASAN_HOOKS