mirror of
https://github.com/libp2p/go-reuseport.git
synced 2025-09-27 11:12:10 +08:00
203 lines
4.1 KiB
Go
203 lines
4.1 KiB
Go
package reuseport
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func echo(c net.Conn) {
|
|
io.Copy(c, c)
|
|
c.Close()
|
|
}
|
|
|
|
func acceptAndEcho(l net.Listener) {
|
|
for {
|
|
c, err := l.Accept()
|
|
if err != nil {
|
|
return
|
|
}
|
|
go echo(c)
|
|
}
|
|
}
|
|
|
|
func CI() bool {
|
|
return os.Getenv("TRAVIS") == "true"
|
|
}
|
|
|
|
func TestListenSamePort(t *testing.T) {
|
|
|
|
// any ports
|
|
any := [][]string{
|
|
[]string{"tcp", "127.0.0.1:0"},
|
|
[]string{"tcp", "[::1]:0"},
|
|
[]string{"tcp4", "127.0.0.1:0"},
|
|
[]string{"tcp6", "[::1]:0"},
|
|
[]string{"udp", "127.0.0.1:0"},
|
|
[]string{"udp", "[::1]:0"},
|
|
[]string{"udp4", "127.0.0.1:0"},
|
|
[]string{"udp6", "[::1]:0"},
|
|
}
|
|
|
|
// specific ports. off in CI
|
|
specific := [][]string{
|
|
[]string{"tcp", "127.0.0.1:5556"},
|
|
[]string{"tcp", "[::1]:5557"},
|
|
[]string{"tcp4", "127.0.0.1:5558"},
|
|
[]string{"tcp6", "[::1]:5559"},
|
|
[]string{"udp", "127.0.0.1:5560"},
|
|
[]string{"udp", "[::1]:5561"},
|
|
[]string{"udp4", "127.0.0.1:5562"},
|
|
[]string{"udp6", "[::1]:5563"},
|
|
}
|
|
|
|
testCases := any
|
|
if !CI() {
|
|
testCases = append(testCases, specific...)
|
|
}
|
|
|
|
for _, tcase := range testCases {
|
|
network := tcase[0]
|
|
addr := tcase[1]
|
|
t.Log("testing", network, addr)
|
|
|
|
l1, err := Listen(network, addr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
defer l1.Close()
|
|
t.Log("listening", l1.Addr())
|
|
|
|
l2, err := Listen(l1.Addr().Network(), l1.Addr().String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
defer l2.Close()
|
|
t.Log("listening", l2.Addr())
|
|
|
|
l3, err := Listen(l2.Addr().Network(), l2.Addr().String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
defer l3.Close()
|
|
t.Log("listening", l3.Addr())
|
|
|
|
if l1.Addr().String() != l2.Addr().String() {
|
|
t.Fatal("addrs should match", l1.Addr(), l2.Addr())
|
|
}
|
|
|
|
if l1.Addr().String() != l3.Addr().String() {
|
|
t.Fatal("addrs should match", l1.Addr(), l3.Addr())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestListenDialSamePort(t *testing.T) {
|
|
|
|
any := [][]string{
|
|
[]string{"tcp", "127.0.0.1:0", "127.0.0.1:0"},
|
|
[]string{"tcp4", "127.0.0.1:0", "127.0.0.1:0"},
|
|
[]string{"tcp6", "[::1]:0", "[::1]:0"},
|
|
[]string{"udp", "127.0.0.1:0", "127.0.0.1:0"},
|
|
[]string{"udp4", "127.0.0.1:0", "127.0.0.1:0"},
|
|
[]string{"udp6", "[::1]:0", "[::1]:0"},
|
|
}
|
|
|
|
specific := [][]string{
|
|
[]string{"tcp", "127.0.0.1:5570", "127.0.0.1:5571"},
|
|
[]string{"tcp4", "127.0.0.1:5572", "127.0.0.1:5573"},
|
|
[]string{"tcp6", "[::1]:5573", "[::1]:5574"},
|
|
[]string{"udp", "127.0.0.1:5670", "127.0.0.1:5671"},
|
|
[]string{"udp4", "127.0.0.1:5672", "127.0.0.1:5673"},
|
|
[]string{"udp6", "[::1]:5673", "[::1]:5674"},
|
|
}
|
|
|
|
testCases := any
|
|
if !CI() {
|
|
testCases = append(testCases, specific...)
|
|
}
|
|
|
|
for _, tcase := range testCases {
|
|
t.Log("testing", tcase)
|
|
network := tcase[0]
|
|
addr1 := tcase[1]
|
|
addr2 := tcase[2]
|
|
|
|
l1, err := Listen(network, addr1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
defer l1.Close()
|
|
t.Log("listening", l1.Addr())
|
|
|
|
l2, err := Listen(network, addr2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
defer l2.Close()
|
|
t.Log("listening", l2.Addr())
|
|
|
|
go acceptAndEcho(l1)
|
|
go acceptAndEcho(l2)
|
|
|
|
c1, err := Dial(network, l1.Addr().String(), l2.Addr().String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
defer c1.Close()
|
|
t.Log("dialed", c1.LocalAddr(), c1.RemoteAddr())
|
|
|
|
if l1.Addr().String() != c1.LocalAddr().String() {
|
|
t.Fatal("addrs should match", l1.Addr(), c1.LocalAddr())
|
|
}
|
|
|
|
if l2.Addr().String() != c1.RemoteAddr().String() {
|
|
t.Fatal("addrs should match", l2.Addr(), c1.RemoteAddr())
|
|
}
|
|
|
|
hello1 := []byte("hello world")
|
|
hello2 := make([]byte, len(hello1))
|
|
if _, err := c1.Write(hello1); err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
|
|
if _, err := c1.Read(hello2); err != nil {
|
|
t.Fatal(err)
|
|
continue
|
|
}
|
|
|
|
if !bytes.Equal(hello1, hello2) {
|
|
t.Fatal("echo failed", string(hello1), "!=", string(hello2))
|
|
}
|
|
t.Log("echoed", string(hello2))
|
|
}
|
|
}
|
|
|
|
func TestUnixNotSupported(t *testing.T) {
|
|
|
|
testCases := [][]string{
|
|
[]string{"unix", "/tmp/foo"},
|
|
}
|
|
|
|
for _, tcase := range testCases {
|
|
network := tcase[0]
|
|
addr := tcase[1]
|
|
t.Log("testing", network, addr)
|
|
|
|
_, err := Listen(network, addr)
|
|
if err == nil {
|
|
t.Fatal("unix supported")
|
|
continue
|
|
}
|
|
}
|
|
}
|