| 1 | package fleetapi |
| 2 | |
| 3 | // White-box (package fleetapi, not fleetapi_test): pins the transport |
| 4 | // construction New() does, which no exported surface exposes — C2's fix |
| 5 | // shape (a Transport with dial/TLS/response-header timeouts and no |
| 6 | // Client.Timeout) is otherwise invisible to a caller until an actual slow |
| 7 | // transfer either survives or doesn't. |
| 8 | |
| 9 | import ( |
| 10 | "net/http" |
| 11 | "testing" |
| 12 | ) |
| 13 | |
| 14 | func TestClientHasNoWholeExchangeTimeoutButBoundsResponseHeaders(t *testing.T) { |
| 15 | s, err := New("https://tunnel.example.com", "pi/box-a", "tok") |
| 16 | if err != nil { |
| 17 | t.Fatalf("New: %v", err) |
| 18 | } |
| 19 | st, ok := s.(*store) |
| 20 | if !ok { |
| 21 | t.Fatalf("New returned %T, want *store", s) |
| 22 | } |
| 23 | if st.client.Timeout != 0 { |
| 24 | t.Errorf("client.Timeout = %v, want 0 (a whole-exchange deadline would fail slow-but-progressing artifact downloads)", st.client.Timeout) |
| 25 | } |
| 26 | tr, ok := st.client.Transport.(*http.Transport) |
| 27 | if !ok { |
| 28 | t.Fatalf("client.Transport = %T, want *http.Transport", st.client.Transport) |
| 29 | } |
| 30 | if tr.ResponseHeaderTimeout != callTimeout { |
| 31 | t.Errorf("ResponseHeaderTimeout = %v, want %v (a wedged edge must still fail fast)", tr.ResponseHeaderTimeout, callTimeout) |
| 32 | } |
| 33 | if tr.TLSHandshakeTimeout != callTimeout { |
| 34 | t.Errorf("TLSHandshakeTimeout = %v, want %v", tr.TLSHandshakeTimeout, callTimeout) |
| 35 | } |
| 36 | if tr.DialContext == nil { |
| 37 | t.Error("DialContext = nil, want a dialer with a connect timeout set") |
| 38 | } |
| 39 | } |
| 40 | |