Merge component 'engine' from git@github.com:moby/moby master

This commit is contained in:
GordonTheTurtle
2018-02-12 17:05:46 +00:00
15 changed files with 339 additions and 255 deletions
@@ -26,7 +26,7 @@ import (
// We'll also end up with many tasks all pointing to the same plugin ID.
//
// TODO(@cpuguy83): registry auth is intentionally not supported until we work out
// the right way to pass registry crednetials via secrets.
// the right way to pass registry credentials via secrets.
type Controller struct {
backend Backend
spec runtime.PluginSpec
@@ -409,7 +409,7 @@ func (d *Driver) terminateServiceVM(id, context string, force bool) (err error)
svm.signalStopFinished(err)
}()
// Now it's possible that the serivce VM failed to start and now we are trying to termiante it.
// Now it's possible that the serivce VM failed to start and now we are trying to terminate it.
// In this case, we will relay the error to the goroutines waiting for this vm to stop.
if err := svm.getStartError(); err != nil {
logrus.Debugf("lcowdriver: terminateservicevm: %s had failed to start up: %s", id, err)
+2 -2
View File
@@ -42,7 +42,7 @@ func PutMessage(msg *Message) {
messagePool.Put(msg)
}
// Message is datastructure that represents piece of output produced by some
// Message is data structure that represents piece of output produced by some
// container. The Line member is a slice of an array whose contents can be
// changed after a log driver's Log() method returns.
//
@@ -133,7 +133,7 @@ func (w *LogWatcher) WatchClose() <-chan struct{} {
return w.closeNotifier
}
// Capability defines the list of capabilties that a driver can implement
// Capability defines the list of capabilities that a driver can implement
// These capabilities are not required to be a logging driver, however do
// determine how a logging driver can be used
type Capability struct {
@@ -1,48 +0,0 @@
package main
import (
"net/http"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/request"
"github.com/go-check/check"
)
func (s *DockerSuite) TestSessionCreate(c *check.C) {
testRequires(c, ExperimentalDaemon)
res, body, err := request.Post("/session", func(r *http.Request) error {
r.Header.Set("X-Docker-Expose-Session-Uuid", "testsessioncreate") // so we don't block default name if something else is using it
r.Header.Set("Upgrade", "h2c")
return nil
})
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusSwitchingProtocols)
c.Assert(res.Header.Get("Upgrade"), checker.Equals, "h2c")
c.Assert(body.Close(), checker.IsNil)
}
func (s *DockerSuite) TestSessionCreateWithBadUpgrade(c *check.C) {
testRequires(c, ExperimentalDaemon)
res, body, err := request.Post("/session")
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
buf, err := request.ReadBody(body)
c.Assert(err, checker.IsNil)
out := string(buf)
c.Assert(out, checker.Contains, "no upgrade")
res, body, err = request.Post("/session", func(r *http.Request) error {
r.Header.Set("Upgrade", "foo")
return nil
})
c.Assert(err, checker.IsNil)
c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
buf, err = request.ReadBody(body)
c.Assert(err, checker.IsNil)
out = string(buf)
c.Assert(out, checker.Contains, "not supported")
}
@@ -1,78 +0,0 @@
package main
import (
"strings"
"time"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/cli"
"github.com/go-check/check"
)
func (s *DockerSuite) TestPause(c *check.C) {
testRequires(c, IsPausable)
name := "testeventpause"
runSleepingContainer(c, "-d", "--name", name)
cli.DockerCmd(c, "pause", name)
pausedContainers := strings.Fields(
cli.DockerCmd(c, "ps", "-f", "status=paused", "-q", "-a").Combined(),
)
c.Assert(len(pausedContainers), checker.Equals, 1)
cli.DockerCmd(c, "unpause", name)
out := cli.DockerCmd(c, "events", "--since=0", "--until", daemonUnixTime(c)).Combined()
events := strings.Split(strings.TrimSpace(out), "\n")
actions := eventActionsByIDAndType(c, events, name, "container")
c.Assert(actions[len(actions)-2], checker.Equals, "pause")
c.Assert(actions[len(actions)-1], checker.Equals, "unpause")
}
func (s *DockerSuite) TestPauseMultipleContainers(c *check.C) {
testRequires(c, IsPausable)
containers := []string{
"testpausewithmorecontainers1",
"testpausewithmorecontainers2",
}
for _, name := range containers {
runSleepingContainer(c, "-d", "--name", name)
}
cli.DockerCmd(c, append([]string{"pause"}, containers...)...)
pausedContainers := strings.Fields(
cli.DockerCmd(c, "ps", "-f", "status=paused", "-q", "-a").Combined(),
)
c.Assert(len(pausedContainers), checker.Equals, len(containers))
cli.DockerCmd(c, append([]string{"unpause"}, containers...)...)
out := cli.DockerCmd(c, "events", "--since=0", "--until", daemonUnixTime(c)).Combined()
events := strings.Split(strings.TrimSpace(out), "\n")
for _, name := range containers {
actions := eventActionsByIDAndType(c, events, name, "container")
c.Assert(actions[len(actions)-2], checker.Equals, "pause")
c.Assert(actions[len(actions)-1], checker.Equals, "unpause")
}
}
func (s *DockerSuite) TestPauseFailsOnWindowsServerContainers(c *check.C) {
testRequires(c, DaemonIsWindows, NotPausable)
runSleepingContainer(c, "-d", "--name=test")
out, _, _ := dockerCmdWithError("pause", "test")
c.Assert(out, checker.Contains, "cannot pause Windows Server Containers")
}
func (s *DockerSuite) TestStopPausedContainer(c *check.C) {
testRequires(c, DaemonIsLinux)
id := runSleepingContainer(c)
cli.WaitRun(c, id)
cli.DockerCmd(c, "pause", id)
cli.DockerCmd(c, "stop", id)
cli.WaitForInspectResult(c, id, "{{.State.Running}}", "false", 30*time.Second)
}
@@ -0,0 +1,84 @@
package container
import (
"context"
"fmt"
"io/ioutil"
"strconv"
"strings"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/integration-cli/daemon"
"github.com/stretchr/testify/assert"
"golang.org/x/sys/unix"
)
// This is a regression test for #36145
// It ensures that a container can be started when the daemon was improperly
// shutdown when the daemon is brought back up.
//
// The regression is due to improper error handling preventing a container from
// being restored and as such have the resources cleaned up.
//
// To test this, we need to kill dockerd, then kill both the containerd-shim and
// the container process, then start dockerd back up and attempt to start the
// container again.
func TestContainerStartOnDaemonRestart(t *testing.T) {
t.Parallel()
d := daemon.New(t, "", "dockerd", daemon.Config{})
d.StartWithBusybox(t, "--iptables=false")
defer d.Stop(t)
client, err := d.NewClient()
assert.NoError(t, err, "error creating client")
ctx := context.Background()
c, err := client.ContainerCreate(ctx,
&container.Config{
Image: "busybox",
Cmd: []string{"top"},
},
nil,
nil,
"",
)
assert.NoError(t, err, "error creating test container")
defer client.ContainerRemove(ctx, c.ID, types.ContainerRemoveOptions{Force: true})
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
assert.NoError(t, err, "error starting test container")
inspect, err := client.ContainerInspect(ctx, c.ID)
assert.NoError(t, err, "error getting inspect data")
ppid := getContainerdShimPid(t, inspect)
err = d.Kill()
assert.NoError(t, err, "failed to kill test daemon")
err = unix.Kill(inspect.State.Pid, unix.SIGKILL)
assert.NoError(t, err, "failed to kill container process")
err = unix.Kill(ppid, unix.SIGKILL)
assert.NoError(t, err, "failed to kill containerd-shim")
d.Start(t, "--iptables=false")
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
assert.NoError(t, err, "failed to start test container")
}
func getContainerdShimPid(t *testing.T, c types.ContainerJSON) int {
statB, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", c.State.Pid))
assert.NoError(t, err, "error looking up containerd-shim pid")
// ppid is the 4th entry in `/proc/pid/stat`
ppid, err := strconv.Atoi(strings.Fields(string(statB))[3])
assert.NoError(t, err, "error converting ppid field to int")
assert.NotEqual(t, ppid, 1, "got unexpected ppid")
return ppid
}
@@ -0,0 +1,98 @@
package container // import "github.com/docker/docker/integration/container"
import (
"context"
"io"
"testing"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/integration/internal/request"
"github.com/docker/docker/internal/testutil"
"github.com/gotestyourself/gotestyourself/poll"
"github.com/gotestyourself/gotestyourself/skip"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPause(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType == "windows" && testEnv.DaemonInfo.Isolation == "process")
defer setupTest(t)()
client := request.NewAPIClient(t)
ctx := context.Background()
name := "testeventpause"
cID := container.Run(t, ctx, client, container.WithName(name))
poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
since := request.DaemonUnixTime(ctx, t, client, testEnv)
err := client.ContainerPause(ctx, name)
require.NoError(t, err)
inspect, err := client.ContainerInspect(ctx, cID)
require.NoError(t, err)
assert.Equal(t, inspect.State.Paused, true)
err = client.ContainerUnpause(ctx, name)
require.NoError(t, err)
until := request.DaemonUnixTime(ctx, t, client, testEnv)
messages, errs := client.Events(ctx, types.EventsOptions{
Since: since,
Until: until,
Filters: filters.NewArgs(filters.Arg("container", name)),
})
assert.Equal(t, getEventActions(t, messages, errs), []string{"pause", "unpause"})
}
func TestPauseFailsOnWindowsServerContainers(t *testing.T) {
skip.If(t, (testEnv.DaemonInfo.OSType != "windows" || testEnv.DaemonInfo.Isolation != "process"))
defer setupTest(t)()
client := request.NewAPIClient(t)
ctx := context.Background()
cID := container.Run(t, ctx, client)
poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
err := client.ContainerPause(ctx, cID)
testutil.ErrorContains(t, err, "cannot pause Windows Server Containers")
}
func TestPauseStopPausedContainer(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
defer setupTest(t)()
client := request.NewAPIClient(t)
ctx := context.Background()
cID := container.Run(t, ctx, client)
poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
err := client.ContainerPause(ctx, cID)
require.NoError(t, err)
err = client.ContainerStop(ctx, cID, nil)
require.NoError(t, err)
poll.WaitOn(t, containerIsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond))
}
func getEventActions(t *testing.T, messages <-chan events.Message, errs <-chan error) []string {
actions := []string{}
for {
select {
case err := <-errs:
assert.Equal(t, err == nil || err == io.EOF, true)
return actions
case e := <-messages:
actions = append(actions, e.Status)
}
}
}
@@ -8,9 +8,8 @@ import (
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/integration/internal/request"
"github.com/gotestyourself/gotestyourself/icmd"
"github.com/gotestyourself/gotestyourself/poll"
@@ -25,23 +24,9 @@ func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
names := []string{"verifyRestart1", "verifyRestart2"}
for _, name := range names {
resp, err := client.ContainerCreate(ctx,
&container.Config{
Cmd: []string{"false"},
Image: "busybox",
},
&container.HostConfig{
RestartPolicy: container.RestartPolicy{
Name: "always",
},
},
&network.NetworkingConfig{},
name,
)
require.NoError(t, err)
err = client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
require.NoError(t, err)
container.Run(t, ctx, client, container.WithName(name), container.WithCmd("false"), func(c *container.TestContainerConfig) {
c.HostConfig.RestartPolicy.Name = "always"
})
}
for _, name := range names {
@@ -65,25 +50,13 @@ func TestDeleteDevicemapper(t *testing.T) {
client := request.NewAPIClient(t)
ctx := context.Background()
foo, err := client.ContainerCreate(ctx,
&container.Config{
Cmd: []string{"echo"},
Image: "busybox",
},
&container.HostConfig{},
&network.NetworkingConfig{},
"foo",
)
require.NoError(t, err)
id := container.Run(t, ctx, client, container.WithName("foo"), container.WithCmd("echo"))
err = client.ContainerStart(ctx, foo.ID, types.ContainerStartOptions{})
require.NoError(t, err)
poll.WaitOn(t, containerIsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond))
inspect, err := client.ContainerInspect(ctx, foo.ID)
inspect, err := client.ContainerInspect(ctx, id)
require.NoError(t, err)
poll.WaitOn(t, containerIsStopped(ctx, client, foo.ID), poll.WithDelay(100*time.Millisecond))
deviceID := inspect.GraphDriver.Data["DeviceId"]
// Find pool name from device name
@@ -94,7 +67,7 @@ func TestDeleteDevicemapper(t *testing.T) {
result := icmd.RunCommand("dmsetup", "message", devicePool, "0", fmt.Sprintf("delete %s", deviceID))
result.Assert(t, icmd.Success)
err = client.ContainerRemove(ctx, foo.ID, types.ContainerRemoveOptions{})
err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{})
require.NoError(t, err)
}
@@ -3,7 +3,6 @@ package container // import "github.com/docker/docker/integration/container"
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"strconv"
"strings"
@@ -11,9 +10,10 @@ import (
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/client"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/integration/internal/request"
"github.com/docker/docker/pkg/stdcopy"
"github.com/gotestyourself/gotestyourself/poll"
@@ -31,44 +31,32 @@ func TestUpdateMemory(t *testing.T) {
client := request.NewAPIClient(t)
ctx := context.Background()
c, err := client.ContainerCreate(ctx,
&container.Config{
Cmd: []string{"top"},
Image: "busybox",
},
&container.HostConfig{
Resources: container.Resources{
Memory: 200 * 1024 * 1024,
},
},
nil,
"",
)
require.NoError(t, err)
cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) {
c.HostConfig.Resources = containertypes.Resources{
Memory: 200 * 1024 * 1024,
}
})
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
require.NoError(t, err)
poll.WaitOn(t, containerIsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))
poll.WaitOn(t, containerIsInState(ctx, client, c.ID, "running"), poll.WithDelay(100*time.Millisecond))
_, err = client.ContainerUpdate(ctx, c.ID, container.UpdateConfig{
Resources: container.Resources{
_, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{
Resources: containertypes.Resources{
Memory: 314572800,
MemorySwap: 524288000,
},
})
require.NoError(t, err)
inspect, err := client.ContainerInspect(ctx, c.ID)
inspect, err := client.ContainerInspect(ctx, cID)
require.NoError(t, err)
assert.Equal(t, inspect.HostConfig.Memory, int64(314572800))
assert.Equal(t, inspect.HostConfig.MemorySwap, int64(524288000))
body, err := getContainerSysFSValue(ctx, client, c.ID, "/sys/fs/cgroup/memory/memory.limit_in_bytes")
body, err := getContainerSysFSValue(ctx, client, cID, "/sys/fs/cgroup/memory/memory.limit_in_bytes")
require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(body), "314572800")
body, err = getContainerSysFSValue(ctx, client, c.ID, "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes")
body, err = getContainerSysFSValue(ctx, client, cID, "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes")
require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(body), "524288000")
}
@@ -76,25 +64,11 @@ func TestUpdateMemory(t *testing.T) {
func TestUpdateCPUQUota(t *testing.T) {
t.Parallel()
defer setupTest(t)()
client := request.NewAPIClient(t)
ctx := context.Background()
c, err := client.ContainerCreate(ctx, &container.Config{
Image: "busybox",
Cmd: []string{"top"},
}, nil, nil, "")
if err != nil {
t.Fatal(err)
}
defer func() {
if err := client.ContainerRemove(ctx, c.ID, types.ContainerRemoveOptions{Force: true}); err != nil {
panic(fmt.Sprintf("failed to clean up after test: %v", err))
}
}()
if err := client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{}); err != nil {
t.Fatal(err)
}
cID := container.Run(t, ctx, client)
for _, test := range []struct {
desc string
@@ -105,15 +79,15 @@ func TestUpdateCPUQUota(t *testing.T) {
{desc: "a lower value", update: 10000},
{desc: "unset value", update: -1},
} {
if _, err := client.ContainerUpdate(ctx, c.ID, container.UpdateConfig{
Resources: container.Resources{
if _, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{
Resources: containertypes.Resources{
CPUQuota: test.update,
},
}); err != nil {
t.Fatal(err)
}
inspect, err := client.ContainerInspect(ctx, c.ID)
inspect, err := client.ContainerInspect(ctx, cID)
if err != nil {
t.Fatal(err)
}
@@ -122,7 +96,7 @@ func TestUpdateCPUQUota(t *testing.T) {
t.Fatalf("quota not updated in the API, expected %d, got: %d", test.update, inspect.HostConfig.CPUQuota)
}
execCreate, err := client.ContainerExecCreate(ctx, c.ID, types.ExecConfig{
execCreate, err := client.ContainerExecCreate(ctx, cID, types.ExecConfig{
Cmd: []string{"/bin/cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"},
AttachStdout: true,
AttachStderr: true,
@@ -1,12 +1,16 @@
package request // import "github.com/docker/docker/integration/internal/request"
import (
"fmt"
"net"
"net/http"
"testing"
"time"
"golang.org/x/net/context"
"github.com/docker/docker/client"
"github.com/docker/docker/internal/test/environment"
"github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig"
"github.com/stretchr/testify/require"
@@ -49,3 +53,24 @@ func NewTLSAPIClient(t *testing.T, host, cacertPath, certPath, keyPath string) (
}
return client.NewClientWithOpts(client.WithHost(host), client.WithHTTPClient(httpClient))
}
// daemonTime provides the current time on the daemon host
func daemonTime(ctx context.Context, t *testing.T, client client.APIClient, testEnv *environment.Execution) time.Time {
if testEnv.IsLocalDaemon() {
return time.Now()
}
info, err := client.Info(ctx)
require.NoError(t, err)
dt, err := time.Parse(time.RFC3339Nano, info.SystemTime)
require.NoError(t, err, "invalid time format in GET /info response")
return dt
}
// DaemonUnixTime returns the current time on the daemon host with nanoseconds precision.
// It return the time formatted how the client sends timestamps to the server.
func DaemonUnixTime(ctx context.Context, t *testing.T, client client.APIClient, testEnv *environment.Execution) string {
dt := daemonTime(ctx, t, client, testEnv)
return fmt.Sprintf("%d.%09d", dt.Unix(), int64(dt.Nanosecond()))
}
@@ -5,9 +5,9 @@ import (
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/integration/internal/swarm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -27,20 +27,15 @@ func TestDockerNetworkConnectAlias(t *testing.T) {
Attachable: true,
})
require.NoError(t, err)
_, err = client.ContainerCreate(ctx,
&container.Config{
Cmd: []string{"top"},
Image: "busybox",
},
&container.HostConfig{},
&network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
container.Create(t, ctx, client, container.WithName("ng1"), func(c *container.TestContainerConfig) {
c.NetworkingConfig = &network.NetworkingConfig{
map[string]*network.EndpointSettings{
name: {},
},
},
"ng1",
)
require.NoError(t, err)
}
})
err = client.NetworkConnect(ctx, name, "ng1", &network.EndpointSettings{
Aliases: []string{
"aaa",
@@ -56,20 +51,14 @@ func TestDockerNetworkConnectAlias(t *testing.T) {
assert.Equal(t, len(ng1.NetworkSettings.Networks[name].Aliases), 2)
assert.Equal(t, ng1.NetworkSettings.Networks[name].Aliases[0], "aaa")
_, err = client.ContainerCreate(ctx,
&container.Config{
Cmd: []string{"top"},
Image: "busybox",
},
&container.HostConfig{},
&network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
container.Create(t, ctx, client, container.WithName("ng2"), func(c *container.TestContainerConfig) {
c.NetworkingConfig = &network.NetworkingConfig{
map[string]*network.EndpointSettings{
name: {},
},
},
"ng2",
)
require.NoError(t, err)
}
})
err = client.NetworkConnect(ctx, name, "ng2", &network.EndpointSettings{
Aliases: []string{
"bbb",
@@ -0,0 +1,33 @@
package session // import "github.com/docker/docker/integration/session"
import (
"fmt"
"os"
"testing"
"github.com/docker/docker/internal/test/environment"
)
var testEnv *environment.Execution
func TestMain(m *testing.M) {
var err error
testEnv, err = environment.New()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = environment.EnsureFrozenImagesLinux(testEnv)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
testEnv.Print()
os.Exit(m.Run())
}
func setupTest(t *testing.T) func() {
environment.ProtectAll(t, testEnv)
return func() { testEnv.Clean(t) }
}
@@ -0,0 +1,48 @@
package session // import "github.com/docker/docker/integration/session"
import (
"net/http"
"testing"
req "github.com/docker/docker/integration-cli/request"
"github.com/gotestyourself/gotestyourself/skip"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSessionCreate(t *testing.T) {
skip.If(t, !testEnv.DaemonInfo.ExperimentalBuild)
defer setupTest(t)()
res, body, err := req.Post("/session", func(r *http.Request) error {
r.Header.Set("X-Docker-Expose-Session-Uuid", "testsessioncreate") // so we don't block default name if something else is using it
r.Header.Set("Upgrade", "h2c")
return nil
})
require.NoError(t, err)
require.NoError(t, body.Close())
assert.Equal(t, res.StatusCode, http.StatusSwitchingProtocols)
assert.Equal(t, res.Header.Get("Upgrade"), "h2c")
}
func TestSessionCreateWithBadUpgrade(t *testing.T) {
skip.If(t, !testEnv.DaemonInfo.ExperimentalBuild)
res, body, err := req.Post("/session")
require.NoError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err := req.ReadBody(body)
require.NoError(t, err)
assert.Contains(t, string(buf), "no upgrade")
res, body, err = req.Post("/session", func(r *http.Request) error {
r.Header.Set("Upgrade", "foo")
return nil
})
require.NoError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err = req.ReadBody(body)
require.NoError(t, err)
assert.Contains(t, string(buf), "not supported")
}
@@ -7,10 +7,9 @@ import (
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/integration/internal/request"
"github.com/stretchr/testify/require"
)
@@ -20,22 +19,9 @@ func TestEvents(t *testing.T) {
ctx := context.Background()
client := request.NewAPIClient(t)
container, err := client.ContainerCreate(ctx,
&container.Config{
Image: "busybox",
Tty: true,
WorkingDir: "/root",
Cmd: strslice.StrSlice([]string{"top"}),
},
&container.HostConfig{},
&network.NetworkingConfig{},
"foo",
)
require.NoError(t, err)
err = client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{})
require.NoError(t, err)
cID := container.Run(t, ctx, client)
id, err := client.ContainerExecCreate(ctx, container.ID,
id, err := client.ContainerExecCreate(ctx, cID,
types.ExecConfig{
Cmd: strslice.StrSlice([]string{"echo", "hello"}),
},
@@ -43,7 +29,7 @@ func TestEvents(t *testing.T) {
require.NoError(t, err)
filters := filters.NewArgs(
filters.Arg("container", container.ID),
filters.Arg("container", cID),
filters.Arg("event", "exec_die"),
)
msg, errors := client.Events(ctx, types.EventsOptions{
@@ -61,7 +47,7 @@ func TestEvents(t *testing.T) {
select {
case m := <-msg:
require.Equal(t, m.Type, "container")
require.Equal(t, m.Actor.ID, container.ID)
require.Equal(t, m.Actor.ID, cID)
require.Equal(t, m.Action, "exec_die")
require.Equal(t, m.Actor.Attributes["execID"], id.ID)
require.Equal(t, m.Actor.Attributes["exitCode"], "0")
@@ -159,7 +159,7 @@ func (c *client) Restore(ctx context.Context, id string, attachStdio StdioCallba
return attachStdio(dio)
}
t, err := ctr.Task(ctx, attachIO)
if err != nil && !errdefs.IsNotFound(errors.Cause(err)) {
if err != nil && !containerderrors.IsNotFound(err) {
return false, -1, err
}