github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/integration/network/network_test.go (about) 1 package network // import "github.com/docker/docker/integration/network" 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "net/http" 8 "os/exec" 9 "strings" 10 "testing" 11 12 "github.com/docker/docker/api/types" 13 "github.com/docker/docker/integration/internal/container" 14 "github.com/docker/docker/integration/internal/network" 15 "github.com/docker/docker/testutil/daemon" 16 "github.com/docker/docker/testutil/request" 17 "gotest.tools/v3/assert" 18 is "gotest.tools/v3/assert/cmp" 19 "gotest.tools/v3/icmd" 20 "gotest.tools/v3/skip" 21 ) 22 23 func TestRunContainerWithBridgeNone(t *testing.T) { 24 skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run") 25 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 26 skip.If(t, testEnv.IsUserNamespace) 27 skip.If(t, testEnv.IsRootless, "rootless mode has different view of network") 28 29 d := daemon.New(t) 30 d.StartWithBusybox(t, "-b", "none") 31 defer d.Stop(t) 32 33 c := d.NewClientT(t) 34 ctx := context.Background() 35 36 id1 := container.Run(ctx, t, c) 37 defer c.ContainerRemove(ctx, id1, types.ContainerRemoveOptions{Force: true}) 38 39 result, err := container.Exec(ctx, c, id1, []string{"ip", "l"}) 40 assert.NilError(t, err) 41 assert.Check(t, is.Equal(false, strings.Contains(result.Combined(), "eth0")), "There shouldn't be eth0 in container in default(bridge) mode when bridge network is disabled") 42 43 id2 := container.Run(ctx, t, c, container.WithNetworkMode("bridge")) 44 defer c.ContainerRemove(ctx, id2, types.ContainerRemoveOptions{Force: true}) 45 46 result, err = container.Exec(ctx, c, id2, []string{"ip", "l"}) 47 assert.NilError(t, err) 48 assert.Check(t, is.Equal(false, strings.Contains(result.Combined(), "eth0")), "There shouldn't be eth0 in container in bridge mode when bridge network is disabled") 49 50 nsCommand := "ls -l /proc/self/ns/net | awk -F '->' '{print $2}'" 51 cmd := exec.Command("sh", "-c", nsCommand) 52 stdout := bytes.NewBuffer(nil) 53 cmd.Stdout = stdout 54 err = cmd.Run() 55 assert.NilError(t, err, "Failed to get current process network namespace: %+v", err) 56 57 id3 := container.Run(ctx, t, c, container.WithNetworkMode("host")) 58 defer c.ContainerRemove(ctx, id3, types.ContainerRemoveOptions{Force: true}) 59 60 result, err = container.Exec(ctx, c, id3, []string{"sh", "-c", nsCommand}) 61 assert.NilError(t, err) 62 assert.Check(t, is.Equal(stdout.String(), result.Combined()), "The network namespace of container should be the same with host when --net=host and bridge network is disabled") 63 } 64 65 // TestNetworkInvalidJSON tests that POST endpoints that expect a body return 66 // the correct error when sending invalid JSON requests. 67 func TestNetworkInvalidJSON(t *testing.T) { 68 defer setupTest(t)() 69 70 // POST endpoints that accept / expect a JSON body; 71 endpoints := []string{ 72 "/networks/create", 73 "/networks/bridge/connect", 74 "/networks/bridge/disconnect", 75 } 76 77 for _, ep := range endpoints { 78 ep := ep 79 t.Run(ep[1:], func(t *testing.T) { 80 t.Parallel() 81 82 t.Run("invalid content type", func(t *testing.T) { 83 res, body, err := request.Post(ep, request.RawString("{}"), request.ContentType("text/plain")) 84 assert.NilError(t, err) 85 assert.Check(t, is.Equal(res.StatusCode, http.StatusBadRequest)) 86 87 buf, err := request.ReadBody(body) 88 assert.NilError(t, err) 89 assert.Check(t, is.Contains(string(buf), "unsupported Content-Type header (text/plain): must be 'application/json'")) 90 }) 91 92 t.Run("invalid JSON", func(t *testing.T) { 93 res, body, err := request.Post(ep, request.RawString("{invalid json"), request.JSON) 94 assert.NilError(t, err) 95 assert.Check(t, is.Equal(res.StatusCode, http.StatusBadRequest)) 96 97 buf, err := request.ReadBody(body) 98 assert.NilError(t, err) 99 assert.Check(t, is.Contains(string(buf), "invalid JSON: invalid character 'i' looking for beginning of object key string")) 100 }) 101 102 t.Run("extra content after JSON", func(t *testing.T) { 103 res, body, err := request.Post(ep, request.RawString(`{} trailing content`), request.JSON) 104 assert.NilError(t, err) 105 assert.Check(t, is.Equal(res.StatusCode, http.StatusBadRequest)) 106 107 buf, err := request.ReadBody(body) 108 assert.NilError(t, err) 109 assert.Check(t, is.Contains(string(buf), "unexpected content after JSON")) 110 }) 111 112 t.Run("empty body", func(t *testing.T) { 113 // empty body should not produce an 500 internal server error, or 114 // any 5XX error (this is assuming the request does not produce 115 // an internal server error for another reason, but it shouldn't) 116 res, _, err := request.Post(ep, request.RawString(``), request.JSON) 117 assert.NilError(t, err) 118 assert.Check(t, res.StatusCode < http.StatusInternalServerError) 119 }) 120 }) 121 } 122 } 123 124 // TestNetworkList verifies that /networks returns a list of networks either 125 // with, or without a trailing slash (/networks/). Regression test for https://github.com/moby/moby/issues/24595 126 func TestNetworkList(t *testing.T) { 127 defer setupTest(t)() 128 129 endpoints := []string{ 130 "/networks", 131 "/networks/", 132 } 133 134 for _, ep := range endpoints { 135 ep := ep 136 t.Run(ep, func(t *testing.T) { 137 t.Parallel() 138 139 res, body, err := request.Get(ep, request.JSON) 140 assert.NilError(t, err) 141 assert.Equal(t, res.StatusCode, http.StatusOK) 142 143 buf, err := request.ReadBody(body) 144 assert.NilError(t, err) 145 var nws []types.NetworkResource 146 err = json.Unmarshal(buf, &nws) 147 assert.NilError(t, err) 148 assert.Assert(t, len(nws) > 0) 149 }) 150 } 151 } 152 153 func TestHostIPv4BridgeLabel(t *testing.T) { 154 skip.If(t, testEnv.OSType == "windows") 155 skip.If(t, testEnv.IsRemoteDaemon) 156 skip.If(t, testEnv.IsRootless, "rootless mode has different view of network") 157 d := daemon.New(t) 158 d.Start(t) 159 defer d.Stop(t) 160 c := d.NewClientT(t) 161 defer c.Close() 162 ctx := context.Background() 163 164 ipv4SNATAddr := "172.0.0.172" 165 // Create a bridge network with --opt com.docker.network.host_ipv4=172.0.0.172 166 bridgeName := "hostIPv4Bridge" 167 network.CreateNoError(ctx, t, c, bridgeName, 168 network.WithDriver("bridge"), 169 network.WithOption("com.docker.network.host_ipv4", ipv4SNATAddr), 170 network.WithOption("com.docker.network.bridge.name", bridgeName), 171 ) 172 out, err := c.NetworkInspect(ctx, bridgeName, types.NetworkInspectOptions{Verbose: true}) 173 assert.NilError(t, err) 174 assert.Assert(t, len(out.IPAM.Config) > 0) 175 // Make sure the SNAT rule exists 176 icmd.RunCommand("iptables", "-t", "nat", "-C", "POSTROUTING", "-s", out.IPAM.Config[0].Subnet, "!", "-o", bridgeName, "-j", "SNAT", "--to-source", ipv4SNATAddr).Assert(t, icmd.Success) 177 }