Пример #1
0
func getHealth(c *check.C, name string) *types.Health {
	out, _ := dockerCmd(c, "inspect", "--format={{json .State.Health}}", name)
	var health types.Health
	err := json.Unmarshal([]byte(out), &health)
	c.Check(err, checker.Equals, nil)
	return &health
}
Пример #2
0
func (s *StreamHandlerSuite) TestStreamUntilRemoved(c *check.C) {
	var l string
	var err error

	res := s.Get(c)
	c.Check(res.StatusCode, check.Equals, 200)

	r := bufio.NewReader(res.Body)

	// Write before rename
	s.Printf(c, "hello\n")

	// Read bytes written before rename
	l, err = r.ReadString('\n')
	c.Check(err, check.IsNil)
	c.Check(l, check.Equals, "hello\n")

	// Remove
	err = os.Remove(s.FileName)
	c.Assert(err, check.IsNil)

	// Read EOF
	l, err = r.ReadString('\n')
	// c.Check(err, check.Equals, io.ErrUnexpectedEOF) LINUX
	// c.Check(err, check.Equals, io.EOF) MAC
	c.Check(err, check.Not(check.IsNil))
	c.Check(l, check.Equals, "")
}
Пример #3
0
func (s *DockerSuite) TestInspectApiContainerResponse(c *check.C) {
	testRequires(c, DaemonIsLinux)
	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")

	cleanedContainerID := strings.TrimSpace(out)
	keysBase := []string{"Id", "State", "Created", "Path", "Args", "Config", "Image", "NetworkSettings",
		"ResolvConfPath", "HostnamePath", "HostsPath", "LogPath", "Name", "Driver", "MountLabel", "ProcessLabel", "GraphDriver"}

	cases := []struct {
		version string
		keys    []string
	}{
		{"v1.20", append(keysBase, "Mounts")},
		{"v1.19", append(keysBase, "Volumes", "VolumesRW")},
	}

	for _, cs := range cases {
		body := getInspectBody(c, cs.version, cleanedContainerID)

		var inspectJSON map[string]interface{}
		err := json.Unmarshal(body, &inspectJSON)
		c.Assert(err, checker.IsNil, check.Commentf("Unable to unmarshal body for version %s", cs.version))

		for _, key := range cs.keys {
			_, ok := inspectJSON[key]
			c.Check(ok, checker.True, check.Commentf("%s does not exist in response for version %s", key, cs.version))
		}

		//Issue #6830: type not properly converted to JSON/back
		_, ok := inspectJSON["Path"].(bool)
		c.Assert(ok, checker.False, check.Commentf("Path of `true` should not be converted to boolean `true` via JSON marshalling"))
	}
}
Пример #4
0
func (s *StreamHandlerSuite) TestStreamFlushesBeforeTailing(c *check.C) {
	s.Printf(c, "hello\n")

	f, err := os.Open(s.FileName)
	c.Assert(err, check.IsNil)

	_, err = f.Seek(3, os.SEEK_SET)
	c.Assert(err, check.IsNil)

	h := s.BuildHandler(f)
	res := s.GetFromHandler(c, h)
	c.Check(res.StatusCode, check.Equals, 200)

	r := bufio.NewReader(res.Body)

	l, err := r.ReadString('\n')
	c.Check(err, check.IsNil)
	c.Check(l, check.Equals, "lo\n")

	s.Printf(c, "world\n")

	l, err = r.ReadString('\n')
	c.Check(err, check.IsNil)
	c.Check(l, check.Equals, "world\n")
}
Пример #5
0
func (s *DockerSuite) TestClientSetsTLSServerName(c *check.C) {
	c.Skip("Flakey test")
	// there may be more than one hit to the server for each registry request
	serverNameReceived := []string{}
	var serverName string

	virtualHostServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		serverNameReceived = append(serverNameReceived, r.TLS.ServerName)
	}))
	defer virtualHostServer.Close()
	// discard TLS handshake errors written by default to os.Stderr
	virtualHostServer.Config.ErrorLog = log.New(ioutil.Discard, "", 0)

	u, err := url.Parse(virtualHostServer.URL)
	c.Assert(err, check.IsNil)
	hostPort := u.Host
	serverName = strings.Split(hostPort, ":")[0]

	repoName := fmt.Sprintf("%v/dockercli/image:latest", hostPort)
	cmd := exec.Command(dockerBinary, "pull", repoName)
	cmd.Run()

	// check that the fake server was hit at least once
	c.Assert(len(serverNameReceived) > 0, check.Equals, true)
	// check that for each hit the right server name was received
	for _, item := range serverNameReceived {
		c.Check(item, check.Equals, serverName)
	}
}
func (s *DockerCmdSuite) TestDockerCmdSuccess(c *check.C) {
	// Run error suite, should fail.
	output := String{}
	result := check.Run(&dockerCmdSuccessSuite{}, &check.RunConf{Output: &output})
	c.Check(result.Succeeded, check.Equals, 1)
	c.Check(result.Failed, check.Equals, 0)
}
Пример #7
0
func (s *DirectoryServerSuite) TestHandler_ServeHTTP_StreamFileFromOffsetLargerThanFile(t *check.C) {
	response, body := fetchStreamingResponse(t, "/path?tail=&tail_offset=1000000")
	t.Check(response.StatusCode, check.Equals, 200)

	trimmed_body := strings.Trim(body, string(0))
	t.Check(len(trimmed_body), check.Equals, 0)
}
Пример #8
0
func (s *StreamHandlerSuite) TestStreamUntilRenamed(c *check.C) {
	var l string
	var err error

	res := s.Get(c)
	c.Check(res.StatusCode, check.Equals, 200)

	r := bufio.NewReader(res.Body)

	// Write before rename
	s.Printf(c, "hello\n")

	// Read bytes written before rename
	l, err = r.ReadString('\n')
	c.Check(err, check.IsNil)
	c.Check(l, check.Equals, "hello\n")

	// Rename
	y := s.TempFileName(c)
	err = os.Rename(s.FileName, y)
	c.Assert(err, check.IsNil)

	// Read EOF
	l, err = r.ReadString('\n')
	c.Check(err, check.Equals, io.EOF)
	c.Check(l, check.Equals, "")
}
// start a service, and then make its task unhealthy during running
// finally, unhealthy task should be detected and killed
func (s *DockerSwarmSuite) TestServiceHealthRun(c *check.C) {
	testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows

	d := s.AddDaemon(c, true, true)

	// build image with health-check
	// note: use `daemon.buildImageWithOut` to build, do not use `buildImage` to build
	imageName := "testhealth"
	_, _, err := d.BuildImageWithOut(imageName,
		`FROM busybox
		RUN touch /status
		HEALTHCHECK --interval=1s --timeout=1s --retries=1\
		  CMD cat /status`,
		true)
	c.Check(err, check.IsNil)

	serviceName := "healthServiceRun"
	out, err := d.Cmd("service", "create", "--name", serviceName, imageName, "top")
	c.Assert(err, checker.IsNil, check.Commentf(out))
	id := strings.TrimSpace(out)

	var tasks []swarm.Task
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		tasks = d.GetServiceTasks(c, id)
		return tasks, nil
	}, checker.HasLen, 1)

	task := tasks[0]

	// wait for task to start
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		task = d.GetTask(c, task.ID)
		return task.Status.State, nil
	}, checker.Equals, swarm.TaskStateRunning)
	containerID := task.Status.ContainerStatus.ContainerID

	// wait for container to be healthy
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		out, _ := d.Cmd("inspect", "--format={{.State.Health.Status}}", containerID)
		return strings.TrimSpace(out), nil
	}, checker.Equals, "healthy")

	// make it fail
	d.Cmd("exec", containerID, "rm", "/status")
	// wait for container to be unhealthy
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		out, _ := d.Cmd("inspect", "--format={{.State.Health.Status}}", containerID)
		return strings.TrimSpace(out), nil
	}, checker.Equals, "unhealthy")

	// Task should be terminated
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		task = d.GetTask(c, task.ID)
		return task.Status.State, nil
	}, checker.Equals, swarm.TaskStateFailed)

	if !strings.Contains(task.Status.Err, container.ErrContainerUnhealthy.Error()) {
		c.Fatal("unhealthy task exits because of other error")
	}
}
Пример #10
0
func (s *DeaClientSuite) TestDeaNotStarted(c *check.C) {
	s.StartDea(http.NotFoundHandler())
	s.StopDea()

	r := s.Get("/")
	c.Check(r.StatusCode, check.Equals, http.StatusInternalServerError)
	c.Check(readBody(r), check.Matches, ".*unreachable")
}
// start a service whose task is unhealthy at beginning
// its tasks should be blocked in starting stage, until health check is passed
func (s *DockerSwarmSuite) TestServiceHealthStart(c *check.C) {
	testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows

	d := s.AddDaemon(c, true, true)

	// service started from this image won't pass health check
	imageName := "testhealth"
	_, _, err := d.BuildImageWithOut(imageName,
		`FROM busybox
		HEALTHCHECK --interval=1s --timeout=1s --retries=1024\
		  CMD cat /status`,
		true)
	c.Check(err, check.IsNil)

	serviceName := "healthServiceStart"
	out, err := d.Cmd("service", "create", "--name", serviceName, imageName, "top")
	c.Assert(err, checker.IsNil, check.Commentf(out))
	id := strings.TrimSpace(out)

	var tasks []swarm.Task
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		tasks = d.GetServiceTasks(c, id)
		return tasks, nil
	}, checker.HasLen, 1)

	task := tasks[0]

	// wait for task to start
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		task = d.GetTask(c, task.ID)
		return task.Status.State, nil
	}, checker.Equals, swarm.TaskStateStarting)

	containerID := task.Status.ContainerStatus.ContainerID

	// wait for health check to work
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		out, _ := d.Cmd("inspect", "--format={{.State.Health.FailingStreak}}", containerID)
		failingStreak, _ := strconv.Atoi(strings.TrimSpace(out))
		return failingStreak, nil
	}, checker.GreaterThan, 0)

	// task should be blocked at starting status
	task = d.GetTask(c, task.ID)
	c.Assert(task.Status.State, check.Equals, swarm.TaskStateStarting)

	// make it healthy
	d.Cmd("exec", containerID, "touch", "/status")

	// Task should be at running status
	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
		task = d.GetTask(c, task.ID)
		return task.Status.State, nil
	}, checker.Equals, swarm.TaskStateRunning)
}
Пример #12
0
func (s *MaxLatencyWriterSuite) TestWrite(c *check.C) {
	x := &testWriteFlusher{}
	y := NewMaxLatencyWriter(x, 10*time.Millisecond)

	c.Check(x.WriteCounter, check.Equals, 0)

	y.Write([]byte("x"))

	c.Check(x.WriteCounter, check.Equals, 1)

	y.Stop()
}
Пример #13
0
func (s *DeaClientSuite) TestDeaStatusInternalServerError(c *check.C) {
	f := func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintln(w, `internal server error`)
	}

	s.StartDea(http.HandlerFunc(f))

	r := s.Get("/")
	c.Check(r.StatusCode, check.Equals, http.StatusInternalServerError)
	c.Check(readBody(r), check.Matches, "internal server error")
}
Пример #14
0
func (s *DeaClientSuite) TestDeaStatusOK(c *check.C) {
	f := func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		fmt.Fprintln(w, `{ "instance_path": "/tmp/fuz" }`)
	}

	s.StartDea(http.HandlerFunc(f))

	r := s.Get("/")
	c.Check(r.StatusCode, check.Equals, http.StatusOK)
	c.Check(readBody(r), check.Equals, "/tmp/fuz")
}
Пример #15
0
func (s *DeaClientSuite) TestDeaInvalidJsonField(c *check.C) {
	f := func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		fmt.Fprintln(w, `{ "other_instance_path": "/tmp/fuz" }`)
	}

	s.StartDea(http.HandlerFunc(f))

	r := s.Get("/")
	c.Check(r.StatusCode, check.Equals, http.StatusInternalServerError)
	c.Check(readBody(r), check.Matches, ".*invalid JSON")
}
Пример #16
0
func (s *DeaClientSuite) TestDeaRequestPath(c *check.C) {
	f := func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, `{ "instance_path": "%s" }`, r.URL.String())
	}

	s.StartDea(http.HandlerFunc(f))

	r := s.Get("/some/path/?query")
	c.Check(r.StatusCode, check.Equals, http.StatusOK)
	c.Check(readBody(r), check.Equals, "/some/path/?query")
}
Пример #17
0
func (s *DeaClientSuite) TestDeaStatusInternalServerErrorHeader(c *check.C) {
	f := func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("X-Hello", "World")
		w.WriteHeader(http.StatusInternalServerError)
	}

	s.StartDea(http.HandlerFunc(f))

	r := s.Get("/")
	c.Check(r.StatusCode, check.Equals, http.StatusInternalServerError)
	c.Check(r.Header.Get("X-Hello"), check.Equals, "World")
}
Пример #18
0
func (s *MaxLatencyWriterSuite) TestStop(c *check.C) {
	x := &testWriteFlusher{}
	y := NewMaxLatencyWriter(x, 10*time.Millisecond)

	c.Check(x.FlushCounter, check.Equals, 0)

	y.Stop()

	time.Sleep(15 * time.Millisecond)

	c.Check(x.FlushCounter, check.Equals, 0)
}
Пример #19
0
func waitForHealthStatus(c *check.C, name string, prev string, expected string) {
	prev = prev + "\n"
	expected = expected + "\n"
	for {
		out, _ := dockerCmd(c, "inspect", "--format={{.State.Health.Status}}", name)
		if out == expected {
			return
		}
		c.Check(out, checker.Equals, prev)
		if out != prev {
			return
		}
		time.Sleep(100 * time.Millisecond)
	}
}
Пример #20
0
func (s *DirectoryServerSuite) TestHandler_ServeHTTP_StreamFileFromValidOffset(t *check.C) {
	response, body := fetchStreamingResponse(t, "/path?tail=&tail_offset=0")
	t.Check(response.StatusCode, check.Equals, 200)

	// Check transfer encoding.
	te := response.TransferEncoding
	if len(te) != 1 || te[0] != "chunked" {
		t.Fail()
	}

	matched, _ := regexp.MatchString("^blah0blah1blah2", body)
	if !matched {
		t.Fail()
	}
}
Пример #21
0
// #17131, #17139, #17173
func (s *DockerSuite) TestInspectApiEmptyFieldsInConfigPre121(c *check.C) {
	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")

	cleanedContainerID := strings.TrimSpace(out)

	cases := []string{"v1.19", "v1.20"}
	for _, version := range cases {
		body := getInspectBody(c, version, cleanedContainerID)

		var inspectJSON map[string]interface{}
		err := json.Unmarshal(body, &inspectJSON)
		c.Assert(err, checker.IsNil, check.Commentf("Unable to unmarshal body for version %s", version))
		config, ok := inspectJSON["Config"]
		c.Assert(ok, checker.True, check.Commentf("Unable to find 'Config'"))
		cfg := config.(map[string]interface{})
		for _, f := range []string{"MacAddress", "NetworkDisabled", "ExposedPorts"} {
			_, ok := cfg[f]
			c.Check(ok, checker.True, check.Commentf("Api version %s expected to include %s in 'Config'", version, f))
		}
	}
}
Пример #22
0
// TestPullFromCentralRegistry pulls an image from the central registry and verifies that the client
// prints all expected output.
func (s *DockerHubPullSuite) TestPullFromCentralRegistry(c *check.C) {
	testRequires(c, DaemonIsLinux)
	out := s.Cmd(c, "pull", "hello-world")
	defer deleteImages("hello-world")

	c.Assert(out, checker.Contains, "Using default tag: latest", check.Commentf("expected the 'latest' tag to be automatically assumed"))
	c.Assert(out, checker.Contains, "Pulling from library/hello-world", check.Commentf("expected the 'library/' prefix to be automatically assumed"))
	c.Assert(out, checker.Contains, "Downloaded newer image for hello-world:latest")

	matches := regexp.MustCompile(`Digest: (.+)\n`).FindAllStringSubmatch(out, -1)
	c.Assert(len(matches), checker.Equals, 1, check.Commentf("expected exactly one image digest in the output"))
	c.Assert(len(matches[0]), checker.Equals, 2, check.Commentf("unexpected number of submatches for the digest"))
	_, err := digest.ParseDigest(matches[0][1])
	c.Check(err, checker.IsNil, check.Commentf("invalid digest %q in output", matches[0][1]))

	// We should have a single entry in images.
	img := strings.TrimSpace(s.Cmd(c, "images"))
	splitImg := strings.Split(img, "\n")
	c.Assert(splitImg, checker.HasLen, 2)
	c.Assert(splitImg[1], checker.Matches, `hello-world\s+latest.*?`, check.Commentf("invalid output for `docker images` (expected image and tag name"))
}
Пример #23
0
func (s *StreamHandlerSuite) TestStream(c *check.C) {
	res := s.Get(c)
	c.Check(res.StatusCode, check.Equals, 200)

	// The header was already sent, now write something to the file
	s.Printf(c, "hello\n")

	r := bufio.NewReader(res.Body)
	l, err := r.ReadString('\n')
	c.Check(err, check.IsNil)
	c.Check(l, check.Equals, "hello\n")
}
Пример #24
0
func (s *StreamHandlerSuite) TestStreamFromCurrentPosition(c *check.C) {
	s.Printf(c, "hello\n")

	res := s.Get(c)
	c.Check(res.StatusCode, check.Equals, 200)

	s.Printf(c, "world\n")

	r := bufio.NewReader(res.Body)
	l, err := r.ReadString('\n')
	c.Check(err, check.IsNil)
	c.Check(l, check.Equals, "world\n")
}
Пример #25
0
func (s *StreamHandlerSuite) TestStreamWithIdleTimeout(c *check.C) {
	var l string
	var err error

	f := s.BuildFile(c)

	handler := &StreamHandler{
		File:          f,
		FlushInterval: 1 * time.Millisecond,
		IdleTimeout:   200 * time.Millisecond,
	}

	res := s.GetFromHandler(c, handler)
	c.Check(res.StatusCode, check.Equals, 200)

	r := bufio.NewReader(res.Body)

	// Write before timing out
	time.Sleep(15 * time.Millisecond)
	s.Printf(c, "hi there!\n")

	// Read the write
	l, _ = r.ReadString('\n')
	c.Check(l, check.Equals, "hi there!\n")

	// Write after timing out
	time.Sleep(250 * time.Millisecond)

	// Wait again to ensure the timeout logic is no longer in use
	time.Sleep(250 * time.Millisecond)

	s.Printf(c, "what?\n")

	// Read an unexepected EOF
	_, err = r.ReadString('\n')
	c.Check(err, check.Equals, io.ErrUnexpectedEOF)
}
Пример #26
0
func (s *DockerSuite) TestHealth(c *check.C) {
	testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows

	imageName := "testhealth"
	_, err := buildImage(imageName,
		`FROM busybox
		RUN echo OK > /status
		CMD ["/bin/sleep", "120"]
		STOPSIGNAL SIGKILL
		HEALTHCHECK --interval=1s --timeout=30s \
		  CMD cat /status`,
		true)

	c.Check(err, check.IsNil)

	// No health status before starting
	name := "test_health"
	dockerCmd(c, "create", "--name", name, imageName)
	out, _ := dockerCmd(c, "ps", "-a", "--format={{.Status}}")
	c.Check(out, checker.Equals, "Created\n")

	// Inspect the options
	out, _ = dockerCmd(c, "inspect",
		"--format=timeout={{.Config.Healthcheck.Timeout}} "+
			"interval={{.Config.Healthcheck.Interval}} "+
			"retries={{.Config.Healthcheck.Retries}} "+
			"test={{.Config.Healthcheck.Test}}", name)
	c.Check(out, checker.Equals, "timeout=30s interval=1s retries=0 test=[CMD-SHELL cat /status]\n")

	// Start
	dockerCmd(c, "start", name)
	waitForHealthStatus(c, name, "starting", "healthy")

	// Make it fail
	dockerCmd(c, "exec", name, "rm", "/status")
	waitForHealthStatus(c, name, "healthy", "unhealthy")

	// Inspect the status
	out, _ = dockerCmd(c, "inspect", "--format={{.State.Health.Status}}", name)
	c.Check(out, checker.Equals, "unhealthy\n")

	// Make it healthy again
	dockerCmd(c, "exec", name, "touch", "/status")
	waitForHealthStatus(c, name, "unhealthy", "healthy")

	// Remove container
	dockerCmd(c, "rm", "-f", name)

	// Disable the check from the CLI
	out, _ = dockerCmd(c, "create", "--name=noh", "--no-healthcheck", imageName)
	out, _ = dockerCmd(c, "inspect", "--format={{.Config.Healthcheck.Test}}", "noh")
	c.Check(out, checker.Equals, "[NONE]\n")
	dockerCmd(c, "rm", "noh")

	// Disable the check with a new build
	_, err = buildImage("no_healthcheck",
		`FROM testhealth
		HEALTHCHECK NONE`, true)
	c.Check(err, check.IsNil)

	out, _ = dockerCmd(c, "inspect", "--format={{.ContainerConfig.Healthcheck.Test}}", "no_healthcheck")
	c.Check(out, checker.Equals, "[NONE]\n")

	// Enable the checks from the CLI
	_, _ = dockerCmd(c, "run", "-d", "--name=fatal_healthcheck",
		"--health-interval=0.5s",
		"--health-retries=3",
		"--health-cmd=cat /status",
		"no_healthcheck")
	waitForHealthStatus(c, "fatal_healthcheck", "starting", "healthy")
	health := getHealth(c, "fatal_healthcheck")
	c.Check(health.Status, checker.Equals, "healthy")
	c.Check(health.FailingStreak, checker.Equals, 0)
	last := health.Log[len(health.Log)-1]
	c.Check(last.ExitCode, checker.Equals, 0)
	c.Check(last.Output, checker.Equals, "OK\n")

	// Fail the check
	dockerCmd(c, "exec", "fatal_healthcheck", "rm", "/status")
	waitForHealthStatus(c, "fatal_healthcheck", "healthy", "unhealthy")

	failsStr, _ := dockerCmd(c, "inspect", "--format={{.State.Health.FailingStreak}}", "fatal_healthcheck")
	fails, err := strconv.Atoi(strings.TrimSpace(failsStr))
	c.Check(err, check.IsNil)
	c.Check(fails >= 3, checker.Equals, true)
	dockerCmd(c, "rm", "-f", "fatal_healthcheck")

	// Check timeout
	// Note: if the interval is too small, it seems that Docker spends all its time running health
	// checks and never gets around to killing it.
	_, _ = dockerCmd(c, "run", "-d", "--name=test",
		"--health-interval=1s", "--health-cmd=sleep 5m", "--health-timeout=1ms", imageName)
	waitForHealthStatus(c, "test", "starting", "unhealthy")
	health = getHealth(c, "test")
	last = health.Log[len(health.Log)-1]
	c.Check(health.Status, checker.Equals, "unhealthy")
	c.Check(last.ExitCode, checker.Equals, -1)
	c.Check(last.Output, checker.Equals, "Health check exceeded timeout (1ms)")
	dockerCmd(c, "rm", "-f", "test")

	// Check JSON-format
	_, err = buildImage(imageName,
		`FROM busybox
		RUN echo OK > /status
		CMD ["/bin/sleep", "120"]
		STOPSIGNAL SIGKILL
		HEALTHCHECK --interval=1s --timeout=30s \
		  CMD ["cat", "/my status"]`,
		true)
	c.Check(err, check.IsNil)
	out, _ = dockerCmd(c, "inspect",
		"--format={{.Config.Healthcheck.Test}}", imageName)
	c.Check(out, checker.Equals, "[CMD cat /my status]\n")

}
Пример #27
0
func (s *DirectoryServerSuite) TestHandler_ServeHTTP_StreamFileFromNegavtiveOffset(t *check.C) {
	response, body := fetchStreamingResponse(t, "/path?tail=&tail_offset=-1")
	t.Check(response.StatusCode, check.Equals, 500)
	t.Check(body, check.Matches, ".*Tail offset must be a positive integer.*")
}
Пример #28
0
func (s *StreamHandlerSuite) TestStreamUntilRemoved(c *check.C) {
	var l string
	var err error

	// Create a second file in the same directory
	tbd := filepath.Join(filepath.Dir(s.FileName), "to_be_deleted")
	_, err = os.Create(tbd)
	c.Check(err, check.IsNil)

	res := s.Get(c)
	c.Check(res.StatusCode, check.Equals, 200)

	r := bufio.NewReader(res.Body)

	// Write before remove
	s.Printf(c, "hello\n")

	// Remove second file - this should not cause a fail
	err = os.Remove(tbd)
	c.Check(err, check.IsNil)

	// Read bytes written before remove
	l, err = r.ReadString('\n')
	c.Check(err, check.IsNil)
	c.Check(l, check.Equals, "hello\n")

	// Remove
	err = os.Remove(s.FileName)
	c.Assert(err, check.IsNil)

	// Read EOF
	l, err = r.ReadString('\n')
	c.Check(err, check.Not(check.IsNil))
	c.Check(l, check.Equals, "")
}
Пример #29
0
func (cs *ContainerdSuite) TestRestart(t *check.C) {
	bundleName := "busybox-top"
	if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil {
		t.Fatal(err)
	}

	totalCtr := 10

	for i := 0; i < totalCtr; i++ {
		containerID := fmt.Sprintf("top%d", i)
		c, err := cs.StartContainer(containerID, bundleName)
		if err != nil {
			t.Fatal(err)
		}

		e := c.GetNextEvent()

		t.Assert(*e, checker.Equals, types.Event{
			Type:      "start-container",
			Id:        containerID,
			Status:    0,
			Pid:       "",
			Timestamp: e.Timestamp,
		})
	}

	// restart daemon gracefully (SIGINT)
	cs.RestartDaemon(false)

	// check that status is running
	containers, err := cs.ListRunningContainers()
	if err != nil {
		t.Fatal(err)
	}
	sortContainers(containers)
	t.Assert(len(containers), checker.Equals, totalCtr)
	for i := 0; i < totalCtr; i++ {
		t.Assert(containers[i].Id, checker.Equals, fmt.Sprintf("top%d", i))
		t.Assert(containers[i].Status, checker.Equals, "running")
	}

	// Now kill daemon (SIGKILL)
	cs.StopDaemon(true)

	// Sleep a second to allow thevent e timestamp to change since
	// it's second based
	<-time.After(3 * time.Second)

	// Kill a couple of containers
	killedCtr := map[int]bool{4: true, 2: true}

	var f func(*types.Event)
	deathChans := make([]chan error, len(killedCtr))
	deathChansIdx := 0

	for i := range killedCtr {
		ch := make(chan error, 1)
		deathChans[deathChansIdx] = ch
		deathChansIdx++
		syscall.Kill(int(containers[i].Pids[0]), syscall.SIGKILL)

		// Filter to be notified of their death
		containerID := fmt.Sprintf("top%d", i)
		f = func(event *types.Event) {
			expectedEvent := types.Event{
				Type:   "exit",
				Id:     containerID,
				Status: 137,
				Pid:    "init",
			}
			expectedEvent.Timestamp = event.Timestamp
			if ok := t.Check(*event, checker.Equals, expectedEvent); !ok {
				ch <- fmt.Errorf("Unexpected event: %#v", *event)
			} else {
				ch <- nil
			}
		}
		cs.SetContainerEventFilter(containerID, f)
	}

	cs.RestartDaemon(true)

	// Ensure we got our events
	for i := range deathChans {
		done := false
		for done == false {
			select {
			case err := <-deathChans[i]:
				t.Assert(err, checker.Equals, nil)
				done = true
			case <-time.After(3 * time.Second):
				t.Fatal("Exit event for container not received after 3 seconds")
			}
		}
	}

	// check that status is running
	containers, err = cs.ListRunningContainers()
	if err != nil {
		t.Fatal(err)
	}
	sortContainers(containers)
	t.Assert(len(containers), checker.Equals, totalCtr-len(killedCtr))
	idShift := 0
	for i := 0; i < totalCtr-len(killedCtr); i++ {
		if _, ok := killedCtr[i+idShift]; ok {
			idShift++
		}
		t.Assert(containers[i].Id, checker.Equals, fmt.Sprintf("top%d", i+idShift))
		t.Assert(containers[i].Status, checker.Equals, "running")
	}
}