101 lines
3.4 KiB
Go
101 lines
3.4 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package speech
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func TestResolveServerAddressPrecedence(t *testing.T) {
|
|
runtimeDirectory := t.TempDir()
|
|
cacheDirectory := t.TempDir()
|
|
t.Setenv("XDG_RUNTIME_DIR", runtimeDirectory)
|
|
t.Setenv("XDG_CACHE_HOME", cacheDirectory)
|
|
t.Setenv("SPEECHD_SOCKET", "/tmp/legacy-speech.sock")
|
|
t.Setenv("SPEECHD_ADDRESS", "unix_socket:/tmp/address-speech.sock")
|
|
|
|
for _, test := range []struct {
|
|
name, override, speechAddress, legacySocket, runtimeDir, want string
|
|
}{
|
|
{"explicit", "/tmp/explicit-speech.sock", "unix_socket:/tmp/address-speech.sock", "/tmp/legacy-speech.sock", runtimeDirectory, "/tmp/explicit-speech.sock"},
|
|
{"address", "", "unix_socket:/tmp/address-speech.sock", "/tmp/legacy-speech.sock", runtimeDirectory, "/tmp/address-speech.sock"},
|
|
{"legacy", "", "", "/tmp/legacy-speech.sock", runtimeDirectory, "/tmp/legacy-speech.sock"},
|
|
{"runtime", "", "", "", runtimeDirectory, filepath.Join(runtimeDirectory, "speech-dispatcher", "speechd.sock")},
|
|
{"cache", "", "", "", "", filepath.Join(cacheDirectory, "speech-dispatcher", "speechd.sock")},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
t.Setenv("SPEECHD_ADDRESS", test.speechAddress)
|
|
t.Setenv("SPEECHD_SOCKET", test.legacySocket)
|
|
t.Setenv("XDG_RUNTIME_DIR", test.runtimeDir)
|
|
got, err := resolveServerAddress(test.override)
|
|
if err != nil || got.network != "unix" || got.address != test.want {
|
|
t.Fatalf("address = %+v, error = %v; want %q", got, err, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseServerAddress(t *testing.T) {
|
|
for _, test := range []struct {
|
|
input, network, address string
|
|
}{
|
|
{"unix_socket:/tmp/speech.sock", "unix", "/tmp/speech.sock"},
|
|
{"inet_socket", "tcp4", "127.0.0.1:6560"},
|
|
{"inet_socket:localhost:6561", "tcp4", "localhost:6561"},
|
|
} {
|
|
got, err := parseServerAddress(test.input)
|
|
if err != nil || got.network != test.network || got.address != test.address {
|
|
t.Fatalf("parse %q = %+v, %v", test.input, got, err)
|
|
}
|
|
}
|
|
for _, address := range []string{"invalid:/tmp/speech.sock", "unix_socket:relative.sock", "inet_socket:localhost:0", "inet_socket:localhost:bad"} {
|
|
if _, err := parseServerAddress(address); err == nil {
|
|
t.Fatalf("accepted invalid address %q", address)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestClientAndDiscoveryHonorSpeechdAddress(t *testing.T) {
|
|
path, _ := newSettingsServer(t, func(command string) string {
|
|
if command == "LIST OUTPUT_MODULES" {
|
|
return "200-test\r\n200 OK\r\n"
|
|
}
|
|
return ""
|
|
})
|
|
t.Setenv("SPEECHD_ADDRESS", "unix_socket:"+path)
|
|
t.Setenv("SPEECHD_SOCKET", "/tmp/absent-speech.sock")
|
|
client := New("")
|
|
defer client.Close(context.Background())
|
|
if err := client.Connect(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := Discover(context.Background(), ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestTCPAddressConnects(t *testing.T) {
|
|
listener, err := net.Listen("tcp4", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer listener.Close()
|
|
server := newSettingsServerListener(t, listener, nil)
|
|
port := listener.Addr().(*net.TCPAddr).Port
|
|
t.Setenv("SPEECHD_ADDRESS", "inet_socket:127.0.0.1:"+strconv.Itoa(port))
|
|
client := New("")
|
|
defer client.Close(context.Background())
|
|
if err := client.Connect(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !server.saw(1, "HISTORY GET CLIENT_ID") {
|
|
t.Fatal("speech client did not use the TCP server")
|
|
}
|
|
}
|