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  }