Explorar o código

integ-cli: fix clock skew against remote test daemon

This fixes the `docker events`-related tests as they have been
failing due to clock skew between CI machine and test daemon on
some other machine (even 1-2 seconds of diff causes races as
we pass local time to --since/--until).

If we're running in same host, we keep using time.Now(), otherwise
we read the system time of the daemon from `/info` endpoint.

Fixes pretty much all events-related tests on windows CI.

Signed-off-by: Ahmet Alp Balkan <ahmetalpbalkan@gmail.com>
Ahmet Alp Balkan %!s(int64=10) %!d(string=hai) anos
pai
achega
e424c54d9c

+ 17 - 17
integration-cli/docker_cli_events_test.go

@@ -45,7 +45,7 @@ func TestEventsContainerFailStartDie(t *testing.T) {
 		t.Fatalf("Container run with command blerg should have failed, but it did not")
 		t.Fatalf("Container run with command blerg should have failed, but it did not")
 	}
 	}
 
 
-	eventsCmd = exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
+	eventsCmd = exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, _, _ = runCommandWithOutput(eventsCmd)
 	out, _, _ = runCommandWithOutput(eventsCmd)
 	events := strings.Split(out, "\n")
 	events := strings.Split(out, "\n")
 	if len(events) <= 1 {
 	if len(events) <= 1 {
@@ -70,7 +70,7 @@ func TestEventsLimit(t *testing.T) {
 	for i := 0; i < 30; i++ {
 	for i := 0; i < 30; i++ {
 		dockerCmd(t, "run", "busybox", "echo", strconv.Itoa(i))
 		dockerCmd(t, "run", "busybox", "echo", strconv.Itoa(i))
 	}
 	}
-	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
+	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, _, _ := runCommandWithOutput(eventsCmd)
 	out, _, _ := runCommandWithOutput(eventsCmd)
 	events := strings.Split(out, "\n")
 	events := strings.Split(out, "\n")
 	nEvents := len(events) - 1
 	nEvents := len(events) - 1
@@ -82,7 +82,7 @@ func TestEventsLimit(t *testing.T) {
 
 
 func TestEventsContainerEvents(t *testing.T) {
 func TestEventsContainerEvents(t *testing.T) {
 	dockerCmd(t, "run", "--rm", "busybox", "true")
 	dockerCmd(t, "run", "--rm", "busybox", "true")
-	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
+	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, exitCode, err := runCommandWithOutput(eventsCmd)
 	out, exitCode, err := runCommandWithOutput(eventsCmd)
 	if exitCode != 0 || err != nil {
 	if exitCode != 0 || err != nil {
 		t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
 		t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
@@ -125,7 +125,7 @@ func TestEventsImageUntagDelete(t *testing.T) {
 	if err := deleteImages(name); err != nil {
 	if err := deleteImages(name); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
+	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, exitCode, err := runCommandWithOutput(eventsCmd)
 	out, exitCode, err := runCommandWithOutput(eventsCmd)
 	if exitCode != 0 || err != nil {
 	if exitCode != 0 || err != nil {
 		t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
 		t.Fatalf("Failed to get events with exit code %d: %s", exitCode, err)
@@ -148,7 +148,7 @@ func TestEventsImageUntagDelete(t *testing.T) {
 }
 }
 
 
 func TestEventsImagePull(t *testing.T) {
 func TestEventsImagePull(t *testing.T) {
-	since := time.Now().Unix()
+	since := daemonTime(t).Unix()
 
 
 	defer deleteImages("hello-world")
 	defer deleteImages("hello-world")
 
 
@@ -159,7 +159,7 @@ func TestEventsImagePull(t *testing.T) {
 
 
 	eventsCmd := exec.Command(dockerBinary, "events",
 	eventsCmd := exec.Command(dockerBinary, "events",
 		fmt.Sprintf("--since=%d", since),
 		fmt.Sprintf("--since=%d", since),
-		fmt.Sprintf("--until=%d", time.Now().Unix()))
+		fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, _, _ := runCommandWithOutput(eventsCmd)
 	out, _, _ := runCommandWithOutput(eventsCmd)
 
 
 	events := strings.Split(strings.TrimSpace(out), "\n")
 	events := strings.Split(strings.TrimSpace(out), "\n")
@@ -174,7 +174,7 @@ func TestEventsImagePull(t *testing.T) {
 
 
 func TestEventsImageImport(t *testing.T) {
 func TestEventsImageImport(t *testing.T) {
 	defer deleteAllContainers()
 	defer deleteAllContainers()
-	since := time.Now().Unix()
+	since := daemonTime(t).Unix()
 
 
 	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
 	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
 	out, _, err := runCommandWithOutput(runCmd)
 	out, _, err := runCommandWithOutput(runCmd)
@@ -193,7 +193,7 @@ func TestEventsImageImport(t *testing.T) {
 
 
 	eventsCmd := exec.Command(dockerBinary, "events",
 	eventsCmd := exec.Command(dockerBinary, "events",
 		fmt.Sprintf("--since=%d", since),
 		fmt.Sprintf("--since=%d", since),
-		fmt.Sprintf("--until=%d", time.Now().Unix()))
+		fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, _, _ = runCommandWithOutput(eventsCmd)
 	out, _, _ = runCommandWithOutput(eventsCmd)
 
 
 	events := strings.Split(strings.TrimSpace(out), "\n")
 	events := strings.Split(strings.TrimSpace(out), "\n")
@@ -219,7 +219,7 @@ func TestEventsFilters(t *testing.T) {
 		}
 		}
 	}
 	}
 
 
-	since := time.Now().Unix()
+	since := daemonTime(t).Unix()
 	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
 	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", "busybox", "true"))
 	if err != nil {
 	if err != nil {
 		t.Fatal(out, err)
 		t.Fatal(out, err)
@@ -228,13 +228,13 @@ func TestEventsFilters(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(out, err)
 		t.Fatal(out, err)
 	}
 	}
-	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", "event=die"))
+	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", "event=die"))
 	if err != nil {
 	if err != nil {
 		t.Fatalf("Failed to get events: %s", err)
 		t.Fatalf("Failed to get events: %s", err)
 	}
 	}
 	parseEvents(out, "die")
 	parseEvents(out, "die")
 
 
-	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", "event=die", "--filter", "event=start"))
+	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", "event=die", "--filter", "event=start"))
 	if err != nil {
 	if err != nil {
 		t.Fatalf("Failed to get events: %s", err)
 		t.Fatalf("Failed to get events: %s", err)
 	}
 	}
@@ -250,7 +250,7 @@ func TestEventsFilters(t *testing.T) {
 }
 }
 
 
 func TestEventsFilterImageName(t *testing.T) {
 func TestEventsFilterImageName(t *testing.T) {
-	since := time.Now().Unix()
+	since := daemonTime(t).Unix()
 	defer deleteAllContainers()
 	defer deleteAllContainers()
 
 
 	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "-d", "busybox", "true"))
 	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "-d", "busybox", "true"))
@@ -266,7 +266,7 @@ func TestEventsFilterImageName(t *testing.T) {
 	container2 := stripTrailingCharacters(out)
 	container2 := stripTrailingCharacters(out)
 
 
 	for _, s := range []string{"busybox", "busybox:latest"} {
 	for _, s := range []string{"busybox", "busybox:latest"} {
-		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", fmt.Sprintf("image=%s", s))
+		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", fmt.Sprintf("image=%s", s))
 		out, _, err := runCommandWithOutput(eventsCmd)
 		out, _, err := runCommandWithOutput(eventsCmd)
 		if err != nil {
 		if err != nil {
 			t.Fatalf("Failed to get events, error: %s(%s)", err, out)
 			t.Fatalf("Failed to get events, error: %s(%s)", err, out)
@@ -294,7 +294,7 @@ func TestEventsFilterImageName(t *testing.T) {
 }
 }
 
 
 func TestEventsFilterContainerID(t *testing.T) {
 func TestEventsFilterContainerID(t *testing.T) {
-	since := time.Now().Unix()
+	since := daemonTime(t).Unix()
 	defer deleteAllContainers()
 	defer deleteAllContainers()
 
 
 	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
 	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
@@ -310,7 +310,7 @@ func TestEventsFilterContainerID(t *testing.T) {
 	container2 := stripTrailingCharacters(out)
 	container2 := stripTrailingCharacters(out)
 
 
 	for _, s := range []string{container1, container2, container1[:12], container2[:12]} {
 	for _, s := range []string{container1, container2, container1[:12], container2[:12]} {
-		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", fmt.Sprintf("container=%s", s))
+		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", fmt.Sprintf("container=%s", s))
 		out, _, err := runCommandWithOutput(eventsCmd)
 		out, _, err := runCommandWithOutput(eventsCmd)
 		if err != nil {
 		if err != nil {
 			t.Fatalf("Failed to get events, error: %s(%s)", err, out)
 			t.Fatalf("Failed to get events, error: %s(%s)", err, out)
@@ -342,7 +342,7 @@ func TestEventsFilterContainerID(t *testing.T) {
 }
 }
 
 
 func TestEventsFilterContainerName(t *testing.T) {
 func TestEventsFilterContainerName(t *testing.T) {
-	since := time.Now().Unix()
+	since := daemonTime(t).Unix()
 	defer deleteAllContainers()
 	defer deleteAllContainers()
 
 
 	_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "busybox", "true"))
 	_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "busybox", "true"))
@@ -356,7 +356,7 @@ func TestEventsFilterContainerName(t *testing.T) {
 	}
 	}
 
 
 	for _, s := range []string{"container_1", "container_2"} {
 	for _, s := range []string{"container_1", "container_2"} {
-		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", fmt.Sprintf("container=%s", s))
+		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(t).Unix()), "--filter", fmt.Sprintf("container=%s", s))
 		out, _, err := runCommandWithOutput(eventsCmd)
 		out, _, err := runCommandWithOutput(eventsCmd)
 		if err != nil {
 		if err != nil {
 			t.Fatalf("Failed to get events, error : %s(%s)", err, out)
 			t.Fatalf("Failed to get events, error : %s(%s)", err, out)

+ 2 - 6
integration-cli/docker_cli_events_unix_test.go

@@ -9,7 +9,6 @@ import (
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
 	"testing"
 	"testing"
-	"time"
 	"unicode"
 	"unicode"
 
 
 	"github.com/kr/pty"
 	"github.com/kr/pty"
@@ -17,11 +16,8 @@ import (
 
 
 // #5979
 // #5979
 func TestEventsRedirectStdout(t *testing.T) {
 func TestEventsRedirectStdout(t *testing.T) {
-
-	since := time.Now().Unix()
-
+	since := daemonTime(t).Unix()
 	dockerCmd(t, "run", "busybox", "true")
 	dockerCmd(t, "run", "busybox", "true")
-
 	defer deleteAllContainers()
 	defer deleteAllContainers()
 
 
 	file, err := ioutil.TempFile("", "")
 	file, err := ioutil.TempFile("", "")
@@ -30,7 +26,7 @@ func TestEventsRedirectStdout(t *testing.T) {
 	}
 	}
 	defer os.Remove(file.Name())
 	defer os.Remove(file.Name())
 
 
-	command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, time.Now().Unix(), file.Name())
+	command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, daemonTime(t).Unix(), file.Name())
 	_, tty, err := pty.Open()
 	_, tty, err := pty.Open()
 	if err != nil {
 	if err != nil {
 		t.Fatalf("Could not open pty: %v", err)
 		t.Fatalf("Could not open pty: %v", err)

+ 2 - 3
integration-cli/docker_cli_pause_test.go

@@ -5,7 +5,6 @@ import (
 	"os/exec"
 	"os/exec"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
-	"time"
 )
 )
 
 
 func TestPause(t *testing.T) {
 func TestPause(t *testing.T) {
@@ -28,7 +27,7 @@ func TestPause(t *testing.T) {
 
 
 	dockerCmd(t, "unpause", name)
 	dockerCmd(t, "unpause", name)
 
 
-	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
+	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, _, _ = runCommandWithOutput(eventsCmd)
 	out, _, _ = runCommandWithOutput(eventsCmd)
 	events := strings.Split(out, "\n")
 	events := strings.Split(out, "\n")
 	if len(events) <= 1 {
 	if len(events) <= 1 {
@@ -77,7 +76,7 @@ func TestPauseMultipleContainers(t *testing.T) {
 
 
 	dockerCmd(t, append([]string{"unpause"}, containers...)...)
 	dockerCmd(t, append([]string{"unpause"}, containers...)...)
 
 
-	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", time.Now().Unix()))
+	eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(t).Unix()))
 	out, _, _ = runCommandWithOutput(eventsCmd)
 	out, _, _ = runCommandWithOutput(eventsCmd)
 	events := strings.Split(out, "\n")
 	events := strings.Split(out, "\n")
 	if len(events) <= len(containers)*3-2 {
 	if len(events) <= len(containers)*3-2 {

+ 26 - 0
integration-cli/docker_utils.go

@@ -981,6 +981,32 @@ func readContainerFileWithExec(containerId, filename string) ([]byte, error) {
 	return []byte(out), err
 	return []byte(out), err
 }
 }
 
 
+// daemonTime provides the current time on the daemon host
+func daemonTime(t *testing.T) time.Time {
+	if isLocalDaemon {
+		return time.Now()
+	}
+
+	body, err := sockRequest("GET", "/info", nil)
+	if err != nil {
+		t.Fatal("daemonTime: failed to get /info: %v", err)
+	}
+
+	type infoJSON struct {
+		SystemTime string
+	}
+	var info infoJSON
+	if err = json.Unmarshal(body, &info); err != nil {
+		t.Fatalf("unable to unmarshal /info response: %v", err)
+	}
+
+	dt, err := time.Parse(time.RFC3339Nano, info.SystemTime)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return dt
+}
+
 func setupRegistry(t *testing.T) func() {
 func setupRegistry(t *testing.T) func() {
 	testRequires(t, RegistryHosting)
 	testRequires(t, RegistryHosting)
 	reg, err := newTestRegistryV2(t)
 	reg, err := newTestRegistryV2(t)