Home | History | Annotate | Download | only in tests
      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