Stream live server logs over SSE
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -35,6 +38,32 @@ func TestLogIngestAPIWorkflow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogEventsSSEReplaysHistory(t *testing.T) {
|
||||
router := newTestRouter()
|
||||
hello := createLogIngestAPIFixtures(t, router)
|
||||
batch := validLogBatchRequest(t, hello.SessionToken, 1, 2)
|
||||
assertStatus(t, performJSON(t, router, http.MethodPost, "/api/v1/run/logs/batches", batch), http.StatusOK)
|
||||
|
||||
server := httptest.NewServer(router)
|
||||
defer server.Close()
|
||||
client := server.Client()
|
||||
client.Timeout = 2 * time.Second
|
||||
response, err := client.Get(server.URL + "/api/v1/server-instances/server-1/logs/events?historyLimit=2")
|
||||
if err != nil {
|
||||
t.Fatalf("open log event stream: %v", err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode != http.StatusOK || !strings.HasPrefix(response.Header.Get("Content-Type"), "text/event-stream") {
|
||||
t.Fatalf("unexpected event stream response: status=%d content-type=%q", response.StatusCode, response.Header.Get("Content-Type"))
|
||||
}
|
||||
body := readSSEUntil(t, response, "event: ready")
|
||||
for _, fragment := range []string{"event: stream", "event: log", `"streamId":"log-1"`, `"seq":1`, `"seq":2`} {
|
||||
if !strings.Contains(body, fragment) {
|
||||
t.Fatalf("expected SSE body to contain %q, got:\n%s", fragment, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogIngestAPIDuplicateAndErrors(t *testing.T) {
|
||||
router := newTestRouter()
|
||||
hello := createLogIngestAPIFixtures(t, router)
|
||||
@@ -77,6 +106,20 @@ func createLogIngestAPIFixtures(t *testing.T, router http.Handler) dto.RunContro
|
||||
return hello
|
||||
}
|
||||
|
||||
func readSSEUntil(t *testing.T, response *http.Response, marker string) string {
|
||||
t.Helper()
|
||||
reader := bufio.NewReader(response.Body)
|
||||
var body strings.Builder
|
||||
for !strings.Contains(body.String(), marker) {
|
||||
line, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Fatalf("read event stream: %v\n%s", err, body.String())
|
||||
}
|
||||
body.WriteString(line)
|
||||
}
|
||||
return body.String()
|
||||
}
|
||||
|
||||
func validLogBatchRequest(t *testing.T, sessionToken string, firstSeq uint64, lastSeq uint64) dto.LogBatchIngestRequest {
|
||||
t.Helper()
|
||||
entries := make([]dto.LogEntryBody, 0, lastSeq-firstSeq+1)
|
||||
|
||||
Reference in New Issue
Block a user