github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/daemon/execdriver/lxc/lxc_template_unit_test.go (about) 1 // +build linux 2 3 package lxc 4 5 import ( 6 "bufio" 7 "fmt" 8 "io/ioutil" 9 "math/rand" 10 "os" 11 "path" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/docker/docker/daemon/execdriver" 17 nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template" 18 "github.com/docker/libcontainer/devices" 19 ) 20 21 func TestLXCConfig(t *testing.T) { 22 root, err := ioutil.TempDir("", "TestLXCConfig") 23 if err != nil { 24 t.Fatal(err) 25 } 26 defer os.RemoveAll(root) 27 28 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 29 30 // Memory is allocated randomly for testing 31 rand.Seed(time.Now().UTC().UnixNano()) 32 var ( 33 memMin = 33554432 34 memMax = 536870912 35 mem = memMin + rand.Intn(memMax-memMin) 36 cpuMin = 100 37 cpuMax = 10000 38 cpu = cpuMin + rand.Intn(cpuMax-cpuMin) 39 ) 40 41 driver, err := NewDriver(root, "", false) 42 if err != nil { 43 t.Fatal(err) 44 } 45 command := &execdriver.Command{ 46 ID: "1", 47 Resources: &execdriver.Resources{ 48 Memory: int64(mem), 49 CpuShares: int64(cpu), 50 }, 51 Network: &execdriver.Network{ 52 Mtu: 1500, 53 Interface: nil, 54 }, 55 AllowedDevices: make([]*devices.Device, 0), 56 ProcessConfig: execdriver.ProcessConfig{}, 57 } 58 p, err := driver.generateLXCConfig(command) 59 if err != nil { 60 t.Fatal(err) 61 } 62 grepFile(t, p, 63 fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem)) 64 65 grepFile(t, p, 66 fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", mem*2)) 67 } 68 69 func TestCustomLxcConfig(t *testing.T) { 70 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 71 if err != nil { 72 t.Fatal(err) 73 } 74 defer os.RemoveAll(root) 75 76 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 77 78 driver, err := NewDriver(root, "", false) 79 if err != nil { 80 t.Fatal(err) 81 } 82 processConfig := execdriver.ProcessConfig{ 83 Privileged: false, 84 } 85 command := &execdriver.Command{ 86 ID: "1", 87 LxcConfig: []string{ 88 "lxc.utsname = docker", 89 "lxc.cgroup.cpuset.cpus = 0,1", 90 }, 91 Network: &execdriver.Network{ 92 Mtu: 1500, 93 Interface: nil, 94 }, 95 ProcessConfig: processConfig, 96 } 97 98 p, err := driver.generateLXCConfig(command) 99 if err != nil { 100 t.Fatal(err) 101 } 102 103 grepFile(t, p, "lxc.utsname = docker") 104 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 105 } 106 107 func grepFile(t *testing.T, path string, pattern string) { 108 grepFileWithReverse(t, path, pattern, false) 109 } 110 111 func grepFileWithReverse(t *testing.T, path string, pattern string, inverseGrep bool) { 112 f, err := os.Open(path) 113 if err != nil { 114 t.Fatal(err) 115 } 116 defer f.Close() 117 r := bufio.NewReader(f) 118 var ( 119 line string 120 ) 121 err = nil 122 for err == nil { 123 line, err = r.ReadString('\n') 124 if strings.Contains(line, pattern) == true { 125 if inverseGrep { 126 t.Fatalf("grepFile: pattern \"%s\" found in \"%s\"", pattern, path) 127 } 128 return 129 } 130 } 131 if inverseGrep { 132 return 133 } 134 t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path) 135 } 136 137 func TestEscapeFstabSpaces(t *testing.T) { 138 var testInputs = map[string]string{ 139 " ": "\\040", 140 "": "", 141 "/double space": "/double\\040\\040space", 142 "/some long test string": "/some\\040long\\040test\\040string", 143 "/var/lib/docker": "/var/lib/docker", 144 " leading": "\\040leading", 145 "trailing ": "trailing\\040", 146 } 147 for in, exp := range testInputs { 148 if out := escapeFstabSpaces(in); exp != out { 149 t.Logf("Expected %s got %s", exp, out) 150 t.Fail() 151 } 152 } 153 } 154 155 func TestIsDirectory(t *testing.T) { 156 tempDir, err := ioutil.TempDir("", "TestIsDir") 157 if err != nil { 158 t.Fatal(err) 159 } 160 defer os.RemoveAll(tempDir) 161 162 tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile") 163 if err != nil { 164 t.Fatal(err) 165 } 166 167 if isDirectory(tempDir) != "dir" { 168 t.Logf("Could not identify %s as a directory", tempDir) 169 t.Fail() 170 } 171 172 if isDirectory(tempFile.Name()) != "file" { 173 t.Logf("Could not identify %s as a file", tempFile.Name()) 174 t.Fail() 175 } 176 } 177 178 func TestCustomLxcConfigMounts(t *testing.T) { 179 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 180 if err != nil { 181 t.Fatal(err) 182 } 183 defer os.RemoveAll(root) 184 tempDir, err := ioutil.TempDir("", "TestIsDir") 185 if err != nil { 186 t.Fatal(err) 187 } 188 defer os.RemoveAll(tempDir) 189 190 tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile") 191 if err != nil { 192 t.Fatal(err) 193 } 194 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 195 196 driver, err := NewDriver(root, "", false) 197 if err != nil { 198 t.Fatal(err) 199 } 200 processConfig := execdriver.ProcessConfig{ 201 Privileged: false, 202 } 203 mounts := []execdriver.Mount{ 204 { 205 Source: tempDir, 206 Destination: tempDir, 207 Writable: false, 208 Private: true, 209 }, 210 { 211 Source: tempFile.Name(), 212 Destination: tempFile.Name(), 213 Writable: true, 214 Private: true, 215 }, 216 } 217 command := &execdriver.Command{ 218 ID: "1", 219 LxcConfig: []string{ 220 "lxc.utsname = docker", 221 "lxc.cgroup.cpuset.cpus = 0,1", 222 }, 223 Network: &execdriver.Network{ 224 Mtu: 1500, 225 Interface: nil, 226 }, 227 Mounts: mounts, 228 ProcessConfig: processConfig, 229 } 230 231 p, err := driver.generateLXCConfig(command) 232 if err != nil { 233 t.Fatal(err) 234 } 235 236 grepFile(t, p, "lxc.utsname = docker") 237 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 238 239 grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,ro,create=%s 0 0", tempDir, "/"+tempDir, "dir")) 240 grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,rw,create=%s 0 0", tempFile.Name(), "/"+tempFile.Name(), "file")) 241 } 242 243 func TestCustomLxcConfigMisc(t *testing.T) { 244 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 245 if err != nil { 246 t.Fatal(err) 247 } 248 defer os.RemoveAll(root) 249 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 250 driver, err := NewDriver(root, "", false) 251 if err != nil { 252 t.Fatal(err) 253 } 254 processConfig := execdriver.ProcessConfig{ 255 Privileged: false, 256 } 257 258 processConfig.Env = []string{"HOSTNAME=testhost"} 259 command := &execdriver.Command{ 260 ID: "1", 261 LxcConfig: []string{ 262 "lxc.cgroup.cpuset.cpus = 0,1", 263 }, 264 Network: &execdriver.Network{ 265 Mtu: 1500, 266 Interface: &execdriver.NetworkInterface{ 267 Gateway: "10.10.10.1", 268 IPAddress: "10.10.10.10", 269 IPPrefixLen: 24, 270 Bridge: "docker0", 271 }, 272 }, 273 ProcessConfig: processConfig, 274 CapAdd: []string{"net_admin", "syslog"}, 275 CapDrop: []string{"kill", "mknod"}, 276 } 277 278 p, err := driver.generateLXCConfig(command) 279 if err != nil { 280 t.Fatal(err) 281 } 282 // network 283 grepFile(t, p, "lxc.network.type = veth") 284 grepFile(t, p, "lxc.network.link = docker0") 285 grepFile(t, p, "lxc.network.name = eth0") 286 grepFile(t, p, "lxc.network.ipv4 = 10.10.10.10/24") 287 grepFile(t, p, "lxc.network.ipv4.gateway = 10.10.10.1") 288 grepFile(t, p, "lxc.network.flags = up") 289 290 // hostname 291 grepFile(t, p, "lxc.utsname = testhost") 292 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 293 container := nativeTemplate.New() 294 for _, cap := range container.Capabilities { 295 cap = strings.ToLower(cap) 296 if cap != "mknod" && cap != "kill" { 297 grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", cap)) 298 } 299 } 300 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = kill"), true) 301 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = mknod"), true) 302 } 303 304 func TestCustomLxcConfigMiscOverride(t *testing.T) { 305 root, err := ioutil.TempDir("", "TestCustomLxcConfig") 306 if err != nil { 307 t.Fatal(err) 308 } 309 defer os.RemoveAll(root) 310 os.MkdirAll(path.Join(root, "containers", "1"), 0777) 311 driver, err := NewDriver(root, "", false) 312 if err != nil { 313 t.Fatal(err) 314 } 315 processConfig := execdriver.ProcessConfig{ 316 Privileged: false, 317 } 318 319 processConfig.Env = []string{"HOSTNAME=testhost"} 320 command := &execdriver.Command{ 321 ID: "1", 322 LxcConfig: []string{ 323 "lxc.cgroup.cpuset.cpus = 0,1", 324 "lxc.network.ipv4 = 172.0.0.1", 325 }, 326 Network: &execdriver.Network{ 327 Mtu: 1500, 328 Interface: &execdriver.NetworkInterface{ 329 Gateway: "10.10.10.1", 330 IPAddress: "10.10.10.10", 331 IPPrefixLen: 24, 332 Bridge: "docker0", 333 }, 334 }, 335 ProcessConfig: processConfig, 336 CapAdd: []string{"net_admin", "syslog"}, 337 CapDrop: []string{"kill", "mknod"}, 338 } 339 340 p, err := driver.generateLXCConfig(command) 341 if err != nil { 342 t.Fatal(err) 343 } 344 // network 345 grepFile(t, p, "lxc.network.type = veth") 346 grepFile(t, p, "lxc.network.link = docker0") 347 grepFile(t, p, "lxc.network.name = eth0") 348 grepFile(t, p, "lxc.network.ipv4 = 172.0.0.1") 349 grepFile(t, p, "lxc.network.ipv4.gateway = 10.10.10.1") 350 grepFile(t, p, "lxc.network.flags = up") 351 352 // hostname 353 grepFile(t, p, "lxc.utsname = testhost") 354 grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") 355 container := nativeTemplate.New() 356 for _, cap := range container.Capabilities { 357 cap = strings.ToLower(cap) 358 if cap != "mknod" && cap != "kill" { 359 grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", cap)) 360 } 361 } 362 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = kill"), true) 363 grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = mknod"), true) 364 }