Browse Source

TestDaemonDiscoveryBackendConfigReload behavior

`TestDaemonDiscoveryBackendConfigReload` was doing some wierd things
with files, creating a file (directly in `./integration-cli`), removing
it, then creating a new file.
This is just weird, so fixed it to use a single file, file will go into
a temp dir so it doesn't pollute integration-cli.

It was also blindly sending a SIGHUP to the daemon process then sleeping
for 3 seconds.  This is racey, and slow.
Change this to look for the daemon-reload event in the event stream.
Reload logic is moved to a separate function and blocks (w/ a timeout)
waiting for the reload event to fire.

Runtime of the test is now ~0.5s on my machine, where as it was a
minimum of 3s due to the `time.Sleep` before.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Brian Goff 9 năm trước cách đây
mục cha
commit
20f99a8634

+ 48 - 0
integration-cli/daemon.go

@@ -18,6 +18,7 @@ import (
 	"github.com/docker/docker/pkg/integration/checker"
 	"github.com/docker/docker/pkg/integration/checker"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/tlsconfig"
 	"github.com/docker/docker/pkg/tlsconfig"
+	"github.com/docker/engine-api/types/events"
 	"github.com/docker/go-connections/sockets"
 	"github.com/docker/go-connections/sockets"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
 )
 )
@@ -543,3 +544,50 @@ func (d *Daemon) checkActiveContainerCount(c *check.C) (interface{}, check.Comme
 	}
 	}
 	return len(strings.Split(strings.TrimSpace(out), "\n")), check.Commentf("output: %q", string(out))
 	return len(strings.Split(strings.TrimSpace(out), "\n")), check.Commentf("output: %q", string(out))
 }
 }
+
+func (d *Daemon) reloadConfig() error {
+	if d.cmd == nil || d.cmd.Process == nil {
+		return fmt.Errorf("daemon is not running")
+	}
+
+	errCh := make(chan error)
+	started := make(chan struct{})
+	go func() {
+		_, body, err := sockRequestRawToDaemon("GET", "/events", nil, "", d.sock())
+		close(started)
+		if err != nil {
+			errCh <- err
+		}
+		defer body.Close()
+		dec := json.NewDecoder(body)
+		for {
+			var e events.Message
+			if err := dec.Decode(&e); err != nil {
+				errCh <- err
+				return
+			}
+			if e.Type != events.DaemonEventType {
+				continue
+			}
+			if e.Action != "reload" {
+				continue
+			}
+			close(errCh) // notify that we are done
+			return
+		}
+	}()
+
+	<-started
+	if err := signalDaemonReload(d.cmd.Process.Pid); err != nil {
+		return fmt.Errorf("error signaling daemon reload: %v", err)
+	}
+	select {
+	case err := <-errCh:
+		if err != nil {
+			return fmt.Errorf("error waiting for daemon reload event: %v", err)
+		}
+	case <-time.After(30 * time.Second):
+		return fmt.Errorf("timeout waiting for daemon reload event")
+	}
+	return nil
+}

+ 4 - 0
integration-cli/daemon_unix.go

@@ -7,3 +7,7 @@ import "syscall"
 func signalDaemonDump(pid int) {
 func signalDaemonDump(pid int) {
 	syscall.Kill(pid, syscall.SIGQUIT)
 	syscall.Kill(pid, syscall.SIGQUIT)
 }
 }
+
+func signalDaemonReload(pid int) error {
+	return syscall.Kill(pid, syscall.SIGHUP)
+}

+ 5 - 0
integration-cli/daemon_windows.go

@@ -1,6 +1,7 @@
 package main
 package main
 
 
 import (
 import (
+	"fmt"
 	"strconv"
 	"strconv"
 	"syscall"
 	"syscall"
 	"unsafe"
 	"unsafe"
@@ -40,3 +41,7 @@ func signalDaemonDump(pid int) {
 	}
 	}
 	pulseEvent(h2, procPulseEvent)
 	pulseEvent(h2, procPulseEvent)
 }
 }
