package protocol import ( "bytes" "net" "testing" "time" ) func TestHandshakeRoundTrip(t *testing.T) { in := BuildHandshake(767, "mc.example.com", 25565, 2) h, raw, err := ReadHandshake(bytes.NewReader(in)) if err != nil { t.Fatal(err) } want := Handshake{Protocol: 767, Host: "mc.example.com", Port: 25565, NextState: 2} if h != want { t.Fatalf("got %+v want %+v", h, want) } if !bytes.Equal(raw, in) { t.Fatal("raw bytes not preserved") } } func TestReadHandshakeRejects(t *testing.T) { cases := map[string][]byte{ "legacy": {0xfe, 0x01, 0xfa}, "huge length": {0xff, 0xff, 0xff, 0xff, 0x07}, "zero length": {0x00}, "wrong id": Frame([]byte{0x05, 0x00}), "short host": Frame([]byte{0x00, 0x01, 0x40, 'a'}), "truncated": {0x10, 0x00}, } for name, b := range cases { if _, _, err := ReadHandshake(bytes.NewReader(b)); err == nil { t.Errorf("%s: expected error", name) } } if _, _, err := ReadHandshake(bytes.NewReader([]byte{0xfe, 0x01})); err != ErrLegacy { t.Errorf("want ErrLegacy, got %v", err) } } func TestVarInt(t *testing.T) { if got := AppendVarInt(nil, 300); !bytes.Equal(got, []byte{0xac, 0x02}) { t.Fatalf("got %x", got) } if got := AppendVarInt(nil, -1); len(got) != 5 { t.Fatalf("negative should take 5 bytes, got %x", got) } } func TestStatusExchange(t *testing.T) { c, s := net.Pipe() defer c.Close() go func() { defer s.Close() ServeStatus(s, `{"ok":true}`) }() c.SetDeadline(time.Now().Add(2 * time.Second)) c.Write(Frame([]byte{0})) id, payload, err := ReadPacket(c, maxStatus) if err != nil || id != 0 || !bytes.Contains(payload, []byte(`{"ok":true}`)) { t.Fatalf("id=%d payload=%q err=%v", id, payload, err) } c.Write(Frame(append([]byte{1}, 0, 0, 0, 0, 0, 0, 0, 42))) id, payload, err = ReadPacket(c, 32) if err != nil || id != 1 || payload[7] != 42 { t.Fatalf("pong id=%d payload=%x err=%v", id, payload, err) } } func TestQueryStatus(t *testing.T) { c, s := net.Pipe() defer c.Close() go func() { defer s.Close() if _, _, err := ReadHandshake(s); err != nil { return } ServeStatus(s, `{"players":{"online":3}}`) }() got, err := QueryStatus(c, "x", 25565, 2*time.Second) if err != nil || got != `{"players":{"online":3}}` { t.Fatalf("got %q err=%v", got, err) } }