vitess.io/vitess@v0.16.2/go/mysql/conn_flaky_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 mysql 18 19 import ( 20 "bytes" 21 "context" 22 crypto_rand "crypto/rand" 23 "encoding/binary" 24 "encoding/hex" 25 "fmt" 26 "math/rand" 27 "net" 28 "strconv" 29 "strings" 30 "sync" 31 "testing" 32 "time" 33 34 "vitess.io/vitess/go/vt/sqlparser" 35 36 "github.com/stretchr/testify/assert" 37 38 "vitess.io/vitess/go/test/utils" 39 40 "github.com/stretchr/testify/require" 41 42 "vitess.io/vitess/go/sqltypes" 43 querypb "vitess.io/vitess/go/vt/proto/query" 44 ) 45 46 func createSocketPair(t *testing.T) (net.Listener, *Conn, *Conn) { 47 // Create a listener. 48 listener, err := net.Listen("tcp", "127.0.0.1:") 49 require.NoError(t, err, "Listen failed: %v", err) 50 51 addr := listener.Addr().String() 52 listener.(*net.TCPListener).SetDeadline(time.Now().Add(10 * time.Second)) 53 54 // Dial a client, Accept a server. 55 wg := sync.WaitGroup{} 56 57 var clientConn net.Conn 58 var clientErr error 59 wg.Add(1) 60 go func() { 61 defer wg.Done() 62 clientConn, clientErr = net.DialTimeout("tcp", addr, 10*time.Second) 63 }() 64 65 var serverConn net.Conn 66 var serverErr error 67 wg.Add(1) 68 go func() { 69 defer wg.Done() 70 serverConn, serverErr = listener.Accept() 71 }() 72 73 wg.Wait() 74 require.Nil(t, clientErr, "Dial failed: %v", clientErr) 75 require.Nil(t, serverErr, "Accept failed: %v", serverErr) 76 77 // Create a Conn on both sides. 78 cConn := newConn(clientConn) 79 sConn := newConn(serverConn) 80 sConn.PrepareData = map[uint32]*PrepareData{} 81 82 return listener, sConn, cConn 83 } 84 85 func useWritePacket(t *testing.T, cConn *Conn, data []byte) { 86 defer func() { 87 if x := recover(); x != nil { 88 t.Fatalf("%v", x) 89 } 90 }() 91 92 dataLen := len(data) 93 dataWithHeader := make([]byte, packetHeaderSize+dataLen) 94 copy(dataWithHeader[packetHeaderSize:], data) 95 96 if err := cConn.writePacket(dataWithHeader); err != nil { 97 t.Fatalf("writePacket failed: %v", err) 98 } 99 } 100 101 func useWriteEphemeralPacketBuffered(t *testing.T, cConn *Conn, data []byte) { 102 defer func() { 103 if x := recover(); x != nil { 104 t.Fatalf("%v", x) 105 } 106 }() 107 cConn.startWriterBuffering() 108 defer cConn.endWriterBuffering() 109 110 buf, pos := cConn.startEphemeralPacketWithHeader(len(data)) 111 copy(buf[pos:], data) 112 if err := cConn.writeEphemeralPacket(); err != nil { 113 t.Fatalf("writeEphemeralPacket(false) failed: %v", err) 114 } 115 } 116 117 func useWriteEphemeralPacketDirect(t *testing.T, cConn *Conn, data []byte) { 118 defer func() { 119 if x := recover(); x != nil { 120 t.Fatalf("%v", x) 121 } 122 }() 123 124 buf, pos := cConn.startEphemeralPacketWithHeader(len(data)) 125 copy(buf[pos:], data) 126 if err := cConn.writeEphemeralPacket(); err != nil { 127 t.Fatalf("writeEphemeralPacket(true) failed: %v", err) 128 } 129 } 130 131 func verifyPacketCommsSpecific(t *testing.T, cConn *Conn, data []byte, 132 write func(t *testing.T, cConn *Conn, data []byte), 133 read func() ([]byte, error)) { 134 // Have to do it in the background if it cannot be buffered. 135 // Note we have to wait for it to finish at the end of the 136 // test, as the write may write all the data to the socket, 137 // and the flush may not be done after we're done with the read. 138 wg := sync.WaitGroup{} 139 wg.Add(1) 140 go func() { 141 write(t, cConn, data) 142 wg.Done() 143 }() 144 145 received, err := read() 146 if err != nil || !bytes.Equal(data, received) { 147 t.Fatalf("ReadPacket failed: %v %v", received, err) 148 } 149 wg.Wait() 150 } 151 152 // Write a packet on one side, read it on the other, check it's 153 // correct. We use all possible read and write methods. 154 func verifyPacketComms(t *testing.T, cConn, sConn *Conn, data []byte) { 155 // All three writes, with ReadPacket. 156 verifyPacketCommsSpecific(t, cConn, data, useWritePacket, sConn.ReadPacket) 157 verifyPacketCommsSpecific(t, cConn, data, useWriteEphemeralPacketBuffered, sConn.ReadPacket) 158 verifyPacketCommsSpecific(t, cConn, data, useWriteEphemeralPacketDirect, sConn.ReadPacket) 159 160 // All three writes, with readEphemeralPacket. 161 verifyPacketCommsSpecific(t, cConn, data, useWritePacket, sConn.readEphemeralPacket) 162 sConn.recycleReadPacket() 163 verifyPacketCommsSpecific(t, cConn, data, useWriteEphemeralPacketBuffered, sConn.readEphemeralPacket) 164 sConn.recycleReadPacket() 165 verifyPacketCommsSpecific(t, cConn, data, useWriteEphemeralPacketDirect, sConn.readEphemeralPacket) 166 sConn.recycleReadPacket() 167 168 // All three writes, with readEphemeralPacketDirect, if size allows it. 169 if len(data) < MaxPacketSize { 170 verifyPacketCommsSpecific(t, cConn, data, useWritePacket, sConn.readEphemeralPacketDirect) 171 sConn.recycleReadPacket() 172 verifyPacketCommsSpecific(t, cConn, data, useWriteEphemeralPacketBuffered, sConn.readEphemeralPacketDirect) 173 sConn.recycleReadPacket() 174 verifyPacketCommsSpecific(t, cConn, data, useWriteEphemeralPacketDirect, sConn.readEphemeralPacketDirect) 175 sConn.recycleReadPacket() 176 } 177 } 178 179 func TestRawConnection(t *testing.T) { 180 listener, sConn, cConn := createSocketPair(t) 181 defer func() { 182 listener.Close() 183 sConn.Close() 184 cConn.Close() 185 }() 186 assert.IsType(t, &net.TCPConn{}, sConn.GetRawConn()) 187 assert.IsType(t, &net.TCPConn{}, cConn.GetRawConn()) 188 } 189 190 func TestPackets(t *testing.T) { 191 listener, sConn, cConn := createSocketPair(t) 192 defer func() { 193 listener.Close() 194 sConn.Close() 195 cConn.Close() 196 }() 197 198 // Verify all packets go through correctly. 199 // Small one. 200 data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 201 verifyPacketComms(t, cConn, sConn, data) 202 203 // 0 length packet 204 data = []byte{} 205 verifyPacketComms(t, cConn, sConn, data) 206 207 // Under the limit, still one packet. 208 data = make([]byte, MaxPacketSize-1) 209 data[0] = 0xab 210 data[MaxPacketSize-2] = 0xef 211 verifyPacketComms(t, cConn, sConn, data) 212 213 // Exactly the limit, two packets. 214 data = make([]byte, MaxPacketSize) 215 data[0] = 0xab 216 data[MaxPacketSize-1] = 0xef 217 verifyPacketComms(t, cConn, sConn, data) 218 219 // Over the limit, two packets. 220 data = make([]byte, MaxPacketSize+1000) 221 data[0] = 0xab 222 data[MaxPacketSize+999] = 0xef 223 verifyPacketComms(t, cConn, sConn, data) 224 } 225 226 func TestBasicPackets(t *testing.T) { 227 require := require.New(t) 228 assert := assert.New(t) 229 listener, sConn, cConn := createSocketPair(t) 230 defer func() { 231 listener.Close() 232 sConn.Close() 233 cConn.Close() 234 }() 235 236 // Write OK packet, read it, compare. 237 err := sConn.writeOKPacket(&PacketOK{ 238 affectedRows: 12, 239 lastInsertID: 34, 240 statusFlags: 56, 241 warnings: 78, 242 }) 243 require.NoError(err) 244 245 data, err := cConn.ReadPacket() 246 require.NoError(err) 247 require.NotEmpty(data) 248 assert.EqualValues(data[0], OKPacket, "OKPacket") 249 250 packetOk, err := cConn.parseOKPacket(data) 251 require.NoError(err) 252 assert.EqualValues(12, packetOk.affectedRows) 253 assert.EqualValues(34, packetOk.lastInsertID) 254 assert.EqualValues(56, packetOk.statusFlags) 255 assert.EqualValues(78, packetOk.warnings) 256 257 // Write OK packet with affected GTIDs, read it, compare. 258 sConn.Capabilities |= CapabilityClientSessionTrack 259 cConn.Capabilities |= CapabilityClientSessionTrack 260 ok := PacketOK{ 261 affectedRows: 23, 262 lastInsertID: 45, 263 statusFlags: 67 | ServerSessionStateChanged, 264 warnings: 89, 265 info: "", 266 sessionStateData: "foo-bar", 267 } 268 err = sConn.writeOKPacket(&ok) 269 require.NoError(err) 270 271 data, err = cConn.ReadPacket() 272 require.NoError(err) 273 require.NotEmpty(data) 274 assert.EqualValues(data[0], OKPacket, "OKPacket") 275 276 packetOk, err = cConn.parseOKPacket(data) 277 require.NoError(err) 278 assert.EqualValues(23, packetOk.affectedRows) 279 assert.EqualValues(45, packetOk.lastInsertID) 280 assert.EqualValues(ServerSessionStateChanged, packetOk.statusFlags&ServerSessionStateChanged) 281 assert.EqualValues(89, packetOk.warnings) 282 assert.EqualValues("foo-bar", packetOk.sessionStateData) 283 284 // Write OK packet with EOF header, read it, compare. 285 ok = PacketOK{ 286 affectedRows: 12, 287 lastInsertID: 34, 288 statusFlags: 56, 289 warnings: 78, 290 } 291 err = sConn.writeOKPacketWithEOFHeader(&ok) 292 require.NoError(err) 293 294 data, err = cConn.ReadPacket() 295 require.NoError(err) 296 require.NotEmpty(data) 297 assert.True(cConn.isEOFPacket(data), "expected EOF") 298 299 packetOk, err = cConn.parseOKPacket(data) 300 require.NoError(err) 301 assert.EqualValues(12, packetOk.affectedRows) 302 assert.EqualValues(34, packetOk.lastInsertID) 303 assert.EqualValues(56, packetOk.statusFlags) 304 assert.EqualValues(78, packetOk.warnings) 305 306 // Write error packet, read it, compare. 307 err = sConn.writeErrorPacket(ERAccessDeniedError, SSAccessDeniedError, "access denied: %v", "reason") 308 require.NoError(err) 309 data, err = cConn.ReadPacket() 310 require.NoError(err) 311 require.NotEmpty(data) 312 assert.EqualValues(data[0], ErrPacket, "ErrPacket") 313 314 err = ParseErrorPacket(data) 315 utils.MustMatch(t, err, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "access denied: reason"), "") 316 317 // Write error packet from error, read it, compare. 318 err = sConn.writeErrorPacketFromError(NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "access denied")) 319 require.NoError(err) 320 321 data, err = cConn.ReadPacket() 322 require.NoError(err) 323 require.NotEmpty(data) 324 assert.EqualValues(data[0], ErrPacket, "ErrPacket") 325 326 err = ParseErrorPacket(data) 327 utils.MustMatch(t, err, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "access denied"), "") 328 329 // Write EOF packet, read it, compare first byte. Payload is always ignored. 330 err = sConn.writeEOFPacket(0x8912, 0xabba) 331 require.NoError(err) 332 333 data, err = cConn.ReadPacket() 334 require.NoError(err) 335 require.NotEmpty(data) 336 assert.True(cConn.isEOFPacket(data), "expected EOF") 337 } 338 339 func TestOkPackets(t *testing.T) { 340 listener, sConn, cConn := createSocketPair(t) 341 defer func() { 342 listener.Close() 343 sConn.Close() 344 cConn.Close() 345 }() 346 347 testCases := []struct { 348 dataIn string 349 dataOut string 350 cc uint32 351 expectedErr string 352 }{{ 353 dataIn: ` 354 00000000 00 00 00 02 00 00 00 |.......|`, 355 cc: CapabilityClientProtocol41, 356 }, { 357 dataIn: ` 358 00000000 00 00 00 02 00 |.....|`, 359 cc: CapabilityClientTransactions, 360 expectedErr: "invalid OK packet warnings: &{[0 0 0 2 0] 0}", 361 }, { 362 dataIn: ` 363 00000000 FE 00 00 22 40 00 00 |.....|`, 364 dataOut: `00000000 00 00 00 22 40 00 00 00 04 03 02 00 00 |..."@........|`, 365 cc: CapabilityClientProtocol41 | CapabilityClientTransactions | CapabilityClientSessionTrack | CapabilityClientDeprecateEOF, 366 }, { 367 dataIn: ` 368 00000000 00 00 00 02 40 00 00 00 2a 03 28 00 26 66 32 37 |....@...*.(.&f27| 369 00000010 66 36 39 37 31 2d 30 33 65 37 2d 31 31 65 62 2d |f6971-03e7-11eb-| 370 00000020 38 35 63 35 2d 39 38 61 66 36 35 61 36 64 63 34 |85c5-98af65a6dc4| 371 00000030 61 3a 32 |a:2|`, 372 cc: CapabilityClientProtocol41 | CapabilityClientTransactions | CapabilityClientSessionTrack, 373 }, { 374 dataIn: `00000000 00 00 00 02 40 00 00 00 07 01 05 04 74 65 73 74 |....@.......test|`, 375 dataOut: `00000000 00 00 00 02 40 00 00 00 04 03 02 00 00 |....@........|`, 376 cc: CapabilityClientProtocol41 | CapabilityClientTransactions | CapabilityClientSessionTrack, 377 }, { 378 dataIn: ` 379 00000000 00 00 00 00 40 00 00 00 14 00 0f 0a 61 75 74 6f |....@.......auto| 380 00000010 63 6f 6d 6d 69 74 03 4f 46 46 02 01 31 |commit.OFF..1|`, 381 dataOut: ` 382 00000000 00 00 00 00 40 00 00 00 04 03 02 00 00 |....@........|`, 383 cc: CapabilityClientProtocol41 | CapabilityClientTransactions | CapabilityClientSessionTrack, 384 }, { 385 dataIn: ` 386 00000000 00 00 00 00 40 00 00 00 0a 01 05 04 74 65 73 74 |....@.......test| 387 00000010 02 01 31 |..1|`, 388 dataOut: ` 389 00000000 00 00 00 00 40 00 00 00 04 03 02 00 00 |....@........|`, 390 cc: CapabilityClientProtocol41 | CapabilityClientTransactions | CapabilityClientSessionTrack, 391 }, { 392 dataIn: `0000 00 00 00 03 40 00 00 00 fc 56 04 03 |....@....V..| 393 0010 fc 47 04 00 fc 43 04 30 63 36 63 36 62 34 61 2d |.G...C.0c6c6b4a-| 394 0020 32 64 65 35 2d 31 31 65 64 2d 62 63 37 61 2d 61 |2de5-11ed-bc7a-a| 395 0030 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 34 2c |8a15983d5bd:1-4,| 396 0040 0a 31 33 65 62 66 38 32 38 2d 32 64 65 35 2d 31 |.13ebf828-2de5-1| 397 0050 31 65 64 2d 62 34 65 35 2d 61 38 61 31 35 39 38 |1ed-b4e5-a8a1598| 398 0060 33 64 35 62 64 3a 31 2d 39 2c 0a 31 38 61 30 66 |3d5bd:1-9,.18a0f| 399 0070 30 34 38 2d 32 64 65 34 2d 31 31 65 64 2d 38 63 |048-2de4-11ed-8c| 400 0080 31 63 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a |1c-a8a15983d5bd:| 401 0090 31 2d 33 2c 0a 31 66 36 34 31 62 36 33 2d 32 64 |1-3,.1f641b63-2d| 402 00a0 65 35 2d 31 31 65 64 2d 61 35 31 62 2d 61 38 61 |e5-11ed-a51b-a8a| 403 00b0 31 35 39 38 33 64 35 62 64 3a 31 2d 39 2c 0a 32 |15983d5bd:1-9,.2| 404 00c0 63 36 35 36 35 37 31 2d 32 64 65 35 2d 31 31 65 |c656571-2de5-11e| 405 00d0 64 2d 61 34 37 34 2d 61 38 61 31 35 39 38 33 64 |d-a474-a8a15983d| 406 00e0 35 62 64 3a 31 2d 35 2c 0a 33 32 32 61 34 32 35 |5bd:1-5,.322a425| 407 00f0 34 2d 32 64 65 35 2d 31 31 65 64 2d 61 65 64 31 |4-2de5-11ed-aed1| 408 0100 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d |-a8a15983d5bd:1-| 409 0110 34 2c 0a 33 37 63 35 64 30 34 31 2d 32 64 65 35 |4,.37c5d041-2de5| 410 0120 2d 31 31 65 64 2d 38 64 33 66 2d 61 38 61 31 35 |-11ed-8d3f-a8a15| 411 0130 39 38 33 64 35 62 64 3a 31 2d 31 32 2c 0a 34 31 |983d5bd:1-12,.41| 412 0140 34 33 32 37 32 33 2d 32 64 65 35 2d 31 31 65 64 |432723-2de5-11ed| 413 0150 2d 61 61 36 66 2d 61 38 61 31 35 39 38 33 64 35 |-aa6f-a8a15983d5| 414 0160 62 64 3a 31 2d 37 2c 0a 34 39 38 38 38 35 36 66 |bd:1-7,.4988856f| 415 0170 2d 32 64 65 34 2d 31 31 65 64 2d 39 37 31 36 2d |-2de4-11ed-9716-| 416 0180 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 35 |a8a15983d5bd:1-5| 417 0190 2c 0a 35 35 38 36 61 64 34 65 2d 32 64 65 34 2d |,.5586ad4e-2de4-| 418 01a0 31 31 65 64 2d 38 63 37 33 2d 61 38 61 31 35 39 |11ed-8c73-a8a159| 419 01b0 38 33 64 35 62 64 3a 31 2d 36 2c 0a 36 34 65 39 |83d5bd:1-6,.64e9| 420 01c0 66 32 32 66 2d 32 64 65 34 2d 31 31 65 64 2d 39 |f22f-2de4-11ed-9| 421 01d0 62 65 31 2d 61 38 61 31 35 39 38 33 64 35 62 64 |be1-a8a15983d5bd| 422 01e0 3a 31 2d 33 2c 0a 36 62 31 36 34 37 30 65 2d 32 |:1-3,.6b16470e-2| 423 01f0 64 65 34 2d 31 31 65 64 2d 61 31 33 64 2d 61 38 |de4-11ed-a13d-a8| 424 0200 61 31 35 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a |a15983d5bd:1-4,.| 425 0210 37 35 65 37 65 32 38 65 2d 32 37 61 38 2d 31 31 |75e7e28e-27a8-11| 426 0220 65 64 2d 39 61 30 36 2d 61 38 61 31 35 39 38 33 |ed-9a06-a8a15983| 427 0230 64 35 62 64 3a 31 2d 39 2c 0a 38 31 34 30 32 37 |d5bd:1-9,.814027| 428 0240 66 31 2d 32 64 65 34 2d 31 31 65 64 2d 39 65 33 |f1-2de4-11ed-9e3| 429 0250 63 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 |c-a8a15983d5bd:1| 430 0260 2d 34 2c 0a 38 37 63 32 38 64 64 63 2d 32 64 65 |-4,.87c28ddc-2de| 431 0270 34 2d 31 31 65 64 2d 38 32 37 32 2d 61 38 61 31 |4-11ed-8272-a8a1| 432 0280 35 39 38 33 64 35 62 64 3a 31 2d 31 39 2c 0a 39 |5983d5bd:1-19,.9| 433 0290 30 35 38 33 35 62 37 2d 32 64 65 35 2d 31 31 65 |05835b7-2de5-11e| 434 02a0 64 2d 61 32 39 39 2d 61 38 61 31 35 39 38 33 64 |d-a299-a8a15983d| 435 02b0 35 62 64 3a 31 2d 38 2c 0a 39 37 64 66 36 30 63 |5bd:1-8,.97df60c| 436 02c0 39 2d 32 64 65 34 2d 31 31 65 64 2d 62 39 30 65 |9-2de4-11ed-b90e| 437 02d0 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d |-a8a15983d5bd:1-| 438 02e0 35 2c 0a 39 37 65 39 30 63 30 38 2d 32 64 65 35 |5,.97e90c08-2de5| 439 02f0 2d 31 31 65 64 2d 39 37 30 39 2d 61 38 61 31 35 |-11ed-9709-a8a15| 440 0300 39 38 33 64 35 62 64 3a 31 2d 33 38 2c 0a 39 39 |983d5bd:1-38,.99| 441 0310 64 66 61 32 62 64 2d 32 64 65 33 2d 31 31 65 64 |dfa2bd-2de3-11ed| 442 0320 2d 62 37 39 65 2d 61 38 61 31 35 39 38 33 64 35 |-b79e-a8a15983d5| 443 0330 62 64 3a 31 2c 0a 61 31 62 63 34 33 34 32 2d 32 |bd:1,.a1bc4342-2| 444 0340 64 65 34 2d 31 31 65 64 2d 61 30 62 31 2d 61 38 |de4-11ed-a0b1-a8| 445 0350 61 31 35 39 38 33 64 35 62 64 3a 31 2d 31 36 2c |a15983d5bd:1-16,| 446 0360 0a 61 62 65 35 65 32 61 34 2d 32 64 65 34 2d 31 |.abe5e2a4-2de4-1| 447 0370 31 65 64 2d 62 62 33 63 2d 61 38 61 31 35 39 38 |1ed-bb3c-a8a1598| 448 0380 33 64 35 62 64 3a 31 2d 33 2c 0a 62 37 64 39 61 |3d5bd:1-3,.b7d9a| 449 0390 62 39 37 2d 32 64 65 34 2d 31 31 65 64 2d 39 33 |b97-2de4-11ed-93| 450 03a0 39 64 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a |9d-a8a15983d5bd:| 451 03b0 31 2c 0a 62 64 33 64 30 34 30 30 2d 32 64 65 34 |1,.bd3d0400-2de4| 452 03c0 2d 31 31 65 64 2d 38 62 36 61 2d 61 38 61 31 35 |-11ed-8b6a-a8a15| 453 03d0 39 38 33 64 35 62 64 3a 31 2d 36 2c 0a 63 36 61 |983d5bd:1-6,.c6a| 454 03e0 38 37 33 61 63 2d 32 64 65 35 2d 31 31 65 64 2d |873ac-2de5-11ed-| 455 03f0 38 35 30 33 2d 61 38 61 31 35 39 38 33 64 35 62 |8503-a8a15983d5b| 456 0400 64 3a 31 2d 32 31 2c 0a 64 34 37 65 30 36 32 65 |d:1-21,.d47e062e| 457 0410 2d 32 64 65 35 2d 31 31 65 64 2d 38 63 39 62 2d |-2de5-11ed-8c9b-| 458 0420 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 39 |a8a15983d5bd:1-9| 459 0430 2c 0a 64 65 30 64 63 37 38 30 2d 32 64 65 35 2d |,.de0dc780-2de5-| 460 0440 31 31 65 64 2d 62 31 62 31 2d 61 38 61 31 35 39 |11ed-b1b1-a8a159| 461 0450 38 33 64 35 62 64 3a 31 2d 37 05 09 08 54 5f 52 |83d5bd:1-7...T_R| 462 0460 5f 5f 5f 5f 5f |_____| 463 `, 464 dataOut: ` 465 00000000 00 00 00 03 40 00 00 00 fc 4b 04 03 fc 47 04 00 |....@....K...G..| 466 00000010 fc 43 04 30 63 36 63 36 62 34 61 2d 32 64 65 35 |.C.0c6c6b4a-2de5| 467 00000020 2d 31 31 65 64 2d 62 63 37 61 2d 61 38 61 31 35 |-11ed-bc7a-a8a15| 468 00000030 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a 31 33 65 |983d5bd:1-4,.13e| 469 00000040 62 66 38 32 38 2d 32 64 65 35 2d 31 31 65 64 2d |bf828-2de5-11ed-| 470 00000050 62 34 65 35 2d 61 38 61 31 35 39 38 33 64 35 62 |b4e5-a8a15983d5b| 471 00000060 64 3a 31 2d 39 2c 0a 31 38 61 30 66 30 34 38 2d |d:1-9,.18a0f048-| 472 00000070 32 64 65 34 2d 31 31 65 64 2d 38 63 31 63 2d 61 |2de4-11ed-8c1c-a| 473 00000080 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 33 2c |8a15983d5bd:1-3,| 474 00000090 0a 31 66 36 34 31 62 36 33 2d 32 64 65 35 2d 31 |.1f641b63-2de5-1| 475 000000a0 31 65 64 2d 61 35 31 62 2d 61 38 61 31 35 39 38 |1ed-a51b-a8a1598| 476 000000b0 33 64 35 62 64 3a 31 2d 39 2c 0a 32 63 36 35 36 |3d5bd:1-9,.2c656| 477 000000c0 35 37 31 2d 32 64 65 35 2d 31 31 65 64 2d 61 34 |571-2de5-11ed-a4| 478 000000d0 37 34 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a |74-a8a15983d5bd:| 479 000000e0 31 2d 35 2c 0a 33 32 32 61 34 32 35 34 2d 32 64 |1-5,.322a4254-2d| 480 000000f0 65 35 2d 31 31 65 64 2d 61 65 64 31 2d 61 38 61 |e5-11ed-aed1-a8a| 481 00000100 31 35 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a 33 |15983d5bd:1-4,.3| 482 00000110 37 63 35 64 30 34 31 2d 32 64 65 35 2d 31 31 65 |7c5d041-2de5-11e| 483 00000120 64 2d 38 64 33 66 2d 61 38 61 31 35 39 38 33 64 |d-8d3f-a8a15983d| 484 00000130 35 62 64 3a 31 2d 31 32 2c 0a 34 31 34 33 32 37 |5bd:1-12,.414327| 485 00000140 32 33 2d 32 64 65 35 2d 31 31 65 64 2d 61 61 36 |23-2de5-11ed-aa6| 486 00000150 66 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 |f-a8a15983d5bd:1| 487 00000160 2d 37 2c 0a 34 39 38 38 38 35 36 66 2d 32 64 65 |-7,.4988856f-2de| 488 00000170 34 2d 31 31 65 64 2d 39 37 31 36 2d 61 38 61 31 |4-11ed-9716-a8a1| 489 00000180 35 39 38 33 64 35 62 64 3a 31 2d 35 2c 0a 35 35 |5983d5bd:1-5,.55| 490 00000190 38 36 61 64 34 65 2d 32 64 65 34 2d 31 31 65 64 |86ad4e-2de4-11ed| 491 000001a0 2d 38 63 37 33 2d 61 38 61 31 35 39 38 33 64 35 |-8c73-a8a15983d5| 492 000001b0 62 64 3a 31 2d 36 2c 0a 36 34 65 39 66 32 32 66 |bd:1-6,.64e9f22f| 493 000001c0 2d 32 64 65 34 2d 31 31 65 64 2d 39 62 65 31 2d |-2de4-11ed-9be1-| 494 000001d0 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 33 |a8a15983d5bd:1-3| 495 000001e0 2c 0a 36 62 31 36 34 37 30 65 2d 32 64 65 34 2d |,.6b16470e-2de4-| 496 000001f0 31 31 65 64 2d 61 31 33 64 2d 61 38 61 31 35 39 |11ed-a13d-a8a159| 497 00000200 38 33 64 35 62 64 3a 31 2d 34 2c 0a 37 35 65 37 |83d5bd:1-4,.75e7| 498 00000210 65 32 38 65 2d 32 37 61 38 2d 31 31 65 64 2d 39 |e28e-27a8-11ed-9| 499 00000220 61 30 36 2d 61 38 61 31 35 39 38 33 64 35 62 64 |a06-a8a15983d5bd| 500 00000230 3a 31 2d 39 2c 0a 38 31 34 30 32 37 66 31 2d 32 |:1-9,.814027f1-2| 501 00000240 64 65 34 2d 31 31 65 64 2d 39 65 33 63 2d 61 38 |de4-11ed-9e3c-a8| 502 00000250 61 31 35 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a |a15983d5bd:1-4,.| 503 00000260 38 37 63 32 38 64 64 63 2d 32 64 65 34 2d 31 31 |87c28ddc-2de4-11| 504 00000270 65 64 2d 38 32 37 32 2d 61 38 61 31 35 39 38 33 |ed-8272-a8a15983| 505 00000280 64 35 62 64 3a 31 2d 31 39 2c 0a 39 30 35 38 33 |d5bd:1-19,.90583| 506 00000290 35 62 37 2d 32 64 65 35 2d 31 31 65 64 2d 61 32 |5b7-2de5-11ed-a2| 507 000002a0 39 39 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a |99-a8a15983d5bd:| 508 000002b0 31 2d 38 2c 0a 39 37 64 66 36 30 63 39 2d 32 64 |1-8,.97df60c9-2d| 509 000002c0 65 34 2d 31 31 65 64 2d 62 39 30 65 2d 61 38 61 |e4-11ed-b90e-a8a| 510 000002d0 31 35 39 38 33 64 35 62 64 3a 31 2d 35 2c 0a 39 |15983d5bd:1-5,.9| 511 000002e0 37 65 39 30 63 30 38 2d 32 64 65 35 2d 31 31 65 |7e90c08-2de5-11e| 512 000002f0 64 2d 39 37 30 39 2d 61 38 61 31 35 39 38 33 64 |d-9709-a8a15983d| 513 00000300 35 62 64 3a 31 2d 33 38 2c 0a 39 39 64 66 61 32 |5bd:1-38,.99dfa2| 514 00000310 62 64 2d 32 64 65 33 2d 31 31 65 64 2d 62 37 39 |bd-2de3-11ed-b79| 515 00000320 65 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 |e-a8a15983d5bd:1| 516 00000330 2c 0a 61 31 62 63 34 33 34 32 2d 32 64 65 34 2d |,.a1bc4342-2de4-| 517 00000340 31 31 65 64 2d 61 30 62 31 2d 61 38 61 31 35 39 |11ed-a0b1-a8a159| 518 00000350 38 33 64 35 62 64 3a 31 2d 31 36 2c 0a 61 62 65 |83d5bd:1-16,.abe| 519 00000360 35 65 32 61 34 2d 32 64 65 34 2d 31 31 65 64 2d |5e2a4-2de4-11ed-| 520 00000370 62 62 33 63 2d 61 38 61 31 35 39 38 33 64 35 62 |bb3c-a8a15983d5b| 521 00000380 64 3a 31 2d 33 2c 0a 62 37 64 39 61 62 39 37 2d |d:1-3,.b7d9ab97-| 522 00000390 32 64 65 34 2d 31 31 65 64 2d 39 33 39 64 2d 61 |2de4-11ed-939d-a| 523 000003a0 38 61 31 35 39 38 33 64 35 62 64 3a 31 2c 0a 62 |8a15983d5bd:1,.b| 524 000003b0 64 33 64 30 34 30 30 2d 32 64 65 34 2d 31 31 65 |d3d0400-2de4-11e| 525 000003c0 64 2d 38 62 36 61 2d 61 38 61 31 35 39 38 33 64 |d-8b6a-a8a15983d| 526 000003d0 35 62 64 3a 31 2d 36 2c 0a 63 36 61 38 37 33 61 |5bd:1-6,.c6a873a| 527 000003e0 63 2d 32 64 65 35 2d 31 31 65 64 2d 38 35 30 33 |c-2de5-11ed-8503| 528 000003f0 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d |-a8a15983d5bd:1-| 529 00000400 32 31 2c 0a 64 34 37 65 30 36 32 65 2d 32 64 65 |21,.d47e062e-2de| 530 00000410 35 2d 31 31 65 64 2d 38 63 39 62 2d 61 38 61 31 |5-11ed-8c9b-a8a1| 531 00000420 35 39 38 33 64 35 62 64 3a 31 2d 39 2c 0a 64 65 |5983d5bd:1-9,.de| 532 00000430 30 64 63 37 38 30 2d 32 64 65 35 2d 31 31 65 64 |0dc780-2de5-11ed| 533 00000440 2d 62 31 62 31 2d 61 38 61 31 35 39 38 33 64 35 |-b1b1-a8a15983d5| 534 00000450 62 64 3a 31 2d 37 |bd:1-7|`, 535 cc: CapabilityClientProtocol41 | CapabilityClientTransactions | CapabilityClientSessionTrack, 536 }, { 537 dataIn: `00000000 00 00 00 03 40 00 00 00 fc 56 04 05 |....@....V..| 538 00000010 09 08 54 5f 52 5f 5f 5f 5f 5f 03 fc 47 04 00 fc |..T_R_____.?G..?| 539 00000020 43 04 30 63 36 63 36 62 34 61 2d 32 64 65 35 2d |C.0c6c6b4a-2de5-| 540 00000030 31 31 65 64 2d 62 63 37 61 2d 61 38 61 31 35 39 |11ed-bc7a-a8a159| 541 00000040 38 33 64 35 62 64 3a 31 2d 34 2c 0a 31 33 65 62 |83d5bd:1-4,.13eb| 542 00000050 66 38 32 38 2d 32 64 65 35 2d 31 31 65 64 2d 62 |f828-2de5-11ed-b| 543 00000060 34 65 35 2d 61 38 61 31 35 39 38 33 64 35 62 64 |4e5-a8a15983d5bd| 544 00000070 3a 31 2d 39 2c 0a 31 38 61 30 66 30 34 38 2d 32 |:1-9,.18a0f048-2| 545 00000080 64 65 34 2d 31 31 65 64 2d 38 63 31 63 2d 61 38 |de4-11ed-8c1c-a8| 546 00000090 61 31 35 39 38 33 64 35 62 64 3a 31 2d 33 2c 0a |a15983d5bd:1-3,.| 547 000000a0 31 66 36 34 31 62 36 33 2d 32 64 65 35 2d 31 31 |1f641b63-2de5-11| 548 000000b0 65 64 2d 61 35 31 62 2d 61 38 61 31 35 39 38 33 |ed-a51b-a8a15983| 549 000000c0 64 35 62 64 3a 31 2d 39 2c 0a 32 63 36 35 36 35 |d5bd:1-9,.2c6565| 550 000000d0 37 31 2d 32 64 65 35 2d 31 31 65 64 2d 61 34 37 |71-2de5-11ed-a47| 551 000000e0 34 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 |4-a8a15983d5bd:1| 552 000000f0 2d 35 2c 0a 33 32 32 61 34 32 35 34 2d 32 64 65 |-5,.322a4254-2de| 553 00000100 35 2d 31 31 65 64 2d 61 65 64 31 2d 61 38 61 31 |5-11ed-aed1-a8a1| 554 00000110 35 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a 33 37 |5983d5bd:1-4,.37| 555 00000120 63 35 64 30 34 31 2d 32 64 65 35 2d 31 31 65 64 |c5d041-2de5-11ed| 556 00000130 2d 38 64 33 66 2d 61 38 61 31 35 39 38 33 64 35 |-8d3f-a8a15983d5| 557 00000140 62 64 3a 31 2d 31 32 2c 0a 34 31 34 33 32 37 32 |bd:1-12,.4143272| 558 00000150 33 2d 32 64 65 35 2d 31 31 65 64 2d 61 61 36 66 |3-2de5-11ed-aa6f| 559 00000160 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d |-a8a15983d5bd:1-| 560 00000170 37 2c 0a 34 39 38 38 38 35 36 66 2d 32 64 65 34 |7,.4988856f-2de4| 561 00000180 2d 31 31 65 64 2d 39 37 31 36 2d 61 38 61 31 35 |-11ed-9716-a8a15| 562 00000190 39 38 33 64 35 62 64 3a 31 2d 35 2c 0a 35 35 38 |983d5bd:1-5,.558| 563 000001a0 36 61 64 34 65 2d 32 64 65 34 2d 31 31 65 64 2d |6ad4e-2de4-11ed-| 564 000001b0 38 63 37 33 2d 61 38 61 31 35 39 38 33 64 35 62 |8c73-a8a15983d5b| 565 000001c0 64 3a 31 2d 36 2c 0a 36 34 65 39 66 32 32 66 2d |d:1-6,.64e9f22f-| 566 000001d0 32 64 65 34 2d 31 31 65 64 2d 39 62 65 31 2d 61 |2de4-11ed-9be1-a| 567 000001e0 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 33 2c |8a15983d5bd:1-3,| 568 000001f0 0a 36 62 31 36 34 37 30 65 2d 32 64 65 34 2d 31 |.6b16470e-2de4-1| 569 00000200 31 65 64 2d 61 31 33 64 2d 61 38 61 31 35 39 38 |1ed-a13d-a8a1598| 570 00000210 33 64 35 62 64 3a 31 2d 34 2c 0a 37 35 65 37 65 |3d5bd:1-4,.75e7e| 571 00000220 32 38 65 2d 32 37 61 38 2d 31 31 65 64 2d 39 61 |28e-27a8-11ed-9a| 572 00000230 30 36 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a |06-a8a15983d5bd:| 573 00000240 31 2d 39 2c 0a 38 31 34 30 32 37 66 31 2d 32 64 |1-9,.814027f1-2d| 574 00000250 65 34 2d 31 31 65 64 2d 39 65 33 63 2d 61 38 61 |e4-11ed-9e3c-a8a| 575 00000260 31 35 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a 38 |15983d5bd:1-4,.8| 576 00000270 37 63 32 38 64 64 63 2d 32 64 65 34 2d 31 31 65 |7c28ddc-2de4-11e| 577 00000280 64 2d 38 32 37 32 2d 61 38 61 31 35 39 38 33 64 |d-8272-a8a15983d| 578 00000290 35 62 64 3a 31 2d 31 39 2c 0a 39 30 35 38 33 35 |5bd:1-19,.905835| 579 000002a0 62 37 2d 32 64 65 35 2d 31 31 65 64 2d 61 32 39 |b7-2de5-11ed-a29| 580 000002b0 39 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 |9-a8a15983d5bd:1| 581 000002c0 2d 38 2c 0a 39 37 64 66 36 30 63 39 2d 32 64 65 |-8,.97df60c9-2de| 582 000002d0 34 2d 31 31 65 64 2d 62 39 30 65 2d 61 38 61 31 |4-11ed-b90e-a8a1| 583 000002e0 35 39 38 33 64 35 62 64 3a 31 2d 35 2c 0a 39 37 |5983d5bd:1-5,.97| 584 000002f0 65 39 30 63 30 38 2d 32 64 65 35 2d 31 31 65 64 |e90c08-2de5-11ed| 585 00000300 2d 39 37 30 39 2d 61 38 61 31 35 39 38 33 64 35 |-9709-a8a15983d5| 586 00000310 62 64 3a 31 2d 33 38 2c 0a 39 39 64 66 61 32 62 |bd:1-38,.99dfa2b| 587 00000320 64 2d 32 64 65 33 2d 31 31 65 64 2d 62 37 39 65 |d-2de3-11ed-b79e| 588 00000330 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2c |-a8a15983d5bd:1,| 589 00000340 0a 61 31 62 63 34 33 34 32 2d 32 64 65 34 2d 31 |.a1bc4342-2de4-1| 590 00000350 31 65 64 2d 61 30 62 31 2d 61 38 61 31 35 39 38 |1ed-a0b1-a8a1598| 591 00000360 33 64 35 62 64 3a 31 2d 31 36 2c 0a 61 62 65 35 |3d5bd:1-16,.abe5| 592 00000370 65 32 61 34 2d 32 64 65 34 2d 31 31 65 64 2d 62 |e2a4-2de4-11ed-b| 593 00000380 62 33 63 2d 61 38 61 31 35 39 38 33 64 35 62 64 |b3c-a8a15983d5bd| 594 00000390 3a 31 2d 33 2c 0a 62 37 64 39 61 62 39 37 2d 32 |:1-3,.b7d9ab97-2| 595 000003a0 64 65 34 2d 31 31 65 64 2d 39 33 39 64 2d 61 38 |de4-11ed-939d-a8| 596 000003b0 61 31 35 39 38 33 64 35 62 64 3a 31 2c 0a 62 64 |a15983d5bd:1,.bd| 597 000003c0 33 64 30 34 30 30 2d 32 64 65 34 2d 31 31 65 64 |3d0400-2de4-11ed| 598 000003d0 2d 38 62 36 61 2d 61 38 61 31 35 39 38 33 64 35 |-8b6a-a8a15983d5| 599 000003e0 62 64 3a 31 2d 36 2c 0a 63 36 61 38 37 33 61 63 |bd:1-6,.c6a873ac| 600 000003f0 2d 32 64 65 35 2d 31 31 65 64 2d 38 35 30 33 2d |-2de5-11ed-8503-| 601 00000400 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 32 |a8a15983d5bd:1-2| 602 00000410 31 2c 0a 64 34 37 65 30 36 32 65 2d 32 64 65 35 |1,.d47e062e-2de5| 603 00000420 2d 31 31 65 64 2d 38 63 39 62 2d 61 38 61 31 35 |-11ed-8c9b-a8a15| 604 00000430 39 38 33 64 35 62 64 3a 31 2d 39 2c 0a 64 65 30 |983d5bd:1-9,.de0| 605 00000440 64 63 37 38 30 2d 32 64 65 35 2d 31 31 65 64 2d |dc780-2de5-11ed-| 606 00000450 62 31 62 31 2d 61 38 61 31 35 39 38 33 64 35 62 |b1b1-a8a15983d5b| 607 00000460 64 3a 31 2d 37 |d:1-7| 608 `, 609 dataOut: ` 610 00000000 00 00 00 03 40 00 00 00 fc 4b 04 03 fc 47 04 00 |....@....K...G..| 611 00000010 fc 43 04 30 63 36 63 36 62 34 61 2d 32 64 65 35 |.C.0c6c6b4a-2de5| 612 00000020 2d 31 31 65 64 2d 62 63 37 61 2d 61 38 61 31 35 |-11ed-bc7a-a8a15| 613 00000030 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a 31 33 65 |983d5bd:1-4,.13e| 614 00000040 62 66 38 32 38 2d 32 64 65 35 2d 31 31 65 64 2d |bf828-2de5-11ed-| 615 00000050 62 34 65 35 2d 61 38 61 31 35 39 38 33 64 35 62 |b4e5-a8a15983d5b| 616 00000060 64 3a 31 2d 39 2c 0a 31 38 61 30 66 30 34 38 2d |d:1-9,.18a0f048-| 617 00000070 32 64 65 34 2d 31 31 65 64 2d 38 63 31 63 2d 61 |2de4-11ed-8c1c-a| 618 00000080 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 33 2c |8a15983d5bd:1-3,| 619 00000090 0a 31 66 36 34 31 62 36 33 2d 32 64 65 35 2d 31 |.1f641b63-2de5-1| 620 000000a0 31 65 64 2d 61 35 31 62 2d 61 38 61 31 35 39 38 |1ed-a51b-a8a1598| 621 000000b0 33 64 35 62 64 3a 31 2d 39 2c 0a 32 63 36 35 36 |3d5bd:1-9,.2c656| 622 000000c0 35 37 31 2d 32 64 65 35 2d 31 31 65 64 2d 61 34 |571-2de5-11ed-a4| 623 000000d0 37 34 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a |74-a8a15983d5bd:| 624 000000e0 31 2d 35 2c 0a 33 32 32 61 34 32 35 34 2d 32 64 |1-5,.322a4254-2d| 625 000000f0 65 35 2d 31 31 65 64 2d 61 65 64 31 2d 61 38 61 |e5-11ed-aed1-a8a| 626 00000100 31 35 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a 33 |15983d5bd:1-4,.3| 627 00000110 37 63 35 64 30 34 31 2d 32 64 65 35 2d 31 31 65 |7c5d041-2de5-11e| 628 00000120 64 2d 38 64 33 66 2d 61 38 61 31 35 39 38 33 64 |d-8d3f-a8a15983d| 629 00000130 35 62 64 3a 31 2d 31 32 2c 0a 34 31 34 33 32 37 |5bd:1-12,.414327| 630 00000140 32 33 2d 32 64 65 35 2d 31 31 65 64 2d 61 61 36 |23-2de5-11ed-aa6| 631 00000150 66 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 |f-a8a15983d5bd:1| 632 00000160 2d 37 2c 0a 34 39 38 38 38 35 36 66 2d 32 64 65 |-7,.4988856f-2de| 633 00000170 34 2d 31 31 65 64 2d 39 37 31 36 2d 61 38 61 31 |4-11ed-9716-a8a1| 634 00000180 35 39 38 33 64 35 62 64 3a 31 2d 35 2c 0a 35 35 |5983d5bd:1-5,.55| 635 00000190 38 36 61 64 34 65 2d 32 64 65 34 2d 31 31 65 64 |86ad4e-2de4-11ed| 636 000001a0 2d 38 63 37 33 2d 61 38 61 31 35 39 38 33 64 35 |-8c73-a8a15983d5| 637 000001b0 62 64 3a 31 2d 36 2c 0a 36 34 65 39 66 32 32 66 |bd:1-6,.64e9f22f| 638 000001c0 2d 32 64 65 34 2d 31 31 65 64 2d 39 62 65 31 2d |-2de4-11ed-9be1-| 639 000001d0 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d 33 |a8a15983d5bd:1-3| 640 000001e0 2c 0a 36 62 31 36 34 37 30 65 2d 32 64 65 34 2d |,.6b16470e-2de4-| 641 000001f0 31 31 65 64 2d 61 31 33 64 2d 61 38 61 31 35 39 |11ed-a13d-a8a159| 642 00000200 38 33 64 35 62 64 3a 31 2d 34 2c 0a 37 35 65 37 |83d5bd:1-4,.75e7| 643 00000210 65 32 38 65 2d 32 37 61 38 2d 31 31 65 64 2d 39 |e28e-27a8-11ed-9| 644 00000220 61 30 36 2d 61 38 61 31 35 39 38 33 64 35 62 64 |a06-a8a15983d5bd| 645 00000230 3a 31 2d 39 2c 0a 38 31 34 30 32 37 66 31 2d 32 |:1-9,.814027f1-2| 646 00000240 64 65 34 2d 31 31 65 64 2d 39 65 33 63 2d 61 38 |de4-11ed-9e3c-a8| 647 00000250 61 31 35 39 38 33 64 35 62 64 3a 31 2d 34 2c 0a |a15983d5bd:1-4,.| 648 00000260 38 37 63 32 38 64 64 63 2d 32 64 65 34 2d 31 31 |87c28ddc-2de4-11| 649 00000270 65 64 2d 38 32 37 32 2d 61 38 61 31 35 39 38 33 |ed-8272-a8a15983| 650 00000280 64 35 62 64 3a 31 2d 31 39 2c 0a 39 30 35 38 33 |d5bd:1-19,.90583| 651 00000290 35 62 37 2d 32 64 65 35 2d 31 31 65 64 2d 61 32 |5b7-2de5-11ed-a2| 652 000002a0 39 39 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a |99-a8a15983d5bd:| 653 000002b0 31 2d 38 2c 0a 39 37 64 66 36 30 63 39 2d 32 64 |1-8,.97df60c9-2d| 654 000002c0 65 34 2d 31 31 65 64 2d 62 39 30 65 2d 61 38 61 |e4-11ed-b90e-a8a| 655 000002d0 31 35 39 38 33 64 35 62 64 3a 31 2d 35 2c 0a 39 |15983d5bd:1-5,.9| 656 000002e0 37 65 39 30 63 30 38 2d 32 64 65 35 2d 31 31 65 |7e90c08-2de5-11e| 657 000002f0 64 2d 39 37 30 39 2d 61 38 61 31 35 39 38 33 64 |d-9709-a8a15983d| 658 00000300 35 62 64 3a 31 2d 33 38 2c 0a 39 39 64 66 61 32 |5bd:1-38,.99dfa2| 659 00000310 62 64 2d 32 64 65 33 2d 31 31 65 64 2d 62 37 39 |bd-2de3-11ed-b79| 660 00000320 65 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 |e-a8a15983d5bd:1| 661 00000330 2c 0a 61 31 62 63 34 33 34 32 2d 32 64 65 34 2d |,.a1bc4342-2de4-| 662 00000340 31 31 65 64 2d 61 30 62 31 2d 61 38 61 31 35 39 |11ed-a0b1-a8a159| 663 00000350 38 33 64 35 62 64 3a 31 2d 31 36 2c 0a 61 62 65 |83d5bd:1-16,.abe| 664 00000360 35 65 32 61 34 2d 32 64 65 34 2d 31 31 65 64 2d |5e2a4-2de4-11ed-| 665 00000370 62 62 33 63 2d 61 38 61 31 35 39 38 33 64 35 62 |bb3c-a8a15983d5b| 666 00000380 64 3a 31 2d 33 2c 0a 62 37 64 39 61 62 39 37 2d |d:1-3,.b7d9ab97-| 667 00000390 32 64 65 34 2d 31 31 65 64 2d 39 33 39 64 2d 61 |2de4-11ed-939d-a| 668 000003a0 38 61 31 35 39 38 33 64 35 62 64 3a 31 2c 0a 62 |8a15983d5bd:1,.b| 669 000003b0 64 33 64 30 34 30 30 2d 32 64 65 34 2d 31 31 65 |d3d0400-2de4-11e| 670 000003c0 64 2d 38 62 36 61 2d 61 38 61 31 35 39 38 33 64 |d-8b6a-a8a15983d| 671 000003d0 35 62 64 3a 31 2d 36 2c 0a 63 36 61 38 37 33 61 |5bd:1-6,.c6a873a| 672 000003e0 63 2d 32 64 65 35 2d 31 31 65 64 2d 38 35 30 33 |c-2de5-11ed-8503| 673 000003f0 2d 61 38 61 31 35 39 38 33 64 35 62 64 3a 31 2d |-a8a15983d5bd:1-| 674 00000400 32 31 2c 0a 64 34 37 65 30 36 32 65 2d 32 64 65 |21,.d47e062e-2de| 675 00000410 35 2d 31 31 65 64 2d 38 63 39 62 2d 61 38 61 31 |5-11ed-8c9b-a8a1| 676 00000420 35 39 38 33 64 35 62 64 3a 31 2d 39 2c 0a 64 65 |5983d5bd:1-9,.de| 677 00000430 30 64 63 37 38 30 2d 32 64 65 35 2d 31 31 65 64 |0dc780-2de5-11ed| 678 00000440 2d 62 31 62 31 2d 61 38 61 31 35 39 38 33 64 35 |-b1b1-a8a15983d5| 679 00000450 62 64 3a 31 2d 37 |bd:1-7|`, 680 cc: CapabilityClientProtocol41 | CapabilityClientTransactions | CapabilityClientSessionTrack, 681 }} 682 683 for i, testCase := range testCases { 684 t.Run("data packet:"+strconv.Itoa(i), func(t *testing.T) { 685 data := ReadHexDump(testCase.dataIn) 686 dataOut := data 687 if testCase.dataOut != "" { 688 dataOut = ReadHexDump(testCase.dataOut) 689 } 690 691 cConn.Capabilities = testCase.cc 692 sConn.Capabilities = testCase.cc 693 // parse the packet 694 packetOk, err := cConn.parseOKPacket(data) 695 if testCase.expectedErr != "" { 696 require.Error(t, err) 697 require.Equal(t, testCase.expectedErr, err.Error()) 698 return 699 } 700 require.NoError(t, err, "failed to parse OK packet") 701 702 // write the ok packet from server 703 err = sConn.writeOKPacket(packetOk) 704 require.NoError(t, err, "failed to write OK packet") 705 706 // receive the ok packet on client 707 readData, err := cConn.ReadPacket() 708 require.NoError(t, err, "failed to read packet that was written") 709 assert.Equal(t, dataOut, readData, "data read and written does not match") 710 }) 711 } 712 } 713 714 func ReadHexDump(value string) []byte { 715 lines := strings.Split(value, "\n") 716 var data []byte 717 for _, line := range lines { 718 if len(line) == 0 { 719 continue 720 } 721 indexOfPipe := strings.Index(line, "|") 722 indexOfFirstSpace := strings.Index(line, " ") 723 s := line[indexOfFirstSpace:indexOfPipe] 724 hexValues := strings.Split(s, " ") 725 for _, val := range hexValues { 726 if val != "" { 727 i, _ := hex.DecodeString(val) 728 data = append(data, i...) 729 } 730 } 731 } 732 733 return data 734 } 735 736 // Mostly a sanity check. 737 func TestEOFOrLengthEncodedIntFuzz(t *testing.T) { 738 listener, sConn, cConn := createSocketPair(t) 739 defer func() { 740 listener.Close() 741 sConn.Close() 742 cConn.Close() 743 }() 744 745 for i := 0; i < 100; i++ { 746 bytes := make([]byte, rand.Intn(16)+1) 747 _, err := crypto_rand.Read(bytes) 748 require.NoError(t, err, "error doing rand.Read") 749 750 bytes[0] = 0xfe 751 752 _, _, isInt := readLenEncInt(bytes, 0) 753 isEOF := cConn.isEOFPacket(bytes) 754 if (isInt && isEOF) || (!isInt && !isEOF) { 755 t.Fatalf("0xfe bytestring is EOF xor Int. Bytes %v", bytes) 756 } 757 } 758 } 759 760 // Check various EOF packet sizes in case of deprecated EOF 761 func TestIsEOFPacket(t *testing.T) { 762 listener, sConn, cConn := createSocketPair(t) 763 defer func() { 764 listener.Close() 765 sConn.Close() 766 cConn.Close() 767 }() 768 769 cConn.Capabilities |= CapabilityClientDeprecateEOF 770 771 testCases := []struct { 772 size int 773 isEOF bool 774 }{ 775 { 776 size: 1, 777 isEOF: true, 778 }, 779 { 780 size: MaxPacketSize - 1, 781 isEOF: true, 782 }, 783 { 784 size: MaxPacketSize, 785 isEOF: false, 786 }, 787 { 788 size: MaxPacketSize + 1, 789 isEOF: false, 790 }, 791 } 792 for _, testCase := range testCases { 793 t.Run(fmt.Sprintf("is eof for size: %d", testCase.size), func(t *testing.T) { 794 bytes := make([]byte, testCase.size) 795 _, err := crypto_rand.Read(bytes) 796 require.NoError(t, err) 797 bytes[0] = 0xfe 798 assert.Equal(t, testCase.isEOF, cConn.isEOFPacket(bytes)) 799 }) 800 } 801 } 802 803 func TestMultiStatementStopsOnError(t *testing.T) { 804 listener, sConn, cConn := createSocketPair(t) 805 sConn.Capabilities |= CapabilityClientMultiStatements 806 defer func() { 807 listener.Close() 808 sConn.Close() 809 cConn.Close() 810 }() 811 812 err := cConn.WriteComQuery("error;select 2") 813 require.NoError(t, err) 814 815 // this handler will return results according to the query. In case the query contains "error" it will return an error 816 // panic if the query contains "panic" and it will return selectRowsResult in case of any other query 817 handler := &testRun{t: t, err: fmt.Errorf("execution failed")} 818 res := sConn.handleNextCommand(handler) 819 // Execution error will occur in this case because the query sent is error and testRun will throw an error. 820 // We should send an error packet but not close the connection. 821 require.True(t, res, "we should not break the connection because of execution errors") 822 823 data, err := cConn.ReadPacket() 824 require.NoError(t, err) 825 require.NotEmpty(t, data) 826 require.EqualValues(t, data[0], ErrPacket) // we should see the error here 827 } 828 829 func TestMultiStatement(t *testing.T) { 830 listener, sConn, cConn := createSocketPair(t) 831 sConn.Capabilities |= CapabilityClientMultiStatements 832 defer func() { 833 listener.Close() 834 sConn.Close() 835 cConn.Close() 836 }() 837 838 err := cConn.WriteComQuery("select 1;select 2") 839 require.NoError(t, err) 840 841 // this handler will return results according to the query. In case the query contains "error" it will return an error 842 // panic if the query contains "panic" and it will return selectRowsResult in case of any other query 843 handler := &testRun{t: t, err: NewSQLError(CRMalformedPacket, SSUnknownSQLState, "cannot get column number")} 844 res := sConn.handleNextCommand(handler) 845 //The queries run will be select 1; and select 2; These queries do not return any errors, so the connection should still be open 846 require.True(t, res, "we should not break the connection in case of no errors") 847 // Read the result of the query and assert that it is indeed what we want. This will contain the result of the first query. 848 data, more, _, err := cConn.ReadQueryResult(100, true) 849 require.NoError(t, err) 850 // Since we executed 2 queries, there should be more results to be read 851 require.True(t, more) 852 require.True(t, data.Equal(selectRowsResult)) 853 854 // Read the results for the second query and verify the correctness 855 data, more, _, err = cConn.ReadQueryResult(100, true) 856 require.NoError(t, err) 857 // This was the final query run, so we expect that more should be false as there are no more queries. 858 require.False(t, more) 859 require.True(t, data.Equal(selectRowsResult)) 860 861 // This time we run two queries fist of which will return an error 862 err = cConn.WriteComQuery("error;select 2") 863 require.NoError(t, err) 864 865 res = sConn.handleNextCommand(handler) 866 // Even if the query returns an error we should not close the connection as it is an execution error 867 require.True(t, res, "we should not break the connection because of execution errors") 868 869 // Read the result and assert that we indeed see the error that testRun throws. 870 data, more, _, err = cConn.ReadQueryResult(100, true) 871 require.EqualError(t, err, "cannot get column number (errno 2027) (sqlstate HY000)") 872 // In case of errors in a multi-statement, the following statements are not executed, therefore we want that more should be false 873 require.False(t, more) 874 require.Nil(t, data) 875 } 876 877 func TestMultiStatementOnSplitError(t *testing.T) { 878 listener, sConn, cConn := createSocketPair(t) 879 // Set the splitStatementFunction to return an error. 880 splitStatementFunction = func(blob string) (pieces []string, err error) { 881 return nil, fmt.Errorf("Error in split statements") 882 } 883 defer func() { 884 // Set the splitStatementFunction to the correct function back 885 splitStatementFunction = sqlparser.SplitStatementToPieces 886 }() 887 sConn.Capabilities |= CapabilityClientMultiStatements 888 defer func() { 889 listener.Close() 890 sConn.Close() 891 cConn.Close() 892 }() 893 894 err := cConn.WriteComQuery("select 1;select 2") 895 require.NoError(t, err) 896 897 // this handler will return results according to the query. In case the query contains "error" it will return an error 898 // panic if the query contains "panic" and it will return selectRowsResult in case of any other query 899 handler := &testRun{t: t, err: fmt.Errorf("execution failed")} 900 901 // We will encounter an error in split statement when this multi statement is processed. 902 res := sConn.handleNextCommand(handler) 903 // Since this is an execution error, we should not be closing the connection. 904 require.True(t, res, "we should not break the connection because of execution errors") 905 // Assert that the returned packet is an error packet. 906 data, err := cConn.ReadPacket() 907 require.NoError(t, err) 908 require.NotEmpty(t, data) 909 require.EqualValues(t, data[0], ErrPacket) // we should see the error here 910 } 911 912 func TestInitDbAgainstWrongDbDoesNotDropConnection(t *testing.T) { 913 listener, sConn, cConn := createSocketPair(t) 914 sConn.Capabilities |= CapabilityClientMultiStatements 915 defer func() { 916 listener.Close() 917 sConn.Close() 918 cConn.Close() 919 }() 920 921 err := cConn.writeComInitDB("error") 922 require.NoError(t, err) 923 924 // this handler will return results according to the query. In case the query contains "error" it will return an error 925 // panic if the query contains "panic" and it will return selectRowsResult in case of any other query 926 handler := &testRun{t: t, err: fmt.Errorf("execution failed")} 927 res := sConn.handleNextCommand(handler) 928 require.True(t, res, "we should not break the connection because of execution errors") 929 930 data, err := cConn.ReadPacket() 931 require.NoError(t, err) 932 require.NotEmpty(t, data) 933 require.EqualValues(t, data[0], ErrPacket) // we should see the error here 934 } 935 936 func TestConnectionErrorWhileWritingComQuery(t *testing.T) { 937 // Set the conn for the server connection to the simulated connection which always returns an error on writing 938 sConn := newConn(testConn{ 939 writeToPass: []bool{false, true}, 940 pos: -1, 941 queryPacket: []byte{0x21, 0x00, 0x00, 0x00, ComQuery, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, 942 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x31}, 943 }) 944 945 // this handler will return an error on the first run, and fail the test if it's run more times 946 errorString := make([]byte, 17000) 947 handler := &testRun{t: t, err: fmt.Errorf(string(errorString))} 948 res := sConn.handleNextCommand(handler) 949 require.False(t, res, "we should beak the connection in case of error writing error packet") 950 } 951 952 func TestConnectionErrorWhileWritingComStmtSendLongData(t *testing.T) { 953 // Set the conn for the server connection to the simulated connection which always returns an error on writing 954 sConn := newConn(testConn{ 955 writeToPass: []bool{false, true}, 956 pos: -1, 957 queryPacket: []byte{0x21, 0x00, 0x00, 0x00, ComStmtSendLongData, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, 958 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x31}, 959 }) 960 961 // this handler will return an error on the first run, and fail the test if it's run more times 962 handler := &testRun{t: t, err: fmt.Errorf("not used")} 963 res := sConn.handleNextCommand(handler) 964 require.False(t, res, "we should beak the connection in case of error writing error packet") 965 } 966 967 func TestConnectionErrorWhileWritingComPrepare(t *testing.T) { 968 // Set the conn for the server connection to the simulated connection which always returns an error on writing 969 sConn := newConn(testConn{ 970 writeToPass: []bool{false}, 971 pos: -1, 972 queryPacket: []byte{0x01, 0x00, 0x00, 0x00, ComPrepare}, 973 }) 974 sConn.Capabilities = sConn.Capabilities | CapabilityClientMultiStatements 975 // this handler will return an error on the first run, and fail the test if it's run more times 976 handler := &testRun{t: t, err: fmt.Errorf("not used")} 977 res := sConn.handleNextCommand(handler) 978 require.False(t, res, "we should beak the connection in case of error writing error packet") 979 } 980 981 func TestConnectionErrorWhileWritingComStmtExecute(t *testing.T) { 982 // Set the conn for the server connection to the simulated connection which always returns an error on writing 983 sConn := newConn(testConn{ 984 writeToPass: []bool{false}, 985 pos: -1, 986 queryPacket: []byte{0x21, 0x00, 0x00, 0x00, ComStmtExecute, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, 987 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x31}, 988 }) 989 // this handler will return an error on the first run, and fail the test if it's run more times 990 handler := &testRun{t: t, err: fmt.Errorf("not used")} 991 res := sConn.handleNextCommand(handler) 992 require.False(t, res, "we should beak the connection in case of error writing error packet") 993 } 994 995 var _ Handler = (*testRun)(nil) 996 997 type testConn struct { 998 writeToPass []bool 999 pos int 1000 queryPacket []byte 1001 } 1002 1003 func (t testConn) Read(b []byte) (n int, err error) { 1004 copy(b, t.queryPacket) 1005 return len(b), nil 1006 } 1007 1008 func (t testConn) Write(b []byte) (n int, err error) { 1009 t.pos = t.pos + 1 1010 if t.writeToPass[t.pos] { 1011 return 0, nil 1012 } 1013 return 0, fmt.Errorf("error in writing to connection") 1014 } 1015 1016 func (t testConn) Close() error { 1017 panic("implement me") 1018 } 1019 1020 func (t testConn) LocalAddr() net.Addr { 1021 panic("implement me") 1022 } 1023 1024 func (t testConn) RemoteAddr() net.Addr { 1025 return mockAddress{s: "a"} 1026 } 1027 1028 func (t testConn) SetDeadline(t1 time.Time) error { 1029 panic("implement me") 1030 } 1031 1032 func (t testConn) SetReadDeadline(t1 time.Time) error { 1033 panic("implement me") 1034 } 1035 1036 func (t testConn) SetWriteDeadline(t1 time.Time) error { 1037 panic("implement me") 1038 } 1039 1040 var _ net.Conn = (*testConn)(nil) 1041 1042 type mockAddress struct { 1043 s string 1044 } 1045 1046 func (m mockAddress) Network() string { 1047 return m.s 1048 } 1049 1050 func (m mockAddress) String() string { 1051 return m.s 1052 } 1053 1054 var _ net.Addr = (*mockAddress)(nil) 1055 1056 var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 1057 1058 func randSeq(n int) string { 1059 b := make([]rune, n) 1060 for i := range b { 1061 b[i] = letters[rand.Intn(len(letters))] 1062 } 1063 return string(b) 1064 } 1065 1066 func TestPrepareAndExecute(t *testing.T) { 1067 // this test starts a lot of clients that all send prepared statement parameter values 1068 // and check that the handler received the correct input 1069 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) 1070 defer cancel() 1071 for i := 0; i < 100; i++ { 1072 startGoRoutine(ctx, t, fmt.Sprintf("%d:%s", i, randSeq(i))) 1073 } 1074 1075 for { 1076 select { 1077 case <-ctx.Done(): 1078 return 1079 default: 1080 if t.Failed() { 1081 return 1082 } 1083 } 1084 } 1085 } 1086 1087 func startGoRoutine(ctx context.Context, t *testing.T, s string) { 1088 go func(longData string) { 1089 listener, sConn, cConn := createSocketPair(t) 1090 defer func() { 1091 listener.Close() 1092 sConn.Close() 1093 cConn.Close() 1094 }() 1095 1096 sql := "SELECT * FROM test WHERE id = ?" 1097 mockData := preparePacket(t, sql) 1098 1099 err := cConn.writePacket(mockData) 1100 require.NoError(t, err) 1101 1102 handler := &testRun{ 1103 t: t, 1104 expParamCounts: 1, 1105 expQuery: sql, 1106 expStmtID: 1, 1107 } 1108 1109 ok := sConn.handleNextCommand(handler) 1110 require.True(t, ok, "error handling command for id: %s", s) 1111 1112 resp, err := cConn.ReadPacket() 1113 require.NoError(t, err) 1114 require.EqualValues(t, 0, resp[0]) 1115 1116 for count := 0; ; count++ { 1117 select { 1118 case <-ctx.Done(): 1119 return 1120 default: 1121 } 1122 cConn.sequence = 0 1123 longDataPacket := createSendLongDataPacket(sConn.StatementID, 0, []byte(longData)) 1124 err = cConn.writePacket(longDataPacket) 1125 assert.NoError(t, err) 1126 1127 assert.True(t, sConn.handleNextCommand(handler)) 1128 data := sConn.PrepareData[sConn.StatementID] 1129 assert.NotNil(t, data) 1130 variable := data.BindVars["v1"] 1131 assert.NotNil(t, variable, fmt.Sprintf("%#v", data.BindVars)) 1132 assert.Equalf(t, []byte(longData), variable.Value[len(longData)*count:], "failed at: %d", count) 1133 } 1134 }(s) 1135 } 1136 1137 func createSendLongDataPacket(stmtID uint32, paramID uint16, data []byte) []byte { 1138 stmtIDBinary := make([]byte, 4) 1139 binary.LittleEndian.PutUint32(stmtIDBinary, stmtID) 1140 1141 paramIDBinary := make([]byte, 2) 1142 binary.LittleEndian.PutUint16(paramIDBinary, paramID) 1143 1144 packet := []byte{0, 0, 0, 0, ComStmtSendLongData} 1145 packet = append(packet, stmtIDBinary...) // append stmt ID 1146 packet = append(packet, paramIDBinary...) // append param ID 1147 packet = append(packet, data...) // append data 1148 return packet 1149 } 1150 1151 type testRun struct { 1152 UnimplementedHandler 1153 t *testing.T 1154 err error 1155 expParamCounts int 1156 expQuery string 1157 expStmtID int 1158 } 1159 1160 func (t testRun) ComStmtExecute(c *Conn, prepare *PrepareData, callback func(*sqltypes.Result) error) error { 1161 panic("implement me") 1162 } 1163 1164 func (t testRun) ComRegisterReplica(c *Conn, replicaHost string, replicaPort uint16, replicaUser string, replicaPassword string) error { 1165 panic("implement me") 1166 } 1167 1168 func (t testRun) ComBinlogDump(c *Conn, logFile string, binlogPos uint32) error { 1169 panic("implement me") 1170 } 1171 1172 func (t testRun) ComBinlogDumpGTID(c *Conn, logFile string, logPos uint64, gtidSet GTIDSet) error { 1173 panic("implement me") 1174 } 1175 1176 func (t testRun) ComQuery(c *Conn, query string, callback func(*sqltypes.Result) error) error { 1177 if strings.Contains(query, "error") { 1178 return t.err 1179 } 1180 if strings.Contains(query, "panic") { 1181 panic("test panic attack!") 1182 } 1183 if strings.Contains(query, "close before rows read") { 1184 c.writeFields(selectRowsResult) 1185 // We want to close the connection after the fields are written 1186 // and read on the client. So we sleep for 100 milliseconds 1187 time.Sleep(100 * time.Millisecond) 1188 c.Close() 1189 return nil 1190 } 1191 1192 if strings.Contains(query, "twice") { 1193 callback(selectRowsResult) 1194 } 1195 callback(selectRowsResult) 1196 return nil 1197 } 1198 1199 func (t testRun) ComPrepare(c *Conn, query string, bv map[string]*querypb.BindVariable) ([]*querypb.Field, error) { 1200 assert.Equal(t.t, t.expQuery, query) 1201 assert.EqualValues(t.t, t.expStmtID, c.StatementID) 1202 assert.NotNil(t.t, c.PrepareData[c.StatementID]) 1203 assert.EqualValues(t.t, t.expParamCounts, c.PrepareData[c.StatementID].ParamsCount) 1204 assert.Len(t.t, c.PrepareData, int(c.PrepareData[c.StatementID].ParamsCount)) 1205 return nil, nil 1206 } 1207 1208 func (t testRun) WarningCount(c *Conn) uint16 { 1209 return 0 1210 } 1211 1212 var _ Handler = (*testRun)(nil)