Skip to content

Commit

Permalink
Migrate container tests
Browse files Browse the repository at this point in the history
Signed-off-by: apostasie <[email protected]>
  • Loading branch information
apostasie committed Oct 11, 2024
1 parent 0953eba commit 161dc04
Show file tree
Hide file tree
Showing 28 changed files with 907 additions and 568 deletions.
158 changes: 88 additions & 70 deletions cmd/nerdctl/container/container_attach_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,81 +24,99 @@ import (
"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"
)

// skipAttachForDocker should be called by attach-related tests that assert 'read detach keys' in stdout.
func skipAttachForDocker(t *testing.T) {
t.Helper()
if testutil.GetTarget() == testutil.Docker {
t.Skip("When detaching from a container, for a session started with 'docker attach'" +
", it prints 'read escape sequence', but for one started with 'docker (run|start)', it prints nothing." +
" However, the flag is called '--detach-keys' in all cases" +
", so nerdctl prints 'read detach keys' for all cases" +
", and that's why this test is skipped for Docker.")
}
}

// prepareContainerToAttach spins up a container (entrypoint = shell) with `-it` and detaches from it
// so that it can be re-attached to later.
func prepareContainerToAttach(base *testutil.Base, containerName string) {
opts := []func(*testutil.Cmd){
testutil.WithStdin(testutil.NewDelayOnceReader(bytes.NewReader(
func TestAttachDetachKeys(t *testing.T) {
testCase := nerdtest.Setup()

setup := func(data test.Data, helpers test.Helpers) {
// unbuffer(1) emulates tty, which is required by `nerdctl run -t`.
// unbuffer(1) can be installed with `apt-get install expect`.
//
// "-p" is needed because we need unbuffer to read from stdin, and from [1]:
// "Normally, unbuffer does not read from stdin. This simplifies use of unbuffer in some situations.
// To use unbuffer in a pipeline, use the -p flag."
//
// [1] https://linux.die.net/man/1/unbuffer

si := testutil.NewDelayOnceReader(bytes.NewReader(
[]byte{16, 17}, // ctrl+p,ctrl+q, see https://www.physics.udel.edu/~watson/scen103/ascii.html
))),
))

cmd := helpers.
Command("run", "-it", "--name", data.Identifier(), testutil.CommonImage)
cmd.WithWrapper("unbuffer", "-p")
cmd.WithStdin(si)
cmd.Run(&test.Expected{
Output: test.All(
// NOTE:
// When detaching from a container, for a session started with 'docker attach',
// it prints 'read escape sequence', but for one started with 'docker (run|start)', it prints nothing.
// However, the flag is called '--detach-keys' in all cases, and nerdctl does print read detach keys
// in all cases.
// Disabling the contains test here allow both cli to run the test.
// test.Contains("read detach keys"),
func(stdout string, info string, t *testing.T) {
container := nerdtest.InspectContainer(helpers, data.Identifier())
assert.Equal(t, container.State.Running, true, info)
}),
})
}
// unbuffer(1) emulates tty, which is required by `nerdctl run -t`.
// unbuffer(1) can be installed with `apt-get install expect`.
//
// "-p" is needed because we need unbuffer to read from stdin, and from [1]:
// "Normally, unbuffer does not read from stdin. This simplifies use of unbuffer in some situations.
// To use unbuffer in a pipeline, use the -p flag."
//
// [1] https://linux.die.net/man/1/unbuffer
base.CmdWithHelper([]string{"unbuffer", "-p"}, "run", "-it", "--name", containerName, testutil.CommonImage).
CmdOption(opts...).AssertOutContains("read detach keys")
container := base.InspectContainer(containerName)
assert.Equal(base.T, container.State.Running, true)
}

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

skipAttachForDocker(t)

base := testutil.NewBase(t)
containerName := testutil.Identifier(t)

defer base.Cmd("container", "rm", "-f", containerName).AssertOK()
prepareContainerToAttach(base, containerName)

opts := []func(*testutil.Cmd){
testutil.WithStdin(testutil.NewDelayOnceReader(strings.NewReader("expr 1 + 1\nexit\n"))),
testCase.SubTests = []*test.Case{
{
Description: "TestAttachDefaultKeys",
Require: test.Binary("unbuffer"),
Cleanup: func(data test.Data, helpers test.Helpers) {
helpers.Anyhow("container", "rm", "-f", data.Identifier())
},
Setup: setup,
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
si := testutil.NewDelayOnceReader(strings.NewReader("expr 1 + 1\nexit\n"))
// `unbuffer -p` returns 0 even if the underlying nerdctl process returns a non-zero exit code,
// so the exit code cannot be easily tested here.
cmd := helpers.Command("attach", data.Identifier())
cmd.WithStdin(si)
cmd.WithWrapper("unbuffer", "-p")

return cmd
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
Output: func(stdout string, info string, t *testing.T) {
container := nerdtest.InspectContainer(helpers, data.Identifier())
assert.Equal(t, container.State.Running, false, info)
},
}
},
},
{
Description: "TestAttachCustomKeys",
Require: test.Binary("unbuffer"),
Cleanup: func(data test.Data, helpers test.Helpers) {
helpers.Anyhow("container", "rm", "-f", data.Identifier())
},
Setup: setup,
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
si := testutil.NewDelayOnceReader(bytes.NewReader([]byte{1, 2}))
cmd := helpers.
Command("attach", "--detach-keys=ctrl-a,ctrl-b", data.Identifier())
cmd.WithStdin(si)
cmd.WithWrapper("unbuffer", "-p")
return cmd
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
Output: func(stdout string, info string, t *testing.T) {
container := nerdtest.InspectContainer(helpers, data.Identifier())
assert.Equal(t, container.State.Running, true, info)
},
}
},
},
}
// `unbuffer -p` returns 0 even if the underlying nerdctl process returns a non-zero exit code,
// so the exit code cannot be easily tested here.
base.CmdWithHelper([]string{"unbuffer", "-p"}, "attach", containerName).CmdOption(opts...).AssertOutContains("2")
container := base.InspectContainer(containerName)
assert.Equal(base.T, container.State.Running, false)
}

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

skipAttachForDocker(t)

base := testutil.NewBase(t)
containerName := testutil.Identifier(t)

defer base.Cmd("container", "rm", "-f", containerName).AssertOK()
prepareContainerToAttach(base, containerName)

opts := []func(*testutil.Cmd){
testutil.WithStdin(testutil.NewDelayOnceReader(bytes.NewReader(
[]byte{1, 2}, // https://www.physics.udel.edu/~watson/scen103/ascii.html
))),
}
base.CmdWithHelper([]string{"unbuffer", "-p"}, "attach", "--detach-keys=ctrl-a,ctrl-b", containerName).
CmdOption(opts...).AssertOutContains("read detach keys")
container := base.InspectContainer(containerName)
assert.Equal(base.T, container.State.Running, true)
testCase.Run(t)
}
80 changes: 52 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,63 @@
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",
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)
}
Loading

0 comments on commit 161dc04

Please sign in to comment.