Assemble Remote speech before reader delivery
This commit is contained in:
1 parent
f23e89ed93
commit
205cb27483
9 files changed
+492
-33
No files matched your search
@@ -25,6 +25,7 @@ import (
|
||||
"git.stormux.org/storm/cthulhu/internal/input"
|
||||
"git.stormux.org/storm/cthulhu/internal/interaction"
|
||||
"git.stormux.org/storm/cthulhu/internal/tentacle"
|
||||
"git.stormux.org/storm/cthulhu/internal/tentaclewire"
|
||||
)
|
||||
|
||||
// This uses the source-built external executable and real host/SDK IPC. Only
|
||||
@@ -223,6 +224,7 @@ func TestRemoteConnectionCommandCancelsInspectionOnHandoff(t *testing.T) {
|
||||
func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
for _, role := range []string{"controller", "controlled"} {
|
||||
t.Run(role, func(t *testing.T) {
|
||||
remoteText := " " + strings.Repeat("é\x00世界 ", 1500) + " "
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -274,12 +276,39 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
t.Error("invalid relay join or wrong selected role")
|
||||
return
|
||||
}
|
||||
io.WriteString(connection, `{"type":"channel_joined","channel":"synthetic-fixture","clients":[]}`+"\n")
|
||||
peerRole := "master"
|
||||
if role == "controller" {
|
||||
peerRole = "slave"
|
||||
}
|
||||
io.WriteString(connection, `{"type":"channel_joined","channel":"synthetic-fixture","clients":[{"id":7,"connection_type":"`+peerRole+`"}]}`+"\n")
|
||||
if role == "controller" {
|
||||
json.NewEncoder(connection).Encode(map[string]any{"type": "speak", "origin": 7, "priority": 2, "sequence": []any{
|
||||
[]any{"CharacterModeCommand", map[string]any{"state": true}},
|
||||
[]any{"LangChangeCommand", map[string]any{"lang": "fr"}}, remoteText,
|
||||
[]any{"EndUtteranceCommand", map[string]any{}},
|
||||
}})
|
||||
}
|
||||
close(joined)
|
||||
io.Copy(io.Discard, reader)
|
||||
close(closed)
|
||||
}()
|
||||
runtime, forms, _ := remote_command_fixture(t)
|
||||
// Only this fixture supplies a reader owner. Production remains
|
||||
// disabled until output arbitration/security policy is implemented.
|
||||
var deliveries <-chan tentacle.RemoteSpeechDelivery
|
||||
if role == "controller" {
|
||||
runtime.mutex.Lock()
|
||||
for _, command := range runtime.commands {
|
||||
if command.id == "remote" {
|
||||
deliveries = command.session.EnableRemoteSpeech()
|
||||
break
|
||||
}
|
||||
}
|
||||
runtime.mutex.Unlock()
|
||||
if deliveries == nil {
|
||||
t.Fatal("Remote fixture session unavailable")
|
||||
}
|
||||
}
|
||||
consent := select_remote_relay(t, forms, listener.Addr().String(), role)
|
||||
credentials := approve_remote_form(t, forms, consent, role)
|
||||
credentials.reply <- internalUIResult{Activated: "inspect-certificate"}
|
||||
@@ -305,6 +334,40 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
if status.form.Title != "Remote relay status" {
|
||||
t.Fatal("missing connection status")
|
||||
}
|
||||
var delivery tentacle.RemoteSpeechDelivery
|
||||
if role == "controller" {
|
||||
select {
|
||||
case delivery = <-deliveries:
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("split relay speech did not reach the reader owner")
|
||||
}
|
||||
var text strings.Builder
|
||||
ends := 0
|
||||
for _, speech := range delivery.Speeches {
|
||||
if !tentaclewire.ValidRemoteSpeech(speech) || speech.Priority != 2 {
|
||||
t.Fatal("invalid speech fragment or changed priority")
|
||||
}
|
||||
for _, part := range speech.Parts {
|
||||
if part.End {
|
||||
ends++
|
||||
} else {
|
||||
if !part.Characters || part.Language != "fr" {
|
||||
t.Fatal("split speech lost character/language state")
|
||||
}
|
||||
text.WriteString(part.Text)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(delivery.Speeches) < 2 || text.String() != remoteText || ends != 1 {
|
||||
t.Fatal("reader owner received partial or altered utterance")
|
||||
}
|
||||
select {
|
||||
case <-deliveries:
|
||||
t.Fatal("one relay utterance became multiple deliveries")
|
||||
default:
|
||||
}
|
||||
delivery.Release()
|
||||
}
|
||||
status.reply <- internalUIResult{Activated: "cancel"}
|
||||
select {
|
||||
case <-closed:
|
||||
@@ -312,6 +375,9 @@ func TestRemoteConnectionCommandPrivateRelay(t *testing.T) {
|
||||
t.Fatal("Disconnect and close retained the relay")
|
||||
}
|
||||
waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 })
|
||||
if role == "controller" && delivery.Context.Err() == nil {
|
||||
t.Fatal("Disconnect retained remote delivery authority")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user