diff --git a/cmd/nerdctl/completion/completion_linux_test.go b/cmd/nerdctl/completion/completion_linux_test.go index 8abb5483964..234c9a21ebc 100644 --- a/cmd/nerdctl/completion/completion_linux_test.go +++ b/cmd/nerdctl/completion/completion_linux_test.go @@ -20,53 +20,189 @@ import ( "testing" "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) func TestCompletion(t *testing.T) { - testutil.DockerIncompatible(t) - base := testutil.NewBase(t) - const gsc = "__complete" - // cmd is executed with base.Args={"--namespace=nerdctl-test"} - base.Cmd(gsc, "--cgroup-manager", "").AssertOutContains("cgroupfs\n") - base.Cmd(gsc, "--snapshotter", "").AssertOutContains("native\n") - base.Cmd(gsc, "").AssertOutContains("run\t") - base.Cmd(gsc, "run", "-").AssertOutContains("--network\t") - base.Cmd(gsc, "run", "--n").AssertOutContains("--network\t") - base.Cmd(gsc, "run", "--ne").AssertOutContains("--network\t") - base.Cmd(gsc, "run", "--net", "").AssertOutContains("host\n") - base.Cmd(gsc, "run", "-it", "--net", "").AssertOutContains("host\n") - base.Cmd(gsc, "run", "-it", "--rm", "--net", "").AssertOutContains("host\n") - base.Cmd(gsc, "run", "--restart", "").AssertOutContains("always\n") - base.Cmd(gsc, "network", "rm", "").AssertOutNotContains("host\n") // host is unremovable - base.Cmd(gsc, "run", "--cap-add", "").AssertOutContains("sys_admin\n") - base.Cmd(gsc, "run", "--cap-add", "").AssertOutNotContains("CAP_SYS_ADMIN\n") // invalid form + nerdtest.Setup() - // Tests with an image - base.Cmd("pull", testutil.AlpineImage).AssertOK() - base.Cmd(gsc, "run", "-i", "").AssertOutContains(testutil.AlpineImage) - base.Cmd(gsc, "run", "-it", "").AssertOutContains(testutil.AlpineImage) - base.Cmd(gsc, "run", "-it", "--rm", "").AssertOutContains(testutil.AlpineImage) + testCase := &test.Case{ + Description: "Base completion", + Require: test.Not(nerdtest.Docker), + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("pull", testutil.AlpineImage) + helpers.Ensure("network", "create", data.Identifier()) + helpers.Ensure("volume", "create", data.Identifier()) + data.Set("identifier", data.Identifier()) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + helpers.Anyhow("volume", "rm", data.Identifier()) + }, + SubTests: []*test.Case{ + { + Description: "--cgroup-manager", + Command: test.RunCommand("__complete", "--cgroup-manager", ""), + Expected: test.Expects(0, nil, test.Contains("cgroupfs\n")), + }, + { + Description: "--snapshotter", + Command: test.RunCommand("__complete", "--snapshotter", ""), + Expected: test.Expects(0, nil, test.Contains("native\n")), + }, + { + Description: "empty", + Command: test.RunCommand("__complete", ""), + Expected: test.Expects(0, nil, test.Contains("run\t")), + }, + { + Description: "run -", + Command: test.RunCommand("__complete", "run", "-"), + Expected: test.Expects(0, nil, test.Contains("--network\t")), + }, + { + Description: "run --n", + Command: test.RunCommand("__complete", "run", "--n"), + Expected: test.Expects(0, nil, test.Contains("--network\t")), + }, + { + Description: "run --ne", + Command: test.RunCommand("__complete", "run", "--ne"), + Expected: test.Expects(0, nil, test.Contains("--network\t")), + }, + { + Description: "run --net", + Command: test.RunCommand("__complete", "run", "--net", ""), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.All( + test.Contains("host\n"), + test.Contains(data.Get("identifier")+"\n"), + ), + } + }, + }, + { + Description: "run -it --net", + Command: test.RunCommand("__complete", "run", "-it", "--net", ""), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.All( + test.Contains("host\n"), + test.Contains(data.Get("identifier")+"\n"), + ), + } + }, + }, + { + Description: "run -ti --rm --net", + Command: test.RunCommand("__complete", "run", "-it", "--rm", "--net", ""), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.All( + test.Contains("host\n"), + test.Contains(data.Get("identifier")+"\n"), + ), + } + }, + }, + { + Description: "run --restart", + Command: test.RunCommand("__complete", "run", "--restart", ""), + Expected: test.Expects(0, nil, test.Contains("always\n")), + }, + { + Description: "network --rm", + Command: test.RunCommand("__complete", "network", "rm", ""), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.All( + test.DoesNotContain("host\n"), + test.Contains(data.Get("identifier")+"\n"), + ), + } + }, + }, + { + Description: "run --cap-add", + Command: test.RunCommand("__complete", "run", "--cap-add", ""), + Expected: test.Expects(0, nil, test.All( + test.Contains("sys_admin\n"), + test.DoesNotContain("CAP_SYS_ADMIN\n"), + )), + }, + { + Description: "volume inspect", + Command: test.RunCommand("__complete", "volume", "inspect", ""), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Get("identifier") + "\n"), + } + }, + }, + { + Description: "volume rm", + Command: test.RunCommand("__complete", "volume", "rm", ""), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Get("identifier") + "\n"), + } + }, + }, + { + Description: "no namespace --cgroup-manager", + Command: func(data test.Data, helpers test.Helpers) test.Command { + cmd := helpers.Command() + cmd.Clear() + cmd.WithBinary("nerdctl") + cmd.WithArgs("__complete", "--cgroup-manager", "") + return cmd + }, + Expected: test.Expects(0, nil, test.Contains("cgroupfs\n")), + }, + { + Description: "no namespace empty", + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command().Clear().WithBinary("nerdctl").WithArgs("__complete", "") + }, + Expected: test.Expects(0, nil, test.Contains("run\t")), + }, + { + Description: "namespace space empty", + Command: func(data test.Data, helpers test.Helpers) test.Command { + // mind {"--namespace=nerdctl-test"} vs {"--namespace", "nerdctl-test"} + return helpers.Command().Clear().WithBinary("nerdctl"). + WithArgs("__complete", "--namespace", testutil.Namespace, "") + }, + Expected: test.Expects(0, nil, test.Contains("run\t")), + }, + { + Description: "run -i", + Command: test.RunCommand("__complete", "run", "-i", ""), + Expected: test.Expects(0, nil, test.Contains(testutil.AlpineImage)), + }, + { + Description: "run -it", + Command: test.RunCommand("__complete", "run", "-it", ""), + Expected: test.Expects(0, nil, test.Contains(testutil.AlpineImage)), + }, + { + Description: "run -it --rm", + Command: test.RunCommand("__complete", "run", "-it", "--rm", ""), + Expected: test.Expects(0, nil, test.Contains(testutil.AlpineImage)), + }, + { + Description: "namespace run -i", + Command: func(data test.Data, helpers test.Helpers) test.Command { + // mind {"--namespace=nerdctl-test"} vs {"--namespace", "nerdctl-test"} + return helpers.Command().Clear().WithBinary("nerdctl"). + WithArgs("__complete", "--namespace", testutil.Namespace, "run", "-i", "") + }, + Expected: test.Expects(0, nil, test.Contains(testutil.AlpineImage+"\n")), + }, + }, + } - // Tests with a network - testNetworkName := "nerdctl-test-completion" - defer base.Cmd("network", "rm", testNetworkName).Run() - base.Cmd("network", "create", testNetworkName).AssertOK() - base.Cmd(gsc, "network", "rm", "").AssertOutContains(testNetworkName) - base.Cmd(gsc, "run", "--net", "").AssertOutContains(testNetworkName) - - // Tests with a volume - testVolumekName := "nerdctl-test-completion" - defer base.Cmd("volume", "rm", testVolumekName).Run() - base.Cmd("volume", "create", testVolumekName).AssertOK() - base.Cmd(gsc, "volume", "inspect", "").AssertOutContains(testVolumekName) - base.Cmd(gsc, "volume", "rm", "").AssertOutContains(testVolumekName) - - // Tests with raw base (without Args={"--namespace=nerdctl-test"}) - rawBase := testutil.NewBase(t) - rawBase.Args = nil // unset "--namespace=nerdctl-test" - rawBase.Cmd(gsc, "--cgroup-manager", "").AssertOutContains("cgroupfs\n") - rawBase.Cmd(gsc, "").AssertOutContains("run\t") - // mind {"--namespace=nerdctl-test"} vs {"--namespace", "nerdctl-test"} - rawBase.Cmd(gsc, "--namespace", testutil.Namespace, "").AssertOutContains("run\t") - rawBase.Cmd(gsc, "--namespace", testutil.Namespace, "run", "-i", "").AssertOutContains(testutil.AlpineImage) + testCase.Run(t) } diff --git a/cmd/nerdctl/network/network_create_linux_test.go b/cmd/nerdctl/network/network_create_linux_test.go index adf61d67c11..ae590d94836 100644 --- a/cmd/nerdctl/network/network_create_linux_test.go +++ b/cmd/nerdctl/network/network_create_linux_test.go @@ -17,66 +17,93 @@ package network import ( - "fmt" "net" + "strings" "testing" "gotest.tools/v3/assert" - "github.com/containerd/nerdctl/v2/cmd/nerdctl/helpers" + ipv6helper "github.com/containerd/nerdctl/v2/cmd/nerdctl/helpers" "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) -func TestNetworkCreateWithMTU(t *testing.T) { - testNetwork := testutil.Identifier(t) - base := testutil.NewBase(t) - - args := []string{ - "network", "create", testNetwork, - "--driver", "bridge", "--opt", "com.docker.network.driver.mtu=9216", - } - base.Cmd(args...).AssertOK() - defer base.Cmd("network", "rm", testNetwork).AssertOK() - - base.Cmd("run", "--rm", "--net", testNetwork, testutil.AlpineImage, "ifconfig", "eth0").AssertOutContains("MTU:9216") -} - func TestNetworkCreate(t *testing.T) { - base := testutil.NewBase(t) - testNetwork := testutil.Identifier(t) - - base.Cmd("network", "create", testNetwork).AssertOK() - defer base.Cmd("network", "rm", testNetwork).AssertOK() - - net := base.InspectNetwork(testNetwork) - assert.Equal(t, len(net.IPAM.Config), 1) - - base.Cmd("run", "--rm", "--net", testNetwork, testutil.CommonImage, "ip", "route").AssertOutContains(net.IPAM.Config[0].Subnet) - - base.Cmd("network", "create", testNetwork+"-1").AssertOK() - defer base.Cmd("network", "rm", testNetwork+"-1").AssertOK() - - base.Cmd("run", "--rm", "--net", testNetwork+"-1", testutil.CommonImage, "ip", "route").AssertOutNotContains(net.IPAM.Config[0].Subnet) -} - -func TestNetworkCreateIPv6(t *testing.T) { - base := testutil.NewBaseWithIPv6Compatible(t) - testNetwork := testutil.Identifier(t) - - subnetStr := "2001:db8:8::/64" - _, subnet, err := net.ParseCIDR(subnetStr) - assert.Assert(t, err == nil) - - base.Cmd("network", "create", "--ipv6", "--subnet", subnetStr, testNetwork).AssertOK() - t.Cleanup(func() { - base.Cmd("network", "rm", testNetwork).Run() - }) + nerdtest.Setup() + + testGroup := &test.Group{ + { + Description: "Network create", + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + netw := nerdtest.InspectNetwork(helpers, data.Identifier()) + assert.Equal(t, len(netw.IPAM.Config), 1) + data.Set("subnet", netw.IPAM.Config[0].Subnet) + + helpers.Ensure("network", "create", data.Identifier()+"-1") + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + helpers.Anyhow("network", "rm", data.Identifier()+"-1") + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + data.Set("container2", helpers.Capture("run", "--rm", "--net", data.Identifier()+"-1", testutil.AlpineImage, "ip", "route")) + return helpers.Command("run", "--rm", "--net", data.Identifier(), testutil.AlpineImage, "ip", "route") + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Errors: nil, + Output: func(stdout string, info string, t *testing.T) { + assert.Assert(t, strings.Contains(stdout, data.Get("subnet")), info) + assert.Assert(t, !strings.Contains(data.Get("container2"), data.Get("subnet")), info) + }, + } + }, + }, + { + Description: "Network create with MTU", + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier(), "--driver", "bridge", "--opt", "com.docker.network.driver.mtu=9216") + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("run", "--rm", "--net", data.Identifier(), testutil.AlpineImage, "ifconfig", "eth0") + }, + Expected: test.Expects(0, nil, test.Contains("MTU:9216")), + }, + { + Description: "Network create with ipv6", + Require: nerdtest.OnlyIPv6, + Setup: func(data test.Data, helpers test.Helpers) { + subnetStr := "2001:db8:8::/64" + data.Set("subnetStr", subnetStr) + _, _, err := net.ParseCIDR(subnetStr) + assert.Assert(t, err == nil) + + helpers.Ensure("network", "create", data.Identifier(), "--ipv6", "--subnet", subnetStr) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("run", "--rm", "--net", data.Identifier(), testutil.CommonImage, "ip", "addr", "show", "dev", "eth0") + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + _, subnet, _ := net.ParseCIDR(data.Get("subnetStr")) + ip := ipv6helper.FindIPv6(stdout) + assert.Assert(t, subnet.Contains(ip), info) + }, + } + }, + }, + } - base.Cmd("run", "--rm", "--net", testNetwork, testutil.CommonImage, "ip", "addr", "show", "dev", "eth0").AssertOutWithFunc(func(stdout string) error { - ip := helpers.FindIPv6(stdout) - if subnet.Contains(ip) { - return nil - } - return fmt.Errorf("expected subnet %s include ip %s", subnet, ip) - }) + testGroup.Run(t) } diff --git a/cmd/nerdctl/network/network_inspect_test.go b/cmd/nerdctl/network/network_inspect_test.go index 1f91f09963e..4aa6147d063 100644 --- a/cmd/nerdctl/network/network_inspect_test.go +++ b/cmd/nerdctl/network/network_inspect_test.go @@ -17,78 +17,101 @@ package network import ( - "runtime" + "encoding/json" + "errors" "testing" "gotest.tools/v3/assert" "github.com/containerd/nerdctl/v2/pkg/inspecttypes/dockercompat" - "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) func TestNetworkInspect(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("IPAMConfig not implemented on Windows yet") - } + nerdtest.Setup() - testNetwork := testutil.Identifier(t) const ( testSubnet = "10.24.24.0/24" testGateway = "10.24.24.1" testIPRange = "10.24.24.0/25" ) - base := testutil.NewBase(t) - defer base.Cmd("network", "rm", testNetwork).Run() - - args := []string{ - "network", "create", "--label", "tag=testNetwork", "--subnet", testSubnet, - "--gateway", testGateway, "--ip-range", testIPRange, - testNetwork, - } - base.Cmd(args...).AssertOK() - got := base.InspectNetwork(testNetwork) - - assert.DeepEqual(base.T, testNetwork, got.Name) - - expectedLabels := map[string]string{ - "tag": "testNetwork", - } - assert.DeepEqual(base.T, expectedLabels, got.Labels) - - expectedIPAM := dockercompat.IPAM{ - Config: []dockercompat.IPAMConfig{ - { - Subnet: testSubnet, - Gateway: testGateway, - IPRange: testIPRange, + testGroup := &test.Group{ + { + Description: "Test network inspect", + // IPAMConfig is not implemented on Windows yet + Require: test.Not(test.Windows), + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", "--label", "tag=testNetwork", "--subnet", testSubnet, + "--gateway", testGateway, "--ip-range", testIPRange, data.Identifier()) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "inspect", data.Identifier()) + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + var dc []dockercompat.Network + + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info) + got := dc[0] + + assert.Equal(t, got.Name, data.Identifier(), info) + assert.Equal(t, got.Labels["tag"], "testNetwork", info) + assert.Equal(t, len(got.IPAM.Config), 1, info) + assert.Equal(t, got.IPAM.Config[0].Subnet, testSubnet, info) + assert.Equal(t, got.IPAM.Config[0].Gateway, testGateway, info) + assert.Equal(t, got.IPAM.Config[0].IPRange, testIPRange, info) + }, + } }, }, - } - assert.DeepEqual(base.T, expectedIPAM, got.IPAM) -} - -func TestNetworkWithNamespace(t *testing.T) { - testutil.DockerIncompatible(t) - - t.Parallel() - - tID := testutil.Identifier(t) - base := testutil.NewBase(t) - baseOther := testutil.NewBaseWithNamespace(t, tID) + { + Description: "Test network with namespace", + Require: test.Not(nerdtest.Docker), + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + helpers.Anyhow("namespace", "remove", data.Identifier()) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "create", data.Identifier()) + }, - tearDown := func() { - base.Cmd("network", "rm", tID).Run() - baseOther.Cmd("namespace", "remove", tID).Run() + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + cmd := helpers.Command().Clear().WithBinary("nerdctl").WithArgs("--namespace", data.Identifier()) + + cmd.Clone().WithArgs("network", "inspect", data.Identifier()).Run(&test.Expected{ + ExitCode: 1, + Errors: []error{errors.New("no such network")}, + }) + + cmd.Clone().WithArgs("network", "remove", data.Identifier()).Run(&test.Expected{ + ExitCode: 1, + Errors: []error{errors.New("no such network")}, + }) + + cmd.Clone().WithArgs("network", "ls").Run(&test.Expected{ + Output: test.DoesNotContain(data.Identifier()), + }) + + cmd.Clone().WithArgs("network", "prune", "-f").Run(&test.Expected{ + Output: test.DoesNotContain(data.Identifier()), + }) + }, + } + }, + }, } - tearDown() - t.Cleanup(tearDown) - - base.Cmd("network", "create", tID).AssertOK() - // Other namespace cannot inspect, prune, see, or remove this network - baseOther.Cmd("network", "inspect", tID).AssertFail() - baseOther.Cmd("network", "prune", "-f").AssertOutNotContains(tID) - baseOther.Cmd("network", "ls").AssertOutNotContains(tID) - baseOther.Cmd("network", "remove", tID).AssertFail() + testGroup.Run(t) } diff --git a/cmd/nerdctl/network/network_list_linux_test.go b/cmd/nerdctl/network/network_list_linux_test.go index 62927f04b3f..a9d2f0124eb 100644 --- a/cmd/nerdctl/network/network_list_linux_test.go +++ b/cmd/nerdctl/network/network_list_linux_test.go @@ -17,60 +17,77 @@ package network import ( - "errors" - "fmt" "strings" "testing" - "github.com/containerd/nerdctl/v2/pkg/testutil" + "gotest.tools/v3/assert" + + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) func TestNetworkLsFilter(t *testing.T) { - t.Parallel() - base := testutil.NewBase(t) - tID := testutil.Identifier(t) - - var net1, net2 = tID + "net-1", tID + "net-2" - var label1 = tID + "=label-1" - netID1 := base.Cmd("network", "create", "--label="+label1, net1).Out() - defer base.Cmd("network", "rm", "-f", netID1).Run() - - netID2 := base.Cmd("network", "create", net2).Out() - defer base.Cmd("network", "rm", "-f", netID2).Run() + nerdtest.Setup() - base.Cmd("network", "ls", "--quiet", "--filter", "label="+tID).AssertOutWithFunc(func(stdout string) error { - var lines = strings.Split(strings.TrimSpace(stdout), "\n") - if len(lines) < 1 { - return errors.New("expected at least 1 lines") - } - netNames := map[string]struct{}{ - netID1[:12]: {}, - } + testCase := &test.Case{ + Description: "Test network list", + Setup: func(data test.Data, helpers test.Helpers) { + data.Set("identifier", data.Identifier()) + data.Set("label", data.Identifier()+"=label-1") + data.Set("netID1", helpers.Capture("network", "create", "--label="+data.Get("label"), data.Identifier()+"-1")) + data.Set("netID2", helpers.Capture("network", "create", data.Identifier()+"-2")) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()+"-1") + helpers.Anyhow("network", "rm", data.Identifier()+"-2") + }, + SubTests: []*test.Case{ + { + Description: "filter label", + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "ls", "--quiet", "--filter", "label="+data.Get("label")) + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: func(stdout string, info string, t *testing.T) { + var lines = strings.Split(strings.TrimSpace(stdout), "\n") + assert.Assert(t, len(lines) >= 1, info) + netNames := map[string]struct{}{ + data.Get("netID1")[:12]: {}, + } - for _, name := range lines { - _, ok := netNames[name] - if !ok { - return fmt.Errorf("unexpected netume %s found", name) - } - } - return nil - }) + for _, name := range lines { + _, ok := netNames[name] + assert.Assert(t, ok, info) + } + }, + } + }, + }, + { + Description: "filter name", + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "ls", "--quiet", "--filter", "name="+data.Get("identifier")+"-2") + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: func(stdout string, info string, t *testing.T) { + var lines = strings.Split(strings.TrimSpace(stdout), "\n") + assert.Assert(t, len(lines) >= 1, info) + netNames := map[string]struct{}{ + data.Get("netID2")[:12]: {}, + } - base.Cmd("network", "ls", "--quiet", "--filter", "name="+net2).AssertOutWithFunc(func(stdout string) error { - var lines = strings.Split(strings.TrimSpace(stdout), "\n") - if len(lines) < 1 { - return errors.New("expected at least 1 lines") - } - netNames := map[string]struct{}{ - netID2[:12]: {}, - } + for _, name := range lines { + _, ok := netNames[name] + assert.Assert(t, ok, info) + } + }, + } + }, + }, + }, + } - for _, name := range lines { - _, ok := netNames[name] - if !ok { - return fmt.Errorf("unexpected netume %s found", name) - } - } - return nil - }) + testCase.Run(t) } diff --git a/cmd/nerdctl/network/network_prune_linux_test.go b/cmd/nerdctl/network/network_prune_linux_test.go index cb137c4c68f..1692ac55053 100644 --- a/cmd/nerdctl/network/network_prune_linux_test.go +++ b/cmd/nerdctl/network/network_prune_linux_test.go @@ -20,19 +20,52 @@ import ( "testing" "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) func TestNetworkPrune(t *testing.T) { - base := testutil.NewBase(t) - testNetwork := testutil.Identifier(t) - base.Cmd("network", "create", testNetwork).AssertOK() - defer base.Cmd("network", "prune", "-f").Run() - - tID := testutil.Identifier(t) - base.Cmd("run", "-d", "--net", testNetwork, "--name", tID, testutil.NginxAlpineImage).AssertOK() - defer base.Cmd("rm", "-f", tID).Run() - - base.Cmd("network", "prune", "-f").AssertOutNotContains(testNetwork) - base.Cmd("stop", tID).AssertOK() - base.Cmd("network", "prune", "-f").AssertOutContains(testNetwork) + nerdtest.Setup() + + testGroup := &test.Group{ + { + Description: "Prune does not collect started container network", + Require: nerdtest.Private, + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + helpers.Ensure("run", "-d", "--net", data.Identifier(), "--name", data.Identifier(), testutil.NginxAlpineImage) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rm", "-f", data.Identifier()) + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Command: test.RunCommand("network", "prune", "-f"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.DoesNotContain(data.Identifier()), + } + }, + }, + { + Description: "Prune does collect stopped container network", + Require: nerdtest.Private, + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + helpers.Ensure("run", "-d", "--net", data.Identifier(), "--name", data.Identifier(), testutil.NginxAlpineImage) + helpers.Ensure("stop", data.Identifier()) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rm", "-f", data.Identifier()) + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Command: test.RunCommand("network", "prune", "-f"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Identifier()), + } + }, + }, + } + + testGroup.Run(t) } diff --git a/cmd/nerdctl/network/network_remove_linux_test.go b/cmd/nerdctl/network/network_remove_linux_test.go index 7b8acb7b4b8..9e5bbaf200a 100644 --- a/cmd/nerdctl/network/network_remove_linux_test.go +++ b/cmd/nerdctl/network/network_remove_linux_test.go @@ -17,99 +17,124 @@ package network import ( + "errors" "testing" "github.com/vishvananda/netlink" "gotest.tools/v3/assert" - "github.com/containerd/nerdctl/v2/pkg/rootlessutil" "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) func TestNetworkRemove(t *testing.T) { - if rootlessutil.IsRootless() { - t.Skip("test skipped for remove rootless network") + nerdtest.Setup() + + testCase := &test.Case{ + Description: "TestNetworkRemove", + Require: test.Not(nerdtest.Rootless), + SubTests: []*test.Case{ + { + Description: "Simple network remove", + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + data.Set("netID", nerdtest.InspectNetwork(helpers, data.Identifier()).ID) + helpers.Ensure("run", "--rm", "--net", data.Identifier(), "--name", data.Identifier(), testutil.CommonImage) + // Verity the network is here + _, err := netlink.LinkByName("br-" + data.Get("netID")[:12]) + assert.NilError(t, err, "failed to find network br-"+data.Get("netID")[:12], "%v") + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "rm", data.Identifier()) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + _, err := netlink.LinkByName("br-" + data.Get("netID")[:12]) + assert.Error(t, err, "Link not found", info) + }, + } + }, + }, + { + Description: "Network remove when linked to container", + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + helpers.Ensure("run", "-d", "--net", data.Identifier(), "--name", data.Identifier(), testutil.CommonImage, "sleep", "infinity") + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "rm", data.Identifier()) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rm", "-f", data.Identifier()) + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 1, + Errors: []error{errors.New("is in use")}, + } + }, + }, + { + Description: "Network remove by id", + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + data.Set("netID", nerdtest.InspectNetwork(helpers, data.Identifier()).ID) + helpers.Ensure("run", "--rm", "--net", data.Identifier(), "--name", data.Identifier(), testutil.CommonImage) + // Verity the network is here + _, err := netlink.LinkByName("br-" + data.Get("netID")[:12]) + assert.NilError(t, err, "failed to find network br-"+data.Get("netID")[:12], "%v") + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "rm", data.Get("netID")) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + _, err := netlink.LinkByName("br-" + data.Get("netID")[:12]) + assert.Error(t, err, "Link not found", info) + }, + } + }, + }, + { + Description: "Network remove by short id", + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + data.Set("netID", nerdtest.InspectNetwork(helpers, data.Identifier()).ID) + helpers.Ensure("run", "--rm", "--net", data.Identifier(), "--name", data.Identifier(), testutil.CommonImage) + // Verity the network is here + _, err := netlink.LinkByName("br-" + data.Get("netID")[:12]) + assert.NilError(t, err, "failed to find network br-"+data.Get("netID")[:12], "%v") + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("network", "rm", data.Get("netID")[:12]) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + }, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + _, err := netlink.LinkByName("br-" + data.Get("netID")[:12]) + assert.Error(t, err, "Link not found", info) + }, + } + }, + }, + }, } - base := testutil.NewBase(t) - networkName := testutil.Identifier(t) - base.Cmd("network", "create", networkName).AssertOK() - defer base.Cmd("network", "rm", networkName).Run() - - networkID := base.InspectNetwork(networkName).ID - - tID := testutil.Identifier(t) - base.Cmd("run", "--rm", "--net", networkName, "--name", tID, testutil.CommonImage).AssertOK() - - _, err := netlink.LinkByName("br-" + networkID[:12]) - assert.NilError(t, err) - - base.Cmd("network", "rm", networkName).AssertOK() - - _, err = netlink.LinkByName("br-" + networkID[:12]) - assert.Error(t, err, "Link not found") -} - -func TestNetworkRemoveWhenLinkWithContainer(t *testing.T) { - if rootlessutil.IsRootless() { - t.Skip("test skipped for remove rootless network") - } - base := testutil.NewBase(t) - networkName := testutil.Identifier(t) - - base.Cmd("network", "create", networkName).AssertOK() - defer base.Cmd("network", "rm", networkName).AssertOK() - - tID := testutil.Identifier(t) - base.Cmd("run", "-d", "--net", networkName, "--name", tID, testutil.AlpineImage, "sleep", "infinity").AssertOK() - defer base.Cmd("rm", "-f", tID).Run() - base.Cmd("network", "rm", networkName).AssertFail() -} - -func TestNetworkRemoveById(t *testing.T) { - if rootlessutil.IsRootless() { - t.Skip("test skipped for remove rootless network") - } - base := testutil.NewBase(t) - networkName := testutil.Identifier(t) - - base.Cmd("network", "create", networkName).AssertOK() - defer base.Cmd("network", "rm", networkName).Run() - - networkID := base.InspectNetwork(networkName).ID - - tID := testutil.Identifier(t) - base.Cmd("run", "--rm", "--net", networkName, "--name", tID, testutil.CommonImage).AssertOK() - - _, err := netlink.LinkByName("br-" + networkID[:12]) - assert.NilError(t, err) - - base.Cmd("network", "rm", networkID).AssertOK() - - _, err = netlink.LinkByName("br-" + networkID[:12]) - assert.Error(t, err, "Link not found") -} - -func TestNetworkRemoveByShortId(t *testing.T) { - if rootlessutil.IsRootless() { - t.Skip("test skipped for remove rootless network") - } - base := testutil.NewBase(t) - networkName := testutil.Identifier(t) - - base.Cmd("network", "create", networkName).AssertOK() - defer base.Cmd("network", "rm", networkName).Run() - - networkID := base.InspectNetwork(networkName).ID - - tID := testutil.Identifier(t) - base.Cmd("run", "--rm", "--net", networkName, "--name", tID, testutil.CommonImage).AssertOK() - - _, err := netlink.LinkByName("br-" + networkID[:12]) - assert.NilError(t, err) - - base.Cmd("network", "rm", networkID[:12]).AssertOK() - - _, err = netlink.LinkByName("br-" + networkID[:12]) - assert.Error(t, err, "Link not found") + testCase.Run(t) } diff --git a/cmd/nerdctl/system/system_events_linux_test.go b/cmd/nerdctl/system/system_events_linux_test.go index 5838e710866..c12d0161576 100644 --- a/cmd/nerdctl/system/system_events_linux_test.go +++ b/cmd/nerdctl/system/system_events_linux_test.go @@ -17,96 +17,84 @@ package system import ( - "fmt" - "strings" "testing" "time" - "gotest.tools/v3/assert" - "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) -func testEventFilter(t *testing.T, args ...string) string { - t.Parallel() - base := testutil.NewBase(t) - testContainerName := testutil.Identifier(t) - defer base.Cmd("rm", "-f", testContainerName).Run() - - fullArgs := []string{"events", "--filter"} - fullArgs = append(fullArgs, args...) - fullArgs = append(fullArgs, - "--format", - "json", - ) - - eventsCmd := base.Cmd(fullArgs...).Start() - base.Cmd("run", "--rm", testutil.CommonImage).Start() - time.Sleep(3 * time.Second) - return eventsCmd.Stdout() +func testEventFilterExecutor(data test.Data, helpers test.Helpers) test.Command { + cmd := helpers.Command("events", "--filter", data.Get("filter"), "--format", "json") + cmd.Background(1 * time.Second) + helpers.Ensure("run", "--rm", testutil.CommonImage) + return cmd } func TestEventFilters(t *testing.T) { + nerdtest.Setup() - type testCase struct { - name string - args []string - nerdctlOut string - dockerOut string - dockerSkip bool - } - testCases := []testCase{ + testGroup := &test.Group{ { - name: "CapitializedFilter", - args: []string{"event=START"}, - nerdctlOut: "\"Status\":\"start\"", - dockerOut: "\"status\":\"start\"", - dockerSkip: true, + Description: "CapitalizedFilter", + Require: test.Not(nerdtest.Docker), + Command: testEventFilterExecutor, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Get("output")), + } + }, + Data: test.WithData("filter", "event=START"). + Set("output", "\"Status\":\"start\""), }, { - name: "StartEventFilter", - args: []string{"event=start"}, - nerdctlOut: "\"Status\":\"start\"", - dockerOut: "\"status\":\"start\"", - dockerSkip: false, + Description: "StartEventFilter", + Command: testEventFilterExecutor, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Get("output")), + } + }, + Data: test.WithData("filter", "event=start"). + Set("output", "tatus\":\"start\""), }, { - name: "UnsupportedEventFilter", - args: []string{"event=unknown"}, - nerdctlOut: "\"Status\":\"unknown\"", - dockerSkip: true, + Description: "UnsupportedEventFilter", + Require: test.Not(nerdtest.Docker), + Command: testEventFilterExecutor, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Get("output")), + } + }, + Data: test.WithData("filter", "event=unknown"). + Set("output", "\"Status\":\"unknown\""), }, { - name: "StatusFilter", - args: []string{"status=start"}, - nerdctlOut: "\"Status\":\"start\"", - dockerOut: "\"status\":\"start\"", - dockerSkip: false, + Description: "StatusFilter", + Command: testEventFilterExecutor, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Get("output")), + } + }, + Data: test.WithData("filter", "status=start"). + Set("output", "tatus\":\"start\""), }, { - name: "UnsupportedStatusFilter", - args: []string{"status=unknown"}, - nerdctlOut: "\"Status\":\"unknown\"", - dockerSkip: true, + Description: "UnsupportedStatusFilter", + Require: test.Not(nerdtest.Docker), + Command: testEventFilterExecutor, + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: test.Contains(data.Get("output")), + } + }, + Data: test.WithData("filter", "status=unknown"). + Set("output", "\"Status\":\"unknown\""), }, } - for _, tc := range testCases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - actualOut := testEventFilter(t, tc.args...) - errorMsg := fmt.Sprintf("%s failed;\nActual Filter Result: '%s'", tc.name, actualOut) - - isDocker := testutil.GetTarget() == testutil.Docker - if isDocker && tc.dockerSkip { - t.Skip("test is incompatible with Docker") - } - - if isDocker { - assert.Equal(t, true, strings.Contains(actualOut, tc.dockerOut), errorMsg) - } else { - assert.Equal(t, true, strings.Contains(actualOut, tc.nerdctlOut), errorMsg) - } - }) - } + testGroup.Run(t) } diff --git a/cmd/nerdctl/system/system_info_test.go b/cmd/nerdctl/system/system_info_test.go index 3a10033930d..3c8f5c252da 100644 --- a/cmd/nerdctl/system/system_info_test.go +++ b/cmd/nerdctl/system/system_info_test.go @@ -21,41 +21,56 @@ import ( "fmt" "testing" + "gotest.tools/v3/assert" + "github.com/containerd/nerdctl/v2/pkg/infoutil" "github.com/containerd/nerdctl/v2/pkg/inspecttypes/dockercompat" - "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) -func testInfoJSON(stdout string) error { - var info dockercompat.Info - if err := json.Unmarshal([]byte(stdout), &info); err != nil { - return err - } +func testInfoComparator(stdout string, info string, t *testing.T) { + var dinf dockercompat.Info + err := json.Unmarshal([]byte(stdout), &dinf) + assert.NilError(t, err, "failed to unmarshal stdout"+info) unameM := infoutil.UnameM() - if info.Architecture != unameM { - return fmt.Errorf("expected info.Architecture to be %q, got %q", unameM, info.Architecture) - } - return nil + assert.Assert(t, dinf.Architecture == unameM, fmt.Sprintf("expected info.Architecture to be %q, got %q", unameM, dinf.Architecture)+info) } func TestInfo(t *testing.T) { - base := testutil.NewBase(t) - base.Cmd("info", "--format", "{{json .}}").AssertOutWithFunc(testInfoJSON) -} + nerdtest.Setup() -func TestInfoConvenienceForm(t *testing.T) { - testutil.DockerIncompatible(t) // until https://github.com/docker/cli/pull/3355 gets merged - base := testutil.NewBase(t) - base.Cmd("info", "--format", "json").AssertOutWithFunc(testInfoJSON) -} - -func TestInfoWithNamespace(t *testing.T) { - testutil.DockerIncompatible(t) - base := testutil.NewBase(t) - base.Args = nil // unset "--namespace=nerdctl-test" - - base.Cmd("info").AssertOutContains("Namespace: default") + testGroup := &test.Group{ + { + Description: "info", + Command: test.RunCommand("info", "--format", "{{json .}}"), + Expected: test.Expects(0, nil, testInfoComparator), + }, + { + Description: "info convenience form", + Command: test.RunCommand("info", "--format", "json"), + Expected: test.Expects(0, nil, testInfoComparator), + }, + { + Description: "info with namespace", + Require: test.Not(nerdtest.Docker), + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command().Clear().WithBinary("nerdctl").WithArgs("info") + }, + Expected: test.Expects(0, nil, test.Contains("Namespace: default")), + }, + { + Description: "info with namespace env var", + Env: map[string]string{ + "CONTAINERD_NAMESPACE": "test", + }, + Require: test.Not(nerdtest.Docker), + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command().Clear().WithBinary("nerdctl").WithArgs("info") + }, + Expected: test.Expects(0, nil, test.Contains("Namespace: test")), + }, + } - base.Env = append(base.Env, "CONTAINERD_NAMESPACE=test") - base.Cmd("info").AssertOutContains("Namespace: test") + testGroup.Run(t) } diff --git a/cmd/nerdctl/system/system_prune_linux_test.go b/cmd/nerdctl/system/system_prune_linux_test.go index d792282398f..40d08f1beea 100644 --- a/cmd/nerdctl/system/system_prune_linux_test.go +++ b/cmd/nerdctl/system/system_prune_linux_test.go @@ -17,86 +17,90 @@ package system import ( - "bytes" "fmt" - "io" - "os" - "os/exec" "strings" "testing" - "github.com/containerd/log" + "gotest.tools/v3/assert" "github.com/containerd/nerdctl/v2/pkg/buildkitutil" "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) func TestSystemPrune(t *testing.T) { - testutil.RequiresBuild(t) - // FIXME: using a dedicated namespace does not work with rootful (because of buildkit running) - // t.Parallel() - // namespaceID := testutil.Identifier(t) - // base := testutil.NewBaseWithNamespace(t, namespaceID) - base := testutil.NewBase(t) - base.Cmd("container", "prune", "-f").AssertOK() - base.Cmd("network", "prune", "-f").AssertOK() - base.Cmd("volume", "prune", "-f").AssertOK() - base.Cmd("image", "prune", "-f", "--all").AssertOK() - - nID := testutil.Identifier(t) - base.Cmd("network", "create", nID).AssertOK() - defer base.Cmd("network", "rm", nID).Run() - - vID := testutil.Identifier(t) - base.Cmd("volume", "create", vID).AssertOK() - defer base.Cmd("volume", "rm", vID).Run() - - vID2 := base.Cmd("volume", "create").Out() - defer base.Cmd("volume", "rm", vID2).Run() - - tID := testutil.Identifier(t) - base.Cmd("run", "-v", fmt.Sprintf("%s:/volume", vID), "--net", nID, - "--name", tID, testutil.CommonImage).AssertOK() - defer base.Cmd("rm", "-f", tID).Run() - - base.Cmd("ps", "-a").AssertOutContains(tID) - base.Cmd("images").AssertOutContains(testutil.ImageRepo(testutil.CommonImage)) - - base.Cmd("system", "prune", "-f", "--volumes", "--all").AssertOK() - base.Cmd("volume", "ls").AssertOutContains(vID) // docker system prune --all --volume does not prune named volume - base.Cmd("volume", "ls").AssertOutNotContains(vID2) // docker system prune --all --volume prune anonymous volume - base.Cmd("ps", "-a").AssertOutNotContains(tID) - base.Cmd("network", "ls").AssertOutNotContains(nID) - base.Cmd("images").AssertOutNotContains(testutil.ImageRepo(testutil.CommonImage)) - - if testutil.GetTarget() != testutil.Nerdctl { - t.Skip("test skipped for buildkitd is not available with docker-compatible tests") + nerdtest.Setup() + + testGroup := &test.Group{ + { + Description: "volume prune all success", + // Private because of prune evidently + Require: nerdtest.Private, + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("network", "create", data.Identifier()) + helpers.Ensure("volume", "create", data.Identifier()) + anonIdentifier := helpers.Capture("volume", "create") + helpers.Ensure("run", "-v", fmt.Sprintf("%s:/volume", data.Identifier()), + "--net", data.Identifier(), "--name", data.Identifier(), testutil.CommonImage) + + data.Set("anonIdentifier", anonIdentifier) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("network", "rm", data.Identifier()) + helpers.Anyhow("volume", "rm", data.Identifier()) + helpers.Anyhow("volume", "rm", data.Get("anonIdentifier")) + helpers.Anyhow("rm", "-f", data.Identifier()) + }, + Command: test.RunCommand("system", "prune", "-f", "--volumes", "--all"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + volumes := helpers.Capture("volume", "ls") + networks := helpers.Capture("network", "ls") + images := helpers.Capture("images") + containers := helpers.Capture("ps", "-a") + assert.Assert(t, strings.Contains(volumes, data.Identifier()), volumes) + assert.Assert(t, !strings.Contains(volumes, data.Get("anonIdentifier")), volumes) + assert.Assert(t, !strings.Contains(containers, data.Identifier()), containers) + assert.Assert(t, !strings.Contains(networks, data.Identifier()), networks) + assert.Assert(t, !strings.Contains(images, testutil.CommonImage), images) + }, + } + }, + }, + { + Description: "buildkit", + // FIXME: using a dedicated namespace does not work with rootful (because of buildkitd) + NoParallel: true, + // buildkitd is not available with docker + Require: test.Require(nerdtest.Build, test.Not(nerdtest.Docker)), + // FIXME: this test will happily say "green" even if the command actually fails to do its duty + // if there is nothing in the build cache. + // Ensure with setup here that we DO build something first + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("system", "prune", "-f", "--volumes", "--all") + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + buildctlBinary, err := buildkitutil.BuildctlBinary() + if err != nil { + t.Fatal(err) + } + + host, err := buildkitutil.GetBuildkitHost(testutil.Namespace) + if err != nil { + t.Fatal(err) + } + + buildctlArgs := buildkitutil.BuildctlBaseArgs(host) + buildctlArgs = append(buildctlArgs, "du") + + return helpers.CustomCommand(buildctlBinary, buildctlArgs...) + }, + Expected: test.Expects(0, nil, test.Contains("Total:\t\t0B")), + }, } - buildctlBinary, err := buildkitutil.BuildctlBinary() - if err != nil { - t.Fatal(err) - } - host, err := buildkitutil.GetBuildkitHost(testutil.Namespace) - if err != nil { - t.Fatal(err) - } - - buildctlArgs := buildkitutil.BuildctlBaseArgs(host) - buildctlArgs = append(buildctlArgs, "du") - log.L.Debugf("running %s %v", buildctlBinary, buildctlArgs) - buildctlCmd := exec.Command(buildctlBinary, buildctlArgs...) - buildctlCmd.Env = os.Environ() - stdout := bytes.NewBuffer(nil) - buildctlCmd.Stdout = stdout - if err := buildctlCmd.Run(); err != nil { - t.Fatal(err) - } - readAll, err := io.ReadAll(stdout) - if err != nil { - t.Fatal(err) - } - if !strings.Contains(string(readAll), "Total:\t\t0B") { - t.Errorf("buildkit cache is not pruned: %s", string(readAll)) - } + testGroup.Run(t) }