Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Part 5: tests #3550

Merged
merged 3 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 59 additions & 65 deletions cmd/nerdctl/container/container_commit_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,76 +21,70 @@ 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"
)

/*
This test below is meant to assert that https://github.com/containerd/nerdctl/issues/827 is NOT fixed.
Obviously, once we fix the issue, it should be replaced by something that assert it works.
Unfortunately, this is flaky.
It will regularly succeed or fail, making random PR fail the Kube check.
*/

func TestKubeCommitPush(t *testing.T) {
t.Parallel()

base := testutil.NewBaseForKubernetes(t)
tID := testutil.Identifier(t)

var containerID string
// var registryIP string

setup := func() {
testutil.KubectlHelper(base, "run", "--image", testutil.CommonImage, tID, "--", "sleep", "Inf").
AssertOK()

testutil.KubectlHelper(base, "wait", "pod", tID, "--for=condition=ready", "--timeout=1m").
AssertOK()

testutil.KubectlHelper(base, "exec", tID, "--", "mkdir", "-p", "/tmp/whatever").
AssertOK()

cmd := testutil.KubectlHelper(base, "get", "pods", tID, "-o", "jsonpath={ .status.containerStatuses[0].containerID }")
cmd.Run()
containerID = strings.TrimPrefix(cmd.Out(), "containerd://")

// This below is missing configuration to allow for plain http communication
// This is left here for future work to successfully start a registry usable in the cluster
/*
// Start a registry
testutil.KubectlHelper(base, "run", "--port", "5000", "--image", testutil.RegistryImageStable, "testregistry").
AssertOK()

testutil.KubectlHelper(base, "wait", "pod", "testregistry", "--for=condition=ready", "--timeout=1m").
AssertOK()

cmd = testutil.KubectlHelper(base, "get", "pods", tID, "-o", "jsonpath={ .status.hostIPs[0].ip }")
cmd.Run()
registryIP = cmd.Out()

cmd = testutil.KubectlHelper(base, "apply", "-f", "-", fmt.Sprintf(`apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry
namespace: nerdctl-test
data:
localRegistryHosting.v1: |
host: "%s:5000"
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
`, registryIP))
*/

func TestKubeCommitSave(t *testing.T) {
testCase := nerdtest.Setup()

testCase.Require = nerdtest.OnlyKubernetes

testCase.Setup = func(data test.Data, helpers test.Helpers) {
containerID := ""
// NOTE: kubectl namespaces are not the same as containerd namespaces.
// We still want kube test objects segregated in their own Kube API namespace.
nerdtest.KubeCtlCommand(helpers, "create", "namespace", "nerdctl-test-k8s").Run(&test.Expected{})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nerdctl-test-k8s should a constant

nerdtest.KubeCtlCommand(helpers, "run", "--image", testutil.CommonImage, data.Identifier(), "--", "sleep", "Inf").Run(&test.Expected{})
nerdtest.KubeCtlCommand(helpers, "wait", "pod", data.Identifier(), "--for=condition=ready", "--timeout=1m").Run(&test.Expected{})
nerdtest.KubeCtlCommand(helpers, "exec", data.Identifier(), "--", "mkdir", "-p", "/tmp/whatever").Run(&test.Expected{})
nerdtest.KubeCtlCommand(helpers, "get", "pods", data.Identifier(), "-o", "jsonpath={ .status.containerStatuses[0].containerID }").Run(&test.Expected{
Output: func(stdout string, info string, t *testing.T) {
containerID = strings.TrimPrefix(stdout, "containerd://")
},
})
Comment on lines +38 to +45
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need to specify the namespace nerdctl-test-k8s explicitly?

Copy link
Contributor Author

@apostasie apostasie Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary per-se, but was asked for when the k8s env was introduced: #3296 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary per-se

will these commands be run in the default namespace or in nerdctl-test-k8s?

Copy link
Contributor Author

@apostasie apostasie Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k8s namespaces are not the same as containerd namespaces (yeah, really confusing).

Commands run by nerdctl for this environment are run inside the k8s.io containerd namespace (instead of the nerdctl-test usual namespace).

Then nerdctl-test-k8s is a k8 namespace, unrelated.

data.Set("containerID", containerID)
}

tearDown := func() {
testutil.KubectlHelper(base, "delete", "pod", "--all").Run()
testCase.Cleanup = func(data test.Data, helpers test.Helpers) {
nerdtest.KubeCtlCommand(helpers, "delete", "pod", "--all").Run(nil)
}

tearDown()
t.Cleanup(tearDown)
setup()
testCase.Command = func(data test.Data, helpers test.Helpers) test.TestableCommand {
helpers.Ensure("commit", data.Get("containerID"), "testcommitsave")
return helpers.Command("save", "testcommitsave")
}

t.Run("test commit / push on Kube (https://github.com/containerd/nerdctl/issues/827)", func(t *testing.T) {
base.Cmd("commit", containerID, "testcommitsave").AssertOK()
base.Cmd("save", "testcommitsave").AssertOK()
})
testCase.Expected = test.Expects(0, nil, nil)

testCase.Run(t)

// This below is missing configuration to allow for plain http communication
// This is left here for future work to successfully start a registry usable in the cluster
/*
// Start a registry
nerdtest.KubeCtlCommand(helpers, "run", "--port", "5000", "--image", testutil.RegistryImageStable, "testregistry").
Run(&test.Expected{})

nerdtest.KubeCtlCommand(helpers, "wait", "pod", "testregistry", "--for=condition=ready", "--timeout=1m").
AssertOK()

cmd = nerdtest.KubeCtlCommand(helpers, "get", "pods", tID, "-o", "jsonpath={ .status.hostIPs[0].ip }")
cmd.Run(&test.Expected{
Output: func(stdout string, info string, t *testing.T) {
registryIP = stdout
},
})

cmd = nerdtest.KubeCtlCommand(helpers, "apply", "-f", "-", fmt.Sprintf(`apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry
namespace: nerdctl-test
data:
localRegistryHosting.v1: |
host: "%s:5000"
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
`, registryIP))
*/
}
81 changes: 53 additions & 28 deletions cmd/nerdctl/container/container_commit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,64 @@
package container

import (
"fmt"
"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 TestCommit(t *testing.T) {
t.Parallel()
base := testutil.NewBase(t)
switch base.Info().CgroupDriver {
case "none", "":
t.Skip("requires cgroup (for pausing)")
}
testContainer := testutil.Identifier(t)
testImage := testutil.Identifier(t) + "-img"
defer base.Cmd("rm", "-f", testContainer).Run()
defer base.Cmd("rmi", testImage).Run()

for _, pause := range []string{
"true",
"false",
} {
base.Cmd("run", "-d", "--name", testContainer, testutil.CommonImage, "sleep", "infinity").AssertOK()
base.EnsureContainerStarted(testContainer)
base.Cmd("exec", testContainer, "sh", "-euxc", `echo hello-test-commit > /foo`).AssertOK()
base.Cmd(
"commit",
"-c", `CMD ["/foo"]`,
"-c", `ENTRYPOINT ["cat"]`,
fmt.Sprintf("--pause=%s", pause),
testContainer, testImage).AssertOK()
base.Cmd("run", "--rm", testImage).AssertOutExactly("hello-test-commit\n")
base.Cmd("rm", "-f", testContainer).Run()
base.Cmd("rmi", testImage).Run()
testCase := nerdtest.Setup()

testCase.SubTests = []*test.Case{
{
Description: "with pause",
Require: nerdtest.CGroup,
Cleanup: func(data test.Data, helpers test.Helpers) {
helpers.Anyhow("rm", "-f", data.Identifier())
helpers.Anyhow("rmi", "-f", data.Identifier())
},
Setup: func(data test.Data, helpers test.Helpers) {
helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage, "sleep", "infinity")
nerdtest.EnsureContainerStarted(helpers, data.Identifier())
helpers.Ensure("exec", data.Identifier(), "sh", "-euxc", `echo hello-test-commit > /foo`)
},
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
helpers.Ensure(
"commit",
"-c", `CMD ["/foo"]`,
"-c", `ENTRYPOINT ["cat"]`,
"--pause=true",
data.Identifier(), data.Identifier())
return helpers.Command("run", "--rm", data.Identifier())
},
Expected: test.Expects(0, nil, test.Equals("hello-test-commit\n")),
},
{
Description: "no pause",
Require: test.Not(test.Windows),
Cleanup: func(data test.Data, helpers test.Helpers) {
helpers.Anyhow("rm", "-f", data.Identifier())
helpers.Anyhow("rmi", "-f", data.Identifier())
},
Setup: func(data test.Data, helpers test.Helpers) {
helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage, "sleep", "infinity")
nerdtest.EnsureContainerStarted(helpers, data.Identifier())
helpers.Ensure("exec", data.Identifier(), "sh", "-euxc", `echo hello-test-commit > /foo`)
},
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
helpers.Ensure(
"commit",
"-c", `CMD ["/foo"]`,
"-c", `ENTRYPOINT ["cat"]`,
"--pause=false",
data.Identifier(), data.Identifier())
return helpers.Command("run", "--rm", data.Identifier())
},
Expected: test.Expects(0, nil, test.Equals("hello-test-commit\n")),
},
}

testCase.Run(t)
}
25 changes: 13 additions & 12 deletions cmd/nerdctl/issues/issues_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,24 @@ import (

"github.com/containerd/nerdctl/v2/pkg/testutil"
"github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest"
"github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest/registry"
"github.com/containerd/nerdctl/v2/pkg/testutil/test"
"github.com/containerd/nerdctl/v2/pkg/testutil/testregistry"
)

