github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/binlog/event/util_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  // binlog events generator for MySQL used to generate some binlog events for tests.
    15  // Readability takes precedence over performance.
    16  
    17  package event
    18  
    19  import (
    20  	"io"
    21  	"testing"
    22  
    23  	"github.com/pingcap/tiflow/dm/pkg/terror"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  type testCase struct {
    28  	input  []byte
    29  	output map[byte][]byte
    30  	err    error
    31  }
    32  
    33  type testCaseTimezone struct {
    34  	input  []byte
    35  	output string
    36  	err    error
    37  }
    38  
    39  func TestStatusVarsToKV(t *testing.T) {
    40  	t.Parallel()
    41  	testCases := []testCase{
    42  		// only Q_FLAGS2_CODE
    43  		{
    44  			[]byte{0, 0, 0, 0, 0},
    45  			map[byte][]byte{
    46  				0: {0, 0, 0, 0},
    47  			},
    48  			nil,
    49  		},
    50  		// only Q_CHARSET_CODE
    51  		{
    52  			[]byte{4, 33, 0, 33, 0, 8, 0},
    53  			map[byte][]byte{
    54  				4: {33, 0, 33, 0, 8, 0},
    55  			},
    56  			nil,
    57  		},
    58  		// copied from a integration test
    59  		{
    60  			[]byte{0, 0, 0, 0, 0, 1, 4, 0, 8, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0, 12, 1, 97, 108, 108, 95, 109, 111, 100, 101, 0},
    61  			map[byte][]byte{
    62  				0:  {0, 0, 0, 0},
    63  				1:  {4, 0, 8, 0, 0, 0, 0, 0},
    64  				6:  {3, 115, 116, 100},
    65  				4:  {33, 0, 33, 0, 8, 0},
    66  				12: {1, 97, 108, 108, 95, 109, 111, 100, 101, 0},
    67  			},
    68  			nil,
    69  		},
    70  		// wrong input
    71  		{
    72  			[]byte{0, 0, 0, 0, 0, 1},
    73  			map[byte][]byte{
    74  				0: {0, 0, 0, 0},
    75  			},
    76  			terror.ErrBinlogStatusVarsParse.Delegate(io.EOF, []byte{0, 0, 0, 0, 0, 1}, 6),
    77  		},
    78  		// undocumented status_vars
    79  		{
    80  			[]byte{0, 0, 0, 0, 0, 1, 32, 0, 160, 85, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 45, 0, 45, 0, 8, 0, 12, 1, 111, 110, 108, 105, 110, 101, 95, 100, 100, 108, 0, 16, 0},
    81  			map[byte][]byte{
    82  				0:  {0, 0, 0, 0},
    83  				1:  {32, 0, 160, 85, 0, 0, 0, 0},
    84  				6:  {3, 115, 116, 100},
    85  				4:  {45, 0, 45, 0, 8, 0},
    86  				12: {1, 111, 110, 108, 105, 110, 101, 95, 100, 100, 108, 0},
    87  				16: {0},
    88  			},
    89  			nil,
    90  		},
    91  		// OVER_MAX_DBS_IN_EVENT_MTS in Q_UPDATED_DB_NAMES
    92  		{
    93  			[]byte{0, 0, 0, 0, 0, 1, 0, 0, 160, 85, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 45, 0, 45, 0, 33, 0, 12, 254},
    94  			map[byte][]byte{
    95  				0:  {0, 0, 0, 0},
    96  				1:  {0, 0, 160, 85, 0, 0, 0, 0},
    97  				6:  {3, 115, 116, 100},
    98  				4:  {45, 0, 45, 0, 33, 0},
    99  				12: {254},
   100  			},
   101  			nil,
   102  		},
   103  		{
   104  			[]byte{0, 0, 0, 0, 0, 1, 0, 0, 32, 80, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 33, 0, 11, 4, 114, 111, 111, 116, 9, 108, 111, 99, 97, 108, 104, 111, 115, 116, 12, 2, 109, 121, 115, 113, 108, 0, 97, 117, 116, 104, 111, 114, 105, 122, 101, 0},
   105  			map[byte][]byte{
   106  				0:  {0, 0, 0, 0},
   107  				1:  {0, 0, 32, 80, 0, 0, 0, 0},
   108  				6:  {3, 115, 116, 100},
   109  				4:  {33, 0, 33, 0, 33, 0},
   110  				11: {4, 114, 111, 111, 116, 9, 108, 111, 99, 97, 108, 104, 111, 115, 116},
   111  				12: {2, 109, 121, 115, 113, 108, 0, 97, 117, 116, 104, 111, 114, 105, 122, 101, 0},
   112  			},
   113  			nil,
   114  		},
   115  		{
   116  			[]byte{0, 0, 0, 0, 0, 1, 0, 0, 40, 0, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 83, 0, 5, 6, 83, 89, 83, 84, 69, 77, 128, 19, 29, 12},
   117  			map[byte][]byte{
   118  				0:   {0, 0, 0, 0},
   119  				1:   {0, 0, 40, 0, 0, 0, 0, 0},
   120  				6:   {3, 115, 116, 100},
   121  				4:   {33, 0, 33, 0, 83, 0},
   122  				5:   {6, 83, 89, 83, 84, 69, 77}, // "SYSTEM" of length 6
   123  				128: {19, 29, 12},                // Q_HRNOW from MariaDB
   124  			},
   125  			nil,
   126  		},
   127  	}
   128  
   129  	for _, test := range testCases {
   130  		vars, err := statusVarsToKV(test.input)
   131  		if test.err != nil {
   132  			require.Equal(t, test.err.Error(), err.Error())
   133  		} else {
   134  			require.NoError(t, err)
   135  		}
   136  		require.Equal(t, test.output, vars)
   137  	}
   138  }
   139  
   140  func TestGetTimezoneByStatusVars(t *testing.T) {
   141  	t.Parallel()
   142  	testCases := []testCaseTimezone{
   143  		//+08:00
   144  		{
   145  			[]byte{0, 0, 0, 0, 0, 1, 32, 0, 160, 69, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 8, 0, 8, 0, 46, 0, 5, 6, 43, 48, 56, 58, 48, 48, 12, 1, 109, 97, 110, 121, 95, 116, 97, 98, 108, 101, 115, 95, 116, 101, 115, 116, 0},
   146  			"+08:00",
   147  			nil,
   148  		},
   149  		//-06:00
   150  		{
   151  			[]byte{0, 0, 0, 0, 0, 1, 32, 0, 160, 69, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 8, 0, 8, 0, 46, 0, 5, 6, 45, 48, 54, 58, 48, 48, 12, 1, 109, 97, 110, 121, 95, 116, 97, 98, 108, 101, 115, 95, 116, 101, 115, 116, 0},
   152  			"-06:00",
   153  			nil,
   154  		},
   155  		// SYSTEM
   156  		{
   157  			[]byte{0, 0, 0, 0, 0, 1, 32, 0, 160, 69, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 8, 0, 8, 0, 46, 0, 5, 6, 83, 89, 83, 84, 69, 77, 12, 1, 109, 97, 110, 121, 95, 116, 97, 98, 108, 101, 115, 95, 116, 101, 115, 116, 0},
   158  			"+0:00",
   159  			nil,
   160  		},
   161  	}
   162  
   163  	for _, test := range testCases {
   164  		// to simulate Syncer.upstreamTZ
   165  		upstreamTZStr := "+0:00"
   166  		vars, err := GetTimezoneByStatusVars(test.input, upstreamTZStr)
   167  		if test.err != nil {
   168  			require.Equal(t, test.err.Error(), err.Error())
   169  		} else {
   170  			require.NoError(t, err)
   171  		}
   172  		require.Equal(t, test.output, vars)
   173  	}
   174  }