@@ -12,6 +12,7 @@ import (
12
12
"compress/gzip"
13
13
"compress/zlib"
14
14
"context"
15
+ crand "crypto/rand"
15
16
"crypto/tls"
16
17
"crypto/x509"
17
18
"encoding/json"
@@ -5281,8 +5282,8 @@ func benchmarkClientServerParallel(b *testing.B, parallelism int, mode testMode)
5281
5282
func BenchmarkServer (b * testing.B ) {
5282
5283
b .ReportAllocs ()
5283
5284
// Child process mode;
5284
- if url := os .Getenv ("TEST_BENCH_SERVER_URL " ); url != "" {
5285
- n , err := strconv .Atoi (os .Getenv ("TEST_BENCH_CLIENT_N " ))
5285
+ if url := os .Getenv ("GO_TEST_BENCH_SERVER_URL " ); url != "" {
5286
+ n , err := strconv .Atoi (os .Getenv ("GO_TEST_BENCH_CLIENT_N " ))
5286
5287
if err != nil {
5287
5288
panic (err )
5288
5289
}
@@ -5316,8 +5317,8 @@ func BenchmarkServer(b *testing.B) {
5316
5317
5317
5318
cmd := testenv .Command (b , os .Args [0 ], "-test.run=^$" , "-test.bench=^BenchmarkServer$" )
5318
5319
cmd .Env = append ([]string {
5319
- fmt .Sprintf ("TEST_BENCH_CLIENT_N =%d" , b .N ),
5320
- fmt .Sprintf ("TEST_BENCH_SERVER_URL =%s" , ts .URL ),
5320
+ fmt .Sprintf ("GO_TEST_BENCH_CLIENT_N =%d" , b .N ),
5321
+ fmt .Sprintf ("GO_TEST_BENCH_SERVER_URL =%s" , ts .URL ),
5321
5322
}, os .Environ ()... )
5322
5323
out , err := cmd .CombinedOutput ()
5323
5324
if err != nil {
@@ -5338,39 +5339,63 @@ func getNoBody(urlStr string) (*Response, error) {
5338
5339
// A benchmark for profiling the client without the HTTP server code.
5339
5340
// The server code runs in a subprocess.
5340
5341
func BenchmarkClient (b * testing.B ) {
5342
+ var data = []byte ("Hello world.\n " )
5343
+
5344
+ url := startClientBenchmarkServer (b , HandlerFunc (func (w ResponseWriter , _ * Request ) {
5345
+ w .Header ().Set ("Content-Type" , "text/html; charset=utf-8" )
5346
+ w .Write (data )
5347
+ }))
5348
+
5349
+ // Do b.N requests to the server.
5350
+ b .StartTimer ()
5351
+ for i := 0 ; i < b .N ; i ++ {
5352
+ res , err := Get (url )
5353
+ if err != nil {
5354
+ b .Fatalf ("Get: %v" , err )
5355
+ }
5356
+ body , err := io .ReadAll (res .Body )
5357
+ res .Body .Close ()
5358
+ if err != nil {
5359
+ b .Fatalf ("ReadAll: %v" , err )
5360
+ }
5361
+ if ! bytes .Equal (body , data ) {
5362
+ b .Fatalf ("Got body: %q" , body )
5363
+ }
5364
+ }
5365
+ b .StopTimer ()
5366
+ }
5367
+
5368
+ func startClientBenchmarkServer (b * testing.B , handler Handler ) string {
5341
5369
b .ReportAllocs ()
5342
5370
b .StopTimer ()
5343
- defer afterTest (b )
5344
5371
5345
- var data = []byte ("Hello world.\n " )
5346
- if server := os .Getenv ("TEST_BENCH_SERVER" ); server != "" {
5372
+ if server := os .Getenv ("GO_TEST_BENCH_SERVER" ); server != "" {
5347
5373
// Server process mode.
5348
- port := os .Getenv ("TEST_BENCH_SERVER_PORT " ) // can be set by user
5374
+ port := os .Getenv ("GO_TEST_BENCH_SERVER_PORT " ) // can be set by user
5349
5375
if port == "" {
5350
5376
port = "0"
5351
5377
}
5352
5378
ln , err := net .Listen ("tcp" , "localhost:" + port )
5353
5379
if err != nil {
5354
- fmt .Fprintln (os .Stderr , err .Error ())
5355
- os .Exit (1 )
5380
+ log .Fatal (err )
5356
5381
}
5357
5382
fmt .Println (ln .Addr ().String ())
5383
+
5358
5384
HandleFunc ("/" , func (w ResponseWriter , r * Request ) {
5359
5385
r .ParseForm ()
5360
5386
if r .Form .Get ("stop" ) != "" {
5361
5387
os .Exit (0 )
5362
5388
}
5363
- w .Header ().Set ("Content-Type" , "text/html; charset=utf-8" )
5364
- w .Write (data )
5389
+ handler .ServeHTTP (w , r )
5365
5390
})
5366
5391
var srv Server
5367
5392
log .Fatal (srv .Serve (ln ))
5368
5393
}
5369
5394
5370
5395
// Start server process.
5371
5396
ctx , cancel := context .WithCancel (context .Background ())
5372
- cmd := testenv .CommandContext (b , ctx , os .Args [0 ], "-test.run=^$" , "-test.bench=^BenchmarkClient $" )
5373
- cmd .Env = append (cmd .Environ (), "TEST_BENCH_SERVER =yes" )
5397
+ cmd := testenv .CommandContext (b , ctx , os .Args [0 ], "-test.run=^$" , "-test.bench=^" + b . Name () + " $" )
5398
+ cmd .Env = append (cmd .Environ (), "GO_TEST_BENCH_SERVER =yes" )
5374
5399
cmd .Stderr = os .Stderr
5375
5400
stdout , err := cmd .StdoutPipe ()
5376
5401
if err != nil {
@@ -5385,10 +5410,6 @@ func BenchmarkClient(b *testing.B) {
5385
5410
done <- cmd .Wait ()
5386
5411
close (done )
5387
5412
}()
5388
- defer func () {
5389
- cancel ()
5390
- <- done
5391
- }()
5392
5413
5393
5414
// Wait for the server in the child process to respond and tell us
5394
5415
// its listening address, once it's started listening:
@@ -5401,29 +5422,56 @@ func BenchmarkClient(b *testing.B) {
5401
5422
b .Fatalf ("initial probe of child process failed: %v" , err )
5402
5423
}
5403
5424
5425
+ // Instruct server process to stop.
5426
+ b .Cleanup (func () {
5427
+ getNoBody (url + "?stop=yes" )
5428
+ if err := <- done ; err != nil {
5429
+ b .Fatalf ("subprocess failed: %v" , err )
5430
+ }
5431
+
5432
+ cancel ()
5433
+ <- done
5434
+
5435
+ afterTest (b )
5436
+ })
5437
+
5438
+ return url
5439
+ }
5440
+
5441
+ func BenchmarkClientGzip (b * testing.B ) {
5442
+ const responseSize = 1024 * 1024
5443
+
5444
+ var buf bytes.Buffer
5445
+ gz := gzip .NewWriter (& buf )
5446
+ if _ , err := io .CopyN (gz , crand .Reader , responseSize ); err != nil {
5447
+ b .Fatal (err )
5448
+ }
5449
+ gz .Close ()
5450
+
5451
+ data := buf .Bytes ()
5452
+
5453
+ url := startClientBenchmarkServer (b , HandlerFunc (func (w ResponseWriter , _ * Request ) {
5454
+ w .Header ().Set ("Content-Encoding" , "gzip" )
5455
+ w .Write (data )
5456
+ }))
5457
+
5404
5458
// Do b.N requests to the server.
5405
5459
b .StartTimer ()
5406
5460
for i := 0 ; i < b .N ; i ++ {
5407
5461
res , err := Get (url )
5408
5462
if err != nil {
5409
5463
b .Fatalf ("Get: %v" , err )
5410
5464
}
5411
- body , err := io .ReadAll ( res .Body )
5465
+ n , err := io .Copy ( io . Discard , res .Body )
5412
5466
res .Body .Close ()
5413
5467
if err != nil {
5414
5468
b .Fatalf ("ReadAll: %v" , err )
5415
5469
}
5416
- if ! bytes . Equal ( body , data ) {
5417
- b .Fatalf ("Got body: %q " , body )
5470
+ if n != responseSize {
5471
+ b .Fatalf ("ReadAll: expected %d bytes, got %d " , responseSize , n )
5418
5472
}
5419
5473
}
5420
5474
b .StopTimer ()
5421
-
5422
- // Instruct server process to stop.
5423
- getNoBody (url + "?stop=yes" )
5424
- if err := <- done ; err != nil {
5425
- b .Fatalf ("subprocess failed: %v" , err )
5426
- }
5427
5475
}
5428
5476
5429
5477
func BenchmarkServerFakeConnNoKeepAlive (b * testing.B ) {
0 commit comments