Files
moby/daemon/cluster/executor/container/container_test.go
Derek McGowan afd6487b2e Create github.com/moby/moby/api module
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-07-21 09:30:05 -07:00

216 lines
5.6 KiB
Go

package container
import (
"testing"
"github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/mount"
swarmapi "github.com/moby/swarmkit/v2/api"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestIsolationConversion(t *testing.T) {
tests := []struct {
name string
from swarmapi.ContainerSpec_Isolation
to container.Isolation
}{
{name: "default", from: swarmapi.ContainerIsolationDefault, to: container.IsolationDefault},
{name: "process", from: swarmapi.ContainerIsolationProcess, to: container.IsolationProcess},
{name: "hyperv", from: swarmapi.ContainerIsolationHyperV, to: container.IsolationHyperV},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
task := swarmapi.Task{
Spec: swarmapi.TaskSpec{
Runtime: &swarmapi.TaskSpec_Container{
Container: &swarmapi.ContainerSpec{
Image: "alpine:latest",
Isolation: tc.from,
},
},
},
}
config := containerConfig{task: &task}
// NOTE(dperny): you shouldn't ever pass nil outside of testing,
// because if there are CSI volumes, the code will panic. However,
// in testing. this is acceptable.
assert.Equal(t, tc.to, config.hostConfig(nil).Isolation)
})
}
}
func TestContainerLabels(t *testing.T) {
c := &containerConfig{
task: &swarmapi.Task{
ID: "real-task.id",
Spec: swarmapi.TaskSpec{
Runtime: &swarmapi.TaskSpec_Container{
Container: &swarmapi.ContainerSpec{
Labels: map[string]string{
"com.docker.swarm.task": "user-specified-task",
"com.docker.swarm.task.id": "user-specified-task.id",
"com.docker.swarm.task.name": "user-specified-task.name",
"com.docker.swarm.node.id": "user-specified-node.id",
"com.docker.swarm.service.id": "user-specified-service.id",
"com.docker.swarm.service.name": "user-specified-service.name",
"this-is-a-user-label": "this is a user label's value",
},
},
},
},
ServiceID: "real-service.id",
Slot: 123,
NodeID: "real-node.id",
Annotations: swarmapi.Annotations{
Name: "real-service.name.123.real-task.id",
},
ServiceAnnotations: swarmapi.Annotations{
Name: "real-service.name",
},
},
}
expected := map[string]string{
"com.docker.swarm.task": "",
"com.docker.swarm.task.id": "real-task.id",
"com.docker.swarm.task.name": "real-service.name.123.real-task.id",
"com.docker.swarm.node.id": "real-node.id",
"com.docker.swarm.service.id": "real-service.id",
"com.docker.swarm.service.name": "real-service.name",
"this-is-a-user-label": "this is a user label's value",
}
labels := c.labels()
assert.DeepEqual(t, expected, labels)
}
func TestCredentialSpecConversion(t *testing.T) {
tests := []struct {
name string
from swarmapi.Privileges_CredentialSpec
to []string
}{
{
name: "none",
from: swarmapi.Privileges_CredentialSpec{},
to: nil,
},
{
name: "config",
from: swarmapi.Privileges_CredentialSpec{
Source: &swarmapi.Privileges_CredentialSpec_Config{Config: "0bt9dmxjvjiqermk6xrop3ekq"},
},
to: []string{"credentialspec=config://0bt9dmxjvjiqermk6xrop3ekq"},
},
{
name: "file",
from: swarmapi.Privileges_CredentialSpec{
Source: &swarmapi.Privileges_CredentialSpec_File{File: "foo.json"},
},
to: []string{"credentialspec=file://foo.json"},
},
{
name: "registry",
from: swarmapi.Privileges_CredentialSpec{
Source: &swarmapi.Privileges_CredentialSpec_Registry{Registry: "testing"},
},
to: []string{"credentialspec=registry://testing"},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
task := swarmapi.Task{
Spec: swarmapi.TaskSpec{
Runtime: &swarmapi.TaskSpec_Container{
Container: &swarmapi.ContainerSpec{
Privileges: &swarmapi.Privileges{
CredentialSpec: &tc.from,
},
},
},
},
}
config := containerConfig{task: &task}
// NOTE(dperny): you shouldn't ever pass nil outside of testing,
// because if there are CSI volumes, the code will panic. However,
// in testing. this is acceptable.
assert.DeepEqual(t, tc.to, config.hostConfig(nil).SecurityOpt)
})
}
}
func TestTmpfsConversion(t *testing.T) {
tests := []struct {
name string
from []swarmapi.Mount
to []mount.Mount
}{
{
name: "tmpfs-exec",
from: []swarmapi.Mount{
{
Source: "/foo",
Target: "/bar",
Type: swarmapi.MountTypeTmpfs,
TmpfsOptions: &swarmapi.Mount_TmpfsOptions{
Options: "[[\"exec\"]]",
},
},
},
to: []mount.Mount{
{
Source: "/foo",
Target: "/bar",
Type: mount.TypeTmpfs,
TmpfsOptions: &mount.TmpfsOptions{
Options: [][]string{{"exec"}},
},
},
},
},
{
name: "tmpfs-noexec",
from: []swarmapi.Mount{
{
Source: "/foo",
Target: "/bar",
Type: swarmapi.MountTypeTmpfs,
TmpfsOptions: &swarmapi.Mount_TmpfsOptions{
Options: "[[\"noexec\"]]",
},
},
},
to: []mount.Mount{
{
Source: "/foo",
Target: "/bar",
Type: mount.TypeTmpfs,
TmpfsOptions: &mount.TmpfsOptions{
Options: [][]string{{"noexec"}},
},
},
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
task := swarmapi.Task{
Spec: swarmapi.TaskSpec{
Runtime: &swarmapi.TaskSpec_Container{
Container: &swarmapi.ContainerSpec{
Image: "alpine:latest",
Mounts: tc.from,
},
},
},
}
config := containerConfig{task: &task}
assert.Check(t, is.DeepEqual(tc.to, config.hostConfig(nil).Mounts))
})
}
}