dawn_node: handle signals (e.g. ctrl+C)

In all three modes, this cancels the current operations as soon as
possible. For tests that hang, this ensures we can Ctrl+C the process
and get the stdout from those tests.

Bug: dawn:1163
Change-Id: Ib3e45b533adaf510e1f9454a59ef1e821fc3eccd
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/68300
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Antonio Maiorano 2021-11-04 14:53:10 +00:00 committed by Dawn LUCI CQ
parent 15dc49ce75
commit cb41115907

View File

@ -28,12 +28,14 @@ import (
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
"os/signal"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
"github.com/mattn/go-colorable" "github.com/mattn/go-colorable"
@ -60,8 +62,11 @@ Usage:
os.Exit(1) os.Exit(1)
} }
var colors bool var (
var stdout io.Writer colors bool
stdout io.Writer
mainCtx context.Context
)
type dawnNodeFlags []string type dawnNodeFlags []string
@ -76,7 +81,21 @@ func (f *dawnNodeFlags) Set(value string) error {
return nil return nil
} }
func makeMainCtx() context.Context {
ctx, cancel := context.WithCancel(context.Background())
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Printf("Signal received: %v\n", sig)
cancel()
}()
return ctx
}
func run() error { func run() error {
mainCtx = makeMainCtx()
colors = os.Getenv("TERM") != "dumb" || colors = os.Getenv("TERM") != "dumb" ||
isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsTerminal(os.Stdout.Fd()) ||
isatty.IsCygwinTerminal(os.Stdout.Fd()) isatty.IsCygwinTerminal(os.Stdout.Fd())
@ -483,7 +502,8 @@ func (r *runner) runServer(caseIndices <-chan int, results chan<- result) error
args = append(args, "--gpu-provider-flag", f) args = append(args, "--gpu-provider-flag", f)
} }
cmd := exec.Command(r.node, args...) ctx := mainCtx
cmd := exec.CommandContext(ctx, r.node, args...)
serverLog := &bytes.Buffer{} serverLog := &bytes.Buffer{}
@ -502,6 +522,8 @@ func (r *runner) runServer(caseIndices <-chan int, results chan<- result) error
case port = <-pl.port: case port = <-pl.port:
case <-time.After(time.Second * 10): case <-time.After(time.Second * 10):
return fmt.Errorf("timeout waiting for server port:\n%v", serverLog.String()) return fmt.Errorf("timeout waiting for server port:\n%v", serverLog.String())
case <-ctx.Done():
return ctx.Err()
} }
return nil return nil
@ -725,7 +747,7 @@ type result struct {
// runTestcase() runs the CTS testcase with the given query, returning the test // runTestcase() runs the CTS testcase with the given query, returning the test
// result. // result.
func (r *runner) runTestcase(query string) result { func (r *runner) runTestcase(query string) result {
ctx, cancel := context.WithTimeout(context.Background(), testTimeout) ctx, cancel := context.WithTimeout(mainCtx, testTimeout)
defer cancel() defer cancel()
args := []string{ args := []string{