github.com/dmaizel/tests@v0.0.0-20210728163746-cae6a2d9cee8/integration/docker/kill_test.go (about) 1 // Copyright (c) 2018 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package docker 6 7 import ( 8 "fmt" 9 "strings" 10 "syscall" 11 "time" 12 13 . "github.com/kata-containers/tests" 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/ginkgo/extensions/table" 16 . "github.com/onsi/gomega" 17 ) 18 19 const ( 20 canBeTrapped = true 21 ) 22 23 var genericSignalMap = map[syscall.Signal]bool{ 24 syscall.SIGHUP: canBeTrapped, 25 syscall.SIGINT: canBeTrapped, 26 syscall.SIGQUIT: canBeTrapped, 27 syscall.SIGILL: canBeTrapped, 28 syscall.SIGTRAP: canBeTrapped, 29 syscall.SIGIOT: canBeTrapped, 30 syscall.SIGFPE: canBeTrapped, 31 syscall.SIGUSR1: canBeTrapped, 32 syscall.SIGSEGV: canBeTrapped, 33 syscall.SIGUSR2: canBeTrapped, 34 syscall.SIGPIPE: canBeTrapped, 35 syscall.SIGALRM: canBeTrapped, 36 syscall.SIGTERM: canBeTrapped, 37 syscall.SIGCHLD: canBeTrapped, 38 syscall.SIGCONT: canBeTrapped, 39 syscall.SIGTSTP: canBeTrapped, 40 syscall.SIGTTIN: canBeTrapped, 41 syscall.SIGTTOU: canBeTrapped, 42 syscall.SIGURG: canBeTrapped, 43 syscall.SIGXCPU: canBeTrapped, 44 syscall.SIGXFSZ: canBeTrapped, 45 syscall.SIGVTALRM: canBeTrapped, 46 syscall.SIGPROF: canBeTrapped, 47 syscall.SIGWINCH: canBeTrapped, 48 syscall.SIGIO: canBeTrapped, 49 } 50 51 func withoutSignal() TableEntry { 52 // Value denoting a command interrupted by a signal (http://www.tldp.org/LDP/abs/html/exitcodes.html) 53 const interruptedBySignal = 128 54 55 expectedExitCode := interruptedBySignal + int(syscall.SIGKILL) 56 return Entry("without a signal", syscall.Signal(0), expectedExitCode, true) 57 } 58 59 func withSignalNotExitCode(signal syscall.Signal) TableEntry { 60 return Entry(fmt.Sprintf("with '%d' (%s) signal, don't change the exit code", signal, signal), signal, 0, false) 61 } 62 63 func withGenericSignals(signalsMap map[syscall.Signal]bool) []TableEntry { 64 var table []TableEntry 65 var expectedExitCode int 66 for signal, trap := range signalsMap { 67 expectedExitCode = int(signal) 68 if !trap { 69 // 128 -> command interrupted by a signal 70 // http://www.tldp.org/LDP/abs/html/exitcodes.html 71 expectedExitCode += 128 72 73 } 74 table = append(table, Entry(fmt.Sprintf("with '%d'(%s) signal", int(signal), signal), signal, expectedExitCode, true)) 75 } 76 return append(table, withoutSignal(), withSignalNotExitCode(syscall.SIGSTOP)) 77 } 78 79 var _ = Describe("docker kill", func() { 80 var ( 81 args []string 82 id string 83 ) 84 85 BeforeEach(func() { 86 id = randomDockerName() 87 }) 88 89 AfterEach(func() { 90 Expect(RemoveDockerContainer(id)).To(BeTrue()) 91 Expect(ExistDockerContainer(id)).NotTo(BeTrue()) 92 }) 93 94 DescribeTable("killing container", 95 func(signal syscall.Signal, expectedExitCode int, waitForExit bool) { 96 args = []string{"--name", id, "-dt", Image, "sh", "-c"} 97 98 switch signal { 99 case syscall.SIGQUIT, syscall.SIGILL, syscall.SIGBUS, syscall.SIGFPE, syscall.SIGSEGV, syscall.SIGPIPE: 100 Skip("This is not forwarded by kata-shim " + 101 "https://github.com/kata-containers/shim/issues/4") 102 case syscall.SIGWINCH: 103 } 104 105 trapTag := "TRAP_RUNNING" 106 trapCmd := fmt.Sprintf("trap \"exit %d\" %d; echo %s", signal, signal, trapTag) 107 infiniteLoop := "while :; do sleep 1; done" 108 109 if signal > 0 { 110 args = append(args, fmt.Sprintf("%s; %s", trapCmd, infiniteLoop)) 111 } else { 112 args = append(args, infiniteLoop) 113 } 114 115 _, _, runExitCode := dockerRun(args...) 116 Expect(runExitCode).To(Equal(0)) 117 118 if signal > 0 { 119 exitCh := make(chan bool) 120 121 go func() { 122 for { 123 // Don't check for error here since the command 124 // can fail if the container is not running yet. 125 logs, _ := LogsDockerContainer(id) 126 if strings.Contains(logs, trapTag) { 127 break 128 } 129 130 time.Sleep(time.Second) 131 } 132 133 close(exitCh) 134 }() 135 136 var err error 137 138 select { 139 case <-exitCh: 140 err = nil 141 case <-time.After(time.Duration(Timeout) * time.Second): 142 err = fmt.Errorf("Timeout reached after %ds", Timeout) 143 } 144 145 Expect(err).ToNot(HaveOccurred()) 146 147 dockerKill("-s", fmt.Sprintf("%d", signal), id) 148 } else { 149 dockerKill(id) 150 } 151 152 exitCode, err := ExitCodeDockerContainer(id, waitForExit) 153 Expect(err).ToNot(HaveOccurred()) 154 Expect(exitCode).To(Equal(expectedExitCode)) 155 }, 156 withOSSignals(genericSignalMap)..., 157 ) 158 })