Skip to content

Commit 3dc7b02

Browse files
chore: add event streaming test endpoints (#5)
This change adds mock endpoints that stream server-sent events. These will support the test suite in openapi-generation. Also added the ability to run the server using a different bind address. This is helpful when running the project locally outside of docker.
1 parent 6387eaf commit 3dc7b02

File tree

3 files changed

+147
-3
lines changed

3 files changed

+147
-3
lines changed

cmd/server/main.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package main
22

33
import (
4+
"flag"
45
"log"
56
"net/http"
67

78
"github.com/speakeasy-api/speakeasy-api-test-service/internal/acceptHeaders"
89
"github.com/speakeasy-api/speakeasy-api-test-service/internal/errors"
10+
"github.com/speakeasy-api/speakeasy-api-test-service/internal/eventstreams"
911
"github.com/speakeasy-api/speakeasy-api-test-service/internal/pagination"
1012
"github.com/speakeasy-api/speakeasy-api-test-service/internal/readonlywriteonly"
1113
"github.com/speakeasy-api/speakeasy-api-test-service/internal/responseHeaders"
@@ -16,7 +18,11 @@ import (
1618
"github.com/speakeasy-api/speakeasy-api-test-service/internal/requestbody"
1719
)
1820

21+
var bindArg = flag.String("b", ":8080", "Bind address")
22+
1923
func main() {
24+
flag.Parse()
25+
2026
r := mux.NewRouter()
2127
r.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
2228
_, _ = w.Write([]byte("pong"))
@@ -33,9 +39,19 @@ func main() {
3339
r.HandleFunc("/readonlyorwriteonly", readonlywriteonly.HandleReadOrWrite).Methods(http.MethodPost)
3440
r.HandleFunc("/readonlyandwriteonly", readonlywriteonly.HandleReadAndWrite).Methods(http.MethodPost)
3541
r.HandleFunc("/writeonlyoutput", readonlywriteonly.HandleWriteOnlyOutput).Methods(http.MethodPost)
42+
r.HandleFunc("/eventstreams/json", eventstreams.HandleEventStreamJSON).Methods(http.MethodPost)
43+
r.HandleFunc("/eventstreams/text", eventstreams.HandleEventStreamText).Methods(http.MethodPost)
44+
r.HandleFunc("/eventstreams/multiline", eventstreams.HandleEventStreamMultiLine).Methods(http.MethodPost)
45+
r.HandleFunc("/eventstreams/rich", eventstreams.HandleEventStreamRich).Methods(http.MethodPost)
46+
r.HandleFunc("/eventstreams/chat", eventstreams.HandleEventStreamChat).Methods(http.MethodPost)
47+
48+
bind := ":8080"
49+
if bindArg != nil {
50+
bind = *bindArg
51+
}
3652

37-
log.Println("Listening on :8080")
38-
if err := http.ListenAndServe(":8080", r); err != nil {
53+
log.Printf("Listening on %s\n", bind)
54+
if err := http.ListenAndServe(bind, r); err != nil {
3955
log.Fatal(err)
4056
}
4157
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ module github.com/speakeasy-api/speakeasy-api-test-service
22

33
go 1.19
44

5-
require github.com/gorilla/mux v1.8.0 // indirect
5+
require github.com/gorilla/mux v1.8.0

internal/eventstreams/service.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package eventstreams
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"time"
7+
)
8+
9+
func pushEvents(rw http.ResponseWriter, events [][]string) {
10+
for _, event := range events {
11+
for _, line := range event {
12+
fmt.Fprintln(rw, line)
13+
}
14+
fmt.Fprintln(rw, "")
15+
16+
if f, ok := rw.(http.Flusher); ok {
17+
f.Flush()
18+
}
19+
20+
time.Sleep(100 * time.Millisecond)
21+
}
22+
}
23+
24+
func HandleEventStreamJSON(rw http.ResponseWriter, _ *http.Request) {
25+
rw.Header().Add("Content-Type", "text/event-stream")
26+
27+
pushEvents(rw, [][]string{
28+
{
29+
`data: {"content": "Hello"}`,
30+
},
31+
32+
{
33+
`data: {"content": " "}`,
34+
},
35+
36+
{
37+
`data: {"content": "world"}`,
38+
},
39+
40+
{
41+
`data: {"content": "!"}`,
42+
},
43+
})
44+
}
45+
46+
func HandleEventStreamText(rw http.ResponseWriter, _ *http.Request) {
47+
rw.Header().Add("Content-Type", "text/event-stream")
48+
49+
pushEvents(rw, [][]string{
50+
{
51+
`data: Hello`,
52+
},
53+
54+
{
55+
`data: `,
56+
},
57+
58+
{
59+
`data: world`,
60+
},
61+
62+
{
63+
`data: !`,
64+
},
65+
})
66+
}
67+
68+
func HandleEventStreamMultiLine(rw http.ResponseWriter, _ *http.Request) {
69+
rw.Header().Add("Content-Type", "text/event-stream")
70+
71+
pushEvents(rw, [][]string{
72+
{
73+
`data: YHOO`,
74+
`data: +2`,
75+
`data: 10`,
76+
},
77+
})
78+
}
79+
80+
func HandleEventStreamRich(rw http.ResponseWriter, _ *http.Request) {
81+
rw.Header().Add("Content-Type", "text/event-stream")
82+
83+
pushEvents(rw, [][]string{
84+
{
85+
`id: job-1`,
86+
`event: completion`,
87+
`data: {"completion": "Hello", "stop_reason": null, "model": "jeeves-1"}`,
88+
},
89+
90+
{
91+
`event: heartbeat`,
92+
`data: ping`,
93+
`retry: 3000`,
94+
},
95+
96+
{
97+
`id: job-1`,
98+
`event: completion`,
99+
`data: {"completion": "world!", "stop_reason": "stop_sequence", "model": "jeeves-1"}`,
100+
},
101+
})
102+
}
103+
104+
func HandleEventStreamChat(rw http.ResponseWriter, _ *http.Request) {
105+
rw.Header().Add("Content-Type", "text/event-stream")
106+
107+
pushEvents(rw, [][]string{
108+
{
109+
`data: {"content": "Hello"}`,
110+
},
111+
112+
{
113+
`data: {"content": " "}`,
114+
},
115+
116+
{
117+
`data: {"content": "world"}`,
118+
},
119+
120+
{
121+
`data: {"content": "!"}`,
122+
},
123+
124+
{
125+
`data: [DONE]`,
126+
},
127+
})
128+
}

0 commit comments

Comments
 (0)