util_test.go 3.3 KB

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