runconfig/hostconfig_test.go
f6ed5905
 // +build !windows
 
d4aec5f0
 package runconfig
 
 import (
 	"bytes"
 	"fmt"
 	"io/ioutil"
 	"testing"
7ac4232e
 
91e197d6
 	"github.com/docker/docker/api/types/container"
56f77d5a
 	"github.com/docker/docker/pkg/sysinfo"
7120976d
 	"github.com/stretchr/testify/assert"
d4aec5f0
 )
 
f6ed5905
 // TODO Windows: This will need addressing for a Windows daemon.
d4aec5f0
 func TestNetworkModeTest(t *testing.T) {
7ac4232e
 	networkModes := map[container.NetworkMode][]bool{
d4aec5f0
 		// private, bridge, host, container, none, default
 		"":                         {true, false, false, false, false, false},
 		"something:weird":          {true, false, false, false, false, false},
 		"bridge":                   {true, true, false, false, false, false},
 		DefaultDaemonNetworkMode(): {true, true, false, false, false, false},
 		"host":           {false, false, true, false, false, false},
 		"container:name": {false, false, false, true, false, false},
 		"none":           {true, false, false, false, true, false},
 		"default":        {true, false, false, false, false, true},
 	}
7ac4232e
 	networkModeNames := map[container.NetworkMode]string{
d4aec5f0
 		"":                         "",
2ab94e11
 		"something:weird":          "something:weird",
d4aec5f0
 		"bridge":                   "bridge",
 		DefaultDaemonNetworkMode(): "bridge",
 		"host":           "host",
 		"container:name": "container",
 		"none":           "none",
 		"default":        "default",
 	}
 	for networkMode, state := range networkModes {
 		if networkMode.IsPrivate() != state[0] {
 			t.Fatalf("NetworkMode.IsPrivate for %v should have been %v but was %v", networkMode, state[0], networkMode.IsPrivate())
 		}
 		if networkMode.IsBridge() != state[1] {
 			t.Fatalf("NetworkMode.IsBridge for %v should have been %v but was %v", networkMode, state[1], networkMode.IsBridge())
 		}
 		if networkMode.IsHost() != state[2] {
 			t.Fatalf("NetworkMode.IsHost for %v should have been %v but was %v", networkMode, state[2], networkMode.IsHost())
 		}
 		if networkMode.IsContainer() != state[3] {
 			t.Fatalf("NetworkMode.IsContainer for %v should have been %v but was %v", networkMode, state[3], networkMode.IsContainer())
 		}
 		if networkMode.IsNone() != state[4] {
 			t.Fatalf("NetworkMode.IsNone for %v should have been %v but was %v", networkMode, state[4], networkMode.IsNone())
 		}
 		if networkMode.IsDefault() != state[5] {
 			t.Fatalf("NetworkMode.IsDefault for %v should have been %v but was %v", networkMode, state[5], networkMode.IsDefault())
 		}
 		if networkMode.NetworkName() != networkModeNames[networkMode] {
 			t.Fatalf("Expected name %v, got %v", networkModeNames[networkMode], networkMode.NetworkName())
 		}
 	}
 }
 
 func TestIpcModeTest(t *testing.T) {
7120976d
 	ipcModes := map[container.IpcMode]struct {
 		private   bool
 		host      bool
 		container bool
 		shareable bool
 		valid     bool
 		ctrName   string
 	}{
 		"":                      {valid: true},
 		"private":               {private: true, valid: true},
 		"something:weird":       {},
 		":weird":                {},
 		"host":                  {host: true, valid: true},
 		"container":             {},
 		"container:":            {container: true, valid: true, ctrName: ""},
 		"container:name":        {container: true, valid: true, ctrName: "name"},
 		"container:name1:name2": {container: true, valid: true, ctrName: "name1:name2"},
 		"shareable":             {shareable: true, valid: true},
d4aec5f0
 	}
7120976d
 
d4aec5f0
 	for ipcMode, state := range ipcModes {
7120976d
 		assert.Equal(t, state.private, ipcMode.IsPrivate(), "IpcMode.IsPrivate() parsing failed for %q", ipcMode)
 		assert.Equal(t, state.host, ipcMode.IsHost(), "IpcMode.IsHost()  parsing failed for %q", ipcMode)
 		assert.Equal(t, state.container, ipcMode.IsContainer(), "IpcMode.IsContainer()  parsing failed for %q", ipcMode)
 		assert.Equal(t, state.shareable, ipcMode.IsShareable(), "IpcMode.IsShareable()  parsing failed for %q", ipcMode)
 		assert.Equal(t, state.valid, ipcMode.Valid(), "IpcMode.Valid()  parsing failed for %q", ipcMode)
 		assert.Equal(t, state.ctrName, ipcMode.Container(), "IpcMode.Container() parsing failed for %q", ipcMode)
d4aec5f0
 	}
 }
 
 func TestUTSModeTest(t *testing.T) {
7ac4232e
 	utsModes := map[container.UTSMode][]bool{
d4aec5f0
 		// private, host, valid
 		"":                {true, false, true},
 		"something:weird": {true, false, false},
 		"host":            {false, true, true},
 		"host:name":       {true, false, true},
 	}
 	for utsMode, state := range utsModes {
 		if utsMode.IsPrivate() != state[0] {
 			t.Fatalf("UtsMode.IsPrivate for %v should have been %v but was %v", utsMode, state[0], utsMode.IsPrivate())
 		}
 		if utsMode.IsHost() != state[1] {
 			t.Fatalf("UtsMode.IsHost for %v should have been %v but was %v", utsMode, state[1], utsMode.IsHost())
 		}
 		if utsMode.Valid() != state[2] {
 			t.Fatalf("UtsMode.Valid for %v should have been %v but was %v", utsMode, state[2], utsMode.Valid())
 		}
 	}
 }
 
