github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/model/codec/v1/convert_test.go (about)

     1  // Copyright 2021 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 v1
    15  
    16  import (
    17  	"testing"
    18  
    19  	"github.com/pingcap/tidb/pkg/parser/charset"
    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/stretchr/testify/require"
    24  )
    25  
    26  func TestRowRedoConvert(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	row := &RowChangedEvent{
    30  		StartTs:  100,
    31  		CommitTs: 120,
    32  		Table:    &TableName{Schema: "test", Table: "table1", TableID: 57},
    33  		PreColumns: []*Column{{
    34  			Name:  "a1",
    35  			Type:  mysql.TypeLong,
    36  			Flag:  model.BinaryFlag | model.MultipleKeyFlag | model.HandleKeyFlag,
    37  			Value: int64(1),
    38  		}, {
    39  			Name:  "a2",
    40  			Type:  mysql.TypeVarchar,
    41  			Value: []byte("char"),
    42  		}, {
    43  			Name:  "a3",
    44  			Type:  mysql.TypeLong,
    45  			Flag:  model.BinaryFlag | model.MultipleKeyFlag | model.HandleKeyFlag,
    46  			Value: int64(1),
    47  		}, {
    48  			Name:    "a4",
    49  			Type:    mysql.TypeTinyBlob,
    50  			Charset: charset.CharsetGBK,
    51  			Value:   []byte("你好"),
    52  		}, nil},
    53  		Columns: []*Column{{
    54  			Name:  "a1",
    55  			Type:  mysql.TypeLong,
    56  			Flag:  model.BinaryFlag | model.MultipleKeyFlag | model.HandleKeyFlag,
    57  			Value: int64(2),
    58  		}, {
    59  			Name:  "a2",
    60  			Type:  mysql.TypeVarchar,
    61  			Value: []byte("char-updated"),
    62  		}, {
    63  			Name:  "a3",
    64  			Type:  mysql.TypeLong,
    65  			Flag:  model.BinaryFlag | model.MultipleKeyFlag | model.HandleKeyFlag,
    66  			Value: int64(2),
    67  		}, {
    68  			Name:    "a4",
    69  			Type:    mysql.TypeTinyBlob,
    70  			Charset: charset.CharsetGBK,
    71  			Value:   []byte("世界"),
    72  		}, nil},
    73  		IndexColumns: [][]int{{1, 3}},
    74  	}
    75  
    76  	redoLog := &RedoLog{RedoRow: &RedoRowChangedEvent{Row: row}}
    77  	PreMarshal(redoLog)
    78  	require.Equal(t, 5, len(redoLog.RedoRow.PreColumns))
    79  	require.Equal(t, 5, len(redoLog.RedoRow.Columns))
    80  	data, err := redoLog.MarshalMsg(nil)
    81  	require.Nil(t, err)
    82  
    83  	redoLog2 := &RedoLog{}
    84  	_, err = redoLog2.UnmarshalMsg(data)
    85  	require.Nil(t, err)
    86  	PostUnmarshal(redoLog2)
    87  	require.Equal(t, row, redoLog2.RedoRow.Row)
    88  }
    89  
    90  func TestRowRedoConvertWithEmptySlice(t *testing.T) {
    91  	t.Parallel()
    92  
    93  	row := &RowChangedEvent{
    94  		StartTs:  100,
    95  		CommitTs: 120,
    96  		Table:    &TableName{Schema: "test", Table: "table1", TableID: 57},
    97  		PreColumns: []*Column{{
    98  			Name:  "a1",
    99  			Type:  mysql.TypeLong,
   100  			Flag:  model.BinaryFlag | model.MultipleKeyFlag | model.HandleKeyFlag,
   101  			Value: int64(1),
   102  		}, {
   103  			Name:  "a2",
   104  			Type:  mysql.TypeVarchar,
   105  			Value: []byte(""), // empty slice should be marshal and unmarshal safely
   106  		}},
   107  		Columns: []*Column{{
   108  			Name:  "a1",
   109  			Type:  mysql.TypeLong,
   110  			Flag:  model.BinaryFlag | model.MultipleKeyFlag | model.HandleKeyFlag,
   111  			Value: int64(2),
   112  		}, {
   113  			Name:  "a2",
   114  			Type:  mysql.TypeVarchar,
   115  			Value: []byte(""),
   116  		}},
   117  		IndexColumns: [][]int{{1}},
   118  	}
   119  
   120  	redoLog := &RedoLog{RedoRow: &RedoRowChangedEvent{Row: row}}
   121  	PreMarshal(redoLog)
   122  	data, err := redoLog.MarshalMsg(nil)
   123  	require.Nil(t, err)
   124  
   125  	redoLog2 := &RedoLog{}
   126  	_, err = redoLog2.UnmarshalMsg(data)
   127  	require.Nil(t, err)
   128  	PostUnmarshal(redoLog2)
   129  	require.Equal(t, row, redoLog2.RedoRow.Row)
   130  }
   131  
   132  func TestDDLRedoConvert(t *testing.T) {
   133  	t.Parallel()
   134  
   135  	ddl := &DDLEvent{
   136  		StartTs:  1020,
   137  		CommitTs: 1030,
   138  		Type:     timodel.ActionAddColumn,
   139  		Query:    "ALTER TABLE test.t1 ADD COLUMN a int",
   140  	}
   141  
   142  	redoLog := &RedoLog{RedoDDL: &RedoDDLEvent{DDL: ddl}}
   143  	PreMarshal(redoLog)
   144  	data, err := redoLog.MarshalMsg(nil)
   145  	require.Nil(t, err)
   146  
   147  	redoLog2 := &RedoLog{}
   148  	_, err = redoLog2.UnmarshalMsg(data)
   149  	require.Nil(t, err)
   150  	PostUnmarshal(redoLog2)
   151  	require.Equal(t, ddl, redoLog2.RedoDDL.DDL)
   152  }