github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/death_windows_test.go (about) 1 // +build windows 2 3 package f_test 4 5 import ( 6 "bytes" 7 "io/ioutil" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "syscall" 12 "testing" 13 "time" 14 15 . "github.com/smartystreets/goconvey/convey" 16 ) 17 18 func TestDeath(t *testing.T) { 19 Convey("Validate death happens cleanly on windows with ctrl-c event", t, func() { 20 // create source file 21 const source = ` 22 package main 23 import ( 24 "syscall" 25 "github.com/vrecan/death" 26 ) 27 func main() { 28 death := death.NewDeath(syscall.SIGINT) 29 death.WaitForDeath() 30 } 31 ` 32 tmp, err := ioutil.TempDir("", "TestCtrlBreak") 33 if err != nil { 34 t.Fatal("TempDir failed: ", err) 35 } 36 defer os.RemoveAll(tmp) 37 38 // write ctrlbreak.go 39 name := filepath.Join(tmp, "ctlbreak") 40 src := name + ".go" 41 f, err := os.Create(src) 42 if err != nil { 43 t.Fatalf("Failed to create %v: %v", src, err) 44 } 45 defer f.Close() 46 f.Write([]byte(source)) 47 48 // compile it 49 exe := name + ".exe" 50 defer os.Remove(exe) 51 o, err := exec.Command("go", "build", "-o", exe, src).CombinedOutput() 52 if err != nil { 53 t.Fatalf("Failed to compile: %v\n%v", err, string(o)) 54 } 55 56 // run it 57 cmd := exec.Command(exe) 58 var b bytes.Buffer 59 cmd.Stdout = &b 60 cmd.Stderr = &b 61 cmd.SysProcAttr = &syscall.SysProcAttr{ 62 CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, 63 } 64 err = cmd.Start() 65 if err != nil { 66 t.Fatalf("Start failed: %v", err) 67 } 68 go func() { 69 time.Sleep(1 * time.Second) 70 sendCtrlBreak(t, cmd.Process.Pid) 71 }() 72 err = cmd.Wait() 73 if err != nil { 74 t.Fatalf("Program exited with error: %v\n%v", err, string(b.Bytes())) 75 } 76 }) 77 } 78 79 func sendCtrlBreak(t *testing.T, pid int) { 80 d, e := syscall.LoadDLL("kernel32.dll") 81 if e != nil { 82 t.Fatalf("LoadDLL: %v\n", e) 83 } 84 p, e := d.FindProc("GenerateConsoleCtrlEvent") 85 if e != nil { 86 t.Fatalf("FindProc: %v\n", e) 87 } 88 r, _, e := p.Call(syscall.CTRL_BREAK_EVENT, uintptr(pid)) 89 if r == 0 { 90 t.Fatalf("GenerateConsoleCtrlEvent: %v\n", e) 91 } 92 }