Close out the repository audit

This commit is contained in:
2026-08-13 13:52:16 +00:00
parent 13b06039b1
commit fc8ddada9a
29 changed files with 421 additions and 263 deletions

View File

@@ -19,7 +19,13 @@ func main() {
}
func runCommand(args []string, stdout, stderr io.Writer, runner func(context.Context, []string, io.Writer, io.Writer) error) error {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
return runCommandWithSignalContext(args, stdout, stderr, runner, signal.NotifyContext)
}
type signalContextFunc func(context.Context, ...os.Signal) (context.Context, context.CancelFunc)
func runCommandWithSignalContext(args []string, stdout, stderr io.Writer, runner func(context.Context, []string, io.Writer, io.Writer) error, signalContext signalContextFunc) error {
ctx, stop := signalContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
return runner(ctx, args, stdout, stderr)
}

View File

@@ -7,50 +7,30 @@ import (
"os"
"syscall"
"testing"
"time"
)
func TestRunCommandCancelsActionContextOnSignal(t *testing.T) {
for _, tt := range []struct {
name string
signal os.Signal
}{
{name: "Interrupt", signal: os.Interrupt},
{name: "Terminate", signal: syscall.SIGTERM},
} {
t.Run(tt.name, func(t *testing.T) {
started := make(chan struct{})
done := make(chan error, 1)
go func() {
done <- runCommand(nil, io.Discard, io.Discard, func(ctx context.Context, _ []string, _, _ io.Writer) error {
close(started)
<-ctx.Done()
return ctx.Err()
})
}()
func TestRunCommandBuildsCancelableSignalContext(t *testing.T) {
var signals []os.Signal
stopped := false
signalContext := func(parent context.Context, requested ...os.Signal) (context.Context, context.CancelFunc) {
signals = append([]os.Signal(nil), requested...)
ctx, cancel := context.WithCancel(parent)
cancel()
return ctx, func() {
stopped = true
}
}
select {
case <-started:
case <-time.After(time.Second):
t.Fatal("runner did not receive an action context")
}
process, err := os.FindProcess(os.Getpid())
if err != nil {
t.Fatalf("FindProcess() error = %v", err)
}
if err := process.Signal(tt.signal); err != nil {
t.Fatalf("Signal(%v) error = %v", tt.signal, err)
}
select {
case err := <-done:
if !errors.Is(err, context.Canceled) {
t.Fatalf("runCommand() error = %v, want context cancellation", err)
}
case <-time.After(time.Second):
t.Fatal("interrupt did not cancel the action context")
}
})
err := runCommandWithSignalContext(nil, io.Discard, io.Discard, func(ctx context.Context, _ []string, _, _ io.Writer) error {
return ctx.Err()
}, signalContext)
if !errors.Is(err, context.Canceled) {
t.Fatalf("runCommandWithSignalContext() error = %v, want context cancellation", err)
}
if len(signals) != 2 || signals[0] != os.Interrupt || signals[1] != syscall.SIGTERM {
t.Fatalf("requested signals = %#v, want Interrupt and SIGTERM", signals)
}
if !stopped {
t.Fatal("signal context stop function was not called")
}
}

View File

@@ -0,0 +1,58 @@
//go:build unix
package main
import (
"context"
"errors"
"io"
"os"
"syscall"
"testing"
"time"
)
func TestRunCommandCancelsActionContextOnSignal(t *testing.T) {
for _, tt := range []struct {
name string
signal os.Signal
}{
{name: "Interrupt", signal: os.Interrupt},
{name: "Terminate", signal: syscall.SIGTERM},
} {
t.Run(tt.name, func(t *testing.T) {
started := make(chan struct{})
done := make(chan error, 1)
go func() {
done <- runCommand(nil, io.Discard, io.Discard, func(ctx context.Context, _ []string, _, _ io.Writer) error {
close(started)
<-ctx.Done()
return ctx.Err()
})
}()
select {
case <-started:
case <-time.After(time.Second):
t.Fatal("runner did not receive an action context")
}
process, err := os.FindProcess(os.Getpid())
if err != nil {
t.Fatalf("FindProcess() error = %v", err)
}
if err := process.Signal(tt.signal); err != nil {
t.Fatalf("Signal(%v) error = %v", tt.signal, err)
}
select {
case err := <-done:
if !errors.Is(err, context.Canceled) {
t.Fatalf("runCommand() error = %v, want context cancellation", err)
}
case <-time.After(time.Second):
t.Fatal("interrupt did not cancel the action context")
}
})
}
}