spark-server/internal/transport/tcp/session/conn_test.go
zhr ae9a71034d feat: implement Spark IM V3 modular monolith
Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 19:52:11 +08:00

72 lines
1.6 KiB
Go

package session
import (
"testing"
"spark-server/internal/pkg/errs"
"spark-server/internal/transport/tcp/protocol"
)
func TestOutboundDropDoesNotClose(t *testing.T) {
c := NewConn("1", "127.0.0.1:1", 1)
if err := c.Send(&Packet{Command: protocol.CmdHeartbeat}); err != nil {
t.Fatal(err)
}
err := c.Send(&Packet{Command: protocol.CmdHeartbeat})
if err != errs.ErrOutboundDropped {
t.Fatalf("want drop, got %v", err)
}
if c.Drops() != 1 {
t.Fatalf("drops %d", c.Drops())
}
if c.State() == StateClosed {
t.Fatal("drop must not close")
}
}
func TestKickSameDevice(t *testing.T) {
m := NewManager()
var kicked []byte
old := NewConn("old", "10.0.0.1:1", 8)
old.Authenticate(7, 9)
old.SetIO(func(b []byte) error { kicked = append(kicked, b...); return nil }, nil)
if err := m.Bind(old); err != nil {
t.Fatal(err)
}
n := NewConn("new", "10.0.0.1:2", 8)
n.Authenticate(7, 9)
if err := m.Bind(n); err != nil {
t.Fatal(err)
}
if old.State() != StateClosed {
t.Fatalf("old state %d", old.State())
}
got, err := protocol.Decode(kicked, 65536)
if err != nil {
t.Fatal(err)
}
if got.Command != protocol.CmdKick {
t.Fatalf("want kick, got %d", got.Command)
}
sessions := m.GetUserSessions(7)
if len(sessions) != 1 || sessions[0].ID() != "new" {
t.Fatalf("sessions %+v", sessions)
}
}
func TestKickDevice(t *testing.T) {
m := NewManager()
c := NewConn("s1", "10.0.0.1:1", 8)
c.Authenticate(3, 4)
if err := m.Bind(c); err != nil {
t.Fatal(err)
}
m.KickDevice(3, 4)
if c.State() != StateClosed {
t.Fatalf("state %d", c.State())
}
if len(m.GetUserSessions(3)) != 0 {
t.Fatal("expected empty")
}
}