6993e891
 func TestUsernsModeTest(t *testing.T) {
 	usrensMode := map[container.UsernsMode][]bool{
 		// private, host, valid
 		"":                {true, false, true},
 		"something:weird": {true, false, false},
 		"host":            {false, true, true},
 		"host:name":       {true, false, true},
 	}
 	for usernsMode, state := range usrensMode {
 		if usernsMode.IsPrivate() != state[0] {
 			t.Fatalf("UsernsMode.IsPrivate for %v should have been %v but was %v", usernsMode, state[0], usernsMode.IsPrivate())
 		}
 		if usernsMode.IsHost() != state[1] {
 			t.Fatalf("UsernsMode.IsHost for %v should have been %v but was %v", usernsMode, state[1], usernsMode.IsHost())
 		}
 		if usernsMode.Valid() != state[2] {
 			t.Fatalf("UsernsMode.Valid for %v should have been %v but was %v", usernsMode, state[2], usernsMode.Valid())
 		}
 	}
 }
 
d4aec5f0
 func TestPidModeTest(t *testing.T) {
7ac4232e
 	pidModes := map[container.PidMode][]bool{
d4aec5f0
 		// private, host, valid
 		"":                {true, false, true},
 		"something:weird": {true, false, false},
 		"host":            {false, true, true},
 		"host:name":       {true, false, true},
 	}
 	for pidMode, state := range pidModes {
 		if pidMode.IsPrivate() != state[0] {
 			t.Fatalf("PidMode.IsPrivate for %v should have been %v but was %v", pidMode, state[0], pidMode.IsPrivate())
 		}
 		if pidMode.IsHost() != state[1] {
 			t.Fatalf("PidMode.IsHost for %v should have been %v but was %v", pidMode, state[1], pidMode.IsHost())
 		}
 		if pidMode.Valid() != state[2] {
 			t.Fatalf("PidMode.Valid for %v should have been %v but was %v", pidMode, state[2], pidMode.Valid())
 		}
 	}
 }
 
 func TestRestartPolicy(t *testing.T) {
7ac4232e
 	restartPolicies := map[container.RestartPolicy][]bool{
d4aec5f0
 		// none, always, failure
6284cf5e
 		{}: {true, false, false},
 		{Name: "something", MaximumRetryCount: 0}:  {false, false, false},
 		{Name: "no", MaximumRetryCount: 0}:         {true, false, false},
 		{Name: "always", MaximumRetryCount: 0}:     {false, true, false},
 		{Name: "on-failure", MaximumRetryCount: 0}: {false, false, true},
d4aec5f0
 	}
 	for restartPolicy, state := range restartPolicies {
 		if restartPolicy.IsNone() != state[0] {
 			t.Fatalf("RestartPolicy.IsNone for %v should have been %v but was %v", restartPolicy, state[0], restartPolicy.IsNone())
 		}
 		if restartPolicy.IsAlways() != state[1] {
 			t.Fatalf("RestartPolicy.IsAlways for %v should have been %v but was %v", restartPolicy, state[1], restartPolicy.IsAlways())
 		}
 		if restartPolicy.IsOnFailure() != state[2] {
 			t.Fatalf("RestartPolicy.IsOnFailure for %v should have been %v but was %v", restartPolicy, state[2], restartPolicy.IsOnFailure())
 		}
 	}
 }
 func TestDecodeHostConfig(t *testing.T) {
 	fixtures := []struct {
 		file string
 	}{
a7e686a7
 		{"fixtures/unix/container_hostconfig_1_14.json"},
 		{"fixtures/unix/container_hostconfig_1_19.json"},
d4aec5f0
 	}
 
 	for _, f := range fixtures {
 		b, err := ioutil.ReadFile(f.file)
 		if err != nil {
 			t.Fatal(err)
 		}
 
ebcb7d6b
 		c, err := decodeHostConfig(bytes.NewReader(b))
d4aec5f0
 		if err != nil {
 			t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
 		}
 
f7f101d5
 		assert.False(t, c.Privileged)
d4aec5f0
 
26ce3f4c
 		if l := len(c.Binds); l != 1 {
 			t.Fatalf("Expected 1 bind, found %d\n", l)
d4aec5f0
 		}
 
53b0d626
 		if len(c.CapAdd) != 1 && c.CapAdd[0] != "NET_ADMIN" {
d4aec5f0
 			t.Fatalf("Expected CapAdd NET_ADMIN, got %v", c.CapAdd)
 		}
 
53b0d626
 		if len(c.CapDrop) != 1 && c.CapDrop[0] != "NET_ADMIN" {
b3e51378
 			t.Fatalf("Expected CapDrop NET_ADMIN, got %v", c.CapDrop)
d4aec5f0
 		}
 	}
 }
