Skip to content

Commit

Permalink
Skip shim tests if shim binary is not found (microsoft#1893)
Browse files Browse the repository at this point in the history
Rather than failing tests when attempting to exec the shim executable,
look up its path first and skip if it is not found.

Most testing binaries require that other binaries be located in the same
directory as them (see `require.Binary`), but since the CI runs the shim
tests directly, add `require.BinaryInPath`, which looks for the binary
in the path or current working directory first.

Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>
  • Loading branch information
helsaawy committed Sep 27, 2023
1 parent 1878d50 commit ae7891e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 22 deletions.
17 changes: 9 additions & 8 deletions test/containerd-shim-runhcs-v1/global_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,30 @@ package main

import (
"bytes"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"github.com/Microsoft/hcsshim/test/pkg/require"
)

const shimExe = "containerd-shim-runhcs-v1.exe"

func runGlobalCommand(t *testing.T, args []string) (string, string, error) {
t.Helper()
wd, err := os.Getwd()
if err != nil {
t.Fatalf("failed os.Getwd() with: %v", err)
}

shim := require.BinaryInPath(t, shimExe)
cmd := exec.Command(
filepath.Join(wd, "containerd-shim-runhcs-v1.exe"),
shim,
args...,
)
t.Logf("execing global command: %s", cmd.String())

outb := bytes.Buffer{}
errb := bytes.Buffer{}
cmd.Stdout = &outb
cmd.Stderr = &errb
err = cmd.Run()
err := cmd.Run()
return outb.String(), errb.String(), err
}

Expand Down
15 changes: 9 additions & 6 deletions test/containerd-shim-runhcs-v1/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import (
"time"

"github.com/Microsoft/go-winio"
"github.com/Microsoft/hcsshim/pkg/annotations"
task "github.com/containerd/containerd/api/runtime/task/v2"
"github.com/containerd/ttrpc"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"

"github.com/Microsoft/hcsshim/pkg/annotations"
"github.com/Microsoft/hcsshim/test/pkg/require"
)

func createStartCommand(t *testing.T) (*exec.Cmd, *bytes.Buffer, *bytes.Buffer) {
Expand All @@ -31,19 +33,20 @@ func createStartCommand(t *testing.T) (*exec.Cmd, *bytes.Buffer, *bytes.Buffer)
func createStartCommandWithID(t *testing.T, id string) (*exec.Cmd, *bytes.Buffer, *bytes.Buffer) {
t.Helper()
bundleDir := t.TempDir()
wd, err := os.Getwd()
if err != nil {
t.Fatalf("failed os.Getwd() with: %v", err)
}

shim := require.BinaryInPath(t, shimExe)
cmd := exec.Command(
filepath.Join(wd, "containerd-shim-runhcs-v1.exe"),
shim,
"--namespace", t.Name(),
"--address", "need-a-real-one",
"--publish-binary", "need-a-real-one",
"--id", id,
"start",
)
cmd.Dir = bundleDir

t.Logf("execing start command: %s", cmd.String())

outb := bytes.Buffer{}
errb := bytes.Buffer{}
cmd.Stdout = &outb
Expand Down
51 changes: 43 additions & 8 deletions test/pkg/require/requires.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package require

import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"

Expand Down Expand Up @@ -42,14 +45,35 @@ func AnyFeature(tb testing.TB, given *flag.IncludeExcludeStringSet, want ...stri
tb.Skipf("skipping test due to missing features: %s", want)
}

// Binary tries to locate `binary` in the PATH (or the current working directory),
// or the same the same directory as the currently-executing binary.
//
// Returns full binary path if it exists, otherwise, skips the test.
func BinaryInPath(tb testing.TB, binary string) string {
tb.Helper()

if path, err := exec.LookPath(binary); err == nil || errors.Is(err, exec.ErrDot) {
p, found, err := fileExists(path)
if found {
return p
}
tb.Logf("did not find binary %q at path %q: %v", binary, path, err)
} else {
tb.Logf("could not look up binary %q: %v", binary, err)
}

return Binary(tb, binary)
}

// Binary checks if `binary` exists in the same directory as the test
// binary.
// Returns full binary path if it exists, otherwise, skips the test.
func Binary(tb testing.TB, binary string) string {
tb.Helper()

executable, err := os.Executable()
if err != nil {
tb.Skipf("error locating executable: %s", err)
tb.Skipf("error locating executable: %v", err)
return ""
}

Expand All @@ -61,22 +85,33 @@ func Binary(tb testing.TB, binary string) string {
// if it exists. Otherwise, it skips the test.
func File(tb testing.TB, path, file string) string {
tb.Helper()

p, found, err := fileExists(filepath.Join(path, file))
if err != nil {
tb.Fatal(err)
} else if !found {
tb.Skipf("file %q not found in %q", file, path)
}
return p
}

// fileExists checks if path points to a valid file.
func fileExists(path string) (string, bool, error) {
path, err := filepath.Abs(path)
if err != nil {
tb.Fatalf("could not resolve path %q: %v", path, err)
return "", false, fmt.Errorf("could not resolve path %q: %w", path, err)
}

p := filepath.Join(path, file)
fi, err := os.Stat(p)
fi, err := os.Stat(path)
switch {
case os.IsNotExist(err):
tb.Skipf("file %q not found", p)
return path, false, nil
case err != nil:
tb.Fatalf("could not stat file %q: %v", p, err)
return "", false, fmt.Errorf("could not stat file %q: %w", path, err)
case fi.IsDir():
tb.Fatalf("path %q is a directory", p)
return "", false, fmt.Errorf("path %q is a directory", path)
default:
}

return p
return path, true, nil
}

0 comments on commit ae7891e

Please sign in to comment.