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.
90 lines
3.2 KiB
90 lines
3.2 KiB
// +build linux,go1.10,!appengine |
|
|
|
/* |
|
* |
|
* Copyright 2018 gRPC authors. |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
*/ |
|
|
|
// The test in this file should be run in an environment that has go1.10 or later, |
|
// as the function SyscallConn() (required to get socket option) was introduced |
|
// to net.TCPListener in go1.10. |
|
|
|
package channelz_test |
|
|
|
import ( |
|
"net" |
|
"reflect" |
|
"syscall" |
|
"testing" |
|
|
|
"golang.org/x/sys/unix" |
|
"google.golang.org/grpc/internal/channelz" |
|
) |
|
|
|
func TestGetSocketOpt(t *testing.T) { |
|
network, addr := "tcp", ":0" |
|
ln, err := net.Listen(network, addr) |
|
if err != nil { |
|
t.Fatalf("net.Listen(%s,%s) failed with err: %v", network, addr, err) |
|
} |
|
defer ln.Close() |
|
go func() { |
|
ln.Accept() |
|
}() |
|
conn, _ := net.Dial(network, ln.Addr().String()) |
|
defer conn.Close() |
|
tcpc := conn.(*net.TCPConn) |
|
raw, err := tcpc.SyscallConn() |
|
if err != nil { |
|
t.Fatalf("SyscallConn() failed due to %v", err) |
|
} |
|
|
|
l := &unix.Linger{Onoff: 1, Linger: 5} |
|
recvTimout := &unix.Timeval{Sec: 100} |
|
sendTimeout := &unix.Timeval{Sec: 8888} |
|
raw.Control(func(fd uintptr) { |
|
err := unix.SetsockoptLinger(int(fd), syscall.SOL_SOCKET, syscall.SO_LINGER, l) |
|
if err != nil { |
|
t.Fatalf("failed to SetsockoptLinger(%v,%v,%v,%v) due to %v", int(fd), syscall.SOL_SOCKET, syscall.SO_LINGER, l, err) |
|
} |
|
err = unix.SetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, recvTimout) |
|
if err != nil { |
|
t.Fatalf("failed to SetsockoptTimeval(%v,%v,%v,%v) due to %v", int(fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, recvTimout, err) |
|
} |
|
err = unix.SetsockoptTimeval(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, sendTimeout) |
|
if err != nil { |
|
t.Fatalf("failed to SetsockoptTimeval(%v,%v,%v,%v) due to %v", int(fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, sendTimeout, err) |
|
} |
|
}) |
|
sktopt := channelz.GetSocketOption(conn) |
|
if !reflect.DeepEqual(sktopt.Linger, l) { |
|
t.Fatalf("get socket option linger, want: %v, got %v", l, sktopt.Linger) |
|
} |
|
if !reflect.DeepEqual(sktopt.RecvTimeout, recvTimout) { |
|
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) |
|
} |
|
if !reflect.DeepEqual(sktopt.SendTimeout, sendTimeout) { |
|
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) |
|
} |
|
if sktopt == nil || sktopt.TCPInfo != nil && sktopt.TCPInfo.State != 1 { |
|
t.Fatalf("TCPInfo.State want 1 (TCP_ESTABLISHED), got %v", sktopt) |
|
} |
|
|
|
sktopt = channelz.GetSocketOption(ln) |
|
if sktopt == nil || sktopt.TCPInfo == nil || sktopt.TCPInfo.State != 10 { |
|
t.Fatalf("TCPInfo.State want 10 (TCP_LISTEN), got %v", sktopt) |
|
} |
|
}
|
|
|