github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/cdc/sink/common/common_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 common
    15  
    16  import (
    17  	"sort"
    18  	"testing"
    19  
    20  	"github.com/google/go-cmp/cmp"
    21  	"github.com/pingcap/check"
    22  	"github.com/pingcap/ticdc/cdc/model"
    23  	"github.com/pingcap/ticdc/pkg/util/testleak"
    24  )
    25  
    26  type SinkCommonSuite struct{}
    27  
    28  func Test(t *testing.T) { check.TestingT(t) }
    29  
    30  var _ = check.Suite(&SinkCommonSuite{})
    31  
    32  func (s SinkCommonSuite) TestSplitResolvedTxn(c *check.C) {
    33  	defer testleak.AfterTest(c)()
    34  	testCases := [][]struct {
    35  		input      []*model.RowChangedEvent
    36  		resolvedTs model.Ts
    37  		expected   map[model.TableID][]*model.SingleTableTxn
    38  	}{{{ // Testing basic transaction collocation, no txns with the same committs
    39  		input: []*model.RowChangedEvent{
    40  			{StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}},
    41  			{StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}},
    42  			{StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}},
    43  			{StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 3}},
    44  			{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
    45  			{StartTs: 1, CommitTs: 11, Table: &model.TableName{TableID: 1}},
    46  			{StartTs: 1, CommitTs: 12, Table: &model.TableName{TableID: 2}},
    47  		},
    48  		resolvedTs: 6,
    49  		expected: map[model.TableID][]*model.SingleTableTxn{
    50  			1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 5, Rows: []*model.RowChangedEvent{
    51  				{StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}},
    52  				{StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}},
    53  			}}},
    54  			2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 6, Rows: []*model.RowChangedEvent{
    55  				{StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}},
    56  			}}},
    57  		},
    58  	}, {
    59  		input: []*model.RowChangedEvent{
    60  			{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 3}},
    61  		},
    62  		resolvedTs: 13,
    63  		expected: map[model.TableID][]*model.SingleTableTxn{
    64  			1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 8, Rows: []*model.RowChangedEvent{
    65  				{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
    66  			}}, {Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 11, Rows: []*model.RowChangedEvent{
    67  				{StartTs: 1, CommitTs: 11, Table: &model.TableName{TableID: 1}},
    68  			}}},
    69  			2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 12, Rows: []*model.RowChangedEvent{
    70  				{StartTs: 1, CommitTs: 12, Table: &model.TableName{TableID: 2}},
    71  			}}},
    72  			3: {{Table: &model.TableName{TableID: 3}, StartTs: 1, CommitTs: 7, Rows: []*model.RowChangedEvent{
    73  				{StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 3}},
    74  			}}, {Table: &model.TableName{TableID: 3}, StartTs: 1, CommitTs: 8, Rows: []*model.RowChangedEvent{
    75  				{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 3}},
    76  			}}},
    77  		},
    78  	}}, {{ // Testing the short circuit path
    79  		input:      []*model.RowChangedEvent{},
    80  		resolvedTs: 6,
    81  		expected:   nil,
    82  	}, {
    83  		input: []*model.RowChangedEvent{
    84  			{StartTs: 1, CommitTs: 11, Table: &model.TableName{TableID: 1}},
    85  			{StartTs: 1, CommitTs: 12, Table: &model.TableName{TableID: 1}},
    86  			{StartTs: 1, CommitTs: 13, Table: &model.TableName{TableID: 2}},
    87  		},
    88  		resolvedTs: 6,
    89  		expected:   map[model.TableID][]*model.SingleTableTxn{},
    90  	}}, {{ // Testing the txns with the same commitTs
    91  		input: []*model.RowChangedEvent{
    92  			{StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}},
    93  			{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
    94  			{StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}},
    95  			{StartTs: 2, CommitTs: 6, Table: &model.TableName{TableID: 2}},
    96  			{StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}},
    97  			{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
    98  			{StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}},
    99  			{StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}},
   100  			{StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}},
   101  		},
   102  		resolvedTs: 6,
   103  		expected: map[model.TableID][]*model.SingleTableTxn{
   104  			1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 5, Rows: []*model.RowChangedEvent{
   105  				{StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}},
   106  			}}},
   107  			2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 6, Rows: []*model.RowChangedEvent{
   108  				{StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}},
   109  				{StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}},
   110  			}}, {Table: &model.TableName{TableID: 2}, StartTs: 2, CommitTs: 6, Rows: []*model.RowChangedEvent{
   111  				{StartTs: 2, CommitTs: 6, Table: &model.TableName{TableID: 2}},
   112  			}}},
   113  		},
   114  	}, {
   115  		input: []*model.RowChangedEvent{
   116  			{StartTs: 2, CommitTs: 7, Table: &model.TableName{TableID: 2}},
   117  			{StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}},
   118  			{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   119  			{StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   120  			{StartTs: 1, CommitTs: 9, Table: &model.TableName{TableID: 1}},
   121  		},
   122  		resolvedTs: 13,
   123  		expected: map[model.TableID][]*model.SingleTableTxn{
   124  			1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 8, Rows: []*model.RowChangedEvent{
   125  				{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   126  				{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   127  				{StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   128  			}}, {Table: &model.TableName{TableID: 1}, StartTs: 2, CommitTs: 8, Rows: []*model.RowChangedEvent{
   129  				{StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   130  				{StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   131  				{StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}},
   132  			}}, {Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 9, Rows: []*model.RowChangedEvent{
   133  				{StartTs: 1, CommitTs: 9, Table: &model.TableName{TableID: 1}},
   134  			}}},
   135  			2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 7, Rows: []*model.RowChangedEvent{
   136  				{StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}},
   137  				{StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}},
   138  			}}, {Table: &model.TableName{TableID: 2}, StartTs: 2, CommitTs: 7, Rows: []*model.RowChangedEvent{
   139  				{StartTs: 2, CommitTs: 7, Table: &model.TableName{TableID: 2}},
   140  			}}},
   141  		},
   142  	}}}
   143  	for _, tc := range testCases {
   144  		cache := NewUnresolvedTxnCache()
   145  		for _, t := range tc {
   146  			cache.Append(nil, t.input...)
   147  			resolved := cache.Resolved(t.resolvedTs)
   148  			for tableID, txns := range resolved {
   149  				sort.Slice(txns, func(i, j int) bool {
   150  					if txns[i].CommitTs != txns[j].CommitTs {
   151  						return txns[i].CommitTs < txns[j].CommitTs
   152  					}
   153  					return txns[i].StartTs < txns[j].StartTs
   154  				})
   155  				resolved[tableID] = txns
   156  			}
   157  			c.Assert(resolved, check.DeepEquals, t.expected,
   158  				check.Commentf("%s", cmp.Diff(resolved, t.expected)))
   159  		}
   160  	}
   161  }