mirror of
https://github.com/genuinetools/reg.git
synced 2024-08-21 06:10:23 -04:00
304 lines
7.1 KiB
Go
304 lines
7.1 KiB
Go
package container // import "github.com/docker/docker/integration/container"
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/api/types/network"
|
|
ctr "github.com/docker/docker/integration/internal/container"
|
|
"github.com/docker/docker/internal/test/request"
|
|
"github.com/docker/docker/oci"
|
|
"gotest.tools/assert"
|
|
is "gotest.tools/assert/cmp"
|
|
"gotest.tools/poll"
|
|
"gotest.tools/skip"
|
|
)
|
|
|
|
func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
|
|
defer setupTest(t)()
|
|
client := request.NewAPIClient(t)
|
|
|
|
testCases := []struct {
|
|
doc string
|
|
image string
|
|
expectedError string
|
|
}{
|
|
{
|
|
doc: "image and tag",
|
|
image: "test456:v1",
|
|
expectedError: "No such image: test456:v1",
|
|
},
|
|
{
|
|
doc: "image no tag",
|
|
image: "test456",
|
|
expectedError: "No such image: test456",
|
|
},
|
|
{
|
|
doc: "digest",
|
|
image: "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
|
|
expectedError: "No such image: sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.doc, func(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := client.ContainerCreate(context.Background(),
|
|
&container.Config{Image: tc.image},
|
|
&container.HostConfig{},
|
|
&network.NetworkingConfig{},
|
|
"",
|
|
)
|
|
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCreateWithInvalidEnv(t *testing.T) {
|
|
defer setupTest(t)()
|
|
client := request.NewAPIClient(t)
|
|
|
|
testCases := []struct {
|
|
env string
|
|
expectedError string
|
|
}{
|
|
{
|
|
env: "",
|
|
expectedError: "invalid environment variable:",
|
|
},
|
|
{
|
|
env: "=",
|
|
expectedError: "invalid environment variable: =",
|
|
},
|
|
{
|
|
env: "=foo",
|
|
expectedError: "invalid environment variable: =foo",
|
|
},
|
|
}
|
|
|
|
for index, tc := range testCases {
|
|
tc := tc
|
|
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := client.ContainerCreate(context.Background(),
|
|
&container.Config{
|
|
Image: "busybox",
|
|
Env: []string{tc.env},
|
|
},
|
|
&container.HostConfig{},
|
|
&network.NetworkingConfig{},
|
|
"",
|
|
)
|
|
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test case for #30166 (target was not validated)
|
|
func TestCreateTmpfsMountsTarget(t *testing.T) {
|
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
|
|
|
defer setupTest(t)()
|
|
client := request.NewAPIClient(t)
|
|
|
|
testCases := []struct {
|
|
target string
|
|
expectedError string
|
|
}{
|
|
{
|
|
target: ".",
|
|
expectedError: "mount path must be absolute",
|
|
},
|
|
{
|
|
target: "foo",
|
|
expectedError: "mount path must be absolute",
|
|
},
|
|
{
|
|
target: "/",
|
|
expectedError: "destination can't be '/'",
|
|
},
|
|
{
|
|
target: "//",
|
|
expectedError: "destination can't be '/'",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
_, err := client.ContainerCreate(context.Background(),
|
|
&container.Config{
|
|
Image: "busybox",
|
|
},
|
|
&container.HostConfig{
|
|
Tmpfs: map[string]string{tc.target: ""},
|
|
},
|
|
&network.NetworkingConfig{},
|
|
"",
|
|
)
|
|
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
|
}
|
|
}
|
|
func TestCreateWithCustomMaskedPaths(t *testing.T) {
|
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
|
|
|
defer setupTest(t)()
|
|
client := request.NewAPIClient(t)
|
|
ctx := context.Background()
|
|
|
|
testCases := []struct {
|
|
maskedPaths []string
|
|
expected []string
|
|
}{
|
|
{
|
|
maskedPaths: []string{},
|
|
expected: []string{},
|
|
},
|
|
{
|
|
maskedPaths: nil,
|
|
expected: oci.DefaultSpec().Linux.MaskedPaths,
|
|
},
|
|
{
|
|
maskedPaths: []string{"/proc/kcore", "/proc/keys"},
|
|
expected: []string{"/proc/kcore", "/proc/keys"},
|
|
},
|
|
}
|
|
|
|
checkInspect := func(t *testing.T, ctx context.Context, name string, expected []string) {
|
|
_, b, err := client.ContainerInspectWithRaw(ctx, name, false)
|
|
assert.NilError(t, err)
|
|
|
|
var inspectJSON map[string]interface{}
|
|
err = json.Unmarshal(b, &inspectJSON)
|
|
assert.NilError(t, err)
|
|
|
|
cfg, ok := inspectJSON["HostConfig"].(map[string]interface{})
|
|
assert.Check(t, is.Equal(true, ok), name)
|
|
|
|
maskedPaths, ok := cfg["MaskedPaths"].([]interface{})
|
|
assert.Check(t, is.Equal(true, ok), name)
|
|
|
|
mps := []string{}
|
|
for _, mp := range maskedPaths {
|
|
mps = append(mps, mp.(string))
|
|
}
|
|
|
|
assert.DeepEqual(t, expected, mps)
|
|
}
|
|
|
|
for i, tc := range testCases {
|
|
name := fmt.Sprintf("create-masked-paths-%d", i)
|
|
config := container.Config{
|
|
Image: "busybox",
|
|
Cmd: []string{"true"},
|
|
}
|
|
hc := container.HostConfig{}
|
|
if tc.maskedPaths != nil {
|
|
hc.MaskedPaths = tc.maskedPaths
|
|
}
|
|
|
|
// Create the container.
|
|
c, err := client.ContainerCreate(context.Background(),
|
|
&config,
|
|
&hc,
|
|
&network.NetworkingConfig{},
|
|
name,
|
|
)
|
|
assert.NilError(t, err)
|
|
|
|
checkInspect(t, ctx, name, tc.expected)
|
|
|
|
// Start the container.
|
|
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
|
|
assert.NilError(t, err)
|
|
|
|
poll.WaitOn(t, ctr.IsInState(ctx, client, c.ID, "exited"), poll.WithDelay(100*time.Millisecond))
|
|
|
|
checkInspect(t, ctx, name, tc.expected)
|
|
}
|
|
}
|
|
|
|
func TestCreateWithCustomReadonlyPaths(t *testing.T) {
|
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
|
|
|
defer setupTest(t)()
|
|
client := request.NewAPIClient(t)
|
|
ctx := context.Background()
|
|
|
|
testCases := []struct {
|
|
doc string
|
|
readonlyPaths []string
|
|
expected []string
|
|
}{
|
|
{
|
|
readonlyPaths: []string{},
|
|
expected: []string{},
|
|
},
|
|
{
|
|
readonlyPaths: nil,
|
|
expected: oci.DefaultSpec().Linux.ReadonlyPaths,
|
|
},
|
|
{
|
|
readonlyPaths: []string{"/proc/asound", "/proc/bus"},
|
|
expected: []string{"/proc/asound", "/proc/bus"},
|
|
},
|
|
}
|
|
|
|
checkInspect := func(t *testing.T, ctx context.Context, name string, expected []string) {
|
|
_, b, err := client.ContainerInspectWithRaw(ctx, name, false)
|
|
assert.NilError(t, err)
|
|
|
|
var inspectJSON map[string]interface{}
|
|
err = json.Unmarshal(b, &inspectJSON)
|
|
assert.NilError(t, err)
|
|
|
|
cfg, ok := inspectJSON["HostConfig"].(map[string]interface{})
|
|
assert.Check(t, is.Equal(true, ok), name)
|
|
|
|
readonlyPaths, ok := cfg["ReadonlyPaths"].([]interface{})
|
|
assert.Check(t, is.Equal(true, ok), name)
|
|
|
|
rops := []string{}
|
|
for _, rop := range readonlyPaths {
|
|
rops = append(rops, rop.(string))
|
|
}
|
|
assert.DeepEqual(t, expected, rops)
|
|
}
|
|
|
|
for i, tc := range testCases {
|
|
name := fmt.Sprintf("create-readonly-paths-%d", i)
|
|
config := container.Config{
|
|
Image: "busybox",
|
|
Cmd: []string{"true"},
|
|
}
|
|
hc := container.HostConfig{}
|
|
if tc.readonlyPaths != nil {
|
|
hc.ReadonlyPaths = tc.readonlyPaths
|
|
}
|
|
|
|
// Create the container.
|
|
c, err := client.ContainerCreate(context.Background(),
|
|
&config,
|
|
&hc,
|
|
&network.NetworkingConfig{},
|
|
name,
|
|
)
|
|
assert.NilError(t, err)
|
|
|
|
checkInspect(t, ctx, name, tc.expected)
|
|
|
|
// Start the container.
|
|
err = client.ContainerStart(ctx, c.ID, types.ContainerStartOptions{})
|
|
assert.NilError(t, err)
|
|
|
|
poll.WaitOn(t, ctr.IsInState(ctx, client, c.ID, "exited"), poll.WithDelay(100*time.Millisecond))
|
|
|
|
checkInspect(t, ctx, name, tc.expected)
|
|
}
|
|
}
|