Files
sub2api/backend/internal/pkg/httputil/preread_body_test.go
T

98 lines
2.6 KiB
Go

package httputil
import (
"bytes"
"io"
"net/http"
"strings"
"testing"
)
func TestPrereadBodyRoundtrip(t *testing.T) {
body := []byte(`{"model":"gpt-5.4"}`)
preread := NewPrereadBody(body)
got, err := io.ReadAll(preread)
if err != nil {
t.Fatalf("read preread body: %v", err)
}
if !bytes.Equal(got, body) {
t.Fatalf("body mismatch: got %q want %q", got, body)
}
if err := preread.Close(); err != nil {
t.Fatalf("close: %v", err)
}
if !bytes.Equal(preread.Bytes(), body) {
t.Fatalf("Bytes() mismatch after close: %q", preread.Bytes())
}
}
func TestPrereadBodyReadableTwiceFromFreshWrapper(t *testing.T) {
// ResetRequestBody 每次都回填新的 PrereadBody;同一实例只被顺序消费一次。
body := []byte("payload")
first := NewPrereadBody(body)
got1, _ := io.ReadAll(first)
if !bytes.Equal(got1, body) {
t.Fatalf("first read mismatch: %q", got1)
}
second := NewPrereadBody(first.Bytes())
got2, _ := io.ReadAll(second)
if !bytes.Equal(got2, body) {
t.Fatalf("second read mismatch: %q", got2)
}
}
func TestReadRequestBodyWithPreallocReturnsPrereadBodySliceWithoutCopy(t *testing.T) {
body := []byte(`{"model":"claude-sonnet-4.5"}`)
req, err := http.NewRequest(http.MethodPost, "/v1/messages", NewPrereadBody(body))
if err != nil {
t.Fatalf("new request: %v", err)
}
req.Header.Set("Content-Length", "0") // 故意与实际不符,验证不依赖 ContentLength
got, err := ReadRequestBodyWithPrealloc(req)
if err != nil {
t.Fatalf("ReadRequestBodyWithPrealloc: %v", err)
}
if &got[0] != &body[0] {
t.Fatalf("expected zero-copy return of the same slice")
}
if !bytes.Equal(got, body) {
t.Fatalf("body mismatch: got %q want %q", got, body)
}
}
func TestReadRequestBodyWithPreallocHandlesNilPrereadBody(t *testing.T) {
req, err := http.NewRequest(http.MethodPost, "/v1/messages", nil)
if err != nil {
t.Fatalf("new request: %v", err)
}
got, err := ReadRequestBodyWithPrealloc(req)
if err != nil || got != nil {
t.Fatalf("expected nil body, got (%#v, %v)", got, err)
}
}
func TestPrereadBodyPartialConsumeThenPreallocReturnsFullBody(t *testing.T) {
body := []byte(strings.Repeat("x", 64))
preread := NewPrereadBody(body)
head := make([]byte, 16)
if _, err := io.ReadFull(preread, head); err != nil {
t.Fatalf("partial read: %v", err)
}
req, err := http.NewRequest(http.MethodPost, "/v1/responses", preread)
if err != nil {
t.Fatalf("new request: %v", err)
}
got, err := ReadRequestBodyWithPrealloc(req)
if err != nil {
t.Fatalf("ReadRequestBodyWithPrealloc: %v", err)
}
if !bytes.Equal(got, body) {
t.Fatalf("expected full body after partial consume, got %d bytes", len(got))
}
}