github.com/zxy12/golang_with_comment@v0.0.0-20190701084843-0e6b2aff5ef3/os/signal/signal_windows_test.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package signal
     6  
     7  import (
     8  	"bytes"
     9  	"internal/testenv"
    10  	"io/ioutil"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"syscall"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  func sendCtrlBreak(t *testing.T, pid int) {
    20  	d, e := syscall.LoadDLL("kernel32.dll")
    21  	if e != nil {
    22  		t.Fatalf("LoadDLL: %v\n", e)
    23  	}
    24  	p, e := d.FindProc("GenerateConsoleCtrlEvent")
    25  	if e != nil {
    26  		t.Fatalf("FindProc: %v\n", e)
    27  	}
    28  	r, _, e := p.Call(syscall.CTRL_BREAK_EVENT, uintptr(pid))
    29  	if r == 0 {
    30  		t.Fatalf("GenerateConsoleCtrlEvent: %v\n", e)
    31  	}
    32  }
    33  
    34  func TestCtrlBreak(t *testing.T) {
    35  	// create source file
    36  	const source = `
    37  package main
    38  
    39  import (
    40  	"log"
    41  	"os"
    42  	"os/signal"
    43  	"time"
    44  )
    45  
    46  
    47  func main() {
    48  	c := make(chan os.Signal, 10)
    49  	signal.Notify(c)
    50  	select {
    51  	case s := <-c:
    52  		if s != os.Interrupt {
    53  			log.Fatalf("Wrong signal received: got %q, want %q\n", s, os.Interrupt)
    54  		}
    55  	case <-time.After(3 * time.Second):
    56  		log.Fatalf("Timeout waiting for Ctrl+Break\n")
    57  	}
    58  }
    59  `
    60  	tmp, err := ioutil.TempDir("", "TestCtrlBreak")
    61  	if err != nil {
    62  		t.Fatal("TempDir failed: ", err)
    63  	}
    64  	defer os.RemoveAll(tmp)
    65  
    66  	// write ctrlbreak.go
    67  	name := filepath.Join(tmp, "ctlbreak")
    68  	src := name + ".go"
    69  	f, err := os.Create(src)
    70  	if err != nil {
    71  		t.Fatalf("Failed to create %v: %v", src, err)
    72  	}
    73  	defer f.Close()
    74  	f.Write([]byte(source))
    75  
    76  	// compile it
    77  	exe := name + ".exe"
    78  	defer os.Remove(exe)
    79  	o, err := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, src).CombinedOutput()
    80  	if err != nil {
    81  		t.Fatalf("Failed to compile: %v\n%v", err, string(o))
    82  	}
    83  
    84  	// run it
    85  	cmd := exec.Command(exe)
    86  	var b bytes.Buffer
    87  	cmd.Stdout = &b
    88  	cmd.Stderr = &b
    89  	cmd.SysProcAttr = &syscall.SysProcAttr{
    90  		CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
    91  	}
    92  	err = cmd.Start()
    93  	if err != nil {
    94  		t.Fatalf("Start failed: %v", err)
    95  	}
    96  	go func() {
    97  		time.Sleep(1 * time.Second)
    98  		sendCtrlBreak(t, cmd.Process.Pid)
    99  	}()
   100  	err = cmd.Wait()
   101  	if err != nil {
   102  		t.Fatalf("Program exited with error: %v\n%v", err, string(b.Bytes()))
   103  	}
   104  }