+
+func signalDaemonReload(pid int) error {
+	return fmt.Errorf("daemon reload not supported")
+}

+ 20 - 11
integration-cli/docker_cli_daemon_test.go

@@ -23,7 +23,6 @@ import (
 	"github.com/docker/docker/pkg/integration/checker"
 	"github.com/docker/docker/pkg/integration/checker"
 	icmd "github.com/docker/docker/pkg/integration/cmd"
 	icmd "github.com/docker/docker/pkg/integration/cmd"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/mount"
-	"github.com/docker/docker/pkg/testutil/tempfile"
 	"github.com/docker/go-units"
 	"github.com/docker/go-units"
 	"github.com/docker/libnetwork/iptables"
 	"github.com/docker/libnetwork/iptables"
 	"github.com/docker/libtrust"
 	"github.com/docker/libtrust"
@@ -2352,32 +2351,42 @@ func (s *DockerSuite) TestDaemonDiscoveryBackendConfigReload(c *check.C) {
 	testRequires(c, SameHostDaemon, DaemonIsLinux)
 	testRequires(c, SameHostDaemon, DaemonIsLinux)
 
 
 	// daemon config file
 	// daemon config file
-	tmpfile := tempfile.NewTempFile(c, "config-test", `{ "debug" : false }`)
-	defer tmpfile.Remove()
+	daemonConfig := `{ "debug" : false }`
+	configFile, err := ioutil.TempFile("", "test-daemon-discovery-backend-config-reload-config")
+	c.Assert(err, checker.IsNil, check.Commentf("could not create temp file for config reload"))
+	configFilePath := configFile.Name()
+	defer func() {
+		configFile.Close()
+		os.RemoveAll(configFile.Name())
+	}()
+
+	_, err = configFile.Write([]byte(daemonConfig))
+	c.Assert(err, checker.IsNil)
 
 
 	d := NewDaemon(c)
 	d := NewDaemon(c)
 	// --log-level needs to be set so that d.Start() doesn't add --debug causing
 	// --log-level needs to be set so that d.Start() doesn't add --debug causing
 	// a conflict with the config
 	// a conflict with the config
-	err := d.Start("--config-file", tmpfile.Name(), "--log-level=info")
+	err = d.Start("--config-file", configFilePath, "--log-level=info")
 	c.Assert(err, checker.IsNil)
 	c.Assert(err, checker.IsNil)
 	defer d.Stop()
 	defer d.Stop()
 
 
 	// daemon config file
 	// daemon config file
-	daemonConfig := `{
+	daemonConfig = `{
 	      "cluster-store": "consul://consuladdr:consulport/some/path",
 	      "cluster-store": "consul://consuladdr:consulport/some/path",
 	      "cluster-advertise": "192.168.56.100:0",
 	      "cluster-advertise": "192.168.56.100:0",
 	      "debug" : false
 	      "debug" : false
 	}`
 	}`
 
 
-	os.Remove(tmpfile.Name())
-	configFile, err := os.Create(tmpfile.Name())
+	err = configFile.Truncate(0)
+	c.Assert(err, checker.IsNil)
+	_, err = configFile.Seek(0, os.SEEK_SET)
 	c.Assert(err, checker.IsNil)
 	c.Assert(err, checker.IsNil)
-	fmt.Fprintf(configFile, "%s", daemonConfig)
-	configFile.Close()
 
 
-	syscall.Kill(d.cmd.Process.Pid, syscall.SIGHUP)
+	_, err = configFile.Write([]byte(daemonConfig))
+	c.Assert(err, checker.IsNil)
 
 
-	time.Sleep(3 * time.Second)
+	err = d.reloadConfig()
+	c.Assert(err, checker.IsNil, check.Commentf("error reloading daemon config"))
 
 
 	out, err := d.Cmd("info")
 	out, err := d.Cmd("info")
 	c.Assert(err, checker.IsNil)
 	c.Assert(err, checker.IsNil)