gh-ost/vendor/github.com/siddontang/go-mysql/failover/failover_test.go
2017-02-12 13:13:54 +02:00

177 lines
3.8 KiB
Go

package failover
import (
"flag"
"fmt"
"testing"
. "github.com/pingcap/check"
)
// We will use go-mysql docker to test
// go-mysql docker will build mysql 1-3 instances
var host = flag.String("host", "127.0.0.1", "go-mysql docker container address")
var enable_failover_test = flag.Bool("test-failover", false, "enable test failover")
func Test(t *testing.T) {
TestingT(t)
}
type failoverTestSuite struct {
s []*Server
}
var _ = Suite(&failoverTestSuite{})
func (s *failoverTestSuite) SetUpSuite(c *C) {
if !*enable_failover_test {
c.Skip("skip test failover")
}
ports := []int{3306, 3307, 3308, 3316, 3317, 3318}
s.s = make([]*Server, len(ports))
for i := 0; i < len(ports); i++ {
s.s[i] = NewServer(fmt.Sprintf("%s:%d", *host, ports[i]), User{"root", ""}, User{"root", ""})
}
var err error
for i := 0; i < len(ports); i++ {
err = s.s[i].StopSlave()
c.Assert(err, IsNil)
err = s.s[i].ResetSlaveALL()
c.Assert(err, IsNil)
_, err = s.s[i].Execute(`SET GLOBAL BINLOG_FORMAT = "ROW"`)
c.Assert(err, IsNil)
_, err = s.s[i].Execute("DROP TABLE IF EXISTS test.go_mysql_test")
c.Assert(err, IsNil)
_, err = s.s[i].Execute("CREATE TABLE IF NOT EXISTS test.go_mysql_test (id INT AUTO_INCREMENT, name VARCHAR(256), PRIMARY KEY(id)) engine=innodb")
c.Assert(err, IsNil)
err = s.s[i].ResetMaster()
c.Assert(err, IsNil)
}
}
func (s *failoverTestSuite) TearDownSuite(c *C) {
}
func (s *failoverTestSuite) TestMysqlFailover(c *C) {
h := new(MysqlGTIDHandler)
m := s.s[0]
s1 := s.s[1]
s2 := s.s[2]
s.testFailover(c, h, m, s1, s2)
}
func (s *failoverTestSuite) TestMariadbFailover(c *C) {
h := new(MariadbGTIDHandler)
for i := 3; i <= 5; i++ {
_, err := s.s[i].Execute("SET GLOBAL gtid_slave_pos = ''")
c.Assert(err, IsNil)
}
m := s.s[3]
s1 := s.s[4]
s2 := s.s[5]
s.testFailover(c, h, m, s1, s2)
}
func (s *failoverTestSuite) testFailover(c *C, h Handler, m *Server, s1 *Server, s2 *Server) {
var err error
err = h.ChangeMasterTo(s1, m)
c.Assert(err, IsNil)
err = h.ChangeMasterTo(s2, m)
c.Assert(err, IsNil)
id := s.checkInsert(c, m, "a")
err = h.WaitCatchMaster(s1, m)
c.Assert(err, IsNil)
err = h.WaitCatchMaster(s2, m)
c.Assert(err, IsNil)
s.checkSelect(c, s1, id, "a")
s.checkSelect(c, s2, id, "a")
err = s2.StopSlaveIOThread()
c.Assert(err, IsNil)
id = s.checkInsert(c, m, "b")
id = s.checkInsert(c, m, "c")
err = h.WaitCatchMaster(s1, m)
c.Assert(err, IsNil)
s.checkSelect(c, s1, id, "c")
best, err := h.FindBestSlaves([]*Server{s1, s2})
c.Assert(err, IsNil)
c.Assert(best, DeepEquals, []*Server{s1})
// promote s1 to master
err = h.Promote(s1)
c.Assert(err, IsNil)
// change s2 to master s1
err = h.ChangeMasterTo(s2, s1)
c.Assert(err, IsNil)
err = h.WaitCatchMaster(s2, s1)
c.Assert(err, IsNil)
s.checkSelect(c, s2, id, "c")
// change m to master s1
err = h.ChangeMasterTo(m, s1)
c.Assert(err, IsNil)
m, s1 = s1, m
id = s.checkInsert(c, m, "d")
err = h.WaitCatchMaster(s1, m)
c.Assert(err, IsNil)
err = h.WaitCatchMaster(s2, m)
c.Assert(err, IsNil)
best, err = h.FindBestSlaves([]*Server{s1, s2})
c.Assert(err, IsNil)
c.Assert(best, DeepEquals, []*Server{s1, s2})
err = s2.StopSlaveIOThread()
c.Assert(err, IsNil)
id = s.checkInsert(c, m, "e")
err = h.WaitCatchMaster(s1, m)
best, err = h.FindBestSlaves([]*Server{s1, s2})
c.Assert(err, IsNil)
c.Assert(best, DeepEquals, []*Server{s1})
}
func (s *failoverTestSuite) checkSelect(c *C, m *Server, id uint64, name string) {
rr, err := m.Execute("SELECT name FROM test.go_mysql_test WHERE id = ?", id)
c.Assert(err, IsNil)
str, _ := rr.GetString(0, 0)
c.Assert(str, Equals, name)
}
func (s *failoverTestSuite) checkInsert(c *C, m *Server, name string) uint64 {
r, err := m.Execute("INSERT INTO test.go_mysql_test (name) VALUES (?)", name)
c.Assert(err, IsNil)
return r.InsertId
}