github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/pkg/filter/filter_test.go (about)

     1  // Copyright 2020 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package filter
    15  
    16  import (
    17  	"testing"
    18  
    19  	"github.com/pingcap/ticdc/pkg/config"
    20  	"github.com/pingcap/ticdc/pkg/util/testleak"
    21  
    22  	"github.com/pingcap/check"
    23  	"github.com/pingcap/parser/model"
    24  )
    25  
    26  type filterSuite struct{}
    27  
    28  var _ = check.Suite(&filterSuite{})
    29  
    30  func Test(t *testing.T) { check.TestingT(t) }
    31  
    32  func (s *filterSuite) TestShouldUseDefaultRules(c *check.C) {
    33  	defer testleak.AfterTest(c)()
    34  	filter, err := NewFilter(config.GetDefaultReplicaConfig())
    35  	c.Assert(err, check.IsNil)
    36  	c.Assert(filter.ShouldIgnoreTable("information_schema", ""), check.IsTrue)
    37  	c.Assert(filter.ShouldIgnoreTable("information_schema", "statistics"), check.IsTrue)
    38  	c.Assert(filter.ShouldIgnoreTable("performance_schema", ""), check.IsTrue)
    39  	c.Assert(filter.ShouldIgnoreTable("metric_schema", "query_duration"), check.IsFalse)
    40  	c.Assert(filter.ShouldIgnoreTable("sns", "user"), check.IsFalse)
    41  	c.Assert(filter.ShouldIgnoreTable("tidb_cdc", "repl_mark_a_a"), check.IsFalse)
    42  }
    43  
    44  func (s *filterSuite) TestShouldUseCustomRules(c *check.C) {
    45  	defer testleak.AfterTest(c)()
    46  	filter, err := NewFilter(&config.ReplicaConfig{
    47  		Filter: &config.FilterConfig{
    48  			Rules: []string{"sns.*", "ecom.*", "!sns.log", "!ecom.test"},
    49  		},
    50  		Cyclic: &config.CyclicConfig{Enable: true},
    51  	})
    52  	c.Assert(err, check.IsNil)
    53  	assertIgnore := func(db, tbl string, boolCheck check.Checker) {
    54  		c.Assert(filter.ShouldIgnoreTable(db, tbl), boolCheck)
    55  	}
    56  	assertIgnore("other", "", check.IsTrue)
    57  	assertIgnore("other", "what", check.IsTrue)
    58  	assertIgnore("sns", "", check.IsFalse)
    59  	assertIgnore("ecom", "order", check.IsFalse)
    60  	assertIgnore("ecom", "order", check.IsFalse)
    61  	assertIgnore("ecom", "test", check.IsTrue)
    62  	assertIgnore("sns", "log", check.IsTrue)
    63  	assertIgnore("information_schema", "", check.IsTrue)
    64  	assertIgnore("tidb_cdc", "repl_mark_a_a", check.IsFalse)
    65  }
    66  
    67  func (s *filterSuite) TestShouldIgnoreTxn(c *check.C) {
    68  	defer testleak.AfterTest(c)()
    69  	testCases := []struct {
    70  		cases []struct {
    71  			schema string
    72  			table  string
    73  			ts     uint64
    74  			ignore bool
    75  		}
    76  		ignoreTxnStartTs []uint64
    77  		rules            []string
    78  	}{
    79  		{
    80  			cases: []struct {
    81  				schema string
    82  				table  string
    83  				ts     uint64
    84  				ignore bool
    85  			}{
    86  				{"sns", "ttta", 1, true},
    87  				{"ecom", "aabb", 2, false},
    88  				{"sns", "log", 3, true},
    89  				{"sns", "log", 4, true},
    90  				{"ecom", "test", 5, true},
    91  				{"test", "test", 6, true},
    92  				{"ecom", "log", 6, false},
    93  			},
    94  			ignoreTxnStartTs: []uint64{1, 3},
    95  			rules:            []string{"sns.*", "ecom.*", "!sns.log", "!ecom.test"},
    96  		},
    97  		{
    98  			cases: []struct {
    99  				schema string
   100  				table  string
   101  				ts     uint64
   102  				ignore bool
   103  			}{
   104  				{"S", "D1", 1, true},
   105  				{"S", "Da", 1, false},
   106  				{"S", "Db", 1, false},
   107  				{"S", "Daa", 1, false},
   108  			},
   109  			ignoreTxnStartTs: []uint64{},
   110  			rules:            []string{"*.*", "!S.D[!a-d]"},
   111  		},
   112  	}
   113  
   114  	for _, ftc := range testCases {
   115  		filter, err := NewFilter(&config.ReplicaConfig{
   116  			Filter: &config.FilterConfig{
   117  				IgnoreTxnStartTs: ftc.ignoreTxnStartTs,
   118  				Rules:            ftc.rules,
   119  			},
   120  		})
   121  		c.Assert(err, check.IsNil)
   122  		for _, tc := range ftc.cases {
   123  			c.Assert(filter.ShouldIgnoreDMLEvent(tc.ts, tc.schema, tc.table), check.Equals, tc.ignore)
   124  			c.Assert(filter.ShouldIgnoreDDLEvent(tc.ts, model.ActionCreateTable, tc.schema, tc.table), check.Equals, tc.ignore)
   125  		}
   126  	}
   127  }
   128  
   129  func (s *filterSuite) TestShouldDiscardDDL(c *check.C) {
   130  	defer testleak.AfterTest(c)()
   131  	config := &config.ReplicaConfig{
   132  		Filter: &config.FilterConfig{
   133  			DDLAllowlist: []model.ActionType{model.ActionAddForeignKey},
   134  		},
   135  	}
   136  	filter, err := NewFilter(config)
   137  	c.Assert(err, check.IsNil)
   138  	c.Assert(filter.ShouldDiscardDDL(model.ActionDropSchema), check.IsFalse)
   139  	c.Assert(filter.ShouldDiscardDDL(model.ActionAddForeignKey), check.IsFalse)
   140  	c.Assert(filter.ShouldDiscardDDL(model.ActionCreateSequence), check.IsTrue)
   141  }
   142  
   143  func (s *filterSuite) TestShouldIgnoreDDL(c *check.C) {
   144  	defer testleak.AfterTest(c)()
   145  	testCases := []struct {
   146  		cases []struct {
   147  			schema  string
   148  			table   string
   149  			ddlType model.ActionType
   150  			ignore  bool
   151  		}
   152  		rules []string
   153  	}{{
   154  		cases: []struct {
   155  			schema  string
   156  			table   string
   157  			ddlType model.ActionType
   158  			ignore  bool
   159  		}{
   160  			{"sns", "", model.ActionCreateSchema, false},
   161  			{"sns", "", model.ActionDropSchema, false},
   162  			{"sns", "", model.ActionModifySchemaCharsetAndCollate, false},
   163  			{"ecom", "", model.ActionCreateSchema, false},
   164  			{"ecom", "aa", model.ActionCreateTable, false},
   165  			{"ecom", "", model.ActionCreateSchema, false},
   166  			{"test", "", model.ActionCreateSchema, true},
   167  		},
   168  		rules: []string{"sns.*", "ecom.*", "!sns.log", "!ecom.test"},
   169  	}, {
   170  		cases: []struct {
   171  			schema  string
   172  			table   string
   173  			ddlType model.ActionType
   174  			ignore  bool
   175  		}{
   176  			{"sns", "", model.ActionCreateSchema, false},
   177  			{"sns", "", model.ActionDropSchema, false},
   178  			{"sns", "", model.ActionModifySchemaCharsetAndCollate, false},
   179  			{"sns", "aa", model.ActionCreateTable, true},
   180  			{"sns", "C1", model.ActionCreateTable, false},
   181  			{"sns", "", model.ActionCreateTable, true},
   182  		},
   183  		rules: []string{"sns.C1"},
   184  	}}
   185  	for _, ftc := range testCases {
   186  		filter, err := NewFilter(&config.ReplicaConfig{
   187  			Filter: &config.FilterConfig{
   188  				IgnoreTxnStartTs: []uint64{},
   189  				Rules:            ftc.rules,
   190  			},
   191  		})
   192  		c.Assert(err, check.IsNil)
   193  		for _, tc := range ftc.cases {
   194  			c.Assert(filter.ShouldIgnoreDDLEvent(1, tc.ddlType, tc.schema, tc.table), check.Equals, tc.ignore, check.Commentf("%#v", tc))
   195  		}
   196  	}
   197  }