okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
a229862
main
1// Shutdown recovery must be checked through the Service caller: shared-daemon 2// E2E cannot safely refuse shutdown while advertising replacement credentials. 3package app 4 5import ( 6"context" 7"errors" 8"net" 9"net/http" 10"net/http/httptest" 11"strconv" 12"sync/atomic" 13"testing" 14 15"albedo/cli/internal/daemon" 16) 17 18func TestStopDaemonDoesNotRecoverAuthenticationRefusal (t * testing.T ) { 19var shutdowns ,healthProbes atomic.Int32 20server := httptest .NewServer (http .HandlerFunc (func (writer http.ResponseWriter ,request * http.Request ) { 21switch request .URL .Path { 22case "/server/shutdown" : 23shutdowns .Add (1 ) 24if request .Method != http .MethodPost || request .Header .Get ("Authorization" )!= "Bearer old" { 25t .Errorf ("unexpected shutdown attempt: %s %q" ,request .Method ,request .Header .Get ("Authorization" )) 26 } 27writer .WriteHeader (http .StatusForbidden ) 28_ ,_ = writer .Write ([]byte (`{"code":"authentication_required","detail":"invalid bearer"}` )) 29case "/server" : 30healthProbes .Add (1 ) 31_ ,_ = writer .Write ([]byte (`{"instance_id":"replacement","protocol":3,"state":"ready","capabilities":{"durable_inputs":1,"session_replay":2,"collection_invalidation":1,"tool_progress":1},"build":null,"digest":null,"extensions":[],"quota":[],"notices":[]}` )) 32default : 33t .Errorf ("unexpected request %s" ,request .URL .Path ) 34writer .WriteHeader (http .StatusNotFound ) 35 } 36 })) 37defer server .Close () 38_ ,portText ,err := net .SplitHostPort (server .Listener .Addr ().String ()) 39if err != nil { 40t .Fatal (err ) 41 } 42port ,err := strconv .Atoi (portText ) 43if err != nil { 44t .Fatal (err ) 45 } 46replacement := daemon.ConnectionSnapshot {Port :port ,Token :"new" ,Version :daemon .ProtocolVersion ,InstanceID :"instance-a" } 47original := replacement 48original .Token = "old" 49conn := daemon .NewConnection (original ,func (context.Context ) (daemon.ConnectionSnapshot ,error ) { 50t .Error ("shutdown must not rediscover a replacement" ) 51return replacement ,nil 52 }) 53t .Cleanup (conn .HTTPClient ().CloseIdleConnections ) 54service := Service {Existing :func (context.Context ) (* daemon.Connection ,error ) {return conn ,nil }} 55err = service .StopDaemon (context .Background ()) 56apiError ,ok := errors.AsType [* daemon.APIError ](err ) 57if ! ok || apiError .StatusCode != http .StatusForbidden { 58t .Fatalf ("want original authentication rejection, got %v" ,err ) 59 } 60if shutdowns .Load ()!= 1 || healthProbes .Load ()!= 0 { 61t .Fatalf ("shutdown was recovered: attempts=%d health probes=%d" ,shutdowns .Load (),healthProbes .Load ()) 62 } 63}