okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
61c43ca
main
1// Error decoding must preserve status and structured causes even for malformed 2// responses, which the real daemon E2E suite does not produce. 3package daemon 4 5import ( 6"context" 7"errors" 8"fmt" 9"io" 10"net" 11"net/http" 12"net/http/httptest" 13"strings" 14"testing" 15) 16 17func TestHTTPFailuresRetainIdentity (t * testing.T ) { 18for _ ,tc := range []struct { 19name ,body ,code string 20status int 21 }{ 22 {"workspace" ,`{"type":"about:blank","title":"Workspace unavailable","status":503,"code":"workspace_unavailable","detail":"wording can change"}` ,"workspace_unavailable" ,503 }, 23 {"forbidden" ,`{"type":"about:blank","title":"Forbidden","status":403,"code":"forbidden","detail":"access denied"}` ,"forbidden" ,403 }, 24 {"unauthorized" ,`{"type":"about:blank","title":"Unauthorized","status":401,"code":"unauthorized","detail":"sign in again"}` ,"unauthorized" ,401 }, 25 {"code only" ,`{"code":"busy"}` ,"busy" ,503 }, 26 {"malformed" ,`<html>bad gateway</html>` ,"" ,502 }, 27 } { 28t .Run (tc .name ,func (t * testing.T ) { 29server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter ,r * http.Request ) { 30w .WriteHeader (tc .status ) 31_ ,_ = io .WriteString (w ,tc .body ) 32 })) 33defer server .Close () 34// This fixed peer has no discovery directory; authentication errors stay local. 35conn := NewConnection (ConnectionSnapshot {Port :server .Listener .Addr ().(* net.TCPAddr ).Port },nil ) 36_ ,requestErr := requestBytes (context .Background (),conn ,operation {Name :"read failure" ,Method :http .MethodGet ,Path :"/failure" ,Policy :readRecovery },responseLimits {bodyBytes :50 * 1024 * 1024 ,errorBytes :64 * 1024 }) 37client := NewChatClient (conn ,"session" ) 38_ ,chatErr := client .GetStatus (context .Background ()) 39for _ ,err := range []error {requestErr ,chatErr } { 40err = fmt .Errorf ("request context: %w" ,err ) 41var apiErr * APIError 42if ! errors .As (err ,& apiErr )|| apiErr .StatusCode != tc .status || apiErr .Code != tc .code { 43t .Fatalf ("lost HTTP failure identity: %v" ,err ) 44 } 45if strings .Contains (err .Error (),"<html>" ) { 46t .Fatalf ("exposed unstructured response body: %v" ,err ) 47 } 48 } 49 }) 50 } 51}