Fix client tests to work on Windows.

- Powershell is no longer available in nanoserver, so change commands to
  run accordingly.
- Set platform specific commands for short and long running containers
- Skips 2 tests which do not run on Windows.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2020-05-26 16:07:53 -07:00
parent 4e08c2de67
commit 3226283470
4 changed files with 79 additions and 27 deletions

View File

@ -32,7 +32,9 @@ const (
)
var (
testImage string
testImage string
shortCommand = withProcessArgs("true")
longCommand = withProcessArgs("/bin/sh", "-c", "while true; do sleep 1; done")
)
func init() {

View File

@ -17,16 +17,41 @@
package containerd
import (
"fmt"
"os"
"path/filepath"
"github.com/Microsoft/hcsshim/osversion"
)
const (
defaultAddress = `\\.\pipe\containerd-containerd-test`
testImage = "mcr.microsoft.com/windows/nanoserver:sac2016"
)
var (
defaultRoot = filepath.Join(os.Getenv("programfiles"), "containerd", "root-test")
defaultState = filepath.Join(os.Getenv("programfiles"), "containerd", "state-test")
testImage string
shortCommand = withTrue()
longCommand = withProcessArgs("ping", "-t", "localhost")
)
func init() {
b := osversion.Build()
switch b {
case osversion.RS1:
testImage = "mcr.microsoft.com/windows/nanoserver:sac2016"
case osversion.RS3:
testImage = "mcr.microsoft.com/windows/nanoserver:1709"
case osversion.RS4:
testImage = "mcr.microsoft.com/windows/nanoserver:1803"
case osversion.RS5:
testImage = "mcr.microsoft.com/windows/nanoserver:1809"
case osversion.V19H1:
testImage = "mcr.microsoft.com/windows/nanoserver:1903"
case 18363: // this isn't in osversion yet, but the image should be available
testImage = "mcr.microsoft.com/windows/nanoserver:1909"
}
fmt.Println("Windows test image:", testImage, ", Windows build version:", b)
}

View File

@ -140,9 +140,13 @@ func TestContainerStart(t *testing.T) {
t.Fatal(err)
}
if pid := task.Pid(); pid < 1 {
t.Errorf("invalid task pid %d", pid)
if runtime.GOOS != "windows" {
// task.Pid not implemented on Windows
if pid := task.Pid(); pid < 1 {
t.Errorf("invalid task pid %d", pid)
}
}
if err := task.Start(ctx); err != nil {
t.Error(err)
task.Delete(ctx)
@ -256,7 +260,7 @@ func TestContainerExec(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "100")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -341,7 +345,7 @@ func TestContainerLargeExecArgs(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "100")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -417,7 +421,7 @@ func TestContainerPids(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "100")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -450,8 +454,9 @@ func TestContainerPids(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if l := len(processes); l != 1 {
t.Errorf("expected 1 process but received %d", l)
// 2 processes, 1 for sh and one for sleep
if l := len(processes); l != 2 {
t.Errorf("expected 2 process but received %d", l)
}
if len(processes) > 0 {
actual := processes[0].Pid
@ -461,6 +466,11 @@ func TestContainerPids(t *testing.T) {
}
}
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
select {
case s := <-statusC:
t.Log(s.Result())
default:
}
t.Error(err)
}
<-statusC
@ -543,7 +553,7 @@ func TestDeleteRunningContainer(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "100")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -598,7 +608,7 @@ func TestContainerKill(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "10")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -635,6 +645,10 @@ func TestContainerKill(t *testing.T) {
func TestKillContainerDeletedByRunc(t *testing.T) {
t.Parallel()
if runtime.GOOS == "windows" {
t.Skip("Test relies on runc and is not supported on Windows")
}
// We skip this case when runtime is crun.
// More information in https://github.com/containerd/containerd/pull/4214#discussion_r422769497
if os.Getenv("RUNC_FLAVOR") == "crun" {
@ -661,7 +675,7 @@ func TestKillContainerDeletedByRunc(t *testing.T) {
}
container, err := client.NewContainer(ctx, id,
WithNewSnapshot(id, image),
WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "10")),
WithNewSpec(oci.WithImageConfig(image), longCommand),
WithRuntime(client.runtime, &options.Options{Root: runcRoot}))
if err != nil {
t.Fatal(err)
@ -772,7 +786,7 @@ func TestContainerExecNoBinaryExists(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "100")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -854,8 +868,11 @@ func TestWaitStoppedTask(t *testing.T) {
t.Fatal(err)
}
if pid := task.Pid(); pid < 1 {
t.Errorf("invalid task pid %d", pid)
if runtime.GOOS != "windows" {
// Getting the pid is not currently implemented on windows
if pid := task.Pid(); pid < 1 {
t.Errorf("invalid task pid %d", pid)
}
}
if err := task.Start(ctx); err != nil {
t.Error(err)
@ -900,7 +917,7 @@ func TestWaitStoppedProcess(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "100")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -987,7 +1004,7 @@ func TestTaskForceDelete(t *testing.T) {
if err != nil {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "30")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -1028,7 +1045,7 @@ func TestProcessForceDelete(t *testing.T) {
if err != nil {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "30")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -1055,7 +1072,11 @@ func TestProcessForceDelete(t *testing.T) {
}
processSpec := spec.Process
withExecArgs(processSpec, "sleep", "20")
if runtime.GOOS == "windows" {
withExecArgs(processSpec, "cmd", "/c", "ping -t localhost")
} else {
withExecArgs(processSpec, "/bin/sh", "-c", "while true; do sleep 1; done")
}
execID := t.Name() + "_exec"
process, err := task.Exec(ctx, execID, processSpec, empty())
if err != nil {
@ -1226,7 +1247,7 @@ func TestDeleteContainerExecCreated(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "100")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -1297,7 +1318,7 @@ func TestContainerMetrics(t *testing.T) {
}
container, err := client.NewContainer(ctx, id,
WithNewSnapshot(id, image),
WithNewSpec(oci.WithImageConfig(image), oci.WithProcessArgs("sleep", "30")))
WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -1655,6 +1676,10 @@ func TestShimSockLength(t *testing.T) {
}
func TestContainerExecLargeOutputWithTTY(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Test does not run on Windows")
}
t.Parallel()
client, err := newClient(t, address)
@ -1675,7 +1700,7 @@ func TestContainerExecLargeOutputWithTTY(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("sleep", "999")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand))
if err != nil {
t.Fatal(err)
}
@ -1771,7 +1796,7 @@ func TestShortRunningTaskPid(t *testing.T) {
t.Fatal(err)
}
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), withProcessArgs("true")))
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), shortCommand))
if err != nil {
t.Fatal(err)
}

View File

@ -31,13 +31,13 @@ const newLine = "\r\n"
func withExitStatus(es int) oci.SpecOpts {
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error {
s.Process.Args = []string{"powershell", "-noprofile", "exit", strconv.Itoa(es)}
s.Process.Args = []string{"cmd", "/c", "exit", strconv.Itoa(es)}
return nil
}
}
func withProcessArgs(args ...string) oci.SpecOpts {
return oci.WithProcessArgs(append([]string{"powershell", "-noprofile"}, args...)...)
return oci.WithProcessArgs(append([]string{"cmd", "/c"}, args...)...)
}
func withCat() oci.SpecOpts {
@ -49,9 +49,9 @@ func withTrue() oci.SpecOpts {
}
func withExecExitStatus(s *specs.Process, es int) {
s.Args = []string{"powershell", "-noprofile", "exit", strconv.Itoa(es)}
s.Args = []string{"cmd", "/c", "exit", strconv.Itoa(es)}
}
func withExecArgs(s *specs.Process, args ...string) {
s.Args = append([]string{"powershell", "-noprofile"}, args...)
s.Args = append([]string{"cmd", "/c"}, args...)
}