package server import ( "testing" protocolnnet "git.noahlan.cn/noahlan/nnet/v2/internal/protocol/nnet" internalunpacker "git.noahlan.cn/noahlan/nnet/v2/internal/unpacker" unpackerpkg "git.noahlan.cn/noahlan/nnet/v2/pkg/unpacker" ) func TestProcessDataWithUnpackerConsumesIncompleteInput(t *testing.T) { unpacker := internalunpacker.NewLengthFieldUnpacker(unpackerpkg.LengthFieldUnpacker{ LengthFieldOffset: 0, LengthFieldLength: 1, LengthAdjustment: 0, InitialBytesToStrip: 0, }) messages, consumed, hasRemaining, err := processDataWithUnpacker([]byte{3, 'a'}, unpacker) if err != nil { t.Fatalf("processDataWithUnpacker error: %v", err) } if len(messages) != 0 { t.Fatalf("messages=%d, want 0", len(messages)) } if consumed != 2 { t.Fatalf("consumed=%d, want 2", consumed) } if !hasRemaining { t.Fatal("hasRemaining=false, want true") } messages, consumed, hasRemaining, err = processDataWithUnpacker([]byte{'b', 'c'}, unpacker) if err != nil { t.Fatalf("processDataWithUnpacker second error: %v", err) } if consumed != 2 { t.Fatalf("second consumed=%d, want 2", consumed) } if hasRemaining { t.Fatal("second hasRemaining=true, want false") } if len(messages) != 1 { t.Fatalf("second messages=%d, want 1", len(messages)) } if string(messages[0]) != "\x03abc" { t.Fatalf("message=%q, want %q", string(messages[0]), "\x03abc") } } func TestProcessDataWithUnpackerIsolatesConnectionBuffers(t *testing.T) { u1 := internalunpacker.NewLengthFieldUnpacker(unpackerpkg.LengthFieldUnpacker{ LengthFieldOffset: 0, LengthFieldLength: 1, LengthAdjustment: 0, InitialBytesToStrip: 0, }) u2 := internalunpacker.NewLengthFieldUnpacker(unpackerpkg.LengthFieldUnpacker{ LengthFieldOffset: 0, LengthFieldLength: 1, LengthAdjustment: 0, InitialBytesToStrip: 0, }) messages, _, hasRemaining, err := processDataWithUnpacker([]byte{3, 'a'}, u1) if err != nil { t.Fatalf("first connection partial error: %v", err) } if len(messages) != 0 || !hasRemaining { t.Fatalf("first connection messages=%d hasRemaining=%v, want 0/true", len(messages), hasRemaining) } messages, _, hasRemaining, err = processDataWithUnpacker([]byte{1, 'z'}, u2) if err != nil { t.Fatalf("second connection complete error: %v", err) } if hasRemaining || len(messages) != 1 || string(messages[0]) != "\x01z" { t.Fatalf("second connection messages=%q hasRemaining=%v, want isolated complete frame", messages, hasRemaining) } messages, _, hasRemaining, err = processDataWithUnpacker([]byte{'b', 'c'}, u1) if err != nil { t.Fatalf("first connection completion error: %v", err) } if hasRemaining || len(messages) != 1 || string(messages[0]) != "\x03abc" { t.Fatalf("first connection messages=%q hasRemaining=%v, want original buffered frame", messages, hasRemaining) } } func TestSplitWebSocketMessagesKeepsPartialFrameState(t *testing.T) { protocol := protocolnnet.NewNNetProtocol("1.0") provider, ok := protocol.(interface{ Unpacker() unpackerpkg.Unpacker }) if !ok { t.Fatal("protocol should provide an unpacker") } unpacker := provider.Unpacker() packet, err := protocol.Encode([]byte("hello"), nil) if err != nil { t.Fatalf("encode error: %v", err) } messages, err := splitWebSocketMessages(packet[:6], unpacker) if err != nil { t.Fatalf("partial split error: %v", err) } if len(messages) != 0 { t.Fatalf("partial messages=%d, want 0", len(messages)) } messages, err = splitWebSocketMessages(packet[6:], unpacker) if err != nil { t.Fatalf("completion split error: %v", err) } if len(messages) != 1 || string(messages[0]) != string(packet) { t.Fatalf("messages=%q, want complete packet", messages) } }