Report only the latest deployment probe request outcome

This commit is contained in:
2026-10-09 11:58:20 +08:00
parent 1b4f8be2bd
commit d5fe1fa88d
2 changed files with 50 additions and 0 deletions
+3
View File
@@ -53,6 +53,9 @@ type report struct {
type transport struct{ report *report }
func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
// These fields describe this request, not the last successful endpoint.
t.report.HTTPStatus = 0
t.report.TransportFailure = ""
response, err := http.DefaultTransport.RoundTrip(req)
if response != nil {
t.report.HTTPStatus = response.StatusCode
+47
View File
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"net"
"net/http"
"strings"
"syscall"
"testing"
@@ -39,6 +40,52 @@ func TestTransportFailureDistinguishesCertificateAndAvailability(t *testing.T) {
}
}
type probeRoundTripFunc func(*http.Request) (*http.Response, error)
func (f probeRoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return f(req)
}
func TestTransportReportTracksOnlyLatestRequest(t *testing.T) {
original := http.DefaultTransport
t.Cleanup(func() { http.DefaultTransport = original })
for _, tc := range []struct {
name string
response *http.Response
err error
status int
failure string
}{
{name: "success clears earlier failure", response: &http.Response{StatusCode: 200}, status: 200},
{name: "HTTP failure clears earlier transport failure", response: &http.Response{StatusCode: 503}, status: 503},
{name: "connection refusal clears earlier HTTP success", err: &net.OpError{Op: "dial", Err: syscall.ECONNREFUSED}, failure: "unavailable"},
{name: "timeout clears earlier HTTP success", err: &net.DNSError{IsTimeout: true}, failure: "unavailable"},
{name: "certificate failure is not availability", err: x509.UnknownAuthorityError{}, failure: "tls_failed"},
{name: "unknown failure remains fatal", err: errors.New("synthetic-sensitive-error"), failure: "transport_failed"},
} {
t.Run(tc.name, func(t *testing.T) {
http.DefaultTransport = probeRoundTripFunc(func(*http.Request) (*http.Response, error) {
return tc.response, tc.err
})
r := report{Phase: "tasks", HTTPStatus: 200, TransportFailure: "tls_failed", Trunks: 3, Providers: 1}
req, err := http.NewRequest(http.MethodGet, "http://diagnostic.invalid/tasks", nil)
if err != nil {
t.Fatal(err)
}
response, err := (transport{&r}).RoundTrip(req)
if response != tc.response || err != tc.err {
t.Fatal("diagnostic changed the actual transport outcome")
}
if r.HTTPStatus != tc.status || r.TransportFailure != tc.failure {
t.Fatalf("status=%d failure=%q, want status=%d failure=%q", r.HTTPStatus, r.TransportFailure, tc.status, tc.failure)
}
if r.Phase != "tasks" || r.Trunks != 3 || r.Providers != 1 {
t.Fatal("diagnostic discarded earlier independent verification facts")
}
})
}
}
func TestDiagnosticNeverSerializesErrorContents(t *testing.T) {
r := report{Phase: "sip"}
rejected(&r, errors.New("synthetic-sensitive-value"))