fix(auth): close cancellation and workspace races
This commit is contained in:
@@ -2,88 +2,80 @@ package compose
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestWindowsCancellationTreatsProcessReapedBeforeTreeTerminationAsSuccess(t *testing.T) {
|
||||
func TestTerminationKillsTheTreeEvenWhenTheDirectChildIsAlreadyReaped(t *testing.T) {
|
||||
done := make(chan error, 1)
|
||||
done <- nil
|
||||
treeFailure := errors.New("tree termination failed")
|
||||
treeCalls := 0
|
||||
directCalls := 0
|
||||
|
||||
err := terminateWindowsProcess(done, func() error {
|
||||
err := terminateProcessTree(done, func() error {
|
||||
treeCalls++
|
||||
return errors.New("tree termination should not run")
|
||||
return treeFailure
|
||||
}, func() error {
|
||||
directCalls++
|
||||
return errors.New("direct termination should not run")
|
||||
}, 0)
|
||||
return os.ErrProcessDone
|
||||
}, time.Second)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("terminateWindowsProcess() error = %v, want nil", err)
|
||||
if treeCalls != 1 {
|
||||
t.Fatalf("tree termination calls = %d, want 1", treeCalls)
|
||||
}
|
||||
if treeCalls != 0 || directCalls != 0 {
|
||||
t.Fatalf("termination calls = tree:%d direct:%d, want none", treeCalls, directCalls)
|
||||
if directCalls != 1 {
|
||||
t.Fatalf("direct termination calls = %d, want 1 fallback after tree failure", directCalls)
|
||||
}
|
||||
if !errors.Is(err, treeFailure) || !errors.Is(err, ErrProcessReap) {
|
||||
t.Fatalf("terminateProcessTree() error = %v, want tree failure and ErrProcessReap", err)
|
||||
}
|
||||
if errors.Is(err, os.ErrProcessDone) {
|
||||
t.Fatalf("terminateProcessTree() error = %v, must treat an already-reaped direct child as benign", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowsCancellationTreatsProcessReapedAfterTreeTerminationAsSuccess(t *testing.T) {
|
||||
func TestTerminationWaitsForTheOriginalProcessAfterTreeTermination(t *testing.T) {
|
||||
done := make(chan error, 1)
|
||||
done <- nil
|
||||
directCalls := 0
|
||||
|
||||
err := terminateWindowsProcess(done, func() error {
|
||||
done <- nil
|
||||
return ErrProcessReap
|
||||
}, func() error {
|
||||
err := terminateProcessTree(done, func() error { return nil }, func() error {
|
||||
directCalls++
|
||||
return errors.New("direct termination should not run")
|
||||
}, 0)
|
||||
return errors.New("direct fallback should not run after a successful tree termination")
|
||||
}, time.Second)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("terminateWindowsProcess() error = %v, want nil", err)
|
||||
t.Fatalf("terminateProcessTree() error = %v, want nil", err)
|
||||
}
|
||||
if directCalls != 0 {
|
||||
t.Fatalf("direct termination calls = %d, want 0", directCalls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowsCancellationTreatsProcessReapedAfterDirectTerminationAsSuccess(t *testing.T) {
|
||||
done := make(chan error, 1)
|
||||
directCalls := 0
|
||||
func TestTerminationJoinsTreeDirectAndReapFailures(t *testing.T) {
|
||||
done := make(chan error)
|
||||
treeFailure := errors.New("tree termination failed")
|
||||
directFailure := errors.New("direct termination failed")
|
||||
|
||||
err := terminateWindowsProcess(done, func() error {
|
||||
return ErrProcessReap
|
||||
}, func() error {
|
||||
directCalls++
|
||||
done <- nil
|
||||
return ErrProcessReap
|
||||
}, 0)
|
||||
err := terminateProcessTree(done, func() error { return treeFailure }, func() error { return directFailure }, 0)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("terminateWindowsProcess() error = %v, want nil", err)
|
||||
}
|
||||
if directCalls != 1 {
|
||||
t.Fatalf("direct termination calls = %d, want 1", directCalls)
|
||||
for _, want := range []error{treeFailure, directFailure, ErrProcessReap} {
|
||||
if !errors.Is(err, want) {
|
||||
t.Fatalf("terminateProcessTree() error = %v, want %v", err, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowsCancellationReportsReapFailureWhenProcessSurvives(t *testing.T) {
|
||||
func TestTerminationReportsReapFailureWhenTheTreeTerminatesButTheProcessNeverReaps(t *testing.T) {
|
||||
done := make(chan error)
|
||||
treeCalls := 0
|
||||
directCalls := 0
|
||||
|
||||
err := terminateWindowsProcess(done, func() error {
|
||||
treeCalls++
|
||||
return ErrProcessReap
|
||||
}, func() error {
|
||||
directCalls++
|
||||
return ErrProcessReap
|
||||
err := terminateProcessTree(done, func() error { return nil }, func() error {
|
||||
return errors.New("direct fallback should not run")
|
||||
}, 0)
|
||||
|
||||
if !errors.Is(err, ErrProcessReap) {
|
||||
t.Fatalf("terminateWindowsProcess() error = %v, want ErrProcessReap", err)
|
||||
}
|
||||
if treeCalls != 1 || directCalls != 1 {
|
||||
t.Fatalf("termination calls = tree:%d direct:%d, want one each", treeCalls, directCalls)
|
||||
t.Fatalf("terminateProcessTree() error = %v, want ErrProcessReap", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user