4785f1a7 |
// +build !windows |
ed39fbeb |
|
e0af23dc |
package daemon |
ed39fbeb |
import ( |
b6e5ea8e |
"errors" |
e0af23dc |
"io/ioutil"
"os" |
dc712b92 |
"path/filepath" |
ed39fbeb |
"testing"
|
91e197d6 |
containertypes "github.com/docker/docker/api/types/container" |
42f2621b |
"github.com/docker/docker/container" |
db63f937 |
"github.com/docker/docker/daemon/config" |
09cd96c5 |
"github.com/docker/docker/pkg/idtools" |
dc712b92 |
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/drivers"
"github.com/docker/docker/volume/local"
"github.com/docker/docker/volume/store" |
09652bf8 |
"github.com/stretchr/testify/require" |
ed39fbeb |
)
|
b6e5ea8e |
type fakeContainerGetter struct {
containers map[string]*container.Container
}
func (f *fakeContainerGetter) GetContainer(cid string) (*container.Container, error) {
container, ok := f.containers[cid]
if !ok {
return nil, errors.New("container not found")
}
return container, nil
}
// Unix test as uses settings which are not available on Windows
func TestAdjustSharedNamespaceContainerName(t *testing.T) {
fakeID := "abcdef1234567890"
hostConfig := &containertypes.HostConfig{
IpcMode: containertypes.IpcMode("container:base"),
PidMode: containertypes.PidMode("container:base"),
NetworkMode: containertypes.NetworkMode("container:base"),
}
containerStore := &fakeContainerGetter{}
containerStore.containers = make(map[string]*container.Container)
containerStore.containers["base"] = &container.Container{
ID: fakeID,
}
adaptSharedNamespaceContainer(containerStore, hostConfig)
if hostConfig.IpcMode != containertypes.IpcMode("container:"+fakeID) {
t.Errorf("Expected IpcMode to be container:%s", fakeID)
}
if hostConfig.PidMode != containertypes.PidMode("container:"+fakeID) {
t.Errorf("Expected PidMode to be container:%s", fakeID)
}
if hostConfig.NetworkMode != containertypes.NetworkMode("container:"+fakeID) {
t.Errorf("Expected NetworkMode to be container:%s", fakeID)
}
}
|
42f2621b |
// Unix test as uses settings which are not available on Windows |
e0af23dc |
func TestAdjustCPUShares(t *testing.T) {
tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
daemon := &Daemon{
repository: tmp,
root: tmp,
}
|
42f2621b |
hostConfig := &containertypes.HostConfig{
Resources: containertypes.Resources{CPUShares: linuxMinCPUShares - 1}, |
ed39fbeb |
} |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, true) |
351f6b8e |
if hostConfig.CPUShares != linuxMinCPUShares {
t.Errorf("Expected CPUShares to be %d", linuxMinCPUShares) |
ed39fbeb |
}
|
351f6b8e |
hostConfig.CPUShares = linuxMaxCPUShares + 1 |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, true) |
351f6b8e |
if hostConfig.CPUShares != linuxMaxCPUShares {
t.Errorf("Expected CPUShares to be %d", linuxMaxCPUShares) |
ed39fbeb |
}
|
5170a2c0 |
hostConfig.CPUShares = 0 |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, true) |
5170a2c0 |
if hostConfig.CPUShares != 0 { |
351f6b8e |
t.Error("Expected CPUShares to be unchanged") |
ed39fbeb |
}
|
5170a2c0 |
hostConfig.CPUShares = 1024 |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, true) |
5170a2c0 |
if hostConfig.CPUShares != 1024 { |
351f6b8e |
t.Error("Expected CPUShares to be unchanged") |
ed39fbeb |
}
}
|
42f2621b |
// Unix test as uses settings which are not available on Windows |
351f6b8e |
func TestAdjustCPUSharesNoAdjustment(t *testing.T) { |
e0af23dc |
tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
daemon := &Daemon{
repository: tmp,
root: tmp,
}
|
42f2621b |
hostConfig := &containertypes.HostConfig{
Resources: containertypes.Resources{CPUShares: linuxMinCPUShares - 1}, |
ed39fbeb |
} |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, false) |
351f6b8e |
if hostConfig.CPUShares != linuxMinCPUShares-1 {
t.Errorf("Expected CPUShares to be %d", linuxMinCPUShares-1) |
ed39fbeb |
}
|
351f6b8e |
hostConfig.CPUShares = linuxMaxCPUShares + 1 |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, false) |
351f6b8e |
if hostConfig.CPUShares != linuxMaxCPUShares+1 {
t.Errorf("Expected CPUShares to be %d", linuxMaxCPUShares+1) |
ed39fbeb |
}
|
5170a2c0 |
hostConfig.CPUShares = 0 |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, false) |
5170a2c0 |
if hostConfig.CPUShares != 0 { |
351f6b8e |
t.Error("Expected CPUShares to be unchanged") |
ed39fbeb |
}
|
5170a2c0 |
hostConfig.CPUShares = 1024 |
e0af23dc |
daemon.adaptContainerSettings(hostConfig, false) |
5170a2c0 |
if hostConfig.CPUShares != 1024 { |
351f6b8e |
t.Error("Expected CPUShares to be unchanged") |
ed39fbeb |
}
} |
42f2621b |
// Unix test as uses settings which are not available on Windows |
cb9aeb04 |
func TestParseSecurityOptWithDeprecatedColon(t *testing.T) { |
42f2621b |
container := &container.Container{}
config := &containertypes.HostConfig{}
// test apparmor |
cb9aeb04 |
config.SecurityOpt = []string{"apparmor=test_profile"} |
42f2621b |
if err := parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected parseSecurityOpt error: %v", err)
}
if container.AppArmorProfile != "test_profile" {
t.Fatalf("Unexpected AppArmorProfile, expected: \"test_profile\", got %q", container.AppArmorProfile)
}
// test seccomp
sp := "/path/to/seccomp_test.json" |
cb9aeb04 |
config.SecurityOpt = []string{"seccomp=" + sp} |
42f2621b |
if err := parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected parseSecurityOpt error: %v", err)
}
if container.SeccompProfile != sp {
t.Fatalf("Unexpected AppArmorProfile, expected: %q, got %q", sp, container.SeccompProfile)
}
// test valid label |
cb9aeb04 |
config.SecurityOpt = []string{"label=user:USER"}
if err := parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected parseSecurityOpt error: %v", err)
}
// test invalid label
config.SecurityOpt = []string{"label"}
if err := parseSecurityOpt(container, config); err == nil {
t.Fatal("Expected parseSecurityOpt error, got nil")
}
// test invalid opt
config.SecurityOpt = []string{"test"}
if err := parseSecurityOpt(container, config); err == nil {
t.Fatal("Expected parseSecurityOpt error, got nil")
}
}
func TestParseSecurityOpt(t *testing.T) {
container := &container.Container{}
config := &containertypes.HostConfig{}
// test apparmor
config.SecurityOpt = []string{"apparmor=test_profile"}
if err := parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected parseSecurityOpt error: %v", err)
}
if container.AppArmorProfile != "test_profile" {
t.Fatalf("Unexpected AppArmorProfile, expected: \"test_profile\", got %q", container.AppArmorProfile)
}
// test seccomp
sp := "/path/to/seccomp_test.json"
config.SecurityOpt = []string{"seccomp=" + sp}
if err := parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected parseSecurityOpt error: %v", err)
}
if container.SeccompProfile != sp {
t.Fatalf("Unexpected SeccompProfile, expected: %q, got %q", sp, container.SeccompProfile)
}
// test valid label
config.SecurityOpt = []string{"label=user:USER"} |
42f2621b |
if err := parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected parseSecurityOpt error: %v", err)
}
// test invalid label
config.SecurityOpt = []string{"label"}
if err := parseSecurityOpt(container, config); err == nil {
t.Fatal("Expected parseSecurityOpt error, got nil")
}
// test invalid opt
config.SecurityOpt = []string{"test"}
if err := parseSecurityOpt(container, config); err == nil {
t.Fatal("Expected parseSecurityOpt error, got nil")
}
}
|
d7fda019 |
func TestParseNNPSecurityOptions(t *testing.T) {
daemon := &Daemon{
configStore: &config.Config{NoNewPrivileges: true},
}
container := &container.Container{}
config := &containertypes.HostConfig{}
// test NNP when "daemon:true" and "no-new-privileges=false""
config.SecurityOpt = []string{"no-new-privileges=false"}
if err := daemon.parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected daemon.parseSecurityOpt error: %v", err)
}
if container.NoNewPrivileges {
t.Fatalf("container.NoNewPrivileges should be FALSE: %v", container.NoNewPrivileges)
}
// test NNP when "daemon:false" and "no-new-privileges=true""
daemon.configStore.NoNewPrivileges = false
config.SecurityOpt = []string{"no-new-privileges=true"}
if err := daemon.parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected daemon.parseSecurityOpt error: %v", err)
}
if !container.NoNewPrivileges {
t.Fatalf("container.NoNewPrivileges should be TRUE: %v", container.NoNewPrivileges)
}
}
|
42f2621b |
func TestNetworkOptions(t *testing.T) {
daemon := &Daemon{} |
db63f937 |
dconfigCorrect := &config.Config{
CommonConfig: config.CommonConfig{ |
42f2621b |
ClusterStore: "consul://localhost:8500",
ClusterAdvertise: "192.168.0.1:8000",
},
}
|
a00940f0 |
if _, err := daemon.networkOptions(dconfigCorrect, nil, nil); err != nil { |
2eee6133 |
t.Fatalf("Expect networkOptions success, got error: %v", err) |
42f2621b |
}
|
db63f937 |
dconfigWrong := &config.Config{
CommonConfig: config.CommonConfig{ |
42f2621b |
ClusterStore: "consul://localhost:8500://test://bbb",
},
}
|
a00940f0 |
if _, err := daemon.networkOptions(dconfigWrong, nil, nil); err == nil { |
2a8d6368 |
t.Fatal("Expected networkOptions error, got nil") |
42f2621b |
}
} |
dc712b92 |
func TestMigratePre17Volumes(t *testing.T) {
rootDir, err := ioutil.TempDir("", "test-daemon-volumes")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(rootDir)
volumeRoot := filepath.Join(rootDir, "volumes")
err = os.MkdirAll(volumeRoot, 0755)
if err != nil {
t.Fatal(err)
}
containerRoot := filepath.Join(rootDir, "containers")
cid := "1234"
err = os.MkdirAll(filepath.Join(containerRoot, cid), 0755) |
09652bf8 |
require.NoError(t, err) |
dc712b92 |
vid := "5678"
vfsPath := filepath.Join(rootDir, "vfs", "dir", vid)
err = os.MkdirAll(vfsPath, 0755) |
09652bf8 |
require.NoError(t, err) |
dc712b92 |
config := []byte(`
{
"ID": "` + cid + `",
"Volumes": {
"/foo": "` + vfsPath + `",
"/bar": "/foo",
"/quux": "/quux"
},
"VolumesRW": {
"/foo": true,
"/bar": true,
"/quux": false
}
}
`)
volStore, err := store.New(volumeRoot)
if err != nil {
t.Fatal(err)
} |
09cd96c5 |
drv, err := local.New(volumeRoot, idtools.IDPair{UID: 0, GID: 0}) |
dc712b92 |
if err != nil {
t.Fatal(err)
}
volumedrivers.Register(drv, volume.DefaultDriverName)
|
edad5270 |
daemon := &Daemon{ |
76d96418 |
root: rootDir,
repository: containerRoot,
volumes: volStore, |
edad5270 |
} |
dc712b92 |
err = ioutil.WriteFile(filepath.Join(containerRoot, cid, "config.v2.json"), config, 600)
if err != nil {
t.Fatal(err)
}
c, err := daemon.load(cid)
if err != nil {
t.Fatal(err)
}
if err := daemon.verifyVolumesInfo(c); err != nil {
t.Fatal(err)
}
expected := map[string]volume.MountPoint{
"/foo": {Destination: "/foo", RW: true, Name: vid},
"/bar": {Source: "/foo", Destination: "/bar", RW: true},
"/quux": {Source: "/quux", Destination: "/quux", RW: false},
}
for id, mp := range c.MountPoints {
x, exists := expected[id]
if !exists {
t.Fatal("volume not migrated")
}
if mp.Source != x.Source || mp.Destination != x.Destination || mp.RW != x.RW || mp.Name != x.Name {
t.Fatalf("got unexpected mountpoint, expected: %+v, got: %+v", x, mp)
}
}
} |