You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

91 lines
3.2 KiB

  1. // +build linux,go1.10,!appengine
  2. /*
  3. *
  4. * Copyright 2018 gRPC authors.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. */
  19. // The test in this file should be run in an environment that has go1.10 or later,
  20. // as the function SyscallConn() (required to get socket option) was introduced
  21. // to net.TCPListener in go1.10.
  22. package channelz_test
  23. import (
  24. "net"
  25. "reflect"
  26. "syscall"
  27. "testing"
  28. "golang.org/x/sys/unix"
  29. "google.golang.org/grpc/internal/channelz"
  30. )
  31. func TestGetSocketOpt(t *testing.T) {
  32. network, addr := "tcp", ":0"
  33. ln, err := net.Listen(network, addr)
  34. if err != nil {
  35. t.Fatalf("net.Listen(%s,%s) failed with err: %v", network, addr, err)
  36. }
  37. defer ln.Close()
  38. go func() {
  39. ln.Accept()
  40. }()
  41. conn, _ := net.Dial(network, ln.Addr().String())
  42. defer conn.Close()
  43. tcpc := conn.(*net.TCPConn)
  44. raw, err := tcpc.SyscallConn()
  45. if err != nil {
  46. t.Fatalf("SyscallConn() failed due to %v", err)
  47. }
  48. l := &unix.Linger{Onoff: 1, Linger: 5}
  49. recvTimout := &unix.Timeval{Sec: 100}
  50. sendTimeout := &unix.Timeval{Sec: 8888}
  51. raw.Control(func(fd uintptr) {
  52. err := unix.SetsockoptLinger(int(fd), syscall.SOL_SOCKET, syscall.SO_LINGER, l)
  53. if err != nil {
  54. t.Fatalf("failed to SetsockoptLinger(%v,%v,%v,%v) due to %v", int(fd), syscall.SOL_SOCKET, syscall.SO_LINGER, l, err)
  55. }
  56. err = unix.SetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, recvTimout)
  57. if err != nil {
  58. t.Fatalf("failed to SetsockoptTimeval(%v,%v,%v,%v) due to %v", int(fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, recvTimout, err)
  59. }
  60. err = unix.SetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, sendTimeout)
  61. if err != nil {
  62. t.Fatalf("failed to SetsockoptTimeval(%v,%v,%v,%v) due to %v", int(fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, sendTimeout, err)
  63. }
  64. })
  65. sktopt := channelz.GetSocketOption(conn)
  66. if !reflect.DeepEqual(sktopt.Linger, l) {
  67. t.Fatalf("get socket option linger, want: %v, got %v", l, sktopt.Linger)
  68. }
  69. if !reflect.DeepEqual(sktopt.RecvTimeout, recvTimout) {
  70. t.Logf("get socket option recv timeout, want: %v, got %v, may be caused by system allowing non or partial setting of this value", recvTimout, sktopt.RecvTimeout)
  71. }
  72. if !reflect.DeepEqual(sktopt.SendTimeout, sendTimeout) {
  73. t.Logf("get socket option send timeout, want: %v, got %v, may be caused by system allowing non or partial setting of this value", sendTimeout, sktopt.SendTimeout)
  74. }
  75. if sktopt == nil || sktopt.TCPInfo != nil && sktopt.TCPInfo.State != 1 {
  76. t.Fatalf("TCPInfo.State want 1 (TCP_ESTABLISHED), got %v", sktopt)
  77. }
  78. sktopt = channelz.GetSocketOption(ln)
  79. if sktopt == nil || sktopt.TCPInfo == nil || sktopt.TCPInfo.State != 10 {
  80. t.Fatalf("TCPInfo.State want 10 (TCP_LISTEN), got %v", sktopt)
  81. }
  82. }