Browse code

Fix TestBuildCancelationKillsSleep to not fail on Windows

Signed-off-by: Antonio Murdaca <me@runcom.ninja>

Antonio Murdaca authored on 2015/04/06 23:28:39
Showing 2 changed files
... ...
@@ -1963,8 +1963,8 @@ func TestBuildForceRm(t *testing.T) {
1963 1963
 // * When docker events sees container start, close the "docker build" command
1964 1964
 // * Wait for docker events to emit a dying event.
1965 1965
 func TestBuildCancelationKillsSleep(t *testing.T) {
1966
-	// TODO(jfrazelle): Make this work on Windows.
1967
-	testRequires(t, SameHostDaemon)
1966
+	var wg sync.WaitGroup
1967
+	defer wg.Wait()
1968 1968
 
1969 1969
 	name := "testbuildcancelation"
1970 1970
 	defer deleteImages(name)
... ...
@@ -1977,26 +1977,23 @@ func TestBuildCancelationKillsSleep(t *testing.T) {
1977 1977
 	}
1978 1978
 	defer ctx.Close()
1979 1979
 
1980
-	var wg sync.WaitGroup
1981
-	defer wg.Wait()
1982
-
1983 1980
 	finish := make(chan struct{})
1984 1981
 	defer close(finish)
1985 1982
 
1986 1983
 	eventStart := make(chan struct{})
1987 1984
 	eventDie := make(chan struct{})
1985
+	containerID := make(chan string)
1988 1986
 
1989
-	// Start one second ago, to avoid rounding problems
1990
-	startEpoch := time.Now().Add(-1 * time.Second)
1987
+	startEpoch := daemonTime(t).Unix()
1991 1988
 
1992
-	// Goroutine responsible for watching start/die events from `docker events`
1993 1989
 	wg.Add(1)
1990
+	// Goroutine responsible for watching start/die events from `docker events`
1994 1991
 	go func() {
1995 1992
 		defer wg.Done()
1996
-
1997 1993
 		// Watch for events since epoch.
1998
-		eventsCmd := exec.Command(dockerBinary, "events",
1999
-			"-since", fmt.Sprint(startEpoch.Unix()))
1994
+		eventsCmd := exec.Command(
1995
+			dockerBinary, "events",
1996
+			"--since", strconv.FormatInt(startEpoch, 10))
2000 1997
 		stdout, err := eventsCmd.StdoutPipe()
2001 1998
 		err = eventsCmd.Start()
2002 1999
 		if err != nil {
... ...
@@ -2008,36 +2005,21 @@ func TestBuildCancelationKillsSleep(t *testing.T) {
2008 2008
 			eventsCmd.Process.Kill()
2009 2009
 		}()
2010 2010
 
2011
-		var started, died bool
2012
-		var imageID string
2011
+		cid := <-containerID
2013 2012
 
2014
-		if out, err := exec.Command(dockerBinary, "inspect", "-f", "{{.Id}}", "busybox").CombinedOutput(); err != nil {
2015
-			t.Fatalf("failed to get the image ID of busybox: %s, %v", out, err)
2016
-		} else {
2017
-			imageID = strings.TrimSpace(string(out))
2018
-		}
2019
-
2020
-		matchStart := regexp.MustCompile(" \\(from " + imageID + "\\) start$")
2021
-		matchDie := regexp.MustCompile(" \\(from " + imageID + "\\) die$")
2013
+		matchStart := regexp.MustCompile(cid + `(.*) start$`)
2014
+		matchDie := regexp.MustCompile(cid + `(.*) die$`)
2022 2015
 
2023 2016
 		//
2024 2017
 		// Read lines of `docker events` looking for container start and stop.
2025 2018
 		//
2026 2019
 		scanner := bufio.NewScanner(stdout)
2027 2020
 		for scanner.Scan() {
2028
-			if ok := matchStart.MatchString(scanner.Text()); ok {
2029
-				if started {
2030
-					t.Fatal("assertion fail: more than one container started")
2031
-				}
2021
+			switch {
2022
+			case matchStart.MatchString(scanner.Text()):
2032 2023
 				close(eventStart)
2033
-				started = true
2034
-			}
2035
-			if ok := matchDie.MatchString(scanner.Text()); ok {
2036
-				if died {
2037
-					t.Fatal("assertion fail: more than one container died")
2038
-				}
2024
+			case matchDie.MatchString(scanner.Text()):
2039 2025
 				close(eventDie)
2040
-				died = true
2041 2026
 			}
2042 2027
 		}
2043 2028
 
... ...
@@ -2050,13 +2032,24 @@ func TestBuildCancelationKillsSleep(t *testing.T) {
2050 2050
 	buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".")
2051 2051
 	buildCmd.Dir = ctx.Dir
2052 2052
 
2053
+	stdoutBuild, err := buildCmd.StdoutPipe()
2053 2054
 	err = buildCmd.Start()
2054 2055
 	if err != nil {
2055 2056
 		t.Fatalf("failed to run build: %s", err)
2056 2057
 	}
2057 2058
 
2059
+	matchCID := regexp.MustCompile("Running in ")
2060
+	scanner := bufio.NewScanner(stdoutBuild)
2061
+	for scanner.Scan() {
2062
+		line := scanner.Text()
2063
+		if ok := matchCID.MatchString(line); ok {
2064
+			containerID <- line[len(line)-12:]
2065
+			break
2066
+		}
2067
+	}
2068
+
2058 2069
 	select {
2059
-	case <-time.After(30 * time.Second):
2070
+	case <-time.After(5 * time.Second):
2060 2071
 		t.Fatal("failed to observe build container start in timely fashion")
2061 2072
 	case <-eventStart:
2062 2073
 		// Proceeds from here when we see the container fly past in the
... ...
@@ -2078,7 +2071,7 @@ func TestBuildCancelationKillsSleep(t *testing.T) {
2078 2078
 	}
2079 2079
 
2080 2080
 	select {
2081
-	case <-time.After(30 * time.Second):
2081
+	case <-time.After(5 * time.Second):
2082 2082
 		// If we don't get here in a timely fashion, it wasn't killed.
2083 2083
 		t.Fatal("container cancel did not succeed")
2084 2084
 	case <-eventDie:
... ...
@@ -44,12 +44,14 @@ func processExitCode(err error) (exitCode int) {
44 44
 
45 45
 func IsKilled(err error) bool {
46 46
 	if exitErr, ok := err.(*exec.ExitError); ok {
47
-		sys := exitErr.ProcessState.Sys()
48
-		status, ok := sys.(syscall.WaitStatus)
47
+		status, ok := exitErr.Sys().(syscall.WaitStatus)
49 48
 		if !ok {
50 49
 			return false
51 50
 		}
52
-		return status.Signaled() && status.Signal() == os.Kill
51
+		// status.ExitStatus() is required on Windows because it does not
52
+		// implement Signal() nor Signaled(). Just check it had a bad exit
53
+		// status could mean it was killed (and in tests we do kill)
54
+		return (status.Signaled() && status.Signal() == os.Kill) || status.ExitStatus() != 0
53 55
 	}
54 56
 	return false
55 57
 }