sanitizer_suppressions_test.cc revision 55e6f3f4e6b799e0affd13f28137661f8707133f
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
18namespace __sanitizer {
19
20static bool MyMatch(const char *templ, const char *func) {
21  char tmp[1024];
22  strcpy(tmp, templ);  // NOLINT
23  return TemplateMatch(tmp, func);
24}
25
26TEST(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
61TEST(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  // Ensure this test is up-to-date when suppression types are added.
69  CHECK_EQ(SuppressionTypeCount, 6);
70}
71
72class SuppressionContextTest : public ::testing::Test {
73 public:
74  virtual void SetUp() { ctx_ = new(placeholder_) SuppressionContext; }
75  virtual void TearDown() { ctx_->~SuppressionContext(); }
76
77 protected:
78  InternalMmapVector<Suppression> *Suppressions() {
79    return &ctx_->suppressions_;
80  }
81  SuppressionContext *ctx_;
82  ALIGNED(64) char placeholder_[sizeof(SuppressionContext)];
83};
84
85TEST_F(SuppressionContextTest, Parse) {
86  ctx_->Parse(
87    "race:foo\n"
88    " 	race:bar\n"  // NOLINT
89    "race:baz	 \n"  // NOLINT
90    "# a comment\n"
91    "race:quz\n"
92  );  // NOLINT
93  EXPECT_EQ((unsigned)4, ctx_->SuppressionCount());
94  EXPECT_EQ((*Suppressions())[3].type, SuppressionRace);
95  EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz"));
96  EXPECT_EQ((*Suppressions())[2].type, SuppressionRace);
97  EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz"));
98  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
99  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
100  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
101  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
102}
103
104TEST_F(SuppressionContextTest, Parse2) {
105  ctx_->Parse(
106    "  	# first line comment\n"  // NOLINT
107    " 	race:bar 	\n"  // NOLINT
108    "race:baz* *baz\n"
109    "# a comment\n"
110    "# last line comment\n"
111  );  // NOLINT
112  EXPECT_EQ((unsigned)2, ctx_->SuppressionCount());
113  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
114  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "baz* *baz"));
115  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
116  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "bar"));
117}
118
119TEST_F(SuppressionContextTest, Parse3) {
120  ctx_->Parse(
121    "# last suppression w/o line-feed\n"
122    "race:foo\n"
123    "race:bar"
124  );  // NOLINT
125  EXPECT_EQ((unsigned)2, ctx_->SuppressionCount());
126  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
127  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
128  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
129  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
130}
131
132TEST_F(SuppressionContextTest, ParseType) {
133  ctx_->Parse(
134    "race:foo\n"
135    "thread:bar\n"
136    "mutex:baz\n"
137    "signal:quz\n"
138  );  // NOLINT
139  EXPECT_EQ((unsigned)4, ctx_->SuppressionCount());
140  EXPECT_EQ((*Suppressions())[3].type, SuppressionSignal);
141  EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz"));
142  EXPECT_EQ((*Suppressions())[2].type, SuppressionMutex);
143  EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz"));
144  EXPECT_EQ((*Suppressions())[1].type, SuppressionThread);
145  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
146  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
147  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
148}
149
150}  // namespace __sanitizer
151