diff --git a/integration-cli/docker_api_swarm_test.go b/integration-cli/docker_api_swarm_test.go index e7d1b98332..7b498d5ea9 100644 --- a/integration-cli/docker_api_swarm_test.go +++ b/integration-cli/docker_api_swarm_test.go @@ -27,6 +27,7 @@ import ( "github.com/docker/docker/internal/test/request" "github.com/docker/swarmkit/ca" "github.com/go-check/check" + "github.com/pkg/errors" "gotest.tools/assert" is "gotest.tools/assert/cmp" ) @@ -313,13 +314,24 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *check.C) { leader *daemon.Daemon // keep track of leader followers []*daemon.Daemon // keep track of followers ) + var lastErr error checkLeader := func(nodes ...*daemon.Daemon) checkF { return func(c *check.C) (interface{}, check.CommentInterface) { // clear these out before each run leader = nil followers = nil for _, d := range nodes { - if d.GetNode(c, d.NodeID()).ManagerStatus.Leader { + n := d.GetNode(c, d.NodeID(), func(err error) bool { + if strings.Contains(errors.Cause(err).Error(), context.DeadlineExceeded.Error()) || strings.Contains(err.Error(), "swarm does not have a leader") { + lastErr = err + return true + } + return false + }) + if n == nil { + return false, check.Commentf("failed to get node: %v", lastErr) + } + if n.ManagerStatus.Leader { leader = d } else { followers = append(followers, d) @@ -391,7 +403,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRaftQuorum(c *check.C) { defer cli.Close() // d1 will eventually step down from leader because there is no longer an active quorum, wait for that to happen - waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) { + waitAndAssert(c, defaultReconciliationTimeout*2, func(c *check.C) (interface{}, check.CommentInterface) { _, err := cli.ServiceCreate(context.Background(), service.Spec, types.ServiceCreateOptions{}) return err.Error(), nil }, checker.Contains, "Make sure more than half of the managers are online.") diff --git a/internal/test/daemon/node.go b/internal/test/daemon/node.go index 33dd365429..d5f6f15263 100644 --- a/internal/test/daemon/node.go +++ b/internal/test/daemon/node.go @@ -15,7 +15,7 @@ import ( type NodeConstructor func(*swarm.Node) // GetNode returns a swarm node identified by the specified id -func (d *Daemon) GetNode(t assert.TestingT, id string) *swarm.Node { +func (d *Daemon) GetNode(t assert.TestingT, id string, errCheck ...func(error) bool) *swarm.Node { if ht, ok := t.(test.HelperT); ok { ht.Helper() } @@ -23,6 +23,13 @@ func (d *Daemon) GetNode(t assert.TestingT, id string) *swarm.Node { defer cli.Close() node, _, err := cli.NodeInspectWithRaw(context.Background(), id) + if err != nil { + for _, f := range errCheck { + if f(err) { + return nil + } + } + } assert.NilError(t, err, "[%s] (*Daemon).GetNode: NodeInspectWithRaw(%q) failed", d.id, id) assert.Check(t, node.ID == id) return &node