Skip to content

Commit

Permalink
tests: Add framework to mock virtcontainers
Browse files Browse the repository at this point in the history
Add a simple test framework to allow the behaviour of the virtcontainers
package to be mocked.

This change introduces a RVC interface and provides two implementations:
one for virtcontainers itself (rvc-implementation.go) and another mock
implementation for the tests to allow the behaviour of the
virtcontainers package to be modified (rvc-implementation_test.go). By
only accessing the virtcontainers implementation via the "vci" variable,
the tests can be switched to the mock implementation.

Note that this mocking is used rather than testing virtcontainers
directly since the virtcontainers API is already tested in that package:
the mock framework thus avoids duplication of test code and allows more
fine-grained error scenarios to be handled.

This change also introduces a single new test, TestCreate(), that
increases the unit test coverage of create.go by using the new framework
to force create() to fail due to a virtcontainers failure in
CreatePod().

Fixes clearcontainers#401.

Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
  • Loading branch information
jodh-intel committed Aug 14, 2017
1 parent 5dea7cb commit cd114f9
Show file tree
Hide file tree
Showing 14 changed files with 730 additions and 18 deletions.
4 changes: 2 additions & 2 deletions create.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func createPod(ociSpec oci.CompatOCISpec, runtimeConfig oci.RuntimeConfig,
return vc.Process{}, err
}

pod, err := vc.CreatePod(podConfig)
pod, err := vci.CreatePod(podConfig)
if err != nil {
return vc.Process{}, err
}
Expand All @@ -209,7 +209,7 @@ func createContainer(ociSpec oci.CompatOCISpec, containerID, bundlePath,
return vc.Process{}, err
}

_, c, err := vc.CreateContainer(podID, contConfig)
_, c, err := vci.CreateContainer(podID, contConfig)
if err != nil {
return vc.Process{}, err
}
Expand Down
41 changes: 41 additions & 0 deletions create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

var testPID = 100
Expand Down Expand Up @@ -95,3 +97,42 @@ func TestCreatePIDFileEmptyPathSuccessful(t *testing.T) {
t.Fatalf("This test should not fail (pidFilePath %q, pid %d)", file, testPID)
}
}

func TestCreate(t *testing.T) {
// change behaviour
testingImpl.listPodFunc = listPodNoPods
testingImpl.forceFailure = true

defer func() {
// reset
testingImpl.listPodFunc = nil
testingImpl.forceFailure = false
}()

tmpdir, err := ioutil.TempDir("", "")
if err != nil {
panic(err)
}

defer os.RemoveAll(tmpdir)

containerID := "foo"
bundlePath := filepath.Join(tmpdir, "bundle")

err = os.MkdirAll(bundlePath, testDirMode)
assert.NoError(t, err)

err = makeOCIBundle(bundlePath)
assert.NoError(t, err)

console := "/dev/pts/999"
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
detach := false
runtimeConfig, err := newRuntimeConfig(tmpdir, console)
assert.NoError(t, err)

err = create(containerID, bundlePath, console, pidFilePath, detach, runtimeConfig)

assert.Error(t, err)
assert.True(t, isMockError(err))
}
8 changes: 4 additions & 4 deletions delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ func delete(containerID string, force bool) error {
}

func deletePod(podID string) error {
if _, err := vc.StopPod(podID); err != nil {
if _, err := vci.StopPod(podID); err != nil {
return err
}

if _, err := vc.DeletePod(podID); err != nil {
if _, err := vci.DeletePod(podID); err != nil {
return err
}

Expand All @@ -127,12 +127,12 @@ func deletePod(podID string) error {

func deleteContainer(podID, containerID string, forceStop bool) error {
if forceStop {
if _, err := vc.StopContainer(podID, containerID); err != nil {
if _, err := vci.StopContainer(podID, containerID); err != nil {
return err
}
}

if _, err := vc.DeleteContainer(podID, containerID); err != nil {
if _, err := vci.DeleteContainer(podID, containerID); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func execute(context *cli.Context) error {
Detach: noNeedForOutput(params.detach, params.ociProcess.Terminal),
}

_, _, process, err := vc.EnterContainer(podID, params.cID, cmd)
_, _, process, err := vci.EnterContainer(podID, params.cID, cmd)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion kill.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func kill(containerID, signal string, all bool) error {
return fmt.Errorf("Container %s not ready or running, cannot send a signal", containerID)
}

if err := vc.KillContainer(podID, containerID, signum, all); err != nil {
if err := vci.KillContainer(podID, containerID, signum, all); err != nil {
return err
}

Expand Down
3 changes: 1 addition & 2 deletions list.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (

"github.com/urfave/cli"

vc "github.com/containers/virtcontainers"
oci "github.com/containers/virtcontainers/pkg/oci"
)

Expand Down Expand Up @@ -200,7 +199,7 @@ func getContainers(context *cli.Context) ([]fullContainerState, error) {
return nil, err
}

podList, err := vc.ListPod()
podList, err := vci.ListPod()
if err != nil {
return nil, err
}
Expand Down
12 changes: 10 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"strings"

"github.com/Sirupsen/logrus"
vc "github.com/containers/virtcontainers"
"github.com/clearcontainers/runtime/pkg/rvc"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/urfave/cli"
)
Expand Down Expand Up @@ -50,6 +50,14 @@ NOTES:

var ccLog = logrus.New()

// concrete virtcontainer implementation
var virtcontainersImpl = &vcImpl{}

// vci is used to access a particular virtcontainers implementation.
// Normally, it refers to the official package, but is re-assigned in
// the tests to allow virtcontainers to be mocked.
var vci rvc.RVC = virtcontainersImpl

func beforeSubcommands(context *cli.Context) error {
if userWantsUsage(context) || (context.NArg() == 1 && (context.Args()[0] == "cc-check")) {
// No setup required if the user just
Expand Down Expand Up @@ -80,7 +88,7 @@ func beforeSubcommands(context *cli.Context) error {
}

// Set virtcontainers logger.
vc.SetLogger(ccLog)
vci.SetLogger(ccLog)

ignoreLogging := false
if context.NArg() == 1 && context.Args()[0] == "cc-env" {
Expand Down
Loading

0 comments on commit cd114f9

Please # to comment.