separate request tests (#5578)
This commit is contained in:
parent
9544a57ee4
commit
0aff67877e
1 changed files with 78 additions and 116 deletions
|
@ -3,7 +3,6 @@ package openai
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -16,49 +15,33 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMiddleware(t *testing.T) {
|
func TestMiddlewareRequests(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
Name string
|
Name string
|
||||||
Method string
|
Method string
|
||||||
Path string
|
Path string
|
||||||
TestPath string
|
|
||||||
Handler func() gin.HandlerFunc
|
Handler func() gin.HandlerFunc
|
||||||
Endpoint func(c *gin.Context)
|
|
||||||
Setup func(t *testing.T, req *http.Request)
|
Setup func(t *testing.T, req *http.Request)
|
||||||
Expected func(t *testing.T, resp *httptest.ResponseRecorder)
|
Expected func(t *testing.T, req *http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
var capturedRequest *http.Request
|
||||||
|
|
||||||
|
captureRequestMiddleware := func() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
bodyBytes, _ := io.ReadAll(c.Request.Body)
|
||||||
|
c.Request.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||||
|
capturedRequest = c.Request
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []testCase{
|
testCases := []testCase{
|
||||||
{
|
{
|
||||||
Name: "chat handler",
|
Name: "chat handler",
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/chat",
|
Path: "/api/chat",
|
||||||
TestPath: "/api/chat",
|
Handler: ChatMiddleware,
|
||||||
Handler: ChatMiddleware,
|
|
||||||
Endpoint: func(c *gin.Context) {
|
|
||||||
var chatReq api.ChatRequest
|
|
||||||
if err := c.ShouldBindJSON(&chatReq); err != nil {
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userMessage := chatReq.Messages[0].Content
|
|
||||||
var assistantMessage string
|
|
||||||
|
|
||||||
switch userMessage {
|
|
||||||
case "Hello":
|
|
||||||
assistantMessage = "Hello!"
|
|
||||||
default:
|
|
||||||
assistantMessage = "I'm not sure how to respond to that."
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, api.ChatResponse{
|
|
||||||
Message: api.Message{
|
|
||||||
Role: "assistant",
|
|
||||||
Content: assistantMessage,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
Setup: func(t *testing.T, req *http.Request) {
|
Setup: func(t *testing.T, req *http.Request) {
|
||||||
body := ChatCompletionRequest{
|
body := ChatCompletionRequest{
|
||||||
Model: "test-model",
|
Model: "test-model",
|
||||||
|
@ -70,88 +53,26 @@ func TestMiddleware(t *testing.T) {
|
||||||
req.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
req.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
},
|
},
|
||||||
Expected: func(t *testing.T, resp *httptest.ResponseRecorder) {
|
Expected: func(t *testing.T, req *http.Request) {
|
||||||
assert.Equal(t, http.StatusOK, resp.Code)
|
var chatReq api.ChatRequest
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&chatReq); err != nil {
|
||||||
var chatResp ChatCompletion
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&chatResp); err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if chatResp.Object != "chat.completion" {
|
if chatReq.Messages[0].Role != "user" {
|
||||||
t.Fatalf("expected chat.completion, got %s", chatResp.Object)
|
t.Fatalf("expected 'user', got %s", chatReq.Messages[0].Role)
|
||||||
}
|
}
|
||||||
|
|
||||||
if chatResp.Choices[0].Message.Content != "Hello!" {
|
if chatReq.Messages[0].Content != "Hello" {
|
||||||
t.Fatalf("expected Hello!, got %s", chatResp.Choices[0].Message.Content)
|
t.Fatalf("expected 'Hello', got %s", chatReq.Messages[0].Content)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "completions handler",
|
Name: "completions handler",
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/generate",
|
Path: "/api/generate",
|
||||||
TestPath: "/api/generate",
|
Handler: CompletionsMiddleware,
|
||||||
Handler: CompletionsMiddleware,
|
|
||||||
Endpoint: func(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, api.GenerateResponse{
|
|
||||||
Response: "Hello!",
|
|
||||||
})
|
|
||||||
},
|
|
||||||
Setup: func(t *testing.T, req *http.Request) {
|
|
||||||
body := CompletionRequest{
|
|
||||||
Model: "test-model",
|
|
||||||
Prompt: "Hello",
|
|
||||||
}
|
|
||||||
|
|
||||||
bodyBytes, _ := json.Marshal(body)
|
|
||||||
|
|
||||||
req.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
},
|
|
||||||
Expected: func(t *testing.T, resp *httptest.ResponseRecorder) {
|
|
||||||
assert.Equal(t, http.StatusOK, resp.Code)
|
|
||||||
var completionResp Completion
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&completionResp); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if completionResp.Object != "text_completion" {
|
|
||||||
t.Fatalf("expected text_completion, got %s", completionResp.Object)
|
|
||||||
}
|
|
||||||
|
|
||||||
if completionResp.Choices[0].Text != "Hello!" {
|
|
||||||
t.Fatalf("expected Hello!, got %s", completionResp.Choices[0].Text)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "completions handler with params",
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/generate",
|
|
||||||
TestPath: "/api/generate",
|
|
||||||
Handler: CompletionsMiddleware,
|
|
||||||
Endpoint: func(c *gin.Context) {
|
|
||||||
var generateReq api.GenerateRequest
|
|
||||||
if err := c.ShouldBindJSON(&generateReq); err != nil {
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
temperature := generateReq.Options["temperature"].(float64)
|
|
||||||
var assistantMessage string
|
|
||||||
|
|
||||||
switch temperature {
|
|
||||||
case 1.6:
|
|
||||||
assistantMessage = "Received temperature of 1.6"
|
|
||||||
default:
|
|
||||||
assistantMessage = fmt.Sprintf("Received temperature of %f", temperature)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, api.GenerateResponse{
|
|
||||||
Response: assistantMessage,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
Setup: func(t *testing.T, req *http.Request) {
|
Setup: func(t *testing.T, req *http.Request) {
|
||||||
temp := float32(0.8)
|
temp := float32(0.8)
|
||||||
body := CompletionRequest{
|
body := CompletionRequest{
|
||||||
|
@ -165,24 +86,65 @@ func TestMiddleware(t *testing.T) {
|
||||||
req.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
req.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
},
|
},
|
||||||
Expected: func(t *testing.T, resp *httptest.ResponseRecorder) {
|
Expected: func(t *testing.T, req *http.Request) {
|
||||||
assert.Equal(t, http.StatusOK, resp.Code)
|
var genReq api.GenerateRequest
|
||||||
var completionResp Completion
|
if err := json.NewDecoder(req.Body).Decode(&genReq); err != nil {
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&completionResp); err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if completionResp.Object != "text_completion" {
|
if genReq.Prompt != "Hello" {
|
||||||
t.Fatalf("expected text_completion, got %s", completionResp.Object)
|
t.Fatalf("expected 'Hello', got %s", genReq.Prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if completionResp.Choices[0].Text != "Received temperature of 1.6" {
|
if genReq.Options["temperature"] != 1.6 {
|
||||||
t.Fatalf("expected Received temperature of 1.6, got %s", completionResp.Choices[0].Text)
|
t.Fatalf("expected 1.6, got %f", genReq.Options["temperature"])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
gin.SetMode(gin.TestMode)
|
||||||
|
router := gin.New()
|
||||||
|
|
||||||
|
endpoint := func(c *gin.Context) {
|
||||||
|
c.Status(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
router = gin.New()
|
||||||
|
router.Use(captureRequestMiddleware())
|
||||||
|
router.Use(tc.Handler())
|
||||||
|
router.Handle(tc.Method, tc.Path, endpoint)
|
||||||
|
req, _ := http.NewRequest(tc.Method, tc.Path, nil)
|
||||||
|
|
||||||
|
if tc.Setup != nil {
|
||||||
|
tc.Setup(t, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := httptest.NewRecorder()
|
||||||
|
router.ServeHTTP(resp, req)
|
||||||
|
|
||||||
|
tc.Expected(t, capturedRequest)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMiddlewareResponses(t *testing.T) {
|
||||||
|
type testCase struct {
|
||||||
|
Name string
|
||||||
|
Method string
|
||||||
|
Path string
|
||||||
|
TestPath string
|
||||||
|
Handler func() gin.HandlerFunc
|
||||||
|
Endpoint func(c *gin.Context)
|
||||||
|
Setup func(t *testing.T, req *http.Request)
|
||||||
|
Expected func(t *testing.T, resp *httptest.ResponseRecorder)
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []testCase{
|
||||||
{
|
{
|
||||||
Name: "completions handler with error",
|
Name: "completions handler error forwarding",
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/generate",
|
Path: "/api/generate",
|
||||||
TestPath: "/api/generate",
|
TestPath: "/api/generate",
|
||||||
|
|
Loading…
Reference in a new issue