@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Kubernetes stops a pod with SIGTERM; only SIGINT was handled, so a deploy killed the
|
||||
// process without running any shutdown code (#50).
|
||||
func TestShutdownContext_IsCancelledBySIGTERMAndSIGINT(t *testing.T) {
|
||||
for _, sig := range []syscall.Signal{syscall.SIGTERM, syscall.SIGINT} {
|
||||
t.Run(sig.String(), func(t *testing.T) {
|
||||
ctx, stop := shutdownContext(context.Background())
|
||||
defer stop()
|
||||
|
||||
if err := syscall.Kill(os.Getpid(), sig); err != nil {
|
||||
t.Fatalf("send %v: %v", sig, err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatalf("context not cancelled by %v", sig)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,10 @@ func (s *wStore) CompleteUpload(_ context.Context, _, id string, t domain.Transc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *wStore) FailUpload(_ context.Context, _, id string, k domain.UploadErrorKind) error {
|
||||
func (s *wStore) FailUpload(ctx context.Context, _, id string, k domain.UploadErrorKind) error {
|
||||
if err := ctx.Err(); err != nil { // like the real store: a cancelled context cannot write
|
||||
return err
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.failed[id] = k
|
||||
@@ -242,7 +245,9 @@ func TestWorkerProcess_FailuresAreTypedAndStillDeleteTheAudio(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestWorkerProcess_ShutdownMidJobLeavesTheRowForTheStartupSweep(t *testing.T) {
|
||||
func TestWorkerProcess_ShutdownMidJobRecordsTheRowInterruptedAtOnce(t *testing.T) {
|
||||
// SIGTERM on a deploy used to leave the row "transcribing" until the NEXT pod's
|
||||
// start-up sweep; the process may exit before any sweep runs (#50).
|
||||
r := newWRig(t, time.Minute)
|
||||
r.tr.block = make(chan struct{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -255,8 +260,8 @@ func TestWorkerProcess_ShutdownMidJobLeavesTheRowForTheStartupSweep(t *testing.T
|
||||
<-done
|
||||
|
||||
_, f := r.st.snapshot()
|
||||
assert.Empty(t, f, "a shutdown is not a transcription failure: the row stays for FailInterruptedUploads to mark interrupted")
|
||||
assert.Empty(t, r.leftovers(t), "but the audio is still deleted")
|
||||
assert.Equal(t, domain.UploadErrInterrupted, f["a"], "the row is recorded interrupted by the dying process, not left for a sweep")
|
||||
assert.Empty(t, r.leftovers(t), "and the audio is still deleted")
|
||||
}
|
||||
|
||||
func TestWorkerProcess_AJobThatOutlivesItsTimeoutIsFailedNotStuck(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user