github.com/morganxf/moby@v1.13.1/daemon/daemon_unix_test.go (about) 1 // +build !windows,!solaris 2 3 package daemon 4 5 import ( 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "testing" 10 11 containertypes "github.com/docker/docker/api/types/container" 12 "github.com/docker/docker/container" 13 "github.com/docker/docker/volume" 14 "github.com/docker/docker/volume/drivers" 15 "github.com/docker/docker/volume/local" 16 "github.com/docker/docker/volume/store" 17 ) 18 19 // Unix test as uses settings which are not available on Windows 20 func TestAdjustCPUShares(t *testing.T) { 21 tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") 22 if err != nil { 23 t.Fatal(err) 24 } 25 defer os.RemoveAll(tmp) 26 daemon := &Daemon{ 27 repository: tmp, 28 root: tmp, 29 } 30 31 hostConfig := &containertypes.HostConfig{ 32 Resources: containertypes.Resources{CPUShares: linuxMinCPUShares - 1}, 33 } 34 daemon.adaptContainerSettings(hostConfig, true) 35 if hostConfig.CPUShares != linuxMinCPUShares { 36 t.Errorf("Expected CPUShares to be %d", linuxMinCPUShares) 37 } 38 39 hostConfig.CPUShares = linuxMaxCPUShares + 1 40 daemon.adaptContainerSettings(hostConfig, true) 41 if hostConfig.CPUShares != linuxMaxCPUShares { 42 t.Errorf("Expected CPUShares to be %d", linuxMaxCPUShares) 43 } 44 45 hostConfig.CPUShares = 0 46 daemon.adaptContainerSettings(hostConfig, true) 47 if hostConfig.CPUShares != 0 { 48 t.Error("Expected CPUShares to be unchanged") 49 } 50 51 hostConfig.CPUShares = 1024 52 daemon.adaptContainerSettings(hostConfig, true) 53 if hostConfig.CPUShares != 1024 { 54 t.Error("Expected CPUShares to be unchanged") 55 } 56 } 57 58 // Unix test as uses settings which are not available on Windows 59 func TestAdjustCPUSharesNoAdjustment(t *testing.T) { 60 tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") 61 if err != nil { 62 t.Fatal(err) 63 } 64 defer os.RemoveAll(tmp) 65 daemon := &Daemon{ 66 repository: tmp, 67 root: tmp, 68 } 69 70 hostConfig := &containertypes.HostConfig{ 71 Resources: containertypes.Resources{CPUShares: linuxMinCPUShares - 1}, 72 } 73 daemon.adaptContainerSettings(hostConfig, false) 74 if hostConfig.CPUShares != linuxMinCPUShares-1 { 75 t.Errorf("Expected CPUShares to be %d", linuxMinCPUShares-1) 76 } 77 78 hostConfig.CPUShares = linuxMaxCPUShares + 1 79 daemon.adaptContainerSettings(hostConfig, false) 80 if hostConfig.CPUShares != linuxMaxCPUShares+1 { 81 t.Errorf("Expected CPUShares to be %d", linuxMaxCPUShares+1) 82 } 83 84 hostConfig.CPUShares = 0 85 daemon.adaptContainerSettings(hostConfig, false) 86 if hostConfig.CPUShares != 0 { 87 t.Error("Expected CPUShares to be unchanged") 88 } 89 90 hostConfig.CPUShares = 1024 91 daemon.adaptContainerSettings(hostConfig, false) 92 if hostConfig.CPUShares != 1024 { 93 t.Error("Expected CPUShares to be unchanged") 94 } 95 } 96 97 // Unix test as uses settings which are not available on Windows 98 func TestParseSecurityOptWithDeprecatedColon(t *testing.T) { 99 container := &container.Container{} 100 config := &containertypes.HostConfig{} 101 102 // test apparmor 103 config.SecurityOpt = []string{"apparmor=test_profile"} 104 if err := parseSecurityOpt(container, config); err != nil { 105 t.Fatalf("Unexpected parseSecurityOpt error: %v", err) 106 } 107 if container.AppArmorProfile != "test_profile" { 108 t.Fatalf("Unexpected AppArmorProfile, expected: \"test_profile\", got %q", container.AppArmorProfile) 109 } 110 111 // test seccomp 112 sp := "/path/to/seccomp_test.json" 113 config.SecurityOpt = []string{"seccomp=" + sp} 114 if err := parseSecurityOpt(container, config); err != nil { 115 t.Fatalf("Unexpected parseSecurityOpt error: %v", err) 116 } 117 if container.SeccompProfile != sp { 118 t.Fatalf("Unexpected AppArmorProfile, expected: %q, got %q", sp, container.SeccompProfile) 119 } 120 121 // test valid label 122 config.SecurityOpt = []string{"label=user:USER"} 123 if err := parseSecurityOpt(container, config); err != nil { 124 t.Fatalf("Unexpected parseSecurityOpt error: %v", err) 125 } 126 127 // test invalid label 128 config.SecurityOpt = []string{"label"} 129 if err := parseSecurityOpt(container, config); err == nil { 130 t.Fatal("Expected parseSecurityOpt error, got nil") 131 } 132 133 // test invalid opt 134 config.SecurityOpt = []string{"test"} 135 if err := parseSecurityOpt(container, config); err == nil { 136 t.Fatal("Expected parseSecurityOpt error, got nil") 137 } 138 } 139 140 func TestParseSecurityOpt(t *testing.T) { 141 container := &container.Container{} 142 config := &containertypes.HostConfig{} 143 144 // test apparmor 145 config.SecurityOpt = []string{"apparmor=test_profile"} 146 if err := parseSecurityOpt(container, config); err != nil { 147 t.Fatalf("Unexpected parseSecurityOpt error: %v", err) 148 } 149 if container.AppArmorProfile != "test_profile" { 150 t.Fatalf("Unexpected AppArmorProfile, expected: \"test_profile\", got %q", container.AppArmorProfile) 151 } 152 153 // test seccomp 154 sp := "/path/to/seccomp_test.json" 155 config.SecurityOpt = []string{"seccomp=" + sp} 156 if err := parseSecurityOpt(container, config); err != nil { 157 t.Fatalf("Unexpected parseSecurityOpt error: %v", err) 158 } 159 if container.SeccompProfile != sp { 160 t.Fatalf("Unexpected SeccompProfile, expected: %q, got %q", sp, container.SeccompProfile) 161 } 162 163 // test valid label 164 config.SecurityOpt = []string{"label=user:USER"} 165 if err := parseSecurityOpt(container, config); err != nil { 166 t.Fatalf("Unexpected parseSecurityOpt error: %v", err) 167 } 168 169 // test invalid label 170 config.SecurityOpt = []string{"label"} 171 if err := parseSecurityOpt(container, config); err == nil { 172 t.Fatal("Expected parseSecurityOpt error, got nil") 173 } 174 175 // test invalid opt 176 config.SecurityOpt = []string{"test"} 177 if err := parseSecurityOpt(container, config); err == nil { 178 t.Fatal("Expected parseSecurityOpt error, got nil") 179 } 180 } 181 182 func TestNetworkOptions(t *testing.T) { 183 daemon := &Daemon{} 184 dconfigCorrect := &Config{ 185 CommonConfig: CommonConfig{ 186 ClusterStore: "consul://localhost:8500", 187 ClusterAdvertise: "192.168.0.1:8000", 188 }, 189 } 190 191 if _, err := daemon.networkOptions(dconfigCorrect, nil, nil); err != nil { 192 t.Fatalf("Expect networkOptions success, got error: %v", err) 193 } 194 195 dconfigWrong := &Config{ 196 CommonConfig: CommonConfig{ 197 ClusterStore: "consul://localhost:8500://test://bbb", 198 }, 199 } 200 201 if _, err := daemon.networkOptions(dconfigWrong, nil, nil); err == nil { 202 t.Fatalf("Expected networkOptions error, got nil") 203 } 204 } 205 206 func TestMigratePre17Volumes(t *testing.T) { 207 rootDir, err := ioutil.TempDir("", "test-daemon-volumes") 208 if err != nil { 209 t.Fatal(err) 210 } 211 defer os.RemoveAll(rootDir) 212 213 volumeRoot := filepath.Join(rootDir, "volumes") 214 err = os.MkdirAll(volumeRoot, 0755) 215 if err != nil { 216 t.Fatal(err) 217 } 218 219 containerRoot := filepath.Join(rootDir, "containers") 220 cid := "1234" 221 err = os.MkdirAll(filepath.Join(containerRoot, cid), 0755) 222 223 vid := "5678" 224 vfsPath := filepath.Join(rootDir, "vfs", "dir", vid) 225 err = os.MkdirAll(vfsPath, 0755) 226 if err != nil { 227 t.Fatal(err) 228 } 229 230 config := []byte(` 231 { 232 "ID": "` + cid + `", 233 "Volumes": { 234 "/foo": "` + vfsPath + `", 235 "/bar": "/foo", 236 "/quux": "/quux" 237 }, 238 "VolumesRW": { 239 "/foo": true, 240 "/bar": true, 241 "/quux": false 242 } 243 } 244 `) 245 246 volStore, err := store.New(volumeRoot) 247 if err != nil { 248 t.Fatal(err) 249 } 250 drv, err := local.New(volumeRoot, 0, 0) 251 if err != nil { 252 t.Fatal(err) 253 } 254 volumedrivers.Register(drv, volume.DefaultDriverName) 255 256 daemon := &Daemon{root: rootDir, repository: containerRoot, volumes: volStore} 257 err = ioutil.WriteFile(filepath.Join(containerRoot, cid, "config.v2.json"), config, 600) 258 if err != nil { 259 t.Fatal(err) 260 } 261 c, err := daemon.load(cid) 262 if err != nil { 263 t.Fatal(err) 264 } 265 if err := daemon.verifyVolumesInfo(c); err != nil { 266 t.Fatal(err) 267 } 268 269 expected := map[string]volume.MountPoint{ 270 "/foo": {Destination: "/foo", RW: true, Name: vid}, 271 "/bar": {Source: "/foo", Destination: "/bar", RW: true}, 272 "/quux": {Source: "/quux", Destination: "/quux", RW: false}, 273 } 274 for id, mp := range c.MountPoints { 275 x, exists := expected[id] 276 if !exists { 277 t.Fatal("volume not migrated") 278 } 279 if mp.Source != x.Source || mp.Destination != x.Destination || mp.RW != x.RW || mp.Name != x.Name { 280 t.Fatalf("got unexpected mountpoint, expected: %+v, got: %+v", x, mp) 281 } 282 } 283 }