From adbadf444dada2ac8d659818d82279252d2d1f35 Mon Sep 17 00:00:00 2001 From: Mikio Hara Date: Thu, 23 Feb 2012 12:16:43 +0900 Subject: [PATCH] net: add a bit clarified multicast listener tests Also adds -external flag to allow use of external networks on tests. R=rsc CC=golang-dev https://golang.org/cl/5693043 --- src/pkg/net/dialgoogle_test.go | 4 +- src/pkg/net/lookup_test.go | 12 +-- src/pkg/net/multicast_test.go | 191 ++++++++++++++++++++------------- src/pkg/net/server_test.go | 2 +- 4 files changed, 123 insertions(+), 86 deletions(-) diff --git a/src/pkg/net/dialgoogle_test.go b/src/pkg/net/dialgoogle_test.go index 81750a3d739..14356da4ce3 100644 --- a/src/pkg/net/dialgoogle_test.go +++ b/src/pkg/net/dialgoogle_test.go @@ -14,7 +14,7 @@ import ( ) // If an IPv6 tunnel is running, we can try dialing a real IPv6 address. -var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present") +var testIPv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present") // fd is already connected to the destination, port 80. // Run an HTTP request to fetch the appropriate page. @@ -130,7 +130,7 @@ func TestDialGoogleIPv6(t *testing.T) { return } // Only run tcp6 if the kernel will take it. - if !*ipv6 || !supportsIPv6 { + if !*testIPv6 || !supportsIPv6 { return } diff --git a/src/pkg/net/lookup_test.go b/src/pkg/net/lookup_test.go index 9a39ca8a1eb..7b9ea844cd4 100644 --- a/src/pkg/net/lookup_test.go +++ b/src/pkg/net/lookup_test.go @@ -8,14 +8,14 @@ package net import ( - "runtime" + "flag" "testing" ) -var avoidMacFirewall = runtime.GOOS == "darwin" +var testExternal = flag.Bool("external", false, "allow use of external networks during test") func TestGoogleSRV(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } @@ -38,7 +38,7 @@ func TestGoogleSRV(t *testing.T) { } func TestGmailMX(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } @@ -52,7 +52,7 @@ func TestGmailMX(t *testing.T) { } func TestGmailTXT(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } @@ -66,7 +66,7 @@ func TestGmailTXT(t *testing.T) { } func TestGoogleDNSAddr(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } diff --git a/src/pkg/net/multicast_test.go b/src/pkg/net/multicast_test.go index 9727ecdc158..1d760c21051 100644 --- a/src/pkg/net/multicast_test.go +++ b/src/pkg/net/multicast_test.go @@ -5,30 +5,46 @@ package net import ( + "errors" "os" "runtime" + "syscall" "testing" ) -var listenMulticastUDPTests = []struct { +var multicastListenerTests = []struct { net string gaddr *UDPAddr flags Flags - ipv6 bool + ipv6 bool // test with underlying AF_INET6 socket }{ // cf. RFC 4727: Experimental Values in IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers + {"udp", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false}, - {"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false}, + {"udp", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, 0, false}, {"udp", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp", &UDPAddr{ParseIP("ff0e::114"), 12345}, 0, true}, + + {"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false}, + {"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, 0, false}, + {"udp6", &UDPAddr{ParseIP("ff01::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff01::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff02::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff02::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff04::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff04::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff05::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff05::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff08::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff08::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff0e::114"), 12345}, 0, true}, } -func TestListenMulticastUDP(t *testing.T) { +// TestMulticastListener tests both single and double listen to a test +// listener with same address family, same group address and same port. +func TestMulticastListener(t *testing.T) { switch runtime.GOOS { case "netbsd", "openbsd", "plan9", "windows": return @@ -38,118 +54,142 @@ func TestListenMulticastUDP(t *testing.T) { } } - for _, tt := range listenMulticastUDPTests { + for _, tt := range multicastListenerTests { if tt.ipv6 && (!supportsIPv6 || os.Getuid() != 0) { continue } - ift, err := Interfaces() + ifi, err := availMulticastInterface(t, tt.flags) if err != nil { - t.Fatalf("Interfaces failed: %v", err) + continue } - var ifi *Interface - for _, x := range ift { - if x.Flags&tt.flags == tt.flags { - ifi = &x - break - } - } - if ifi == nil { - t.Logf("an appropriate multicast interface not found") - return - } - c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) + c1, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) if err != nil { - t.Fatalf("ListenMulticastUDP failed: %v", err) + t.Fatalf("First ListenMulticastUDP failed: %v", err) } - defer c.Close() // test to listen concurrently across multiple listeners - if !tt.ipv6 { - testIPv4MulticastSocketOptions(t, c.fd, ifi) - } else { - testIPv6MulticastSocketOptions(t, c.fd, ifi) - } - ifmat, err := ifi.MulticastAddrs() + checkMulticastListener(t, err, c1, tt.gaddr) + c2, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) if err != nil { - t.Fatalf("MulticastAddrs failed: %v", err) + t.Fatalf("Second ListenMulticastUDP failed: %v", err) } - var found bool - for _, ifma := range ifmat { - if ifma.(*IPAddr).IP.Equal(tt.gaddr.IP) { - found = true - break - } - } - if !found { - t.Fatalf("%q not found in RIB", tt.gaddr.String()) - } - if c.LocalAddr().String() != tt.gaddr.String() { - t.Fatalf("LocalAddr returns %q, expected %q", c.LocalAddr().String(), tt.gaddr.String()) + checkMulticastListener(t, err, c2, tt.gaddr) + c2.Close() + switch c1.fd.family { + case syscall.AF_INET: + testIPv4MulticastSocketOptions(t, c1.fd, ifi) + case syscall.AF_INET6: + testIPv6MulticastSocketOptions(t, c1.fd, ifi) } + c1.Close() } } -func TestSimpleListenMulticastUDP(t *testing.T) { +func TestSimpleMulticastListener(t *testing.T) { switch runtime.GOOS { case "plan9": return } - for _, tt := range listenMulticastUDPTests { + for _, tt := range multicastListenerTests { if tt.ipv6 { continue } - tt.flags = FlagUp | FlagMulticast + tt.flags = FlagUp | FlagMulticast // for windows testing + ifi, err := availMulticastInterface(t, tt.flags) + if err != nil { + continue + } + c1, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) + if err != nil { + t.Fatalf("First ListenMulticastUDP failed: %v", err) + } + checkSimpleMulticastListener(t, err, c1, tt.gaddr) + c2, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) + if err != nil { + t.Fatalf("Second ListenMulticastUDP failed: %v", err) + } + checkSimpleMulticastListener(t, err, c2, tt.gaddr) + c2.Close() + c1.Close() + } +} + +func checkMulticastListener(t *testing.T, err error, c *UDPConn, gaddr *UDPAddr) { + if !multicastRIBContains(t, gaddr.IP) { + t.Fatalf("%q not found in RIB", gaddr.String()) + } + if c.LocalAddr().String() != gaddr.String() { + t.Fatalf("LocalAddr returns %q, expected %q", c.LocalAddr().String(), gaddr.String()) + } +} + +func checkSimpleMulticastListener(t *testing.T, err error, c *UDPConn, gaddr *UDPAddr) { + if c.LocalAddr().String() != gaddr.String() { + t.Fatalf("LocalAddr returns %q, expected %q", c.LocalAddr().String(), gaddr.String()) + } +} + +func availMulticastInterface(t *testing.T, flags Flags) (*Interface, error) { + var ifi *Interface + if flags != Flags(0) { ift, err := Interfaces() if err != nil { t.Fatalf("Interfaces failed: %v", err) } - var ifi *Interface for _, x := range ift { - if x.Flags&tt.flags == tt.flags { + if x.Flags&flags == flags { ifi = &x break } } if ifi == nil { - t.Logf("an appropriate multicast interface not found") - return + return nil, errors.New("an appropriate multicast interface not found") } - c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) - if err != nil { - t.Fatalf("ListenMulticastUDP failed: %v", err) - } - if c.LocalAddr().String() != tt.gaddr.String() { - t.Fatalf("LocalAddr returns %q, expected %q", c.LocalAddr().String(), tt.gaddr.String()) - } - c.Close() } + return ifi, nil +} + +func multicastRIBContains(t *testing.T, ip IP) bool { + ift, err := Interfaces() + if err != nil { + t.Fatalf("Interfaces failed: %v", err) + } + for _, ifi := range ift { + ifmat, err := ifi.MulticastAddrs() + if err != nil { + t.Fatalf("MulticastAddrs failed: %v", err) + } + for _, ifma := range ifmat { + if ifma.(*IPAddr).IP.Equal(ip) { + return true + } + } + } + return false } func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) { - ifmc, err := ipv4MulticastInterface(fd) + _, err := ipv4MulticastInterface(fd) if err != nil { t.Fatalf("ipv4MulticastInterface failed: %v", err) } - t.Logf("IPv4 multicast interface: %v", ifmc) - err = setIPv4MulticastInterface(fd, ifi) - if err != nil { - t.Fatalf("setIPv4MulticastInterface failed: %v", err) + if ifi != nil { + err = setIPv4MulticastInterface(fd, ifi) + if err != nil { + t.Fatalf("setIPv4MulticastInterface failed: %v", err) + } } - - ttl, err := ipv4MulticastTTL(fd) + _, err = ipv4MulticastTTL(fd) if err != nil { t.Fatalf("ipv4MulticastTTL failed: %v", err) } - t.Logf("IPv4 multicast TTL: %v", ttl) err = setIPv4MulticastTTL(fd, 1) if err != nil { t.Fatalf("setIPv4MulticastTTL failed: %v", err) } - - loop, err := ipv4MulticastLoopback(fd) + _, err = ipv4MulticastLoopback(fd) if err != nil { t.Fatalf("ipv4MulticastLoopback failed: %v", err) } - t.Logf("IPv4 multicast loopback: %v", loop) err = setIPv4MulticastLoopback(fd, false) if err != nil { t.Fatalf("setIPv4MulticastLoopback failed: %v", err) @@ -157,31 +197,28 @@ func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) { } func testIPv6MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) { - ifmc, err := ipv6MulticastInterface(fd) + _, err := ipv6MulticastInterface(fd) if err != nil { t.Fatalf("ipv6MulticastInterface failed: %v", err) } - t.Logf("IPv6 multicast interface: %v", ifmc) - err = setIPv6MulticastInterface(fd, ifi) - if err != nil { - t.Fatalf("setIPv6MulticastInterface failed: %v", err) + if ifi != nil { + err = setIPv6MulticastInterface(fd, ifi) + if err != nil { + t.Fatalf("setIPv6MulticastInterface failed: %v", err) + } } - - hoplim, err := ipv6MulticastHopLimit(fd) + _, err = ipv6MulticastHopLimit(fd) if err != nil { t.Fatalf("ipv6MulticastHopLimit failed: %v", err) } - t.Logf("IPv6 multicast hop limit: %v", hoplim) err = setIPv6MulticastHopLimit(fd, 1) if err != nil { t.Fatalf("setIPv6MulticastHopLimit failed: %v", err) } - - loop, err := ipv6MulticastLoopback(fd) + _, err = ipv6MulticastLoopback(fd) if err != nil { t.Fatalf("ipv6MulticastLoopback failed: %v", err) } - t.Logf("IPv6 multicast loopback: %v", loop) err = setIPv6MulticastLoopback(fd, false) if err != nil { t.Fatalf("setIPv6MulticastLoopback failed: %v", err) diff --git a/src/pkg/net/server_test.go b/src/pkg/net/server_test.go index 55691493aa9..b9862168153 100644 --- a/src/pkg/net/server_test.go +++ b/src/pkg/net/server_test.go @@ -95,7 +95,7 @@ func doTest(t *testing.T, network, listenaddr, dialaddr string) { t.Logf("Test %q %q %q", network, listenaddr, dialaddr) switch listenaddr { case "", "0.0.0.0", "[::]", "[::ffff:0.0.0.0]": - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skip wildcard listen during short test") return }