diff --git a/integration/network/helpers.go b/integration/network/helpers.go new file mode 100644 index 0000000000..df609dd410 --- /dev/null +++ b/integration/network/helpers.go @@ -0,0 +1,85 @@ +package network + +import ( + "context" + "fmt" + "testing" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "github.com/docker/docker/pkg/parsers/kernel" + "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/icmd" +) + +// CreateMasterDummy creates a dummy network interface +func CreateMasterDummy(t *testing.T, master string) { + // ip link add type dummy + icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(t, icmd.Success) + icmd.RunCommand("ip", "link", "set", master, "up").Assert(t, icmd.Success) +} + +// CreateVlanInterface creates a vlan network interface +func CreateVlanInterface(t *testing.T, master, slave, id string) { + // ip link add link name . type vlan id + icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(t, icmd.Success) + // ip link set up + icmd.RunCommand("ip", "link", "set", slave, "up").Assert(t, icmd.Success) +} + +// DeleteInterface deletes a network interface +func DeleteInterface(t *testing.T, ifName string) { + icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success) + icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success) + icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success) +} + +// LinkExists verifies that a link exists +func LinkExists(t *testing.T, master string) { + // verify the specified link exists, ip link show + icmd.RunCommand("ip", "link", "show", master).Assert(t, icmd.Success) +} + +// IsNetworkAvailable provides a comparison to check if a docker network is available +func IsNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { + return func() cmp.Result { + networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) + if err != nil { + return cmp.ResultFromError(err) + } + for _, network := range networks { + if network.Name == name { + return cmp.ResultSuccess + } + } + return cmp.ResultFailure(fmt.Sprintf("could not find network %s", name)) + } +} + +// IsNetworkNotAvailable provides a comparison to check if a docker network is not available +func IsNetworkNotAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { + return func() cmp.Result { + networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) + if err != nil { + return cmp.ResultFromError(err) + } + for _, network := range networks { + if network.Name == name { + return cmp.ResultFailure(fmt.Sprintf("network %s is still present", name)) + } + } + return cmp.ResultSuccess + } +} + +// CheckKernelMajorVersionGreaterOrEqualThen returns whether the kernel version is greater or equal than the one provided +func CheckKernelMajorVersionGreaterOrEqualThen(kernelVersion int, majorVersion int) bool { + kv, err := kernel.GetKernelVersion() + if err != nil { + return false + } + if kv.Kernel < kernelVersion || (kv.Kernel == kernelVersion && kv.Major < majorVersion) { + return false + } + return true +} diff --git a/integration/network/ipvlan_test.go b/integration/network/ipvlan/ipvlan_test.go similarity index 93% rename from integration/network/ipvlan_test.go rename to integration/network/ipvlan/ipvlan_test.go index a741d8b7f8..9de78f41bb 100644 --- a/integration/network/ipvlan_test.go +++ b/integration/network/ipvlan/ipvlan_test.go @@ -1,4 +1,4 @@ -package network +package ipvlan import ( "strings" @@ -10,6 +10,7 @@ import ( dclient "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" + n "github.com/docker/docker/integration/network" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" "golang.org/x/net/context" @@ -29,8 +30,8 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) { // master dummy interface 'di' notation represent 'docker ipvlan' master := "di-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) client, err := d.NewClient() assert.NilError(t, err) @@ -43,10 +44,10 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "di-persist")) // Restart docker daemon to test the config has persisted to disk d.Restart(t) - assert.Check(t, isNetworkAvailable(client, "di-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "di-persist")) } func TestDockerNetworkIpvlan(t *testing.T) { @@ -105,8 +106,8 @@ func TestDockerNetworkIpvlan(t *testing.T) { func testIpvlanSubinterface(client dclient.APIClient) func(*testing.T) { return func(t *testing.T) { master := "di-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) _, err := client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ Driver: "ipvlan", @@ -115,15 +116,15 @@ func testIpvlanSubinterface(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "di-subinterface")) // delete the network while preserving the parent link err = client.NetworkRemove(context.Background(), "di-subinterface") assert.NilError(t, err) - assert.Check(t, isNetworkNotAvailable(client, "di-subinterface")) + assert.Check(t, n.IsNetworkNotAvailable(client, "di-subinterface")) // verify the network delete did not delete the predefined link - linkExists(t, "di-dummy0") + n.LinkExists(t, "di-dummy0") } } @@ -131,9 +132,9 @@ func testIpvlanOverlapParent(client dclient.APIClient) func(*testing.T) { return func(t *testing.T) { // verify the same parent interface cannot be used if already in use by an existing network master := "di-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) - createVlanInterface(t, master, "di-dummy0.30", "30") + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) + n.CreateVlanInterface(t, master, "di-dummy0.30", "30") _, err := client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ Driver: "ipvlan", @@ -142,7 +143,7 @@ func testIpvlanOverlapParent(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "di-subinterface")) _, err = client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ Driver: "ipvlan", @@ -162,17 +163,14 @@ func testIpvlanL2NilParent(client dclient.APIClient) func(*testing.T) { Driver: "ipvlan", }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-nil-parent")) + assert.Check(t, n.IsNetworkAvailable(client, "di-nil-parent")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("di-nil-parent")) id2 := container.Run(t, ctx, client, container.WithNetworkMode("di-nil-parent")) - t.Log(time.Now()) - _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) assert.NilError(t, err) - t.Log(time.Now()) } } @@ -183,7 +181,7 @@ func testIpvlanL2InternalMode(client dclient.APIClient) func(*testing.T) { Internal: true, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-internal")) + assert.Check(t, n.IsNetworkAvailable(client, "di-internal")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("di-internal")) @@ -222,7 +220,7 @@ func testIpvlanL3NilParent(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-nil-parent-l3")) + assert.Check(t, n.IsNetworkAvailable(client, "di-nil-parent-l3")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -261,7 +259,7 @@ func testIpvlanL3InternalMode(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-internal-l3")) + assert.Check(t, n.IsNetworkAvailable(client, "di-internal-l3")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -314,7 +312,7 @@ func testIpvlanL2MultiSubnet(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl2")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl2")) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 ctx := context.Background() @@ -402,7 +400,7 @@ func testIpvlanL3MultiSubnet(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl3")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl3")) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 ctx := context.Background() @@ -483,7 +481,7 @@ func testIpvlanAddressing(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl2")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl2")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -521,7 +519,7 @@ func testIpvlanAddressing(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl3")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl3")) id2 := container.Run(t, ctx, client, container.WithNetworkMode("dualstackl3"), @@ -539,5 +537,5 @@ func testIpvlanAddressing(client dclient.APIClient) func(*testing.T) { // ensure Kernel version is >= v4.2 for ipvlan support func ipvlanKernelSupport() bool { - return checkKernelMajorVersionGreaterOrEqualThen(4, 2) + return n.CheckKernelMajorVersionGreaterOrEqualThen(4, 2) } diff --git a/integration/network/ipvlan/main_test.go b/integration/network/ipvlan/main_test.go new file mode 100644 index 0000000000..2d5f62453c --- /dev/null +++ b/integration/network/ipvlan/main_test.go @@ -0,0 +1,33 @@ +package ipvlan // import "github.com/docker/docker/integration/network/ipvlan" + +import ( + "fmt" + "os" + "testing" + + "github.com/docker/docker/internal/test/environment" +) + +var testEnv *environment.Execution + +func TestMain(m *testing.M) { + var err error + testEnv, err = environment.New() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + err = environment.EnsureFrozenImagesLinux(testEnv) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + testEnv.Print() + os.Exit(m.Run()) +} + +func setupTest(t *testing.T) func() { + environment.ProtectAll(t, testEnv) + return func() { testEnv.Clean(t) } +} diff --git a/integration/network/macvlan_test.go b/integration/network/macvlan/macvlan_test.go similarity index 74% rename from integration/network/macvlan_test.go rename to integration/network/macvlan/macvlan_test.go index 31848bca99..7358af873b 100644 --- a/integration/network/macvlan_test.go +++ b/integration/network/macvlan/macvlan_test.go @@ -1,8 +1,7 @@ -package network +package macvlan import ( "context" - "fmt" "strings" "testing" "time" @@ -11,11 +10,9 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" + n "github.com/docker/docker/integration/network" "github.com/docker/docker/internal/test/daemon" - "github.com/docker/docker/pkg/parsers/kernel" "github.com/gotestyourself/gotestyourself/assert" - "github.com/gotestyourself/gotestyourself/assert/cmp" - "github.com/gotestyourself/gotestyourself/icmd" "github.com/gotestyourself/gotestyourself/skip" ) @@ -30,8 +27,8 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) { defer d.Stop(t) master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) client, err := d.NewClient() assert.NilError(t, err) @@ -43,9 +40,9 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-persist")) d.Restart(t) - assert.Check(t, isNetworkAvailable(client, "dm-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-persist")) } func TestDockerNetworkMacvlan(t *testing.T) { @@ -91,8 +88,8 @@ func testMacvlanOverlapParent(client client.APIClient) func(*testing.T) { return func(t *testing.T) { // verify the same parent interface cannot be used if already in use by an existing network master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) _, err := client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ Driver: "macvlan", @@ -101,7 +98,7 @@ func testMacvlanOverlapParent(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-subinterface")) _, err = client.NetworkCreate(context.Background(), "dm-parent-net-overlap", types.NetworkCreate{ Driver: "macvlan", @@ -114,9 +111,9 @@ func testMacvlanOverlapParent(client client.APIClient) func(*testing.T) { err = client.NetworkRemove(context.Background(), "dm-subinterface") assert.NilError(t, err) - assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkNotAvailable(client, "dm-subinterface")) // verify the network delete did not delete the predefined link - linkExists(t, "dm-dummy0") + n.LinkExists(t, "dm-dummy0") } } @@ -124,9 +121,9 @@ func testMacvlanSubinterface(client client.APIClient) func(*testing.T) { return func(t *testing.T) { // verify the same parent interface cannot be used if already in use by an existing network master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) - createVlanInterface(t, master, "dm-dummy0.20", "20") + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) + n.CreateVlanInterface(t, master, "dm-dummy0.20", "20") _, err := client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ Driver: "macvlan", @@ -135,15 +132,15 @@ func testMacvlanSubinterface(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-subinterface")) // delete the network while preserving the parent link err = client.NetworkRemove(context.Background(), "dm-subinterface") assert.NilError(t, err) - assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkNotAvailable(client, "dm-subinterface")) // verify the network delete did not delete the predefined link - linkExists(t, "dm-dummy0.20") + n.LinkExists(t, "dm-dummy0.20") } } @@ -154,7 +151,7 @@ func testMacvlanNilParent(client client.APIClient) func(*testing.T) { Driver: "macvlan", }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-nil-parent")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-nil-parent")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent")) @@ -173,7 +170,7 @@ func testMacvlanInternalMode(client client.APIClient) func(*testing.T) { Internal: true, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-internal")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-internal")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal")) @@ -193,7 +190,6 @@ func testMacvlanInternalMode(client client.APIClient) func(*testing.T) { func testMacvlanMultiSubnet(client client.APIClient) func(*testing.T) { return func(t *testing.T) { - // t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") _, err := client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ Driver: "macvlan", EnableIPv6: true, @@ -221,7 +217,7 @@ func testMacvlanMultiSubnet(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackbridge")) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 ctx := context.Background() @@ -301,7 +297,7 @@ func testMacvlanAddressing(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackbridge")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -319,72 +315,7 @@ func testMacvlanAddressing(client client.APIClient) func(*testing.T) { } } -func isNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { - return func() cmp.Result { - networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) - if err != nil { - return cmp.ResultFromError(err) - } - for _, network := range networks { - if network.Name == name { - return cmp.ResultSuccess - } - } - return cmp.ResultFailure(fmt.Sprintf("could not find network %s", name)) - } -} - -func isNetworkNotAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { - return func() cmp.Result { - networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) - if err != nil { - return cmp.ResultFromError(err) - } - for _, network := range networks { - if network.Name == name { - return cmp.ResultFailure(fmt.Sprintf("network %s is still present", name)) - } - } - return cmp.ResultSuccess - } -} - -func createMasterDummy(t *testing.T, master string) { - // ip link add type dummy - icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(t, icmd.Success) - icmd.RunCommand("ip", "link", "set", master, "up").Assert(t, icmd.Success) -} - -func createVlanInterface(t *testing.T, master, slave, id string) { - // ip link add link name . type vlan id - icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(t, icmd.Success) - // ip link set up - icmd.RunCommand("ip", "link", "set", slave, "up").Assert(t, icmd.Success) -} - -func deleteInterface(t *testing.T, ifName string) { - icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success) - icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success) - icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success) -} - -func linkExists(t *testing.T, master string) { - // verify the specified link exists, ip link show - icmd.RunCommand("ip", "link", "show", master).Assert(t, icmd.Success) -} - // ensure Kernel version is >= v3.9 for macvlan support func macvlanKernelSupport() bool { - return checkKernelMajorVersionGreaterOrEqualThen(3, 9) -} - -func checkKernelMajorVersionGreaterOrEqualThen(kernelVersion int, majorVersion int) bool { - kv, err := kernel.GetKernelVersion() - if err != nil { - return false - } - if kv.Kernel < kernelVersion || (kv.Kernel == kernelVersion && kv.Major < majorVersion) { - return false - } - return true + return n.CheckKernelMajorVersionGreaterOrEqualThen(3, 9) } diff --git a/integration/network/macvlan/main_test.go b/integration/network/macvlan/main_test.go new file mode 100644 index 0000000000..31cf111b22 --- /dev/null +++ b/integration/network/macvlan/main_test.go @@ -0,0 +1,33 @@ +package macvlan // import "github.com/docker/docker/integration/network/macvlan" + +import ( + "fmt" + "os" + "testing" + + "github.com/docker/docker/internal/test/environment" +) + +var testEnv *environment.Execution + +func TestMain(m *testing.M) { + var err error + testEnv, err = environment.New() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + err = environment.EnsureFrozenImagesLinux(testEnv) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + testEnv.Print() + os.Exit(m.Run()) +} + +func setupTest(t *testing.T) func() { + environment.ProtectAll(t, testEnv) + return func() { testEnv.Clean(t) } +}