vitess.io/vitess@v0.16.2/go/vt/binlog/event_streamer_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package binlog 18 19 import ( 20 "testing" 21 22 "vitess.io/vitess/go/test/utils" 23 24 "github.com/stretchr/testify/require" 25 "google.golang.org/protobuf/proto" 26 27 binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" 28 querypb "vitess.io/vitess/go/vt/proto/query" 29 ) 30 31 var dmlErrorCases = []string{ 32 "query", 33 "query /* _stream 10 (eid id `name` ) (null 1 'bmFtZQ==' ); */", 34 "query /* _stream _table_ eid id `name` ) (null 1 'bmFtZQ==' ); */", 35 "query /* _stream _table_ (10 id `name` ) (null 1 'bmFtZQ==' ); */", 36 "query /* _stream _table_ (eid id `name` (null 1 'bmFtZQ==' ); */", 37 "query /* _stream _table_ (eid id `name`) (null 'aaa' 'bmFtZQ==' ); */", 38 "query /* _stream _table_ (eid id `name`) (null 'bmFtZQ==' ); */", 39 "query /* _stream _table_ (eid id `name`) (null 1.1 'bmFtZQ==' ); */", 40 "query /* _stream _table_ (eid id `name`) (null a 'bmFtZQ==' ); */", 41 } 42 43 func TestEventErrors(t *testing.T) { 44 var got *querypb.StreamEvent 45 evs := &EventStreamer{ 46 sendEvent: func(event *querypb.StreamEvent) error { 47 got = event 48 return nil 49 }, 50 } 51 for _, sql := range dmlErrorCases { 52 statements := []FullBinlogStatement{ 53 { 54 Statement: &binlogdatapb.BinlogTransaction_Statement{ 55 Category: binlogdatapb.BinlogTransaction_Statement_BL_INSERT, 56 Sql: []byte(sql), 57 }, 58 }, 59 } 60 err := evs.transactionToEvent(nil, statements) 61 if err != nil { 62 t.Errorf("%s: %v", sql, err) 63 continue 64 } 65 want := &querypb.StreamEvent{ 66 Statements: []*querypb.StreamEvent_Statement{ 67 { 68 Category: querypb.StreamEvent_Statement_Error, 69 Sql: []byte(sql), 70 }, 71 }, 72 } 73 if !proto.Equal(got, want) { 74 t.Errorf("error for SQL: '%v' got: %+v, want: %+v", sql, got, want) 75 } 76 } 77 } 78 79 func TestSetErrors(t *testing.T) { 80 evs := &EventStreamer{ 81 sendEvent: func(event *querypb.StreamEvent) error { 82 return nil 83 }, 84 } 85 statements := []FullBinlogStatement{ 86 { 87 Statement: &binlogdatapb.BinlogTransaction_Statement{ 88 Category: binlogdatapb.BinlogTransaction_Statement_BL_SET, 89 Sql: []byte("SET INSERT_ID=abcd"), 90 }, 91 }, 92 } 93 before := binlogStreamerErrors.Counts()["EventStreamer"] 94 err := evs.transactionToEvent(nil, statements) 95 require.NoError(t, err) 96 got := binlogStreamerErrors.Counts()["EventStreamer"] 97 if got != before+1 { 98 t.Errorf("got: %v, want: %+v", got, before+1) 99 } 100 } 101 102 func TestDMLEvent(t *testing.T) { 103 statements := []FullBinlogStatement{ 104 { 105 Statement: &binlogdatapb.BinlogTransaction_Statement{ 106 Category: binlogdatapb.BinlogTransaction_Statement_BL_SET, 107 Sql: []byte("SET TIMESTAMP=2"), 108 }, 109 }, 110 { 111 Statement: &binlogdatapb.BinlogTransaction_Statement{ 112 Category: binlogdatapb.BinlogTransaction_Statement_BL_SET, 113 Sql: []byte("SET INSERT_ID=10"), 114 }, 115 }, 116 { 117 Statement: &binlogdatapb.BinlogTransaction_Statement{ 118 Category: binlogdatapb.BinlogTransaction_Statement_BL_INSERT, 119 Sql: []byte("query /* _stream _table_ (eid id `name`) (null 1 'bmFtZQ==' ) (null 18446744073709551615 'bmFtZQ==' ); */"), 120 }, 121 }, 122 { 123 Statement: &binlogdatapb.BinlogTransaction_Statement{ 124 Category: binlogdatapb.BinlogTransaction_Statement_BL_INSERT, 125 Sql: []byte("query"), 126 }, 127 }, 128 } 129 eventToken := &querypb.EventToken{ 130 Timestamp: 1, 131 Position: "MariaDB/0-41983-20", 132 } 133 evs := &EventStreamer{ 134 sendEvent: func(event *querypb.StreamEvent) error { 135 for _, statement := range event.Statements { 136 switch statement.Category { 137 case querypb.StreamEvent_Statement_DML: 138 want := `category:DML table_name:"_table_" primary_key_fields:{name:"eid" type:INT64} primary_key_fields:{name:"id" type:UINT64} primary_key_fields:{name:"name" type:VARBINARY} primary_key_values:{lengths:2 lengths:1 lengths:4 values:"101name"} primary_key_values:{lengths:2 lengths:20 lengths:4 values:"1118446744073709551615name"}` 139 utils.MustMatchPB(t, want, statement) 140 case querypb.StreamEvent_Statement_Error: 141 want := `sql:"query"` 142 utils.MustMatchPB(t, want, statement) 143 default: 144 t.Errorf("unexpected: %#v", event) 145 } 146 } 147 // then test the position 148 want := `timestamp:1 position:"MariaDB/0-41983-20"` 149 utils.MustMatchPB(t, want, event.EventToken) 150 return nil 151 }, 152 } 153 err := evs.transactionToEvent(eventToken, statements) 154 require.NoError(t, err) 155 } 156 157 func TestDDLEvent(t *testing.T) { 158 statements := []FullBinlogStatement{ 159 { 160 Statement: &binlogdatapb.BinlogTransaction_Statement{ 161 Category: binlogdatapb.BinlogTransaction_Statement_BL_SET, 162 Sql: []byte("SET TIMESTAMP=2"), 163 }, 164 }, 165 { 166 Statement: &binlogdatapb.BinlogTransaction_Statement{ 167 Category: binlogdatapb.BinlogTransaction_Statement_BL_DDL, 168 Sql: []byte("DDL"), 169 }, 170 }, 171 } 172 eventToken := &querypb.EventToken{ 173 Timestamp: 1, 174 Position: "MariaDB/0-41983-20", 175 } 176 evs := &EventStreamer{ 177 sendEvent: func(event *querypb.StreamEvent) error { 178 for _, statement := range event.Statements { 179 switch statement.Category { 180 case querypb.StreamEvent_Statement_DDL: 181 want := `category:DDL sql:"DDL"` 182 utils.MustMatchPB(t, want, statement) 183 default: 184 t.Errorf("unexpected: %#v", event) 185 } 186 } 187 // then test the position 188 want := `timestamp:1 position:"MariaDB/0-41983-20"` 189 utils.MustMatchPB(t, want, event.EventToken) 190 return nil 191 }, 192 } 193 err := evs.transactionToEvent(eventToken, statements) 194 require.NoError(t, err) 195 }