github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/pkg/sink/codec/maxwell/maxwell_encoder_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 maxwell 15 16 import ( 17 "context" 18 "testing" 19 20 timodel "github.com/pingcap/tidb/pkg/parser/model" 21 "github.com/pingcap/tidb/pkg/parser/mysql" 22 "github.com/pingcap/tiflow/cdc/model" 23 "github.com/pingcap/tiflow/pkg/sink/codec/common" 24 "github.com/stretchr/testify/require" 25 ) 26 27 func TestMaxwellBatchCodec(t *testing.T) { 28 t.Parallel() 29 newEncoder := newBatchEncoder 30 31 tableInfo := model.BuildTableInfo("a", "b", []*model.Column{{Name: "col1", Type: mysql.TypeLong}}, nil) 32 rowCases := [][]*model.RowChangedEvent{{{ 33 CommitTs: 1, 34 TableInfo: tableInfo, 35 Columns: model.Columns2ColumnDatas([]*model.Column{ 36 { 37 Name: "col1", 38 Value: 10, 39 }, 40 }, tableInfo), 41 }}, {}} 42 for _, cs := range rowCases { 43 encoder := newEncoder(&common.Config{}) 44 for _, row := range cs { 45 err := encoder.AppendRowChangedEvent(context.Background(), "", row, nil) 46 require.Nil(t, err) 47 } 48 messages := encoder.Build() 49 if len(cs) == 0 { 50 require.Nil(t, messages) 51 continue 52 } 53 require.Len(t, messages, 1) 54 require.Equal(t, len(cs), messages[0].GetRowsCount()) 55 } 56 57 ddlCases := [][]*model.DDLEvent{{{ 58 CommitTs: 1, 59 TableInfo: &model.TableInfo{ 60 TableName: model.TableName{ 61 Schema: "a", Table: "b", 62 }, 63 TableInfo: &timodel.TableInfo{}, 64 }, 65 Query: "create table a", 66 Type: 1, 67 }}} 68 for _, cs := range ddlCases { 69 encoder := newEncoder(&common.Config{}) 70 for _, ddl := range cs { 71 msg, err := encoder.EncodeDDLEvent(ddl) 72 require.Nil(t, err) 73 require.NotNil(t, msg) 74 } 75 } 76 } 77 78 func TestMaxwellAppendRowChangedEventWithCallback(t *testing.T) { 79 encoder := newBatchEncoder(&common.Config{}) 80 require.NotNil(t, encoder) 81 82 count := 0 83 84 tableInfo := model.BuildTableInfo("a", "b", []*model.Column{{Name: "col1", Type: mysql.TypeVarchar}}, nil) 85 row := &model.RowChangedEvent{ 86 CommitTs: 1, 87 TableInfo: tableInfo, 88 Columns: model.Columns2ColumnDatas([]*model.Column{{ 89 Name: "col1", 90 Value: []byte("aa"), 91 }}, tableInfo), 92 } 93 94 tests := []struct { 95 row *model.RowChangedEvent 96 callback func() 97 }{ 98 { 99 row: row, 100 callback: func() { 101 count += 1 102 }, 103 }, 104 { 105 row: row, 106 callback: func() { 107 count += 2 108 }, 109 }, 110 { 111 row: row, 112 callback: func() { 113 count += 3 114 }, 115 }, 116 { 117 row: row, 118 callback: func() { 119 count += 4 120 }, 121 }, 122 { 123 row: row, 124 callback: func() { 125 count += 5 126 }, 127 }, 128 } 129 130 // Empty build makes sure that the callback build logic not broken. 131 msgs := encoder.Build() 132 require.Len(t, msgs, 0, "no message should be built and no panic") 133 134 // Append the events. 135 for _, test := range tests { 136 err := encoder.AppendRowChangedEvent(context.Background(), "", test.row, test.callback) 137 require.Nil(t, err) 138 } 139 require.Equal(t, 0, count, "nothing should be called") 140 141 msgs = encoder.Build() 142 require.Len(t, msgs, 1, "expected one message") 143 msgs[0].Callback() 144 require.Equal(t, 15, count, "expected all callbacks to be called") 145 }