Files
ngzz-mc/internal/netproto/protocol_test.go

88 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package netproto
import (
"bytes"
"math"
"testing"
)
// TestVarint 变长整数边界(网络协议.md §2)。
func TestVarint(t *testing.T) {
cases := []uint32{0, 1, 127, 128, 300, 16383, 16384, 1<<21 - 1, math.MaxUint32}
for _, want := range cases {
w := &Writer{}
w.Varint(want)
r := NewReader(w.B)
if got := r.Varint(); got != want || r.Err != nil {
t.Fatalf("varint %d 往返失败: got=%d err=%v", want, got, r.Err)
}
}
}
// TestFrame 帧编解码往返(网络协议.md §1)。
func TestFrame(t *testing.T) {
f := Frame{MsgID: MsgBlockChange, Flags: 0, Payload: BlockChange{X: 1, Y: 64, Z: -2, BlockID: 5, Meta: 0}.Encode()}
enc := EncodeFrame(f)
got, rest, err := DecodeFrame(enc)
if err != nil {
t.Fatalf("解码失败: %v", err)
}
if len(rest) != 0 {
t.Fatalf("应无剩余字节,实际 %d", len(rest))
}
if got.MsgID != f.MsgID || !bytes.Equal(got.Payload, f.Payload) {
t.Fatalf("帧往返不一致: %+v", got)
}
// 流式粘包:两帧连续
enc2 := EncodeFrame(Frame{MsgID: MsgHeartbeat, Payload: []byte{9, 9}})
stream := append(append([]byte{}, enc...), enc2...)
g1, rest, err := DecodeFrame(stream)
if err != nil || g1.MsgID != MsgBlockChange {
t.Fatalf("粘包第一帧解析失败: %v", err)
}
g2, rest2, err := DecodeFrame(rest)
if err != nil || g2.MsgID != MsgHeartbeat || len(rest2) != 0 {
t.Fatalf("粘包第二帧解析失败: %v", err)
}
}
// TestBlockChange 方块变更消息往返。
func TestBlockChangeMsg(t *testing.T) {
in := BlockChange{X: -17, Y: 63, Z: 42, BlockID: 7, Meta: 3}
out, err := DecodeBlockChange(in.Encode())
if err != nil {
t.Fatalf("解码失败: %v", err)
}
if out != in {
t.Fatalf("往返不一致: %+v != %+v", out, in)
}
}
// TestPlayerMove 玩家移动消息往返。
func TestPlayerMoveMsg(t *testing.T) {
in := PlayerMove{X: 8.5, Y: 64.0, Z: -3.25, Yaw: 1.57, Pitch: -0.5, OnGround: true}
out, err := DecodePlayerMove(in.Encode())
if err != nil {
t.Fatalf("解码失败: %v", err)
}
if out != in {
t.Fatalf("往返不一致: %+v != %+v", out, in)
}
}
// TestTruncated 截断数据必须报错(防崩溃,网络协议.md §8)。
func TestTruncated(t *testing.T) {
f := Frame{MsgID: MsgHandshake, Payload: []byte{1, 2, 3, 4}}
enc := EncodeFrame(f)
if _, _, err := DecodeFrame(enc[:len(enc)-2]); err == nil {
t.Fatal("截断帧应报错")
}
// 超长帧头应报错
bad := make([]byte, 8)
bad[0] = 0xFF
bad[1] = 0xFF
if _, _, err := DecodeFrame(bad); err == nil {
t.Fatal("超长帧头应报错")
}
}