- Dart: Replace ResponseChecker with HeartbeatMixin - Dart: Remove heartbeat-related fields from ProtobufClient/Server - Dart: Add HeartbeatMixin for cleaner heartbeat logic - Go: Add timeout test in communicator_test.go - Go: Add heartbeat_test.go with heartbeat functionality tests - Go: Add TLS test in tls_test.go - Go: Add message type mismatch tests - Go: Improve tcp_test.go and ws_test.go with comprehensive tests - Dart: Add comprehensive socket_test.dart with multiple test scenarios - Add untracked documentation files
89 lines
2 KiB
Go
89 lines
2 KiB
Go
package toki_socket_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"nhooyr.io/websocket"
|
|
|
|
toki "toki-labs.com/toki_socket/go"
|
|
)
|
|
|
|
func TestHeartbeatDisconnectsWithoutResponse(t *testing.T) {
|
|
clientConn, peerConn := net.Pipe()
|
|
defer peerConn.Close()
|
|
|
|
go func() {
|
|
_, _ = io.Copy(io.Discard, peerConn)
|
|
}()
|
|
|
|
client := toki.NewTcpClient(clientConn, 1, 1, testParserMap())
|
|
defer client.Close()
|
|
|
|
disconnected := make(chan struct{}, 1)
|
|
client.AddDisconnectListener(func(*toki.TcpClient) {
|
|
disconnected <- struct{}{}
|
|
})
|
|
|
|
select {
|
|
case <-disconnected:
|
|
case <-time.After(3500 * time.Millisecond):
|
|
t.Fatal("heartbeat timeout did not disconnect client")
|
|
}
|
|
if client.IsAlive() {
|
|
t.Fatal("client is still marked alive after heartbeat timeout")
|
|
}
|
|
}
|
|
|
|
func TestWsHeartbeatDisconnectsWithoutResponse(t *testing.T) {
|
|
port := freePort(t)
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
conn, err := websocket.Accept(w, r, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer conn.Close(websocket.StatusNormalClosure, "")
|
|
for {
|
|
if _, _, err := conn.Read(r.Context()); err != nil {
|
|
return
|
|
}
|
|
}
|
|
})
|
|
server := &http.Server{Addr: fmt.Sprintf("127.0.0.1:%d", port), Handler: mux}
|
|
ln, err := net.Listen("tcp", server.Addr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer server.Close()
|
|
go func() {
|
|
_ = server.Serve(ln)
|
|
}()
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
client, err := toki.DialWsWithHeartbeat(ctx, "127.0.0.1", port, "/", 1, 1, testParserMap())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer client.Close()
|
|
|
|
disconnected := make(chan struct{}, 1)
|
|
client.AddDisconnectListener(func(*toki.WsClient) {
|
|
disconnected <- struct{}{}
|
|
})
|
|
|
|
select {
|
|
case <-disconnected:
|
|
case <-time.After(3500 * time.Millisecond):
|
|
t.Fatal("websocket heartbeat timeout did not disconnect client")
|
|
}
|
|
if client.IsAlive() {
|
|
t.Fatal("websocket client is still marked alive after heartbeat timeout")
|
|
}
|
|
}
|