github.com/opencontainers/runtime-tools@v0.9.0/validation/kill/kill.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "time" 7 8 "github.com/mndrix/tap-go" 9 rspecs "github.com/opencontainers/runtime-spec/specs-go" 10 "github.com/opencontainers/runtime-tools/generate" 11 "github.com/opencontainers/runtime-tools/specerror" 12 "github.com/opencontainers/runtime-tools/validation/util" 13 uuid "github.com/satori/go.uuid" 14 ) 15 16 func main() { 17 t := tap.New() 18 t.Header(0) 19 bundleDir, err := util.PrepareBundle() 20 if err != nil { 21 util.Fatal(err) 22 } 23 defer os.RemoveAll(bundleDir) 24 25 stoppedConfig, err := util.GetDefaultGenerator() 26 if err != nil { 27 util.Fatal(err) 28 } 29 stoppedConfig.SetProcessArgs([]string{"true"}) 30 runningConfig, err := util.GetDefaultGenerator() 31 if err != nil { 32 util.Fatal(err) 33 } 34 runningConfig.SetProcessArgs([]string{"sleep", "30"}) 35 containerID := uuid.NewV4().String() 36 37 cases := []struct { 38 config *generate.Generator 39 id string 40 action util.LifecycleAction 41 errExpected bool 42 err error 43 }{ 44 // Note: the nil config test case should run first since we are re-using the bundle 45 // kill without id 46 {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)}, 47 // kill a non exist container 48 {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)}, 49 // kill a created 50 {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)}, 51 // kill a stopped 52 {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)}, 53 // kill a running 54 {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)}, 55 } 56 57 for _, c := range cases { 58 config := util.LifecycleConfig{ 59 Config: c.config, 60 BundleDir: bundleDir, 61 Actions: c.action, 62 PreCreate: func(r *util.Runtime) error { 63 r.SetID(c.id) 64 return nil 65 }, 66 PreDelete: func(r *util.Runtime) error { 67 // waiting the 'stoppedConfig' testcase to stop 68 // the 'runningConfig' testcase sleeps 30 seconds, so 10 seconds are enough for this case 69 util.WaitingForStatus(*r, util.LifecycleStatusCreated|util.LifecycleStatusStopped, time.Second*10, time.Second*1) 70 // KILL MUST be supported and KILL cannot be trapped 71 err = r.Kill("KILL") 72 util.WaitingForStatus(*r, util.LifecycleStatusStopped, time.Second*10, time.Second*1) 73 if err != nil { 74 //Be sure to not leave the container around 75 r.Delete() 76 } 77 return err 78 }, 79 } 80 err = util.RuntimeLifecycleValidate(config) 81 util.SpecErrorOK(t, (err == nil) == c.errExpected, c.err, err) 82 } 83 84 t.AutoPlan() 85 }