(t *testing.T)
| 26 | } |
| 27 | |
| 28 | func TestForward_PassthroughEcho(t *testing.T) { |
| 29 | g := NewWithT(t) |
| 30 | // Fake upstream: echoes the request body back, prefixed with a |
| 31 | // canary so the test can assert both that the body reached the |
| 32 | // upstream and the response made it back to the client. |
| 33 | gotBody := make(chan string, 1) |
| 34 | gotAuth := make(chan string, 1) |
| 35 | gotPath := make(chan string, 1) |
| 36 | upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 37 | body, _ := io.ReadAll(r.Body) |
| 38 | gotBody <- string(body) |
| 39 | gotAuth <- r.Header.Get("Authorization") |
| 40 | gotPath <- r.URL.Path |
| 41 | w.Header().Set("X-Echo", "true") |
| 42 | w.WriteHeader(http.StatusOK) |
| 43 | _, _ = w.Write([]byte("echo: " + string(body))) |
| 44 | })) |
| 45 | defer upstream.Close() |
| 46 | |
| 47 | t.Setenv("CLOUD_PROXY_FAKE_KEY", "sk-fake") |
| 48 | |
| 49 | cp := NewCloudProxy() |
| 50 | err := cp.Load(&pb.ModelOptions{ |
| 51 | Proxy: &pb.ProxyOptions{ |
| 52 | UpstreamUrl: upstream.URL, |
| 53 | Mode: modePassthrough, |
| 54 | ApiKeyEnv: "CLOUD_PROXY_FAKE_KEY", |
| 55 | }, |
| 56 | }) |
| 57 | g.Expect(err).NotTo(HaveOccurred()) |
| 58 | |
| 59 | c := newInProcClient(t, cp) |
| 60 | stream, err := c.Forward(context.Background()) |
| 61 | g.Expect(err).NotTo(HaveOccurred()) |
| 62 | |
| 63 | err = stream.Send(&pb.ForwardRequest{ |
| 64 | Path: "/v1/chat/completions", |
| 65 | Method: "POST", |
| 66 | Headers: []*pb.ForwardHeader{{Name: "Content-Type", Value: "application/json"}}, |
| 67 | BodyChunk: []byte(`{"prompt":`), |
| 68 | }) |
| 69 | g.Expect(err).NotTo(HaveOccurred()) |
| 70 | err = stream.Send(&pb.ForwardRequest{BodyChunk: []byte(`"hi"}`)}) |
| 71 | g.Expect(err).NotTo(HaveOccurred()) |
| 72 | err = stream.CloseSend() |
| 73 | g.Expect(err).NotTo(HaveOccurred()) |
| 74 | |
| 75 | // First reply: status + headers. |
| 76 | first, err := stream.Recv() |
| 77 | g.Expect(err).NotTo(HaveOccurred()) |
| 78 | g.Expect(first.Status).To(Equal(int32(http.StatusOK))) |
| 79 | g.Expect(hasHeader(first.Headers, "X-Echo", "true")).To(BeTrue()) |
| 80 | |
| 81 | // Subsequent replies: body. |
| 82 | var body []byte |
| 83 | for { |
| 84 | r, err := stream.Recv() |
| 85 | if errors.Is(err, io.EOF) { |
nothing calls this directly
no test coverage detected