github.com/mforkel/docker-ce-i386@v17.12.1-ce-rc2+incompatible/components/engine/runconfig/hostconfig_test.go (about) 1 // +build !windows 2 3 package runconfig 4 5 import ( 6 "bytes" 7 "fmt" 8 "io/ioutil" 9 "testing" 10 11 "github.com/docker/docker/api/types/container" 12 "github.com/docker/docker/pkg/sysinfo" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 // TODO Windows: This will need addressing for a Windows daemon. 17 func TestNetworkModeTest(t *testing.T) { 18 networkModes := map[container.NetworkMode][]bool{ 19 // private, bridge, host, container, none, default 20 "": {true, false, false, false, false, false}, 21 "something:weird": {true, false, false, false, false, false}, 22 "bridge": {true, true, false, false, false, false}, 23 DefaultDaemonNetworkMode(): {true, true, false, false, false, false}, 24 "host": {false, false, true, false, false, false}, 25 "container:name": {false, false, false, true, false, false}, 26 "none": {true, false, false, false, true, false}, 27 "default": {true, false, false, false, false, true}, 28 } 29 networkModeNames := map[container.NetworkMode]string{ 30 "": "", 31 "something:weird": "something:weird", 32 "bridge": "bridge", 33 DefaultDaemonNetworkMode(): "bridge", 34 "host": "host", 35 "container:name": "container", 36 "none": "none", 37 "default": "default", 38 } 39 for networkMode, state := range networkModes { 40 if networkMode.IsPrivate() != state[0] { 41 t.Fatalf("NetworkMode.IsPrivate for %v should have been %v but was %v", networkMode, state[0], networkMode.IsPrivate()) 42 } 43 if networkMode.IsBridge() != state[1] { 44 t.Fatalf("NetworkMode.IsBridge for %v should have been %v but was %v", networkMode, state[1], networkMode.IsBridge()) 45 } 46 if networkMode.IsHost() != state[2] { 47 t.Fatalf("NetworkMode.IsHost for %v should have been %v but was %v", networkMode, state[2], networkMode.IsHost()) 48 } 49 if networkMode.IsContainer() != state[3] { 50 t.Fatalf("NetworkMode.IsContainer for %v should have been %v but was %v", networkMode, state[3], networkMode.IsContainer()) 51 } 52 if networkMode.IsNone() != state[4] { 53 t.Fatalf("NetworkMode.IsNone for %v should have been %v but was %v", networkMode, state[4], networkMode.IsNone()) 54 } 55 if networkMode.IsDefault() != state[5] { 56 t.Fatalf("NetworkMode.IsDefault for %v should have been %v but was %v", networkMode, state[5], networkMode.IsDefault()) 57 } 58 if networkMode.NetworkName() != networkModeNames[networkMode] { 59 t.Fatalf("Expected name %v, got %v", networkModeNames[networkMode], networkMode.NetworkName()) 60 } 61 } 62 } 63 64 func TestIpcModeTest(t *testing.T) { 65 ipcModes := map[container.IpcMode]struct { 66 private bool 67 host bool 68 container bool 69 shareable bool 70 valid bool 71 ctrName string 72 }{ 73 "": {valid: true}, 74 "private": {private: true, valid: true}, 75 "something:weird": {}, 76 ":weird": {}, 77 "host": {host: true, valid: true}, 78 "container": {}, 79 "container:": {container: true, valid: true, ctrName: ""}, 80 "container:name": {container: true, valid: true, ctrName: "name"}, 81 "container:name1:name2": {container: true, valid: true, ctrName: "name1:name2"}, 82 "shareable": {shareable: true, valid: true}, 83 } 84 85 for ipcMode, state := range ipcModes { 86 assert.Equal(t, state.private, ipcMode.IsPrivate(), "IpcMode.IsPrivate() parsing failed for %q", ipcMode) 87 assert.Equal(t, state.host, ipcMode.IsHost(), "IpcMode.IsHost() parsing failed for %q", ipcMode) 88 assert.Equal(t, state.container, ipcMode.IsContainer(), "IpcMode.IsContainer() parsing failed for %q", ipcMode) 89 assert.Equal(t, state.shareable, ipcMode.IsShareable(), "IpcMode.IsShareable() parsing failed for %q", ipcMode) 90 assert.Equal(t, state.valid, ipcMode.Valid(), "IpcMode.Valid() parsing failed for %q", ipcMode) 91 assert.Equal(t, state.ctrName, ipcMode.Container(), "IpcMode.Container() parsing failed for %q", ipcMode) 92 } 93 } 94 95 func TestUTSModeTest(t *testing.T) { 96 utsModes := map[container.UTSMode][]bool{ 97 // private, host, valid 98 "": {true, false, true}, 99 "something:weird": {true, false, false}, 100 "host": {false, true, true}, 101 "host:name": {true, false, true}, 102 } 103 for utsMode, state := range utsModes { 104 if utsMode.IsPrivate() != state[0] { 105 t.Fatalf("UtsMode.IsPrivate for %v should have been %v but was %v", utsMode, state[0], utsMode.IsPrivate()) 106 } 107 if utsMode.IsHost() != state[1] { 108 t.Fatalf("UtsMode.IsHost for %v should have been %v but was %v", utsMode, state[1], utsMode.IsHost()) 109 } 110 if utsMode.Valid() != state[2] { 111 t.Fatalf("UtsMode.Valid for %v should have been %v but was %v", utsMode, state[2], utsMode.Valid()) 112 } 113 } 114 } 115 116 func TestUsernsModeTest(t *testing.T) { 117 usrensMode := map[container.UsernsMode][]bool{ 118 // private, host, valid 119 "": {true, false, true}, 120 "something:weird": {true, false, false}, 121 "host": {false, true, true}, 122 "host:name": {true, false, true}, 123 } 124 for usernsMode, state := range usrensMode { 125 if usernsMode.IsPrivate() != state[0] { 126 t.Fatalf("UsernsMode.IsPrivate for %v should have been %v but was %v", usernsMode, state[0], usernsMode.IsPrivate()) 127 } 128 if usernsMode.IsHost() != state[1] { 129 t.Fatalf("UsernsMode.IsHost for %v should have been %v but was %v", usernsMode, state[1], usernsMode.IsHost()) 130 } 131 if usernsMode.Valid() != state[2] { 132 t.Fatalf("UsernsMode.Valid for %v should have been %v but was %v", usernsMode, state[2], usernsMode.Valid()) 133 } 134 } 135 } 136 137 func TestPidModeTest(t *testing.T) { 138 pidModes := map[container.PidMode][]bool{ 139 // private, host, valid 140 "": {true, false, true}, 141 "something:weird": {true, false, false}, 142 "host": {false, true, true}, 143 "host:name": {true, false, true}, 144 } 145 for pidMode, state := range pidModes { 146 if pidMode.IsPrivate() != state[0] { 147 t.Fatalf("PidMode.IsPrivate for %v should have been %v but was %v", pidMode, state[0], pidMode.IsPrivate()) 148 } 149 if pidMode.IsHost() != state[1] { 150 t.Fatalf("PidMode.IsHost for %v should have been %v but was %v", pidMode, state[1], pidMode.IsHost()) 151 } 152 if pidMode.Valid() != state[2] { 153 t.Fatalf("PidMode.Valid for %v should have been %v but was %v", pidMode, state[2], pidMode.Valid()) 154 } 155 } 156 } 157 158 func TestRestartPolicy(t *testing.T) { 159 restartPolicies := map[container.RestartPolicy][]bool{ 160 // none, always, failure 161 {}: {true, false, false}, 162 {Name: "something", MaximumRetryCount: 0}: {false, false, false}, 163 {Name: "no", MaximumRetryCount: 0}: {true, false, false}, 164 {Name: "always", MaximumRetryCount: 0}: {false, true, false}, 165 {Name: "on-failure", MaximumRetryCount: 0}: {false, false, true}, 166 } 167 for restartPolicy, state := range restartPolicies { 168 if restartPolicy.IsNone() != state[0] { 169 t.Fatalf("RestartPolicy.IsNone for %v should have been %v but was %v", restartPolicy, state[0], restartPolicy.IsNone()) 170 } 171 if restartPolicy.IsAlways() != state[1] { 172 t.Fatalf("RestartPolicy.IsAlways for %v should have been %v but was %v", restartPolicy, state[1], restartPolicy.IsAlways()) 173 } 174 if restartPolicy.IsOnFailure() != state[2] { 175 t.Fatalf("RestartPolicy.IsOnFailure for %v should have been %v but was %v", restartPolicy, state[2], restartPolicy.IsOnFailure()) 176 } 177 } 178 } 179 func TestDecodeHostConfig(t *testing.T) { 180 fixtures := []struct { 181 file string 182 }{ 183 {"fixtures/unix/container_hostconfig_1_14.json"}, 184 {"fixtures/unix/container_hostconfig_1_19.json"}, 185 } 186 187 for _, f := range fixtures { 188 b, err := ioutil.ReadFile(f.file) 189 if err != nil { 190 t.Fatal(err) 191 } 192 193 c, err := decodeHostConfig(bytes.NewReader(b)) 194 if err != nil { 195 t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err)) 196 } 197 198 assert.False(t, c.Privileged) 199 200 if l := len(c.Binds); l != 1 { 201 t.Fatalf("Expected 1 bind, found %d\n", l) 202 } 203 204 if len(c.CapAdd) != 1 && c.CapAdd[0] != "NET_ADMIN" { 205 t.Fatalf("Expected CapAdd NET_ADMIN, got %v", c.CapAdd) 206 } 207 208 if len(c.CapDrop) != 1 && c.CapDrop[0] != "NET_ADMIN" { 209 t.Fatalf("Expected CapDrop NET_ADMIN, got %v", c.CapDrop) 210 } 211 } 212 } 213 214 func TestValidateResources(t *testing.T) { 215 type resourceTest struct { 216 ConfigCPURealtimePeriod int64 217 ConfigCPURealtimeRuntime int64 218 SysInfoCPURealtimePeriod bool 219 SysInfoCPURealtimeRuntime bool 220 ErrorExpected bool 221 FailureMsg string 222 } 223 224 tests := []resourceTest{ 225 { 226 ConfigCPURealtimePeriod: 1000, 227 ConfigCPURealtimeRuntime: 1000, 228 SysInfoCPURealtimePeriod: true, 229 SysInfoCPURealtimeRuntime: true, 230 ErrorExpected: false, 231 FailureMsg: "Expected valid configuration", 232 }, 233 { 234 ConfigCPURealtimePeriod: 5000, 235 ConfigCPURealtimeRuntime: 5000, 236 SysInfoCPURealtimePeriod: false, 237 SysInfoCPURealtimeRuntime: true, 238 ErrorExpected: true, 239 FailureMsg: "Expected failure when cpu-rt-period is set but kernel doesn't support it", 240 }, 241 { 242 ConfigCPURealtimePeriod: 5000, 243 ConfigCPURealtimeRuntime: 5000, 244 SysInfoCPURealtimePeriod: true, 245 SysInfoCPURealtimeRuntime: false, 246 ErrorExpected: true, 247 FailureMsg: "Expected failure when cpu-rt-runtime is set but kernel doesn't support it", 248 }, 249 { 250 ConfigCPURealtimePeriod: 5000, 251 ConfigCPURealtimeRuntime: 10000, 252 SysInfoCPURealtimePeriod: true, 253 SysInfoCPURealtimeRuntime: false, 254 ErrorExpected: true, 255 FailureMsg: "Expected failure when cpu-rt-runtime is greater than cpu-rt-period", 256 }, 257 } 258 259 for _, rt := range tests { 260 var hc container.HostConfig 261 hc.Resources.CPURealtimePeriod = rt.ConfigCPURealtimePeriod 262 hc.Resources.CPURealtimeRuntime = rt.ConfigCPURealtimeRuntime 263 264 var si sysinfo.SysInfo 265 si.CPURealtimePeriod = rt.SysInfoCPURealtimePeriod 266 si.CPURealtimeRuntime = rt.SysInfoCPURealtimeRuntime 267 268 if err := validateResources(&hc, &si); (err != nil) != rt.ErrorExpected { 269 t.Fatal(rt.FailureMsg, err) 270 } 271 } 272 }