Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/app/app_dcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (app *App) GetActiveNodes() ([]string, error) {
var activeNodes []string
err := app.dcs.Get(pathActiveNodes, &activeNodes)
if err != nil {
if err == dcs.ErrNotFound {
if err == dcs.ErrNotFound || err == dcs.ErrMalformed {
return nil, nil
}
return nil, fmt.Errorf("failed to get active nodes from zk %v", err)
Expand Down
49 changes: 49 additions & 0 deletions tests/features/active_nodes.feature
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,52 @@ Feature: mysync saves quorum hosts in zk
"""
["mysql1","mysql2","mysql3"]
"""

Scenario: mysync recovers from malformed active nodes after restart
Given cluster is up and running
And zookeeper node "/test/active_nodes" should match json_exactly within "30" seconds
"""
["mysql1","mysql2","mysql3"]
"""
When I run command on host "mysql1" with timeout "20" seconds
"""
supervisorctl stop mysync
"""
Then command return code should be "0"
When I run command on host "mysql2" with timeout "20" seconds
"""
supervisorctl stop mysync
"""
Then command return code should be "0"
When I run command on host "mysql3" with timeout "20" seconds
"""
supervisorctl stop mysync
"""
Then command return code should be "0"
When I set raw zookeeper node "/test/active_nodes" to
"""
[[[]garbage
"""
When I run command on host "mysql1" with timeout "20" seconds
"""
supervisorctl start mysync
"""
Then command return code should be "0"
When I run command on host "mysql2" with timeout "20" seconds
"""
supervisorctl start mysync
"""
Then command return code should be "0"
When I run command on host "mysql3" with timeout "20" seconds
"""
supervisorctl start mysync
"""
Then command return code should be "0"
Then mysql host "mysql1" should be master
And mysql host "mysql2" should be replica of "mysql1"
And mysql host "mysql3" should be replica of "mysql1"
And mysql host "mysql1" should be writable
And zookeeper node "/test/active_nodes" should match json_exactly within "30" seconds
"""
["mysql1","mysql2","mysql3"]
"""
20 changes: 15 additions & 5 deletions tests/mysync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1060,11 +1060,7 @@ func (tctx *testContext) createZookeeperNode(node string) error {
return nil
}

func (tctx *testContext) stepISetZookeeperNode(node string, body *godog.DocString) error {
data := []byte(strings.TrimSpace(body.Content))
if !json.Valid(data) {
return fmt.Errorf("node value is not valid json")
}
func (tctx *testContext) setZookeeperNode(node string, data []byte) error {
_, stat, err := tctx.zk.Get(node)
if err != nil && err != zk.ErrNoNode {
return err
Expand All @@ -1077,6 +1073,19 @@ func (tctx *testContext) stepISetZookeeperNode(node string, body *godog.DocStrin
return err
}

func (tctx *testContext) stepISetZookeeperNode(node string, body *godog.DocString) error {
data := []byte(strings.TrimSpace(body.Content))
if !json.Valid(data) {
return fmt.Errorf("node value is not valid json")
}
return tctx.setZookeeperNode(node, data)
}

func (tctx *testContext) stepISetRawZookeeperNode(node string, body *godog.DocString) error {
data := []byte(strings.TrimSpace(body.Content))
return tctx.setZookeeperNode(node, data)
}

func (tctx *testContext) stepIDeleteZookeeperNode(node string) error {
_, stat, err := tctx.zk.Get(node)
if err != nil {
Expand Down Expand Up @@ -1681,6 +1690,7 @@ func InitializeScenario(s *godog.ScenarioContext) {
// zookeeper manipulation
s.Step(`^I get zookeeper node "([^"]*)"$`, tctx.stepIGetZookeeperNode)
s.Step(`^I set zookeeper node "([^"]*)" to$`, tctx.stepISetZookeeperNode)
s.Step(`^I set raw zookeeper node "([^"]*)" to$`, tctx.stepISetRawZookeeperNode)
s.Step(`^I delete zookeeper node "([^"]*)"$`, tctx.stepIDeleteZookeeperNode)

// zookeeper checking
Expand Down
Loading