56f77d5a
 
 func TestValidateResources(t *testing.T) {
 	type resourceTest struct {
 		ConfigCPURealtimePeriod   int64
 		ConfigCPURealtimeRuntime  int64
 		SysInfoCPURealtimePeriod  bool
 		SysInfoCPURealtimeRuntime bool
 		ErrorExpected             bool
 		FailureMsg                string
 	}
 
 	tests := []resourceTest{
 		{
 			ConfigCPURealtimePeriod:   1000,
 			ConfigCPURealtimeRuntime:  1000,
 			SysInfoCPURealtimePeriod:  true,
 			SysInfoCPURealtimeRuntime: true,
 			ErrorExpected:             false,
 			FailureMsg:                "Expected valid configuration",
 		},
 		{
 			ConfigCPURealtimePeriod:   5000,
 			ConfigCPURealtimeRuntime:  5000,
 			SysInfoCPURealtimePeriod:  false,
 			SysInfoCPURealtimeRuntime: true,
 			ErrorExpected:             true,
 			FailureMsg:                "Expected failure when cpu-rt-period is set but kernel doesn't support it",
 		},
 		{
 			ConfigCPURealtimePeriod:   5000,
 			ConfigCPURealtimeRuntime:  5000,
 			SysInfoCPURealtimePeriod:  true,
 			SysInfoCPURealtimeRuntime: false,
 			ErrorExpected:             true,
 			FailureMsg:                "Expected failure when cpu-rt-runtime is set but kernel doesn't support it",
 		},
 		{
 			ConfigCPURealtimePeriod:   5000,
 			ConfigCPURealtimeRuntime:  10000,
 			SysInfoCPURealtimePeriod:  true,
 			SysInfoCPURealtimeRuntime: false,
 			ErrorExpected:             true,
 			FailureMsg:                "Expected failure when cpu-rt-runtime is greater than cpu-rt-period",
 		},
 	}
 
 	for _, rt := range tests {
 		var hc container.HostConfig
 		hc.Resources.CPURealtimePeriod = rt.ConfigCPURealtimePeriod
 		hc.Resources.CPURealtimeRuntime = rt.ConfigCPURealtimeRuntime
 
 		var si sysinfo.SysInfo
 		si.CPURealtimePeriod = rt.SysInfoCPURealtimePeriod
 		si.CPURealtimeRuntime = rt.SysInfoCPURealtimeRuntime
 
4af3389d
 		if err := validateResources(&hc, &si); (err != nil) != rt.ErrorExpected {
56f77d5a
 			t.Fatal(rt.FailureMsg, err)
 		}
 	}
 }