github.com/cloudwego/kitex@v0.9.0/pkg/remote/trans/nphttp2/grpc/keepalive_test.go (about) 1 /* 2 * 3 * Copyright 2019 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * This file may have been modified by CloudWeGo authors. All CloudWeGo 18 * Modifications are Copyright 2021 CloudWeGo Authors. 19 */ 20 21 // This file contains tests related to the following proposals: 22 // https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md 23 // https://github.com/grpc/proposal/blob/master/A9-server-side-conn-mgt.md 24 // https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md 25 package grpc 26 27 import ( 28 "context" 29 "io" 30 "net" 31 "testing" 32 "time" 33 34 "golang.org/x/net/http2" 35 ) 36 37 const defaultTestTimeout = 10 * time.Second 38 39 // TestMaxConnectionIdle tests that a server will send GoAway to an idle 40 // client. An idle client is one who doesn't make any RPC calls for a duration 41 // of MaxConnectionIdle time. 42 func TestMaxConnectionIdle(t *testing.T) { 43 serverConfig := &ServerConfig{ 44 KeepaliveParams: ServerKeepalive{ 45 MaxConnectionIdle: 500 * time.Millisecond, 46 }, 47 } 48 server, client := setUpWithOptions(t, 0, serverConfig, suspended, ConnectOptions{}) 49 defer func() { 50 client.Close() 51 server.stop() 52 }() 53 54 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 55 defer cancel() 56 stream, err := client.NewStream(ctx, &CallHdr{}) 57 if err != nil { 58 t.Fatalf("client.NewStream() failed: %v", err) 59 } 60 client.CloseStream(stream, io.EOF) 61 62 // Wait for the server's MaxConnectionIdle timeout to kick in, and for it 63 // to send a GoAway. 64 timeout := time.NewTimer(time.Second * 1) 65 select { 66 case <-client.Error(): 67 if !timeout.Stop() { 68 <-timeout.C 69 } 70 if reason := client.GetGoAwayReason(); reason != GoAwayNoReason { 71 t.Fatalf("GoAwayReason is %v, want %v", reason, GoAwayNoReason) 72 } 73 case <-timeout.C: 74 t.Fatalf("MaxConnectionIdle timeout expired, expected a GoAway from the server.") 75 } 76 } 77 78 // TestMaxConenctionIdleBusyClient tests that a server will not send GoAway to 79 // a busy client. 80 func TestMaxConnectionIdleBusyClient(t *testing.T) { 81 serverConfig := &ServerConfig{ 82 KeepaliveParams: ServerKeepalive{ 83 MaxConnectionIdle: 500 * time.Millisecond, 84 }, 85 } 86 server, client := setUpWithOptions(t, 0, serverConfig, suspended, ConnectOptions{}) 87 defer func() { 88 client.Close() 89 server.stop() 90 }() 91 92 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 93 defer cancel() 94 _, err := client.NewStream(ctx, &CallHdr{}) 95 if err != nil { 96 t.Fatalf("client.NewStream() failed: %v", err) 97 } 98 99 // Wait for double the MaxConnectionIdle time to make sure the server does 100 // not send a GoAway, as the client has an open stream. 101 timeout := time.NewTimer(time.Second * 1) 102 select { 103 case <-client.GoAway(): 104 if !timeout.Stop() { 105 <-timeout.C 106 } 107 t.Fatalf("A non-idle client received a GoAway.") 108 case <-timeout.C: 109 } 110 } 111 112 // FIXME Test failed because DATA RACE. 113 // TestMaxConnectionAge tests that a server will send GoAway after a duration 114 // of MaxConnectionAge. 115 //func TestMaxConnectionAge(t *testing.T) { 116 // serverConfig := &ServerConfig{ 117 // KeepaliveParams: ServerKeepalive{ 118 // MaxConnectionAge: 1 * time.Second, 119 // MaxConnectionAgeGrace: 1 * time.Second, 120 // }, 121 // } 122 // server, client := setUpWithOptions(t, 0, serverConfig, suspended, ConnectOptions{}) 123 // defer func() { 124 // client.Close() 125 // server.stop() 126 // }() 127 // 128 // ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 129 // defer cancel() 130 // _, err := client.NewStream(ctx, &CallHdr{}) 131 // if err != nil { 132 // t.Fatalf("client.NewStream() failed: %v", err) 133 // } 134 // 135 // // Wait for the server's MaxConnectionAge timeout to kick in, and for it 136 // // to send a GoAway. 137 // timeout := time.NewTimer(4 * time.Second) 138 // select { 139 // case <-client.Error(): 140 // if !timeout.Stop() { 141 // <-timeout.C 142 // } 143 // if reason := client.GetGoAwayReason(); reason != GoAwayNoReason { 144 // t.Fatalf("GoAwayReason is %v, want %v", reason, GoAwayNoReason) 145 // } 146 // case <-timeout.C: 147 // t.Fatalf("MaxConnectionAge timeout expired, expected a GoAway from the server.") 148 // } 149 //} 150 151 // TestKeepaliveServerClosesUnresponsiveClient tests that a server closes 152 // the connection with a client that doesn't respond to keepalive pings. 153 // 154 // This test creates a regular net.Conn connection to the server and sends the 155 // clientPreface and the initial Settings frame, and then remains unresponsive. 156 func TestKeepaliveServerClosesUnresponsiveClient(t *testing.T) { 157 serverConfig := &ServerConfig{ 158 KeepaliveParams: ServerKeepalive{ 159 Time: 250 * time.Millisecond, 160 Timeout: 250 * time.Millisecond, 161 }, 162 } 163 server, client := setUpWithOptions(t, 0, serverConfig, suspended, ConnectOptions{}) 164 defer func() { 165 client.Close() 166 server.stop() 167 }() 168 169 addr := server.addr() 170 conn, err := net.DialTimeout("tcp", addr, time.Second) 171 if err != nil { 172 t.Fatalf("net.Dial(tcp, %v) failed: %v", addr, err) 173 } 174 defer conn.Close() 175 176 if n, err := conn.Write(ClientPreface); err != nil || n != len(ClientPreface) { 177 t.Fatalf("conn.write(clientPreface) failed: n=%v, err=%v", n, err) 178 } 179 framer := newFramer(conn, 0, 0, 0) 180 if err := framer.WriteSettings(http2.Setting{}); err != nil { 181 t.Fatal("framer.WriteSettings(http2.Setting{}) failed:", err) 182 } 183 framer.writer.Flush() 184 185 // We read from the net.Conn till we get an error, which is expected when 186 // the server closes the connection as part of the keepalive logic. 187 errCh := make(chan error) 188 go func() { 189 b := make([]byte, 24) 190 for { 191 if _, err = conn.Read(b); err != nil { 192 errCh <- err 193 return 194 } 195 } 196 }() 197 198 // Server waits for KeepaliveParams.Time seconds before sending out a ping, 199 // and then waits for KeepaliveParams.Timeout for a ping ack. 200 timeout := time.NewTimer(1 * time.Second) 201 select { 202 case err := <-errCh: 203 if err != io.EOF { 204 t.Fatalf("client.Read(_) = _,%v, want io.EOF", err) 205 } 206 case <-timeout.C: 207 t.Fatalf("keepalive timeout expired, server should have closed the connection.") 208 } 209 } 210 211 // TestKeepaliveServerWithResponsiveClient tests that a server doesn't close 212 // the connection with a client that responds to keepalive pings. 213 func TestKeepaliveServerWithResponsiveClient(t *testing.T) { 214 serverConfig := &ServerConfig{ 215 KeepaliveParams: ServerKeepalive{ 216 Time: 500 * time.Millisecond, 217 Timeout: 500 * time.Millisecond, 218 }, 219 } 220 server, client := setUpWithOptions(t, 0, serverConfig, suspended, ConnectOptions{ 221 // FIXME the original ut don't contain KeepaliveParams 222 KeepaliveParams: ClientKeepalive{ 223 Time: 500 * time.Millisecond, 224 Timeout: 500 * time.Millisecond, 225 PermitWithoutStream: true, 226 }, 227 }) 228 defer func() { 229 client.Close() 230 server.stop() 231 }() 232 233 // Give keepalive logic some time by sleeping. 234 time.Sleep(1 * time.Second) 235 236 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 237 defer cancel() 238 // Make sure the client transport is healthy. 239 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 240 t.Fatalf("client.NewStream() failed: %v", err) 241 } 242 } 243 244 // TestKeepaliveClientClosesUnresponsiveServer creates a server which does not 245 // respond to keepalive pings, and makes sure that the client closes the 246 // transport once the keepalive logic kicks in. Here, we set the 247 // `PermitWithoutStream` parameter to true which ensures that the keepalive 248 // logic is running even without any active streams. 249 func TestKeepaliveClientClosesUnresponsiveServer(t *testing.T) { 250 connCh := make(chan net.Conn, 1) 251 client := setUpWithNoPingServer(t, ConnectOptions{KeepaliveParams: ClientKeepalive{ 252 Time: 250 * time.Millisecond, 253 Timeout: 250 * time.Millisecond, 254 PermitWithoutStream: true, 255 }}, connCh) 256 if client == nil { 257 t.Fatalf("setUpWithNoPingServer failed, return nil client") 258 } 259 defer client.Close() 260 261 conn, ok := <-connCh 262 if !ok { 263 t.Fatalf("Server didn't return connection object") 264 } 265 defer conn.Close() 266 267 // Sleep for keepalive to close the connection. 268 time.Sleep(1 * time.Second) 269 270 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 271 defer cancel() 272 // Make sure the client transport is not healthy. 273 if _, err := client.NewStream(ctx, &CallHdr{}); err == nil { 274 t.Fatal("client.NewStream() should have failed, but succeeded") 275 } 276 } 277 278 // TestKeepaliveClientOpenWithUnresponsiveServer creates a server which does 279 // not respond to keepalive pings, and makes sure that the client does not 280 // close the transport. Here, we do not set the `PermitWithoutStream` parameter 281 // to true which ensures that the keepalive logic is turned off without any 282 // active streams, and therefore the transport stays open. 283 func TestKeepaliveClientOpenWithUnresponsiveServer(t *testing.T) { 284 connCh := make(chan net.Conn, 1) 285 client := setUpWithNoPingServer(t, ConnectOptions{KeepaliveParams: ClientKeepalive{ 286 Time: 250 * time.Millisecond, 287 Timeout: 250 * time.Millisecond, 288 }}, connCh) 289 if client == nil { 290 t.Fatalf("setUpWithNoPingServer failed, return nil client") 291 } 292 defer client.Close() 293 294 conn, ok := <-connCh 295 if !ok { 296 t.Fatalf("Server didn't return connection object") 297 } 298 defer conn.Close() 299 300 // Give keepalive some time. 301 time.Sleep(1 * time.Second) 302 303 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 304 defer cancel() 305 // Make sure the client transport is healthy. 306 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 307 t.Fatalf("client.NewStream() failed: %v", err) 308 } 309 } 310 311 // TestKeepaliveClientClosesWithActiveStreams creates a server which does not 312 // respond to keepalive pings, and makes sure that the client closes the 313 // transport even when there is an active stream. 314 func TestKeepaliveClientClosesWithActiveStreams(t *testing.T) { 315 connCh := make(chan net.Conn, 1) 316 client := setUpWithNoPingServer(t, ConnectOptions{KeepaliveParams: ClientKeepalive{ 317 Time: 250 * time.Millisecond, 318 Timeout: 250 * time.Millisecond, 319 }}, connCh) 320 if client == nil { 321 t.Fatalf("setUpWithNoPingServer failed, return nil client") 322 } 323 defer client.Close() 324 325 conn, ok := <-connCh 326 if !ok { 327 t.Fatalf("Server didn't return connection object") 328 } 329 defer conn.Close() 330 331 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 332 defer cancel() 333 // Create a stream, but send no data on it. 334 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 335 t.Fatalf("client.NewStream() failed: %v", err) 336 } 337 338 // Give keepalive some time. 339 time.Sleep(1 * time.Second) 340 341 // Make sure the client transport is not healthy. 342 if _, err := client.NewStream(ctx, &CallHdr{}); err == nil { 343 t.Fatal("client.NewStream() should have failed, but succeeded") 344 } 345 } 346 347 // TestKeepaliveClientStaysHealthyWithResponsiveServer creates a server which 348 // responds to keepalive pings, and makes sure than a client transport stays 349 // healthy without any active streams. 350 func TestKeepaliveClientStaysHealthyWithResponsiveServer(t *testing.T) { 351 server, client := setUpWithOptions(t, 0, &ServerConfig{}, normal, ConnectOptions{ 352 KeepaliveParams: ClientKeepalive{ 353 Time: 500 * time.Millisecond, 354 Timeout: 500 * time.Millisecond, 355 PermitWithoutStream: true, 356 }, 357 }) 358 defer func() { 359 client.Close() 360 server.stop() 361 }() 362 363 // Give keepalive some time. 364 time.Sleep(1 * time.Second) 365 366 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 367 defer cancel() 368 // Make sure the client transport is healthy. 369 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 370 t.Fatalf("client.NewStream() failed: %v", err) 371 } 372 } 373 374 // TestKeepaliveClientFrequency creates a server which expects at most 1 client 375 // ping for every 1.2 seconds, while the client is configured to send a ping 376 // every 1 second. So, this configuration should end up with the client 377 // transport being closed. But we had a bug wherein the client was sending one 378 // ping every [Time+Timeout] instead of every [Time] period, and this test 379 // explicitly makes sure the fix works and the client sends a ping every [Time] 380 // period. 381 func TestKeepaliveClientFrequency(t *testing.T) { 382 serverConfig := &ServerConfig{ 383 KeepaliveEnforcementPolicy: EnforcementPolicy{ 384 MinTime: 200 * time.Millisecond, // 1.2 seconds 385 PermitWithoutStream: true, 386 }, 387 } 388 clientOptions := ConnectOptions{ 389 KeepaliveParams: ClientKeepalive{ 390 Time: 150 * time.Millisecond, 391 Timeout: 300 * time.Millisecond, 392 PermitWithoutStream: true, 393 }, 394 } 395 server, client := setUpWithOptions(t, 0, serverConfig, normal, clientOptions) 396 defer func() { 397 client.Close() 398 server.stop() 399 }() 400 401 timeout := time.NewTimer(1 * time.Second) 402 select { 403 case <-client.Error(): 404 if !timeout.Stop() { 405 <-timeout.C 406 } 407 if reason := client.GetGoAwayReason(); reason != GoAwayTooManyPings { 408 t.Fatalf("GoAwayReason is %v, want %v", reason, GoAwayTooManyPings) 409 } 410 case <-timeout.C: 411 t.Fatalf("client transport still healthy; expected GoAway from the server.") 412 } 413 414 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 415 defer cancel() 416 // Make sure the client transport is not healthy. 417 if _, err := client.NewStream(ctx, &CallHdr{}); err == nil { 418 t.Fatal("client.NewStream() should have failed, but succeeded") 419 } 420 } 421 422 // TestKeepaliveServerEnforcementWithAbusiveClientNoRPC verifies that the 423 // server closes a client transport when it sends too many keepalive pings 424 // (when there are no active streams), based on the configured 425 // EnforcementPolicy. 426 func TestKeepaliveServerEnforcementWithAbusiveClientNoRPC(t *testing.T) { 427 serverConfig := &ServerConfig{ 428 KeepaliveEnforcementPolicy: EnforcementPolicy{ 429 MinTime: 2 * time.Second, 430 }, 431 } 432 clientOptions := ConnectOptions{ 433 KeepaliveParams: ClientKeepalive{ 434 Time: 50 * time.Millisecond, 435 Timeout: 1 * time.Second, 436 PermitWithoutStream: true, 437 }, 438 } 439 server, client := setUpWithOptions(t, 0, serverConfig, normal, clientOptions) 440 defer func() { 441 client.Close() 442 server.stop() 443 }() 444 445 timeout := time.NewTimer(4 * time.Second) 446 select { 447 case <-client.Error(): 448 if !timeout.Stop() { 449 <-timeout.C 450 } 451 if reason := client.GetGoAwayReason(); reason != GoAwayTooManyPings { 452 t.Fatalf("GoAwayReason is %v, want %v", reason, GoAwayTooManyPings) 453 } 454 case <-timeout.C: 455 t.Fatalf("client transport still healthy; expected GoAway from the server.") 456 } 457 458 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 459 defer cancel() 460 // Make sure the client transport is not healthy. 461 if _, err := client.NewStream(ctx, &CallHdr{}); err == nil { 462 t.Fatal("client.NewStream() should have failed, but succeeded") 463 } 464 } 465 466 // TestKeepaliveServerEnforcementWithAbusiveClientWithRPC verifies that the 467 // server closes a client transport when it sends too many keepalive pings 468 // (even when there is an active stream), based on the configured 469 // EnforcementPolicy. 470 func TestKeepaliveServerEnforcementWithAbusiveClientWithRPC(t *testing.T) { 471 serverConfig := &ServerConfig{ 472 KeepaliveEnforcementPolicy: EnforcementPolicy{ 473 MinTime: 2 * time.Second, 474 }, 475 } 476 clientOptions := ConnectOptions{ 477 KeepaliveParams: ClientKeepalive{ 478 Time: 50 * time.Millisecond, 479 Timeout: 1 * time.Second, 480 }, 481 } 482 server, client := setUpWithOptions(t, 0, serverConfig, suspended, clientOptions) 483 defer func() { 484 client.Close() 485 server.stop() 486 }() 487 488 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 489 defer cancel() 490 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 491 t.Fatalf("client.NewStream() failed: %v", err) 492 } 493 494 timeout := time.NewTimer(4 * time.Second) 495 select { 496 case <-client.Error(): 497 if !timeout.Stop() { 498 <-timeout.C 499 } 500 if reason := client.GetGoAwayReason(); reason != GoAwayTooManyPings { 501 t.Fatalf("GoAwayReason is %v, want %v", reason, GoAwayTooManyPings) 502 } 503 case <-timeout.C: 504 t.Fatalf("client transport still healthy; expected GoAway from the server.") 505 } 506 507 // Make sure the client transport is not healthy. 508 if _, err := client.NewStream(ctx, &CallHdr{}); err == nil { 509 t.Fatal("client.NewStream() should have failed, but succeeded") 510 } 511 } 512 513 // TestKeepaliveServerEnforcementWithObeyingClientNoRPC verifies that the 514 // server does not close a client transport (with no active streams) which 515 // sends keepalive pings in accordance to the configured keepalive 516 // EnforcementPolicy. 517 func TestKeepaliveServerEnforcementWithObeyingClientNoRPC(t *testing.T) { 518 serverConfig := &ServerConfig{ 519 KeepaliveEnforcementPolicy: EnforcementPolicy{ 520 MinTime: 50 * time.Millisecond, 521 PermitWithoutStream: true, 522 }, 523 } 524 clientOptions := ConnectOptions{ 525 KeepaliveParams: ClientKeepalive{ 526 Time: 51 * time.Millisecond, 527 Timeout: 500 * time.Millisecond, 528 PermitWithoutStream: true, 529 }, 530 } 531 server, client := setUpWithOptions(t, 0, serverConfig, normal, clientOptions) 532 defer func() { 533 client.Close() 534 server.stop() 535 }() 536 537 // Give keepalive enough time. 538 time.Sleep(500 * time.Millisecond) 539 540 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 541 defer cancel() 542 // Make sure the client transport is healthy. 543 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 544 t.Fatalf("client.NewStream() failed: %v", err) 545 } 546 } 547 548 // TestKeepaliveServerEnforcementWithObeyingClientWithRPC verifies that the 549 // server does not close a client transport (with active streams) which 550 // sends keepalive pings in accordance to the configured keepalive 551 // EnforcementPolicy. 552 func TestKeepaliveServerEnforcementWithObeyingClientWithRPC(t *testing.T) { 553 serverConfig := &ServerConfig{ 554 KeepaliveEnforcementPolicy: EnforcementPolicy{ 555 MinTime: 50 * time.Millisecond, 556 }, 557 } 558 clientOptions := ConnectOptions{ 559 KeepaliveParams: ClientKeepalive{ 560 Time: 51 * time.Millisecond, 561 Timeout: 500 * time.Millisecond, 562 }, 563 } 564 server, client := setUpWithOptions(t, 0, serverConfig, suspended, clientOptions) 565 defer func() { 566 client.Close() 567 server.stop() 568 }() 569 570 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 571 defer cancel() 572 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 573 t.Fatalf("client.NewStream() failed: %v", err) 574 } 575 576 // Give keepalive enough time. 577 time.Sleep(1 * time.Second) 578 579 // Make sure the client transport is healthy. 580 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 581 t.Fatalf("client.NewStream() failed: %v", err) 582 } 583 } 584 585 // TestKeepaliveServerEnforcementWithDormantKeepaliveOnClient verifies that the 586 // server does not closes a client transport, which has been configured to send 587 // more pings than allowed by the server's EnforcementPolicy. This client 588 // transport does not have any active streams and `PermitWithoutStream` is set 589 // to false. This should ensure that the keepalive functionality on the client 590 // side enters a dormant state. 591 func TestKeepaliveServerEnforcementWithDormantKeepaliveOnClient(t *testing.T) { 592 serverConfig := &ServerConfig{ 593 KeepaliveEnforcementPolicy: EnforcementPolicy{ 594 MinTime: 400 * time.Millisecond, 595 }, 596 } 597 clientOptions := ConnectOptions{ 598 KeepaliveParams: ClientKeepalive{ 599 Time: 25 * time.Millisecond, 600 Timeout: 250 * time.Millisecond, 601 }, 602 } 603 server, client := setUpWithOptions(t, 0, serverConfig, normal, clientOptions) 604 defer func() { 605 client.Close() 606 server.stop() 607 }() 608 609 // No active streams on the client. Give keepalive enough time. 610 time.Sleep(500 * time.Millisecond) 611 612 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 613 defer cancel() 614 // Make sure the client transport is healthy. 615 if _, err := client.NewStream(ctx, &CallHdr{}); err != nil { 616 t.Fatalf("client.NewStream() failed: %v", err) 617 } 618 } 619 620 // FIXME syscall.GetTCPUserTimeout() failed: conn is not *net.TCPConn. got *netpoll.TCPConnection 621 // TestTCPUserTimeout tests that the TCP_USER_TIMEOUT socket option is set to 622 // the keepalive timeout, as detailed in proposal A18. 623 //func TestTCPUserTimeout(t *testing.T) { 624 // tests := []struct { 625 // time time.Duration 626 // timeout time.Duration 627 // wantTimeout time.Duration 628 // }{ 629 // { 630 // 10 * time.Second, 631 // 10 * time.Second, 632 // 10 * 1000 * time.Millisecond, 633 // }, 634 // { 635 // 0, 636 // 0, 637 // 0, 638 // }, 639 // } 640 // for _, tt := range tests { 641 // server, client := setUpWithOptions( 642 // t, 643 // 0, 644 // &ServerConfig{ 645 // KeepaliveParams: ServerKeepalive{ 646 // Time: tt.timeout, 647 // Timeout: tt.timeout, 648 // }, 649 // }, 650 // normal, 651 // ConnectOptions{ 652 // KeepaliveParams: ClientKeepalive{ 653 // Time: tt.time, 654 // Timeout: tt.timeout, 655 // }, 656 // }, 657 // ) 658 // defer func() { 659 // client.Close() 660 // server.stop() 661 // }() 662 // 663 // ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 664 // defer cancel() 665 // stream, err := client.NewStream(ctx, &CallHdr{}) 666 // if err != nil { 667 // t.Fatalf("client.NewStream() failed: %v", err) 668 // } 669 // client.CloseStream(stream, io.EOF) 670 // 671 // opt, err := syscall.GetTCPUserTimeout(client.conn) 672 // if err != nil { 673 // t.Fatalf("syscall.GetTCPUserTimeout() failed: %v", err) 674 // } 675 // if opt < 0 { 676 // t.Skipf("skipping test on unsupported environment") 677 // } 678 // if gotTimeout := time.Duration(opt) * time.Millisecond; gotTimeout != tt.wantTimeout { 679 // t.Fatalf("syscall.GetTCPUserTimeout() = %d, want %d", gotTimeout, tt.wantTimeout) 680 // } 681 // } 682 //}