func TestIssue3425(t *testing.T) {
nerdtest.Setup()

var registry *testregistry.RegistryServer
var reg *registry.Server

testCase := &test.Case{
Require: nerdtest.Registry,
Setup: func(data test.Data, helpers test.Helpers) {
base := testutil.NewBase(t)
registry = testregistry.NewWithNoAuth(base, 0, false)
reg = nerdtest.RegistryWithNoAuth(data, helpers, 0, false)
reg.Setup(data, helpers)
},
Cleanup: func(data test.Data, helpers test.Helpers) {
if registry != nil {
registry.Cleanup(nil)
if reg != nil {
reg.Cleanup(data, helpers)
}
},
SubTests: []*test.Case{
Expand All @@ -52,14 +53,14 @@ func TestIssue3425(t *testing.T) {
helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage)
helpers.Ensure("image", "rm", "-f", testutil.CommonImage)
helpers.Ensure("image", "pull", testutil.CommonImage)
helpers.Ensure("tag", testutil.CommonImage, fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier()))
helpers.Ensure("tag", testutil.CommonImage, fmt.Sprintf("localhost:%d/%s", reg.Port, data.Identifier()))
},
Cleanup: func(data test.Data, helpers test.Helpers) {
helpers.Anyhow("rm", "-f", data.Identifier())
helpers.Anyhow("rmi", "-f", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier()))
helpers.Anyhow("rmi", "-f", fmt.Sprintf("localhost:%d/%s", reg.Port, data.Identifier()))
},
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("push", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier()))
return helpers.Command("push", fmt.Sprintf("localhost:%d/%s", reg.Port, data.Identifier()))
},
Expected: test.Expects(0, nil, nil),
},
Expand All @@ -71,14 +72,14 @@ func TestIssue3425(t *testing.T) {
helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage, "touch", "/something")
helpers.Ensure("image", "rm", "-f", testutil.CommonImage)
helpers.Ensure("image", "pull", testutil.CommonImage)
helpers.Ensure("commit", data.Identifier(), fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier()))
helpers.Ensure("commit", data.Identifier(), fmt.Sprintf("localhost:%d/%s", reg.Port, data.Identifier()))
},
Cleanup: func(data test.Data, helpers test.Helpers) {
helpers.Anyhow("rm", "-f", data.Identifier())
helpers.Anyhow("rmi", "-f", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier()))
helpers.Anyhow("rmi", "-f", fmt.Sprintf("localhost:%d/%s", reg.Port, data.Identifier()))
},
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("push", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier()))
return helpers.Command("push", fmt.Sprintf("localhost:%d/%s", reg.Port, data.Identifier()))
},
Expected: test.Expects(0, nil, nil),
},
Expand Down
9 changes: 5 additions & 4 deletions cmd/nerdctl/login/login_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

