From 5cfe26a1770c732b0312108a02bf66ebdae05212 Mon Sep 17 00:00:00 2001 From: davidmdm Date: Mon, 23 Oct 2023 16:52:50 -0400 Subject: [PATCH] make SignalCancelError wrap context.Canceled --- .gitignore | 4 +++- Taskfile.yml | 23 +++++++++++++++++++++++ signal.go | 4 ++++ signal_test.go | 23 +++++++++++++++++++---- 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 Taskfile.yml diff --git a/.gitignore b/.gitignore index 6889601..442f4ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .vscode +*.out + +coverage playground -*.out diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..f3998ac --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,23 @@ +version: "3" + +tasks: + coverage: + cmds: + - rm -rf ./coverage && mkdir ./coverage + - go test -v -p 1 -count 1 -race -test.gocoverdir=./coverage -cover ./... + - go tool covdata percent -i=./coverage + - go tool covdata textfmt -i ./coverage -o ./coverage/results.out + - '{{if eq .CLI_ARGS "html"}} go tool cover -html ./coverage/results.out{{end}}' + + lint: + cmds: + - golangci-lint run ./... + + + # Ironically the task runner is itself a dev dependency of the project. + # To install it run the following command: + # + # go install github.com/go-task/task/v3/cmd/task@latest + install-dev-deps: + cmds: + - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2 diff --git a/signal.go b/signal.go index 1dbc165..21f3c0b 100644 --- a/signal.go +++ b/signal.go @@ -53,6 +53,10 @@ func (err SignalCancelError) Error() string { return fmt.Sprintf("%v: received signal: %s", context.Canceled, err.Signal) } +func (SignalCancelError) Unwrap() error { + return context.Canceled +} + func SignalCause(ctx context.Context) os.Signal { if sigErr := (SignalCancelError{}); errors.As(context.Cause(ctx), &sigErr) { return sigErr.Signal diff --git a/signal_test.go b/signal_test.go index ce65edd..79ff768 100644 --- a/signal_test.go +++ b/signal_test.go @@ -22,7 +22,16 @@ func TestWithCancelation(t *testing.T) { require.NoError(t, err) require.NoError(t, file.Close()) - isCoverage := slices.ContainsFunc(os.Args, func(arg string) bool { return strings.HasPrefix(arg, "-test.gocoverdir=") }) + coverDir := func() string { + args := append([]string{}, os.Args...) + slices.Reverse(args) + for _, arg := range args { + if dir, ok := strings.CutPrefix(arg, "-test.gocoverdir="); ok { + return dir + } + } + return "" + }() build := func() *exec.Cmd { args := []string{ @@ -31,8 +40,8 @@ func TestWithCancelation(t *testing.T) { "-o", file.Name(), } - if isCoverage { - args = append(args, "-coverpkg=./...") + if coverDir != "" { + args = append(args, "-cover", "-coverpkg=./...") } args = append(args, "./acceptance") @@ -44,7 +53,8 @@ func TestWithCancelation(t *testing.T) { acceptanceCMD := func() (cmd *exec.Cmd, stdout *bytes.Buffer) { cmd = exec.Command(file.Name()) - cmd.Env = append(cmd.Env, os.Environ()...) + // cmd.Env = append(cmd.Env, os.Environ()...) + cmd.Env = append(cmd.Env, "GOCOVERDIR="+coverDir) stdout = new(bytes.Buffer) cmd.Stdout = stdout @@ -123,6 +133,11 @@ func TestSignalCause(t *testing.T) { } } +func TestSignalErrorIsCanceled(t *testing.T) { + var e error = xcontext.SignalCancelError{Signal: syscall.SIGTERM} + require.True(t, errors.Is(e, context.Canceled)) +} + func CommandStandardIO(name string, args ...string) *exec.Cmd { cmd := exec.Command(name, args...) cmd.Stdout = os.Stdout