| // +build !windows |
| |
| package daemon // import "github.com/docker/docker/daemon" |
| |
| import ( |
| "errors" |
| "io/ioutil" |
| "os" |
| "testing" |
| |
| containertypes "github.com/docker/docker/api/types/container" |
| "github.com/docker/docker/container" |
| "github.com/docker/docker/daemon/config" |
| ) |
| |
| 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) |
| } |
| } |
| |
| // Unix test as uses settings which are not available on Windows |
| 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, |
| } |
| |
| hostConfig := &containertypes.HostConfig{ |
| Resources: containertypes.Resources{CPUShares: linuxMinCPUShares - 1}, |
| } |
| daemon.adaptContainerSettings(hostConfig, true) |
| if hostConfig.CPUShares != linuxMinCPUShares { |
| t.Errorf("Expected CPUShares to be %d", linuxMinCPUShares) |
| } |
| |
| hostConfig.CPUShares = linuxMaxCPUShares + 1 |
| daemon.adaptContainerSettings(hostConfig, true) |
| if hostConfig.CPUShares != linuxMaxCPUShares { |
| t.Errorf("Expected CPUShares to be %d", linuxMaxCPUShares) |
| } |
| |
| hostConfig.CPUShares = 0 |
| daemon.adaptContainerSettings(hostConfig, true) |
| if hostConfig.CPUShares != 0 { |
| t.Error("Expected CPUShares to be unchanged") |
| } |
| |
| hostConfig.CPUShares = 1024 |
| daemon.adaptContainerSettings(hostConfig, true) |
| if hostConfig.CPUShares != 1024 { |
| t.Error("Expected CPUShares to be unchanged") |
| } |
| } |
| |
| // Unix test as uses settings which are not available on Windows |
| func TestAdjustCPUSharesNoAdjustment(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, |
| } |
| |
| hostConfig := &containertypes.HostConfig{ |
| Resources: containertypes.Resources{CPUShares: linuxMinCPUShares - 1}, |
| } |
| daemon.adaptContainerSettings(hostConfig, false) |
| if hostConfig.CPUShares != linuxMinCPUShares-1 { |
| t.Errorf("Expected CPUShares to be %d", linuxMinCPUShares-1) |
| } |
| |
| hostConfig.CPUShares = linuxMaxCPUShares + 1 |
| daemon.adaptContainerSettings(hostConfig, false) |
| if hostConfig.CPUShares != linuxMaxCPUShares+1 { |
| t.Errorf("Expected CPUShares to be %d", linuxMaxCPUShares+1) |
| } |
| |
| hostConfig.CPUShares = 0 |
| daemon.adaptContainerSettings(hostConfig, false) |
| if hostConfig.CPUShares != 0 { |
| t.Error("Expected CPUShares to be unchanged") |
| } |
| |
| hostConfig.CPUShares = 1024 |
| daemon.adaptContainerSettings(hostConfig, false) |
| if hostConfig.CPUShares != 1024 { |
| t.Error("Expected CPUShares to be unchanged") |
| } |
| } |
| |
| // Unix test as uses settings which are not available on Windows |
| func TestParseSecurityOptWithDeprecatedColon(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 AppArmorProfile, expected: %q, got %q", sp, container.SeccompProfile) |
| } |
| |
| // test valid label |
| 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"} |
| 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 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) |
| } |
| } |
| |
| func TestNetworkOptions(t *testing.T) { |
| daemon := &Daemon{} |
| dconfigCorrect := &config.Config{ |
| CommonConfig: config.CommonConfig{ |
| ClusterStore: "consul://localhost:8500", |
| ClusterAdvertise: "192.168.0.1:8000", |
| }, |
| } |
| |
| if _, err := daemon.networkOptions(dconfigCorrect, nil, nil); err != nil { |
| t.Fatalf("Expect networkOptions success, got error: %v", err) |
| } |
| |
| dconfigWrong := &config.Config{ |
| CommonConfig: config.CommonConfig{ |
| ClusterStore: "consul://localhost:8500://test://bbb", |
| }, |
| } |
| |
| if _, err := daemon.networkOptions(dconfigWrong, nil, nil); err == nil { |
| t.Fatal("Expected networkOptions error, got nil") |
| } |
| } |