"github.com/containerd/nerdctl/v2/pkg/imgutil/dockerconfigresolver"
"github.com/containerd/nerdctl/v2/pkg/testutil"
"github.com/containerd/nerdctl/v2/pkg/testutil/test"
"github.com/containerd/nerdctl/v2/pkg/testutil/testca"
"github.com/containerd/nerdctl/v2/pkg/testutil/testregistry"
)
Expand Down Expand Up @@ -108,8 +109,8 @@ func TestLoginPersistence(t *testing.T) {
t.Run(fmt.Sprintf("Server %s", tc.auth), func(t *testing.T) {
t.Parallel()

username := testregistry.SafeRandomString(30) + "∞"
password := testregistry.SafeRandomString(30) + ":∞"
username := test.RandomStringBase64(30) + "∞"
password := test.RandomStringBase64(30) + ":∞"

// Add the requested authentication
var auth testregistry.Auth
Expand Down Expand Up @@ -297,8 +298,8 @@ func TestLoginAgainstVariants(t *testing.T) {
}

// Generate credentials that are specific to each registry, so that we never cross hit another one
username := testregistry.SafeRandomString(30) + "∞"
password := testregistry.SafeRandomString(30) + ":∞"
username := test.RandomStringBase64(30) + "∞"
password := test.RandomStringBase64(30) + ":∞"

// Get a CA if we want TLS
var ca *testca.CA
Expand Down
7 changes: 6 additions & 1 deletion pkg/testutil/nerdtest/requirements.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,13 @@ var OnlyIPv6 = &test.Requirement{
var OnlyKubernetes = &test.Requirement{
Check: func(data test.Data, helpers test.Helpers) (ret bool, mess string) {
helpers.Write(kubernetes, only)
if _, err := exec.LookPath("kubectl"); err != nil {
return false, fmt.Sprintf("kubectl is not in the path: %+v", err)
}
ret = environmentHasKubernetes()
if !ret {
if ret {
helpers.Write(Namespace, "k8s.io")
} else {
mess = "runner skips Kubernetes compatible tests in the non-Kubernetes environment"
}
return ret, mess
Expand Down
8 changes: 8 additions & 0 deletions pkg/testutil/nerdtest/third-party.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ func BuildCtlCommand(helpers test.Helpers, args ...string) test.TestableCommand
return cmd
}

func KubeCtlCommand(helpers test.Helpers, args ...string) test.TestableCommand {
kubectl, _ := exec.LookPath("kubectl")
cmd := helpers.Custom(kubectl)
cmd.WithArgs("--namespace=nerdctl-test-k8s")
cmd.WithArgs(args...)
return cmd
}

func RegistryWithTokenAuth(data test.Data, helpers test.Helpers, user, pass string, port int, tls bool) (*registry.Server, *registry.TokenAuthServer) {
rca := ca.New(data, helpers.T())
as := registry.NewCesantaAuthServer(data, helpers, rca, 0, user, pass, tls)
Expand Down
Loading