@@ -1929,6 +1929,11 @@ func TestDelay(t *testing.T) {
1929
1929
if elapsed < test .expectedDelay {
1930
1930
t .Fatalf ("expected delay of %s, got %s" , test .expectedDelay , elapsed )
1931
1931
}
1932
+
1933
+ timings := decodeServerTimings (resp .Header .Get ("Server-Timing" ))
1934
+ assert .DeepEqual (t , timings , map [string ]serverTiming {
1935
+ "initial_delay" : {"initial_delay" , test .expectedDelay , "initial delay" },
1936
+ }, "incorrect Server-Timing header value" )
1932
1937
})
1933
1938
}
1934
1939
@@ -2224,6 +2229,38 @@ func TestDrip(t *testing.T) {
2224
2229
assert .StatusCode (t , resp , http .StatusOK )
2225
2230
assert .BodySize (t , resp , 0 )
2226
2231
})
2232
+
2233
+ t .Run ("Server-Timings header" , func (t * testing.T ) {
2234
+ t .Parallel ()
2235
+
2236
+ var (
2237
+ duration = 100 * time .Millisecond
2238
+ delay = 50 * time .Millisecond
2239
+ numBytes = 10
2240
+ )
2241
+
2242
+ url := fmt .Sprintf ("/drip?duration=%s&delay=%s&numbytes=%d" , duration , delay , numBytes )
2243
+ req := newTestRequest (t , "GET" , url )
2244
+ resp := must .DoReq (t , client , req )
2245
+ defer consumeAndCloseBody (resp )
2246
+
2247
+ assert .StatusCode (t , resp , http .StatusOK )
2248
+
2249
+ timings := decodeServerTimings (resp .Header .Get ("Server-Timing" ))
2250
+
2251
+ // compute expected pause between writes to match server logic and
2252
+ // handle lossy floating point truncation in the serialized header
2253
+ // value
2254
+ computedPause := duration / time .Duration (numBytes - 1 )
2255
+ wantPause , _ := time .ParseDuration (fmt .Sprintf ("%.2fms" , computedPause .Seconds ()* 1e3 ))
2256
+
2257
+ assert .DeepEqual (t , timings , map [string ]serverTiming {
2258
+ "total_duration" : {"total_duration" , delay + duration , "total request duration" },
2259
+ "initial_delay" : {"initial_delay" , delay , "initial delay" },
2260
+ "pause_per_write" : {"pause_per_write" , wantPause , "computed pause between writes" },
2261
+ "write_duration" : {"write_duration" , duration , "duration of writes after initial delay" },
2262
+ }, "incorrect Server-Timing header value" )
2263
+ })
2227
2264
}
2228
2265
2229
2266
func TestRange (t * testing.T ) {
@@ -3299,6 +3336,53 @@ func TestSSE(t *testing.T) {
3299
3336
assert .StatusCode (t , resp , http .StatusOK )
3300
3337
assert .BodySize (t , resp , 0 )
3301
3338
})
3339
+
3340
+ t .Run ("Server-Timings trailers" , func (t * testing.T ) {
3341
+ t .Parallel ()
3342
+
3343
+ var (
3344
+ duration = 250 * time .Millisecond
3345
+ delay = 100 * time .Millisecond
3346
+ count = 10
3347
+ params = url.Values {
3348
+ "duration" : {duration .String ()},
3349
+ "delay" : {delay .String ()},
3350
+ "count" : {strconv .Itoa (count )},
3351
+ }
3352
+ )
3353
+
3354
+ req := newTestRequest (t , "GET" , "/sse?" + params .Encode ())
3355
+ resp := must .DoReq (t , client , req )
3356
+
3357
+ // need to fully consume body for Server-Timing trailers to arrive
3358
+ must .ReadAll (t , resp .Body )
3359
+
3360
+ rawTimings := resp .Trailer .Get ("Server-Timing" )
3361
+ t .Logf ("raw Server-Timing header value: %q" , rawTimings )
3362
+
3363
+ timings := decodeServerTimings (rawTimings )
3364
+
3365
+ // Ensure total server time makes sense based on duration and delay
3366
+ total := timings ["total_duration" ]
3367
+ assert .DurationRange (t , total .dur , duration + delay , duration + delay + 25 * time .Millisecond )
3368
+
3369
+ // Ensure computed pause time makes sense based on duration, delay, and
3370
+ // numbytes (should be exact, but we're re-parsing a truncated float in
3371
+ // the header value)
3372
+ pause := timings ["pause_per_write" ]
3373
+ assert .RoughlyEqual (t , pause .dur , duration / time .Duration (count - 1 ), 1 * time .Millisecond )
3374
+
3375
+ // remaining timings should exactly match request parameters, no need
3376
+ // to adjust for per-run variations
3377
+ wantTimings := map [string ]serverTiming {
3378
+ "write_duration" : {"write_duration" , duration , "duration of writes after initial delay" },
3379
+ "initial_delay" : {"initial_delay" , delay , "initial delay" },
3380
+ }
3381
+ for k , want := range wantTimings {
3382
+ got := timings [k ]
3383
+ assert .DeepEqual (t , got , want , "incorrect timing for key %q" , k )
3384
+ }
3385
+ })
3302
3386
}
3303
3387
3304
3388
func TestWebSocketEcho (t * testing.T ) {
0 commit comments