vitess-gh/go/vt/mysqlctl/mysql_flavor_mysql56_test.go

287 строки
10 KiB
Go

// Copyright 2015, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mysqlctl
import (
"reflect"
"testing"
"github.com/youtube/vitess/go/mysql"
"github.com/youtube/vitess/go/sqldb"
blproto "github.com/youtube/vitess/go/vt/binlog/proto"
"github.com/youtube/vitess/go/vt/mysqlctl/proto"
)
// Sample event data for MySQL 5.6.
var (
mysql56FormatEvent = NewMysql56BinlogEvent([]byte{0x78, 0x4e, 0x49, 0x55, 0xf, 0x64, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x35, 0x2e, 0x36, 0x2e, 0x32, 0x34, 0x2d, 0x6c, 0x6f, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0x4e, 0x49, 0x55, 0x13, 0x38, 0xd, 0x0, 0x8, 0x0, 0x12, 0x0, 0x4, 0x4, 0x4, 0x4, 0x12, 0x0, 0x0, 0x5c, 0x0, 0x4, 0x1a, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x2, 0x0, 0x0, 0x0, 0xa, 0xa, 0xa, 0x19, 0x19, 0x0, 0x1, 0x18, 0x4a, 0xf, 0xca})
mysql56GTIDEvent = NewMysql56BinlogEvent([]byte{0xff, 0x4e, 0x49, 0x55, 0x21, 0x64, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0xf5, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x43, 0x91, 0x92, 0xbd, 0xf3, 0x7c, 0x11, 0xe4, 0xbb, 0xeb, 0x2, 0x42, 0xac, 0x11, 0x3, 0x5a, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, 0x45, 0x82, 0x27})
mysql56QueryEvent = NewMysql56BinlogEvent([]byte{0xff, 0x4e, 0x49, 0x55, 0x2, 0x64, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0xdb, 0x3, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x3, 0x73, 0x74, 0x64, 0x4, 0x8, 0x0, 0x8, 0x0, 0x21, 0x0, 0xc, 0x1, 0x74, 0x65, 0x73, 0x74, 0x0, 0x74, 0x65, 0x73, 0x74, 0x0, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x28, 0x27, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x27, 0x29, 0x92, 0x12, 0x79, 0xc3})
)
func TestMysql56IsGTID(t *testing.T) {
if got, want := mysql56FormatEvent.IsGTID(), false; got != want {
t.Errorf("%#v.IsGTID() = %#v, want %#v", mysql56FormatEvent, got, want)
}
if got, want := mysql56QueryEvent.IsGTID(), false; got != want {
t.Errorf("%#v.IsGTID() = %#v, want %#v", mysql56QueryEvent, got, want)
}
if got, want := mysql56GTIDEvent.IsGTID(), true; got != want {
t.Errorf("%#v.IsGTID() = %#v, want %#v", mysql56GTIDEvent, got, want)
}
}
func TestMysql56HasGTID(t *testing.T) {
format := blproto.BinlogFormat{}
if got, want := mysql56FormatEvent.HasGTID(format), false; got != want {
t.Errorf("%#v.HasGTID() = %#v, want %#v", mysql56FormatEvent, got, want)
}
if got, want := mysql56QueryEvent.HasGTID(format), false; got != want {
t.Errorf("%#v.HasGTID() = %#v, want %#v", mysql56QueryEvent, got, want)
}
if got, want := mysql56GTIDEvent.HasGTID(format), true; got != want {
t.Errorf("%#v.HasGTID() = %#v, want %#v", mysql56GTIDEvent, got, want)
}
}
func TestMysql56StripChecksum(t *testing.T) {
format, err := mysql56FormatEvent.Format()
if err != nil {
t.Fatalf("Format() error: %v", err)
}
stripped, gotChecksum, err := mysql56QueryEvent.StripChecksum(format)
if err != nil {
t.Fatalf("StripChecksum() error: %v", err)
}
// Check checksum.
if want := []byte{0x92, 0x12, 0x79, 0xc3}; !reflect.DeepEqual(gotChecksum, want) {
t.Errorf("checksum = %#v, want %#v", gotChecksum, want)
}
// Check query, to make sure checksum was stripped properly.
// Query length is defined as "the rest of the bytes after offset X",
// so the query will be wrong if the checksum is not stripped.
gotQuery, err := stripped.Query(format)
if err != nil {
t.Fatalf("Query() error: %v", err)
}
if want := "insert into test_table (msg) values ('hello')"; string(gotQuery.Sql) != want {
t.Errorf("query = %#v, want %#v", string(gotQuery.Sql), want)
}
}
func TestMysql56GTID(t *testing.T) {
format, err := mysql56FormatEvent.Format()
if err != nil {
t.Fatalf("Format() error: %v", err)
}
input, _, err := mysql56GTIDEvent.StripChecksum(format)
if err != nil {
t.Fatalf("StripChecksum() error: %v", err)
}
if !input.IsGTID() {
t.Fatalf("IsGTID() = false, want true")
}
want, _ := (&mysql56{}).ParseGTID("439192bd-f37c-11e4-bbeb-0242ac11035a:4")
got, err := input.GTID(format)
if err != nil {
t.Fatalf("GTID() error: %v", err)
}
if got != want {
t.Errorf("GTID() = %#v, want %#v", got, want)
}
}
func TestMysql56ParseGTID(t *testing.T) {
input := "00010203-0405-0607-0809-0A0B0C0D0E0F:56789"
want := proto.Mysql56GTID{
Server: proto.SID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
Sequence: 56789,
}
got, err := (&mysql56{}).ParseGTID(input)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got != want {
t.Errorf("(&mysql56{}).ParseGTID(%#v) = %#v, want %#v", input, got, want)
}
}
func TestMysql56ParseReplicationPosition(t *testing.T) {
input := "00010203-0405-0607-0809-0a0b0c0d0e0f:1-2"
sid := proto.SID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
var set proto.GTIDSet = proto.Mysql56GTIDSet{}
set = set.AddGTID(proto.Mysql56GTID{Server: sid, Sequence: 1})
set = set.AddGTID(proto.Mysql56GTID{Server: sid, Sequence: 2})
want := proto.ReplicationPosition{GTIDSet: set}
got, err := (&mysql56{}).ParseReplicationPosition(input)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !got.Equal(want) {
t.Errorf("(&mysql56{}).ParseReplicationPosition(%#v) = %#v, want %#v", input, got, want)
}
}
func TestMysql56VersionMatch(t *testing.T) {
table := map[string]bool{
"10.0.13-MariaDB-1~precise-log": false,
"5.1.63-google-log": false,
"5.6.24-log": true,
}
for input, want := range table {
if got := (&mysql56{}).VersionMatch(input); got != want {
t.Errorf("(&mysql56{}).VersionMatch(%#v) = %v, want %v", input, got, want)
}
}
}
func TestMysql56ResetReplicationCommands(t *testing.T) {
want := []string{
"STOP SLAVE",
"RESET SLAVE",
"RESET MASTER",
}
if got := (&mysql56{}).ResetReplicationCommands(); !reflect.DeepEqual(got, want) {
t.Errorf("(&mysql56{}).ResetReplicationCommands() = %#v, want %#v", got, want)
}
}
func TestMysql56PromoteSlaveCommands(t *testing.T) {
want := []string{"RESET SLAVE"}
if got := (&mysql56{}).PromoteSlaveCommands(); !reflect.DeepEqual(got, want) {
t.Errorf("(&mysql56{}).PromoteSlaveCommands() = %#v, want %#v", got, want)
}
}
func TestMysql56SetSlavePositionCommands(t *testing.T) {
pos, _ := (&mysql56{}).ParseReplicationPosition("00010203-0405-0607-0809-0a0b0c0d0e0f:1-2")
want := []string{
"RESET MASTER",
"SET GLOBAL gtid_purged = '00010203-0405-0607-0809-0a0b0c0d0e0f:1-2'",
}
got, err := (&mysql56{}).SetSlavePositionCommands(pos)
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}
if !reflect.DeepEqual(got, want) {
t.Errorf("(&mysql56{}).SetSlavePositionCommands(%#v) = %#v, want %#v", pos, got, want)
}
}
func TestMysql56SetMasterCommands(t *testing.T) {
params := &sqldb.ConnParams{
Uname: "username",
Pass: "password",
}
masterHost := "localhost"
masterPort := 123
masterConnectRetry := 1234
want := []string{
`CHANGE MASTER TO
MASTER_HOST = 'localhost',
MASTER_PORT = 123,
MASTER_USER = 'username',
MASTER_PASSWORD = 'password',
MASTER_CONNECT_RETRY = 1234,
MASTER_AUTO_POSITION = 1`,
}
got, err := (&mysql56{}).SetMasterCommands(params, masterHost, masterPort, masterConnectRetry)
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}
if !reflect.DeepEqual(got, want) {
t.Errorf("(&mysql56{}).SetMasterCommands(%#v, %#v, %#v, %#v) = %#v, want %#v", params, masterHost, masterPort, masterConnectRetry, got, want)
}
}
func TestMysql56SetMasterCommandsSSL(t *testing.T) {
params := &sqldb.ConnParams{
Uname: "username",
Pass: "password",
SslCa: "ssl-ca",
SslCaPath: "ssl-ca-path",
SslCert: "ssl-cert",
SslKey: "ssl-key",
}
mysql.EnableSSL(params)
masterHost := "localhost"
masterPort := 123
masterConnectRetry := 1234
want := []string{
`CHANGE MASTER TO
MASTER_HOST = 'localhost',
MASTER_PORT = 123,
MASTER_USER = 'username',
MASTER_PASSWORD = 'password',
MASTER_CONNECT_RETRY = 1234,
MASTER_SSL = 1,
MASTER_SSL_CA = 'ssl-ca',
MASTER_SSL_CAPATH = 'ssl-ca-path',
MASTER_SSL_CERT = 'ssl-cert',
MASTER_SSL_KEY = 'ssl-key',
MASTER_AUTO_POSITION = 1`,
}
got, err := (&mysql56{}).SetMasterCommands(params, masterHost, masterPort, masterConnectRetry)
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}
if !reflect.DeepEqual(got, want) {
t.Errorf("(&mysql56{}).SetMasterCommands(%#v, %#v, %#v, %#v) = %#v, want %#v", params, masterHost, masterPort, masterConnectRetry, got, want)
}
}
func TestMysql56MakeBinlogEvent(t *testing.T) {
input := []byte{1, 2, 3}
want := mysql56BinlogEvent{binlogEvent: binlogEvent([]byte{1, 2, 3})}
if got := (&mysql56{}).MakeBinlogEvent(input); !reflect.DeepEqual(got, want) {
t.Errorf("(&mysql56{}).MakeBinlogEvent(%#v) = %#v, want %#v", input, got, want)
}
}
func TestMakeBinlogDumpGTIDCommand(t *testing.T) {
want := []byte{
// flags
0x00, 0x00,
// server_id
0x04, 0x03, 0x02, 0x01,
// binlog_filename_len
0x00, 0x00, 0x00, 0x00,
// binlog_filename (0 length)
// binlog_pos (4 = start of file)
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// data_size (size of everything below)
0x30, 0x00, 0x00, 0x00,
// n_sids
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// sid1
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
// n_intervals
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// start
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// end
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
pos, _ := (&mysql56{}).ParseReplicationPosition("00010203-0405-0607-0809-0a0b0c0d0e0f:1-2")
got := makeBinlogDumpGTIDCommand(0x0000 /* flags */, 0x01020304 /* serverID */, pos.GTIDSet.(proto.Mysql56GTIDSet))
if !reflect.DeepEqual(got, want) {
t.Errorf("makeBinlogDumpGTIDCommand() = %#v, want %#v", got, want)
}
}