49 lines
1.2 KiB
Go
49 lines
1.2 KiB
Go
|
|
package llm
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"io"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
type responseBytesAndError struct {
|
||
|
|
data []byte
|
||
|
|
err error
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *responseBytesAndError) Read(p []byte) (int, error) {
|
||
|
|
if len(r.data) == 0 {
|
||
|
|
return 0, r.err
|
||
|
|
}
|
||
|
|
n := copy(p, r.data)
|
||
|
|
r.data = r.data[n:]
|
||
|
|
if len(r.data) == 0 {
|
||
|
|
return n, r.err
|
||
|
|
}
|
||
|
|
return n, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSuccessfulResponseReadFailuresRetainCause(t *testing.T) {
|
||
|
|
cause := errors.New("private reader diagnostic")
|
||
|
|
for _, test := range []struct {
|
||
|
|
name, prefix string
|
||
|
|
together bool
|
||
|
|
}{
|
||
|
|
{"partial", `{"choices":[`, false},
|
||
|
|
{"complete then failure", successfulProviderResponse, false},
|
||
|
|
{"bytes and error together", successfulProviderResponse, true},
|
||
|
|
} {
|
||
|
|
t.Run(test.name, func(t *testing.T) {
|
||
|
|
var reader io.Reader = io.MultiReader(strings.NewReader(test.prefix), failingReader{err: cause})
|
||
|
|
if test.together {
|
||
|
|
reader = &responseBytesAndError{data: []byte(test.prefix), err: cause}
|
||
|
|
}
|
||
|
|
_, err := decodeOpenAIChatResponse(reader)
|
||
|
|
if !errors.Is(err, ErrTransport) || !errors.Is(err, cause) || errors.Is(err, ErrMalformedResponse) || strings.Contains(err.Error(), cause.Error()) {
|
||
|
|
t.Fatalf("read failure = %v", err)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|