sandbox_unix_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. //go:build !windows
  2. package libnetwork
  3. import (
  4. "strconv"
  5. "testing"
  6. "github.com/docker/docker/errdefs"
  7. "github.com/docker/docker/internal/testutils/netnsutils"
  8. "github.com/docker/docker/libnetwork/config"
  9. "github.com/docker/docker/libnetwork/ipamapi"
  10. "github.com/docker/docker/libnetwork/netlabel"
  11. "github.com/docker/docker/libnetwork/options"
  12. "github.com/docker/docker/libnetwork/osl"
  13. "gotest.tools/v3/assert"
  14. is "gotest.tools/v3/assert/cmp"
  15. )
  16. func getTestEnv(t *testing.T, opts ...[]NetworkOption) (*Controller, []*Network) {
  17. const netType = "bridge"
  18. c, err := New(
  19. OptionBoltdbWithRandomDBFile(t),
  20. config.OptionDriverConfig(netType, map[string]any{
  21. netlabel.GenericData: options.Generic{"EnableIPForwarding": true},
  22. }),
  23. )
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. t.Cleanup(c.Stop)
  28. if len(opts) == 0 {
  29. return c, nil
  30. }
  31. nwList := make([]*Network, 0, len(opts))
  32. for i, opt := range opts {
  33. name := "test_nw_" + strconv.Itoa(i)
  34. newOptions := []NetworkOption{
  35. NetworkOptionGeneric(options.Generic{
  36. netlabel.GenericData: options.Generic{"BridgeName": name},
  37. }),
  38. }
  39. newOptions = append(newOptions, opt...)
  40. n, err := c.NewNetwork(netType, name, "", newOptions...)
  41. if err != nil {
  42. t.Fatal(err)
  43. }
  44. nwList = append(nwList, n)
  45. }
  46. return c, nwList
  47. }
  48. func TestControllerGetSandbox(t *testing.T) {
  49. ctrlr, _ := getTestEnv(t)
  50. t.Run("invalid id", func(t *testing.T) {
  51. const cID = ""
  52. sb, err := ctrlr.GetSandbox(cID)
  53. _, ok := err.(ErrInvalidID)
  54. assert.Check(t, ok, "expected ErrInvalidID, got %[1]v (%[1]T)", err)
  55. assert.Check(t, is.Nil(sb))
  56. })
  57. t.Run("not found", func(t *testing.T) {
  58. const cID = "container-id-with-no-sandbox"
  59. sb, err := ctrlr.GetSandbox(cID)
  60. assert.Check(t, errdefs.IsNotFound(err), "expected a ErrNotFound, got %[1]v (%[1]T)", err)
  61. assert.Check(t, is.Nil(sb))
  62. })
  63. t.Run("existing sandbox", func(t *testing.T) {
  64. const cID = "test-container-id"
  65. expected, err := ctrlr.NewSandbox(cID)
  66. assert.Check(t, err)
  67. sb, err := ctrlr.GetSandbox(cID)
  68. assert.Check(t, err)
  69. assert.Check(t, is.Equal(sb.ContainerID(), cID))
  70. assert.Check(t, is.Equal(sb.ID(), expected.ID()))
  71. assert.Check(t, is.Equal(sb.Key(), expected.Key()))
  72. assert.Check(t, is.Equal(sb.ContainerID(), expected.ContainerID()))
  73. err = sb.Delete()
  74. assert.Check(t, err)
  75. sb, err = ctrlr.GetSandbox(cID)
  76. assert.Check(t, errdefs.IsNotFound(err), "expected a ErrNotFound, got %[1]v (%[1]T)", err)
  77. assert.Check(t, is.Nil(sb))
  78. })
  79. }
  80. func TestSandboxAddEmpty(t *testing.T) {
  81. ctrlr, _ := getTestEnv(t)
  82. sbx, err := ctrlr.NewSandbox("sandbox0")
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. if err := sbx.Delete(); err != nil {
  87. t.Fatal(err)
  88. }
  89. if len(ctrlr.sandboxes) != 0 {
  90. t.Fatalf("controller sandboxes is not empty. len = %d", len(ctrlr.sandboxes))
  91. }
  92. osl.GC()
  93. }
  94. // // If different priorities are specified, internal option and ipv6 addresses mustn't influence endpoint order
  95. func TestSandboxAddMultiPrio(t *testing.T) {
  96. defer netnsutils.SetupTestOSContext(t)()
  97. opts := [][]NetworkOption{
  98. {NetworkOptionEnableIPv6(true), NetworkOptionIpam(ipamapi.DefaultIPAM, "", nil, []*IpamConf{{PreferredPool: "fe90::/64"}}, nil)},
  99. {NetworkOptionInternalNetwork()},
  100. {},
  101. }
  102. ctrlr, nws := getTestEnv(t, opts...)
  103. sbx, err := ctrlr.NewSandbox("sandbox1")
  104. if err != nil {
  105. t.Fatal(err)
  106. }
  107. sid := sbx.ID()
  108. ep1, err := nws[0].CreateEndpoint("ep1")
  109. if err != nil {
  110. t.Fatal(err)
  111. }
  112. ep2, err := nws[1].CreateEndpoint("ep2")
  113. if err != nil {
  114. t.Fatal(err)
  115. }
  116. ep3, err := nws[2].CreateEndpoint("ep3")
  117. if err != nil {
  118. t.Fatal(err)
  119. }
  120. if err := ep1.Join(sbx, JoinOptionPriority(1)); err != nil {
  121. t.Fatal(err)
  122. }
  123. if err := ep2.Join(sbx, JoinOptionPriority(2)); err != nil {
  124. t.Fatal(err)
  125. }
  126. if err := ep3.Join(sbx, JoinOptionPriority(3)); err != nil {
  127. t.Fatal(err)
  128. }
  129. if ctrlr.sandboxes[sid].endpoints[0].ID() != ep3.ID() {
  130. t.Fatal("Expected ep3 to be at the top of the heap. But did not find ep3 at the top of the heap")
  131. }
  132. if len(sbx.Endpoints()) != 3 {
  133. t.Fatal("Expected 3 endpoints to be connected to the sandbox.")
  134. }
  135. if err := ep3.Leave(sbx); err != nil {
  136. t.Fatal(err)
  137. }
  138. if ctrlr.sandboxes[sid].endpoints[0].ID() != ep2.ID() {
  139. t.Fatal("Expected ep2 to be at the top of the heap after removing ep3. But did not find ep2 at the top of the heap")
  140. }
  141. if err := ep2.Leave(sbx); err != nil {
  142. t.Fatal(err)
  143. }
  144. if ctrlr.sandboxes[sid].endpoints[0].ID() != ep1.ID() {
  145. t.Fatal("Expected ep1 to be at the top of the heap after removing ep2. But did not find ep1 at the top of the heap")
  146. }
  147. // Re-add ep3 back
  148. if err := ep3.Join(sbx, JoinOptionPriority(3)); err != nil {
  149. t.Fatal(err)
  150. }
  151. if ctrlr.sandboxes[sid].endpoints[0].ID() != ep3.ID() {
  152. t.Fatal("Expected ep3 to be at the top of the heap after adding ep3 back. But did not find ep3 at the top of the heap")
  153. }
  154. if err := sbx.Delete(); err != nil {
  155. t.Fatal(err)
  156. }
  157. if len(ctrlr.sandboxes) != 0 {
  158. t.Fatalf("controller sandboxes is not empty. len = %d", len(ctrlr.sandboxes))
  159. }
  160. osl.GC()
  161. }
  162. func TestSandboxAddSamePrio(t *testing.T) {
  163. defer netnsutils.SetupTestOSContext(t)()
  164. opts := [][]NetworkOption{
  165. {},
  166. {},
  167. {NetworkOptionEnableIPv6(true), NetworkOptionIpam(ipamapi.DefaultIPAM, "", nil, []*IpamConf{{PreferredPool: "fe90::/64"}}, nil)},
  168. {NetworkOptionInternalNetwork()},
  169. }
  170. ctrlr, nws := getTestEnv(t, opts...)
  171. sbx, err := ctrlr.NewSandbox("sandbox1")
  172. if err != nil {
  173. t.Fatal(err)
  174. }
  175. sid := sbx.ID()
  176. epNw1, err := nws[1].CreateEndpoint("ep1")
  177. if err != nil {
  178. t.Fatal(err)
  179. }
  180. epIPv6, err := nws[2].CreateEndpoint("ep2")
  181. if err != nil {
  182. t.Fatal(err)
  183. }
  184. epInternal, err := nws[3].CreateEndpoint("ep3")
  185. if err != nil {
  186. t.Fatal(err)
  187. }
  188. epNw0, err := nws[0].CreateEndpoint("ep4")
  189. if err != nil {
  190. t.Fatal(err)
  191. }
  192. if err := epNw1.Join(sbx); err != nil {
  193. t.Fatal(err)
  194. }
  195. if err := epIPv6.Join(sbx); err != nil {
  196. t.Fatal(err)
  197. }
  198. if err := epInternal.Join(sbx); err != nil {
  199. t.Fatal(err)
  200. }
  201. if err := epNw0.Join(sbx); err != nil {
  202. t.Fatal(err)
  203. }
  204. // order should now be: epIPv6, epNw0, epNw1, epInternal
  205. if len(sbx.Endpoints()) != 4 {
  206. t.Fatal("Expected 4 endpoints to be connected to the sandbox.")
  207. }
  208. // IPv6 has precedence over IPv4
  209. if ctrlr.sandboxes[sid].endpoints[0].ID() != epIPv6.ID() {
  210. t.Fatal("Expected epIPv6 to be at the top of the heap. But did not find epIPv6 at the top of the heap")
  211. }
  212. // internal network has lowest precedence
  213. if ctrlr.sandboxes[sid].endpoints[3].ID() != epInternal.ID() {
  214. t.Fatal("Expected epInternal to be at the bottom of the heap. But did not find epInternal at the bottom of the heap")
  215. }
  216. if err := epIPv6.Leave(sbx); err != nil {
  217. t.Fatal(err)
  218. }
  219. // 'test_nw_0' has precedence over 'test_nw_1'
  220. if ctrlr.sandboxes[sid].endpoints[0].ID() != epNw0.ID() {
  221. t.Fatal("Expected epNw0 to be at the top of the heap after removing epIPv6. But did not find epNw0 at the top of the heap")
  222. }
  223. if err := epNw1.Leave(sbx); err != nil {
  224. t.Fatal(err)
  225. }
  226. if err := sbx.Delete(); err != nil {
  227. t.Fatal(err)
  228. }
  229. if len(ctrlr.sandboxes) != 0 {
  230. t.Fatalf("controller containers is not empty. len = %d", len(ctrlr.sandboxes))
  231. }
  232. osl.GC()
  233. }