hostconfig_test.go 10 KB

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