Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions cmd/odek/audit_serve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ func TestAudit_WebSocketInvalidModelRejectedEarly(t *testing.T) {
t.Fatalf("session.NewStore: %v", err)
}
ln, mux := buildServeMux(t, store)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down
12 changes: 4 additions & 8 deletions cmd/odek/next_security_vulnerabilities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,8 @@ func TestServe_CSRF_AllowsLocalhostOrigin(t *testing.T) {
func TestServe_API_RequiresServeToken(t *testing.T) {
store := newTestSessionStore(t)
ln, mux := buildServeMux(t, store)
defer ln.Close()

go serveOnListener(ln, mux)
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

resp, err := http.Get("http://" + ln.Addr().String() + "/api/sessions")
Expand All @@ -260,13 +259,12 @@ func TestServe_API_RequiresServeToken(t *testing.T) {
func TestServe_API_RequiresLocalHost(t *testing.T) {
store := newTestSessionStore(t)
ln, mux := buildServeMux(t, store)
defer ln.Close()

testTokenMu.Lock()
token := testLastToken
testTokenMu.Unlock()

go serveOnListener(ln, mux)
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

req, _ := http.NewRequest(http.MethodGet, "http://"+ln.Addr().String()+"/api/sessions", nil)
Expand All @@ -285,13 +283,12 @@ func TestServe_API_RequiresLocalHost(t *testing.T) {
func TestServe_API_AcceptsServeTokenHeader(t *testing.T) {
store := newTestSessionStore(t)
ln, mux := buildServeMux(t, store)
defer ln.Close()

testTokenMu.Lock()
token := testLastToken
testTokenMu.Unlock()

go serveOnListener(ln, mux)
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

req, _ := http.NewRequest(http.MethodGet, "http://"+ln.Addr().String()+"/api/sessions", nil)
Expand All @@ -309,13 +306,12 @@ func TestServe_API_AcceptsServeTokenHeader(t *testing.T) {
func TestServe_API_AcceptsServeTokenCookie(t *testing.T) {
store := newTestSessionStore(t)
ln, mux := buildServeMux(t, store)
defer ln.Close()

testTokenMu.Lock()
token := testLastToken
testTokenMu.Unlock()

go serveOnListener(ln, mux)
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

req, _ := http.NewRequest(http.MethodGet, "http://"+ln.Addr().String()+"/api/sessions", nil)
Expand Down
6 changes: 2 additions & 4 deletions cmd/odek/serve_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -885,9 +885,8 @@ func TestServe_E2E_NoRepetitiveResponses(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMux(t, store)
defer ln.Close()

go serveOnListener(ln, mux)
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

conn := dialTestWS(t, ln.Addr().String())
Expand Down Expand Up @@ -964,9 +963,8 @@ func TestServe_E2E_SessionMessagesStoredWithoutSystemInjections(t *testing.T) {

// Build a mux that also includes the session-by-ID route so we can inspect it.
ln, mux := buildServeMuxWithSessionByID(t, store)
defer ln.Close()

go serveOnListener(ln, mux)
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

conn := dialTestWS(t, ln.Addr().String())
Expand Down
18 changes: 6 additions & 12 deletions cmd/odek/serve_api_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,7 @@ func TestServe_E2E_ServerInfoHelloAndPingPong(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxV2(t, store, nil)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -613,8 +612,7 @@ func TestServe_E2E_ServerKeepalive(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxV2(t, store, nil)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -644,8 +642,7 @@ func TestServe_E2E_SessionSwitchMessage(t *testing.T) {
}

ln, mux := buildServeMuxV2(t, store, nil)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -684,8 +681,7 @@ func TestServe_E2E_WSCancelMessage(t *testing.T) {
}

ln, mux := buildServeMuxV2(t, store, nil)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -729,8 +725,7 @@ func TestServe_E2E_StreamDeltas(t *testing.T) {
ln, mux := buildServeMuxV2(t, store, func(rc *config.ResolvedConfig) {
rc.Stream = true
})
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -796,8 +791,7 @@ func TestServe_E2E_StreamFallbackKeepsBulkPath(t *testing.T) {
ln, mux := buildServeMuxV2(t, store, func(rc *config.ResolvedConfig) {
rc.Stream = true
})
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down
3 changes: 1 addition & 2 deletions cmd/odek/serve_approval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,8 @@ func TestServe_E2E_ApprovalRoundTrip(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxPromptAll(t, store)
defer ln.Close()

go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

conn := dialTestWS(t, ln.Addr().String())
Expand Down
4 changes: 1 addition & 3 deletions cmd/odek/serve_buffer_bleed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ func TestServe_E2E_PromptPathSessionSwitch_ClearsStaleBuffer(t *testing.T) {
}

ln, mux := buildServeMux(t, store)
defer ln.Close()
errCh := make(chan error, 1)
go func() { errCh <- serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down
15 changes: 5 additions & 10 deletions cmd/odek/serve_cancel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ func TestServe_E2E_WSCancelInterruptsApprovalWait(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxPromptAll(t, store)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -199,8 +198,7 @@ func TestServe_E2E_RESTCancelInterruptsApprovalWait(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxPromptAll(t, store)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -335,8 +333,7 @@ func TestServe_E2E_WSCancelRunningPromptTerminalEvent(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxV2(t, store, nil)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -384,8 +381,7 @@ func TestServe_E2E_ApprovalWorksAfterCancel(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxPromptAll(t, store)
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down Expand Up @@ -491,9 +487,8 @@ func TestServe_E2E_CancelDuringSetupWindowHonored(t *testing.T) {
gate := &gatingResolver{entered: make(chan struct{}, 1), release: make(chan struct{})}
resReg := resource.NewRegistry(gate)
ln, mux := buildServeMuxWithResolvers(t, store, resReg)
defer ln.Close()
defer startServeTest(t, ln, mux)()
defer close(gate.release)
go func() { _ = serveOnListener(ln, mux) }()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down
31 changes: 31 additions & 0 deletions cmd/odek/serve_lifecycle_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"errors"
"net"
"net/http"
"testing"
"time"
)

// startServeTest starts the real server and returns a stop function that waits
// for its handlers and session writes to finish. Defer the returned function
// before opening clients, so shutdown precedes environment and temp-dir cleanup.
func startServeTest(t *testing.T, ln net.Listener, mux *http.ServeMux) func() {
t.Helper()
done := make(chan error, 1)
go func() { done <- serveOnListener(ln, mux) }()
return func() {
t.Helper()
http.DefaultClient.CloseIdleConnections()
_ = ln.Close()
select {
case err := <-done:
if err != nil && !errors.Is(err, net.ErrClosed) {
t.Errorf("serve shutdown: %v", err)
}
case <-time.After(20 * time.Second):
t.Fatal("serve shutdown did not finish before test cleanup")
}
}
}
3 changes: 1 addition & 2 deletions cmd/odek/serve_surface_fixes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,7 @@ func TestServe_E2E_PingPongUsesConfigSnapshotNotLiveModel(t *testing.T) {

store := newTestSessionStore(t)
ln, mux := buildServeMuxV2(t, store, func(rc *config.ResolvedConfig) { rc.Model = "initial-model" })
defer ln.Close()
go func() { _ = serveOnListener(ln, mux) }()
defer startServeTest(t, ln, mux)()
waitForHTTP(t, ln.Addr().String())

wsUpgradeLimiter.reset()
Expand Down
Loading
Loading