File: kill.go

package info (click to toggle)
golang-github-opencontainers-runtime-tools 0.9.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,108 kB
  • sloc: sh: 557; makefile: 104
file content (85 lines) | stat: -rw-r--r-- 3,406 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package main

import (
	"fmt"
	"os"
	"time"

	"github.com/mndrix/tap-go"
	rspecs "github.com/opencontainers/runtime-spec/specs-go"
	"github.com/opencontainers/runtime-tools/generate"
	"github.com/opencontainers/runtime-tools/specerror"
	"github.com/opencontainers/runtime-tools/validation/util"
	uuid "github.com/satori/go.uuid"
)

func main() {
	t := tap.New()
	t.Header(0)
	bundleDir, err := util.PrepareBundle()
	if err != nil {
		util.Fatal(err)
	}
	defer os.RemoveAll(bundleDir)

	stoppedConfig, err := util.GetDefaultGenerator()
	if err != nil {
		util.Fatal(err)
	}
	stoppedConfig.SetProcessArgs([]string{"true"})
	runningConfig, err := util.GetDefaultGenerator()
	if err != nil {
		util.Fatal(err)
	}
	runningConfig.SetProcessArgs([]string{"sleep", "30"})
	containerID := uuid.NewV4().String()

	cases := []struct {
		config      *generate.Generator
		id          string
		action      util.LifecycleAction
		errExpected bool
		err         error
	}{
		// Note: the nil config test case should run first since we are re-using the bundle
		// kill without id
		{nil, "", util.LifecycleActionNone, false, specerror.NewError(specerror.KillWithoutIDGenError, fmt.Errorf("`kill` operation MUST generate an error if it is not provided the container ID"), rspecs.Version)},
		// kill a non exist container
		{nil, containerID, util.LifecycleActionNone, false, specerror.NewError(specerror.KillNonCreateRunGenError, fmt.Errorf("attempting to send a signal to a container that is neither `created` nor `running` MUST generate an error"), rspecs.Version)},
		// kill a created
		{stoppedConfig, containerID, util.LifecycleActionCreate | util.LifecycleActionDelete, true, specerror.NewError(specerror.KillSignalImplement, fmt.Errorf("`kill` operation MUST send the specified signal to the container process"), rspecs.Version)},
		// kill a stopped
		{stoppedConfig, containerID, util.LifecycleActionCreate | util.LifecycleActionStart | util.LifecycleActionDelete, false, specerror.NewError(specerror.KillNonCreateRunGenError, fmt.Errorf("attempting to send a signal to a container that is neither `created` nor `running` MUST generate an error"), rspecs.Version)},
		// kill a running
		{runningConfig, containerID, util.LifecycleActionCreate | util.LifecycleActionStart | util.LifecycleActionDelete, true, specerror.NewError(specerror.KillSignalImplement, fmt.Errorf("`kill` operation MUST send the specified signal to the container process"), rspecs.Version)},
	}

	for _, c := range cases {
		config := util.LifecycleConfig{
			Config:    c.config,
			BundleDir: bundleDir,
			Actions:   c.action,
			PreCreate: func(r *util.Runtime) error {
				r.SetID(c.id)
				return nil
			},
			PreDelete: func(r *util.Runtime) error {
				// waiting the 'stoppedConfig' testcase to stop
				// the 'runningConfig' testcase sleeps 30 seconds, so 10 seconds are enough for this case
				util.WaitingForStatus(*r, util.LifecycleStatusCreated|util.LifecycleStatusStopped, time.Second*10, time.Second*1)
				// KILL MUST be supported and KILL cannot be trapped
				err = r.Kill("KILL")
				util.WaitingForStatus(*r, util.LifecycleStatusStopped, time.Second*10, time.Second*1)
				if err != nil {
					//Be sure to not leave the container around
					r.Delete()
				}
				return err
			},
		}
		err = util.RuntimeLifecycleValidate(config)
		util.SpecErrorOK(t, (err == nil) == c.errExpected, c.err, err)
	}

	t.AutoPlan()
}