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 }