1 //===-- sanitizer_flags_test.cc -------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 11 // 12 //===----------------------------------------------------------------------===// 13 #include "sanitizer_common/sanitizer_common.h" 14 #include "sanitizer_common/sanitizer_flags.h" 15 #include "sanitizer_common/sanitizer_flag_parser.h" 16 #include "sanitizer_common/sanitizer_libc.h" 17 #include "sanitizer_common/sanitizer_allocator_internal.h" 18 #include "gtest/gtest.h" 19 20 #include <string.h> 21 22 namespace __sanitizer { 23 24 static const char kFlagName[] = "flag_name"; 25 static const char kFlagDesc[] = "flag description"; 26 27 template <typename T> 28 static void TestFlag(T start_value, const char *env, T final_value) { 29 T flag = start_value; 30 31 FlagParser parser; 32 RegisterFlag(&parser, kFlagName, kFlagDesc, &flag); 33 34 parser.ParseString(env); 35 36 EXPECT_EQ(final_value, flag); 37 } 38 39 template <> 40 void TestFlag(const char *start_value, const char *env, 41 const char *final_value) { 42 const char *flag = start_value; 43 44 FlagParser parser; 45 RegisterFlag(&parser, kFlagName, kFlagDesc, &flag); 46 47 parser.ParseString(env); 48 49 EXPECT_EQ(0, internal_strcmp(final_value, flag)); 50 } 51 52 TEST(SanitizerCommon, BooleanFlags) { 53 TestFlag(false, "flag_name=1", true); 54 TestFlag(false, "flag_name=yes", true); 55 TestFlag(false, "flag_name=true", true); 56 TestFlag(true, "flag_name=0", false); 57 TestFlag(true, "flag_name=no", false); 58 TestFlag(true, "flag_name=false", false); 59 } 60 61 TEST(SanitizerCommon, IntFlags) { 62 TestFlag(-11, 0, -11); 63 TestFlag(-11, "flag_name=0", 0); 64 TestFlag(-11, "flag_name=42", 42); 65 TestFlag(-11, "flag_name=-42", -42); 66 67 // Unrecognized flags are ignored. 68 TestFlag(-11, "--flag_name=42", -11); 69 TestFlag(-11, "zzzzzzz=42", -11); 70 71 EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='"); 72 EXPECT_DEATH(TestFlag(-11, "flag_name=42U", 0), 73 "Invalid value for int option"); 74 } 75 76 TEST(SanitizerCommon, StrFlags) { 77 TestFlag("zzz", 0, "zzz"); 78 TestFlag("zzz", "flag_name=", ""); 79 TestFlag("zzz", "flag_name=abc", "abc"); 80 TestFlag("", "flag_name=abc", "abc"); 81 TestFlag("", "flag_name='abc zxc'", "abc zxc"); 82 // TestStrFlag("", "flag_name=\"abc qwe\" asd", "abc qwe"); 83 } 84 85 static void TestTwoFlags(const char *env, bool expected_flag1, 86 const char *expected_flag2, 87 const char *name1 = "flag1", 88 const char *name2 = "flag2") { 89 bool flag1 = !expected_flag1; 90 const char *flag2 = ""; 91 92 FlagParser parser; 93 RegisterFlag(&parser, name1, kFlagDesc, &flag1); 94 RegisterFlag(&parser, name2, kFlagDesc, &flag2); 95 96 parser.ParseString(env); 97 98 EXPECT_EQ(expected_flag1, flag1); 99 EXPECT_EQ(0, internal_strcmp(flag2, expected_flag2)); 100 } 101 102 TEST(SanitizerCommon, MultipleFlags) { 103 TestTwoFlags("flag1=1 flag2='zzz'", true, "zzz"); 104 TestTwoFlags("flag2='qxx' flag1=0", false, "qxx"); 105 TestTwoFlags("flag1=false:flag2='zzz'", false, "zzz"); 106 TestTwoFlags("flag2=qxx:flag1=yes", true, "qxx"); 107 TestTwoFlags("flag2=qxx\nflag1=yes", true, "qxx"); 108 TestTwoFlags("flag2=qxx\r\nflag1=yes", true, "qxx"); 109 TestTwoFlags("flag2=qxx\tflag1=yes", true, "qxx"); 110 } 111 112 TEST(SanitizerCommon, CommonSuffixFlags) { 113 TestTwoFlags("flag=1 other_flag='zzz'", true, "zzz", "flag", "other_flag"); 114 TestTwoFlags("other_flag='zzz' flag=1", true, "zzz", "flag", "other_flag"); 115 TestTwoFlags("other_flag=' flag=0 ' flag=1", true, " flag=0 ", "flag", 116 "other_flag"); 117 TestTwoFlags("flag=1 other_flag=' flag=0 '", true, " flag=0 ", "flag", 118 "other_flag"); 119 } 120 121 TEST(SanitizerCommon, CommonFlags) { 122 CommonFlags cf; 123 FlagParser parser; 124 RegisterCommonFlags(&parser, &cf); 125 126 cf.SetDefaults(); 127 EXPECT_TRUE(cf.symbolize); 128 EXPECT_STREQ(".", cf.coverage_dir); 129 130 cf.symbolize = false; 131 cf.coverage = true; 132 cf.coverage_direct = true; 133 cf.log_path = "path/one"; 134 135 parser.ParseString("symbolize=1:coverage_direct=false log_path='path/two'"); 136 EXPECT_TRUE(cf.symbolize); 137 EXPECT_TRUE(cf.coverage); 138 EXPECT_FALSE(cf.coverage_direct); 139 EXPECT_STREQ("path/two", cf.log_path); 140 } 141 142 } // namespace __sanitizer 143