mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-22 16:54:25 +01:00
We currently just send the pid in the state. While OCI specifies a few other fields as well, this commit just adds the bundle path and the container id to the state. This should fix the errors seen with hooks that rely on the bundle path. Other fields like running "state" string have been left out. As this would need sending the strings that OCI recognises. Hooks have been implemented in virtcontainers and sending the state string would require calling into OCI specific code in virtcontainers. The bundle path again is OCI specific, but this can be accessed using annotations. Hooks really need to be moved to the cli as they are OCI specific. This however needs network hotplug to be implemented first so that the hooks can be called from the cli after the VM has been created. Fixes #271 Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
270 lines
4.8 KiB
Go
270 lines
4.8 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package virtcontainers
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"sync"
|
|
"testing"
|
|
|
|
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
|
|
. "github.com/kata-containers/runtime/virtcontainers/pkg/mock"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
)
|
|
|
|
// Important to keep these values in sync with hook test binary
|
|
var testKeyHook = "test-key"
|
|
var testContainerIDHook = "test-container-id"
|
|
var testControllerIDHook = "test-controller-id"
|
|
var testProcessIDHook = 12345
|
|
var testBinHookPath = "/usr/bin/virtcontainers/bin/test/hook"
|
|
var testBundlePath = "/test/bundle"
|
|
|
|
func getMockHookBinPath() string {
|
|
if DefaultMockHookBinPath == "" {
|
|
return testBinHookPath
|
|
}
|
|
|
|
return DefaultMockHookBinPath
|
|
}
|
|
|
|
func TestBuildHookState(t *testing.T) {
|
|
t.Skip()
|
|
expected := specs.State{
|
|
Pid: testProcessIDHook,
|
|
}
|
|
|
|
s := &Sandbox{}
|
|
|
|
hookState := buildHookState(testProcessIDHook, s)
|
|
|
|
if reflect.DeepEqual(hookState, expected) == false {
|
|
t.Fatal()
|
|
}
|
|
|
|
s = createTestSandbox()
|
|
hookState = buildHookState(testProcessIDHook, s)
|
|
|
|
expected = specs.State{
|
|
Pid: testProcessIDHook,
|
|
Bundle: testBundlePath,
|
|
ID: testSandboxID,
|
|
}
|
|
|
|
if reflect.DeepEqual(hookState, expected) == false {
|
|
t.Fatal()
|
|
}
|
|
|
|
}
|
|
|
|
func createHook(timeout int) *Hook {
|
|
return &Hook{
|
|
Path: getMockHookBinPath(),
|
|
Args: []string{testKeyHook, testContainerIDHook, testControllerIDHook},
|
|
Env: os.Environ(),
|
|
Timeout: timeout,
|
|
}
|
|
}
|
|
|
|
func createWrongHook() *Hook {
|
|
return &Hook{
|
|
Path: getMockHookBinPath(),
|
|
Args: []string{"wrong-args"},
|
|
Env: os.Environ(),
|
|
}
|
|
}
|
|
|
|
func createTestSandbox() *Sandbox {
|
|
c := &SandboxConfig{
|
|
Annotations: map[string]string{
|
|
vcAnnotations.BundlePathKey: testBundlePath,
|
|
},
|
|
}
|
|
return &Sandbox{
|
|
annotationsLock: &sync.RWMutex{},
|
|
config: c,
|
|
id: testSandboxID,
|
|
}
|
|
}
|
|
|
|
func testRunHookFull(t *testing.T, timeout int, expectFail bool) {
|
|
hook := createHook(timeout)
|
|
|
|
s := createTestSandbox()
|
|
err := hook.runHook(s)
|
|
if expectFail {
|
|
if err == nil {
|
|
t.Fatal("unexpected success")
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Fatalf("unexpected failure: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testRunHook(t *testing.T, timeout int) {
|
|
testRunHookFull(t, timeout, false)
|
|
}
|
|
|
|
func TestRunHook(t *testing.T) {
|
|
cleanUp()
|
|
|
|
testRunHook(t, 0)
|
|
}
|
|
|
|
func TestRunHookTimeout(t *testing.T) {
|
|
testRunHook(t, 1)
|
|
}
|
|
|
|
func TestRunHookExitFailure(t *testing.T) {
|
|
hook := createWrongHook()
|
|
s := createTestSandbox()
|
|
|
|
err := hook.runHook(s)
|
|
if err == nil {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestRunHookTimeoutFailure(t *testing.T) {
|
|
hook := createHook(1)
|
|
|
|
hook.Args = append(hook.Args, "2")
|
|
|
|
s := createTestSandbox()
|
|
|
|
err := hook.runHook(s)
|
|
if err == nil {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestRunHookWaitFailure(t *testing.T) {
|
|
hook := createHook(60)
|
|
|
|
hook.Args = append(hook.Args, "1", "panic")
|
|
s := createTestSandbox()
|
|
|
|
err := hook.runHook(s)
|
|
if err == nil {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func testRunHookInvalidCommand(t *testing.T, timeout int) {
|
|
cleanUp()
|
|
|
|
dir, err := ioutil.TempDir("", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
defer os.RemoveAll(dir)
|
|
|
|
cmd := filepath.Join(dir, "does-not-exist")
|
|
|
|
savedDefaultMockHookBinPath := DefaultMockHookBinPath
|
|
DefaultMockHookBinPath = cmd
|
|
|
|
defer func() {
|
|
DefaultMockHookBinPath = savedDefaultMockHookBinPath
|
|
}()
|
|
|
|
testRunHookFull(t, timeout, true)
|
|
}
|
|
|
|
func TestRunHookInvalidCommand(t *testing.T) {
|
|
testRunHookInvalidCommand(t, 0)
|
|
}
|
|
|
|
func TestRunHookTimeoutInvalidCommand(t *testing.T) {
|
|
testRunHookInvalidCommand(t, 1)
|
|
}
|
|
|
|
func testHooks(t *testing.T, hook *Hook) {
|
|
hooks := &Hooks{
|
|
PreStartHooks: []Hook{*hook},
|
|
PostStartHooks: []Hook{*hook},
|
|
PostStopHooks: []Hook{*hook},
|
|
}
|
|
s := createTestSandbox()
|
|
|
|
err := hooks.preStartHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = hooks.postStartHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = hooks.postStopHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func testFailingHooks(t *testing.T, hook *Hook) {
|
|
hooks := &Hooks{
|
|
PreStartHooks: []Hook{*hook},
|
|
PostStartHooks: []Hook{*hook},
|
|
PostStopHooks: []Hook{*hook},
|
|
}
|
|
s := createTestSandbox()
|
|
|
|
err := hooks.preStartHooks(s)
|
|
if err == nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = hooks.postStartHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = hooks.postStopHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestHooks(t *testing.T) {
|
|
testHooks(t, createHook(0))
|
|
}
|
|
|
|
func TestHooksTimeout(t *testing.T) {
|
|
testHooks(t, createHook(1))
|
|
}
|
|
|
|
func TestFailingHooks(t *testing.T) {
|
|
testFailingHooks(t, createWrongHook())
|
|
}
|
|
|
|
func TestEmptyHooks(t *testing.T) {
|
|
hooks := &Hooks{}
|
|
s := createTestSandbox()
|
|
|
|
err := hooks.preStartHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = hooks.postStartHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = hooks.postStopHooks(s)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|