Fix Remote speech stalls after pause and early completion
This commit is contained in:
1 parent
6867d901b2
commit
19b789ef5c
6 files changed
+131
-30
No files matched your search
@@ -7,6 +7,7 @@ package app
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
@@ -188,10 +189,6 @@ func TestRemoteSpeechStreamCancelAndPause(t *testing.T) {
|
||||
remote_stream_wait(t, f.send(t, effect))
|
||||
remote_stream_wait(t, active.stopped)
|
||||
remote_stream_wait(t, pendingRelease)
|
||||
if kind == "pause" {
|
||||
remote_stream_wait(t, f.speak(t, "discard while paused", 2))
|
||||
f.barrier(t) // Resume accepts future speech only.
|
||||
}
|
||||
futureRelease := f.speak(t, "future", 0)
|
||||
close(active.cleanup)
|
||||
future := f.next(t, "future")
|
||||
@@ -203,6 +200,24 @@ func TestRemoteSpeechStreamCancelAndPause(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteSpeechStreamFreshSpeechAfterPause(t *testing.T) {
|
||||
for _, cancelFirst := range []bool{false, true} {
|
||||
t.Run(map[bool]string{false: "speak", true: "cancel then speak"}[cancelFirst], func(t *testing.T) {
|
||||
f := remote_stream_fixture(t, false)
|
||||
paused := true
|
||||
remote_stream_wait(t, f.send(t, tentaclewire.RemoteSpeech{Kind: "pause", Paused: &paused}))
|
||||
if cancelFirst {
|
||||
remote_stream_wait(t, f.send(t, tentaclewire.RemoteSpeech{Kind: "cancel"}))
|
||||
}
|
||||
released := f.speak(t, "new navigation", 0)
|
||||
call := f.next(t, "new navigation")
|
||||
call.finish <- nil
|
||||
remote_stream_wait(t, released)
|
||||
f.stop(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteSpeechStreamRevocationAndReplacement(t *testing.T) {
|
||||
f := remote_stream_fixture(t, true)
|
||||
leaseContext, revoke := context.WithCancel(f.ctx)
|
||||
@@ -349,6 +364,40 @@ func TestRemoteSpeechStreamIsolatedBackendCancellation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteSpeechStreamEarlyBackendCompletionKeepsReading(t *testing.T) {
|
||||
for _, terminal := range []int{702, 703} {
|
||||
t.Run(fmt.Sprint(terminal), func(t *testing.T) {
|
||||
speaker, server := isolated_voice_fixture(t)
|
||||
server.mutex.Lock()
|
||||
server.queryReplies = map[string]string{"SPEAK": fmt.Sprintf(
|
||||
"230 OK\r\n%d-1\r\n%d-1\r\n%d DONE\r\n225-1\r\n225 QUEUED\r\n", terminal, terminal, terminal)}
|
||||
server.mutex.Unlock()
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
incoming := make(chan tentacle.RemoteSpeechDelivery, 8)
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- run_remote_speech_playback(ctx, speaker, incoming, func(tentacle.RemoteSpeechDelivery) bool { return true }, nil)
|
||||
}()
|
||||
lease := tentaclewire.RemoteLease{Lease: strings.Repeat("b", 32), Epoch: 1}
|
||||
for _, text := range []string{"first", "second", "third"} {
|
||||
released := make(chan struct{})
|
||||
incoming <- tentacle.RemoteSpeechDelivery{Context: ctx, Lease: lease,
|
||||
Speeches: []tentaclewire.RemoteSpeech{remote_render_frame(0, tentaclewire.RemoteSpeechPart{Text: text})},
|
||||
Release: func() { close(released) }}
|
||||
if got := server.next_utterance(t); got.text != text {
|
||||
t.Fatalf("remote output = %q, want %q", got.text, text)
|
||||
}
|
||||
remote_stream_wait(t, released)
|
||||
}
|
||||
cancel()
|
||||
if err := remote_render_result(t, done); !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("stream shutdown: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteSpeechStreamPolicyLossDuringAcquisition(t *testing.T) {
|
||||
speaker, server := isolated_voice_fixture(t)
|
||||
held, resume := make(chan struct{}), make(chan struct{})
|
||||
|
||||
Reference in new issue
Block a user