1 //===-- sanitizer_suppressions_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_suppressions.h" 14 #include "gtest/gtest.h" 15 16 #include <string.h> 17 18 namespace __sanitizer { 19 20 static bool MyMatch(const char *templ, const char *func) { 21 char tmp[1024]; 22 strcpy(tmp, templ); // NOLINT 23 return TemplateMatch(tmp, func); 24 } 25 26 TEST(Suppressions, Match) { 27 EXPECT_TRUE(MyMatch("foobar$", "foobar")); 28 29 EXPECT_TRUE(MyMatch("foobar", "foobar")); 30 EXPECT_TRUE(MyMatch("*foobar*", "foobar")); 31 EXPECT_TRUE(MyMatch("foobar", "prefix_foobar_postfix")); 32 EXPECT_TRUE(MyMatch("*foobar*", "prefix_foobar_postfix")); 33 EXPECT_TRUE(MyMatch("foo*bar", "foo_middle_bar")); 34 EXPECT_TRUE(MyMatch("foo*bar", "foobar")); 35 EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_bar_another_baz")); 36 EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_barbaz")); 37 EXPECT_TRUE(MyMatch("^foobar", "foobar")); 38 EXPECT_TRUE(MyMatch("^foobar", "foobar_postfix")); 39 EXPECT_TRUE(MyMatch("^*foobar", "foobar")); 40 EXPECT_TRUE(MyMatch("^*foobar", "prefix_foobar")); 41 EXPECT_TRUE(MyMatch("foobar$", "foobar")); 42 EXPECT_TRUE(MyMatch("foobar$", "prefix_foobar")); 43 EXPECT_TRUE(MyMatch("*foobar*$", "foobar")); 44 EXPECT_TRUE(MyMatch("*foobar*$", "foobar_postfix")); 45 EXPECT_TRUE(MyMatch("^foobar$", "foobar")); 46 47 EXPECT_FALSE(MyMatch("foo", "baz")); 48 EXPECT_FALSE(MyMatch("foobarbaz", "foobar")); 49 EXPECT_FALSE(MyMatch("foobarbaz", "barbaz")); 50 EXPECT_FALSE(MyMatch("foo*bar", "foobaz")); 51 EXPECT_FALSE(MyMatch("foo*bar", "foo_baz")); 52 EXPECT_FALSE(MyMatch("^foobar", "prefix_foobar")); 53 EXPECT_FALSE(MyMatch("foobar$", "foobar_postfix")); 54 EXPECT_FALSE(MyMatch("^foobar$", "prefix_foobar")); 55 EXPECT_FALSE(MyMatch("^foobar$", "foobar_postfix")); 56 EXPECT_FALSE(MyMatch("foo^bar", "foobar")); 57 EXPECT_FALSE(MyMatch("foo$bar", "foobar")); 58 EXPECT_FALSE(MyMatch("foo$^bar", "foobar")); 59 } 60 61 TEST(Suppressions, TypeStrings) { 62 CHECK(!internal_strcmp(SuppressionTypeString(SuppressionNone), "none")); 63 CHECK(!internal_strcmp(SuppressionTypeString(SuppressionRace), "race")); 64 CHECK(!internal_strcmp(SuppressionTypeString(SuppressionMutex), "mutex")); 65 CHECK(!internal_strcmp(SuppressionTypeString(SuppressionThread), "thread")); 66 CHECK(!internal_strcmp(SuppressionTypeString(SuppressionSignal), "signal")); 67 CHECK(!internal_strcmp(SuppressionTypeString(SuppressionLeak), "leak")); 68 CHECK(!internal_strcmp(SuppressionTypeString(SuppressionLib), 69 "called_from_lib")); 70 CHECK( 71 !internal_strcmp(SuppressionTypeString(SuppressionDeadlock), "deadlock")); 72 // Ensure this test is up-to-date when suppression types are added. 73 CHECK_EQ(SuppressionTypeCount, 8); 74 } 75 76 class SuppressionContextTest : public ::testing::Test { 77 public: 78 virtual void SetUp() { ctx_ = new(placeholder_) SuppressionContext; } 79 virtual void TearDown() { ctx_->~SuppressionContext(); } 80 81 protected: 82 InternalMmapVector<Suppression> *Suppressions() { 83 return &ctx_->suppressions_; 84 } 85 SuppressionContext *ctx_; 86 ALIGNED(64) char placeholder_[sizeof(SuppressionContext)]; 87 }; 88 89 TEST_F(SuppressionContextTest, Parse) { 90 ctx_->Parse( 91 "race:foo\n" 92 " race:bar\n" // NOLINT 93 "race:baz \n" // NOLINT 94 "# a comment\n" 95 "race:quz\n" 96 ); // NOLINT 97 EXPECT_EQ((unsigned)4, ctx_->SuppressionCount()); 98 EXPECT_EQ((*Suppressions())[3].type, SuppressionRace); 99 EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz")); 100 EXPECT_EQ((*Suppressions())[2].type, SuppressionRace); 101 EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz")); 102 EXPECT_EQ((*Suppressions())[1].type, SuppressionRace); 103 EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar")); 104 EXPECT_EQ((*Suppressions())[0].type, SuppressionRace); 105 EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo")); 106 } 107 108 TEST_F(SuppressionContextTest, Parse2) { 109 ctx_->Parse( 110 " # first line comment\n" // NOLINT 111 " race:bar \n" // NOLINT 112 "race:baz* *baz\n" 113 "# a comment\n" 114 "# last line comment\n" 115 ); // NOLINT 116 EXPECT_EQ((unsigned)2, ctx_->SuppressionCount()); 117 EXPECT_EQ((*Suppressions())[1].type, SuppressionRace); 118 EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "baz* *baz")); 119 EXPECT_EQ((*Suppressions())[0].type, SuppressionRace); 120 EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "bar")); 121 } 122 123 TEST_F(SuppressionContextTest, Parse3) { 124 ctx_->Parse( 125 "# last suppression w/o line-feed\n" 126 "race:foo\n" 127 "race:bar" 128 ); // NOLINT 129 EXPECT_EQ((unsigned)2, ctx_->SuppressionCount()); 130 EXPECT_EQ((*Suppressions())[1].type, SuppressionRace); 131 EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar")); 132 EXPECT_EQ((*Suppressions())[0].type, SuppressionRace); 133 EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo")); 134 } 135 136 TEST_F(SuppressionContextTest, ParseType) { 137 ctx_->Parse( 138 "race:foo\n" 139 "thread:bar\n" 140 "mutex:baz\n" 141 "signal:quz\n" 142 ); // NOLINT 143 EXPECT_EQ((unsigned)4, ctx_->SuppressionCount()); 144 EXPECT_EQ((*Suppressions())[3].type, SuppressionSignal); 145 EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz")); 146 EXPECT_EQ((*Suppressions())[2].type, SuppressionMutex); 147 EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz")); 148 EXPECT_EQ((*Suppressions())[1].type, SuppressionThread); 149 EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar")); 150 EXPECT_EQ((*Suppressions())[0].type, SuppressionRace); 151 EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo")); 152 } 153 154 } // namespace __sanitizer 155