...

Source file src/net/interface_unix_test.go

Documentation: net

		 1  // Copyright 2013 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
		 6  // +build darwin dragonfly freebsd linux netbsd openbsd
		 7  
		 8  package net
		 9  
		10  import (
		11  	"fmt"
		12  	"os"
		13  	"os/exec"
		14  	"runtime"
		15  	"strings"
		16  	"testing"
		17  	"time"
		18  )
		19  
		20  type testInterface struct {
		21  	name				 string
		22  	local				string
		23  	remote			 string
		24  	setupCmds		[]*exec.Cmd
		25  	teardownCmds []*exec.Cmd
		26  }
		27  
		28  func (ti *testInterface) setup() error {
		29  	for _, cmd := range ti.setupCmds {
		30  		if out, err := cmd.CombinedOutput(); err != nil {
		31  			return fmt.Errorf("args=%v out=%q err=%v", cmd.Args, string(out), err)
		32  		}
		33  	}
		34  	return nil
		35  }
		36  
		37  func (ti *testInterface) teardown() error {
		38  	for _, cmd := range ti.teardownCmds {
		39  		if out, err := cmd.CombinedOutput(); err != nil {
		40  			return fmt.Errorf("args=%v out=%q err=%v ", cmd.Args, string(out), err)
		41  		}
		42  	}
		43  	return nil
		44  }
		45  
		46  func TestPointToPointInterface(t *testing.T) {
		47  	if testing.Short() {
		48  		t.Skip("avoid external network")
		49  	}
		50  	if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
		51  		t.Skipf("not supported on %s", runtime.GOOS)
		52  	}
		53  	if os.Getuid() != 0 {
		54  		t.Skip("must be root")
		55  	}
		56  
		57  	// We suppose that using IPv4 link-local addresses doesn't
		58  	// harm anyone.
		59  	local, remote := "169.254.0.1", "169.254.0.254"
		60  	ip := ParseIP(remote)
		61  	for i := 0; i < 3; i++ {
		62  		ti := &testInterface{local: local, remote: remote}
		63  		if err := ti.setPointToPoint(5963 + i); err != nil {
		64  			t.Skipf("test requires external command: %v", err)
		65  		}
		66  		if err := ti.setup(); err != nil {
		67  			if e := err.Error(); strings.Contains(e, "No such device") && strings.Contains(e, "gre0") {
		68  				t.Skip("skipping test; no gre0 device. likely running in container?")
		69  			}
		70  			t.Fatal(err)
		71  		} else {
		72  			time.Sleep(3 * time.Millisecond)
		73  		}
		74  		ift, err := Interfaces()
		75  		if err != nil {
		76  			ti.teardown()
		77  			t.Fatal(err)
		78  		}
		79  		for _, ifi := range ift {
		80  			if ti.name != ifi.Name {
		81  				continue
		82  			}
		83  			ifat, err := ifi.Addrs()
		84  			if err != nil {
		85  				ti.teardown()
		86  				t.Fatal(err)
		87  			}
		88  			for _, ifa := range ifat {
		89  				if ip.Equal(ifa.(*IPNet).IP) {
		90  					ti.teardown()
		91  					t.Fatalf("got %v", ifa)
		92  				}
		93  			}
		94  		}
		95  		if err := ti.teardown(); err != nil {
		96  			t.Fatal(err)
		97  		} else {
		98  			time.Sleep(3 * time.Millisecond)
		99  		}
	 100  	}
	 101  }
	 102  
	 103  func TestInterfaceArrivalAndDeparture(t *testing.T) {
	 104  	if testing.Short() {
	 105  		t.Skip("avoid external network")
	 106  	}
	 107  	if os.Getuid() != 0 {
	 108  		t.Skip("must be root")
	 109  	}
	 110  
	 111  	// We suppose that using IPv4 link-local addresses and the
	 112  	// dot1Q ID for Token Ring and FDDI doesn't harm anyone.
	 113  	local, remote := "169.254.0.1", "169.254.0.254"
	 114  	ip := ParseIP(remote)
	 115  	for _, vid := range []int{1002, 1003, 1004, 1005} {
	 116  		ift1, err := Interfaces()
	 117  		if err != nil {
	 118  			t.Fatal(err)
	 119  		}
	 120  		ti := &testInterface{local: local, remote: remote}
	 121  		if err := ti.setBroadcast(vid); err != nil {
	 122  			t.Skipf("test requires external command: %v", err)
	 123  		}
	 124  		if err := ti.setup(); err != nil {
	 125  			t.Fatal(err)
	 126  		} else {
	 127  			time.Sleep(3 * time.Millisecond)
	 128  		}
	 129  		ift2, err := Interfaces()
	 130  		if err != nil {
	 131  			ti.teardown()
	 132  			t.Fatal(err)
	 133  		}
	 134  		if len(ift2) <= len(ift1) {
	 135  			for _, ifi := range ift1 {
	 136  				t.Logf("before: %v", ifi)
	 137  			}
	 138  			for _, ifi := range ift2 {
	 139  				t.Logf("after: %v", ifi)
	 140  			}
	 141  			ti.teardown()
	 142  			t.Fatalf("got %v; want gt %v", len(ift2), len(ift1))
	 143  		}
	 144  		for _, ifi := range ift2 {
	 145  			if ti.name != ifi.Name {
	 146  				continue
	 147  			}
	 148  			ifat, err := ifi.Addrs()
	 149  			if err != nil {
	 150  				ti.teardown()
	 151  				t.Fatal(err)
	 152  			}
	 153  			for _, ifa := range ifat {
	 154  				if ip.Equal(ifa.(*IPNet).IP) {
	 155  					ti.teardown()
	 156  					t.Fatalf("got %v", ifa)
	 157  				}
	 158  			}
	 159  		}
	 160  		if err := ti.teardown(); err != nil {
	 161  			t.Fatal(err)
	 162  		} else {
	 163  			time.Sleep(3 * time.Millisecond)
	 164  		}
	 165  		ift3, err := Interfaces()
	 166  		if err != nil {
	 167  			t.Fatal(err)
	 168  		}
	 169  		if len(ift3) >= len(ift2) {
	 170  			for _, ifi := range ift2 {
	 171  				t.Logf("before: %v", ifi)
	 172  			}
	 173  			for _, ifi := range ift3 {
	 174  				t.Logf("after: %v", ifi)
	 175  			}
	 176  			t.Fatalf("got %v; want lt %v", len(ift3), len(ift2))
	 177  		}
	 178  	}
	 179  }
	 180  
	 181  func TestInterfaceArrivalAndDepartureZoneCache(t *testing.T) {
	 182  	if testing.Short() {
	 183  		t.Skip("avoid external network")
	 184  	}
	 185  	if os.Getuid() != 0 {
	 186  		t.Skip("must be root")
	 187  	}
	 188  
	 189  	// Ensure zoneCache is filled:
	 190  	_, _ = Listen("tcp", "[fe80::1%nonexistent]:0")
	 191  
	 192  	ti := &testInterface{local: "fe80::1"}
	 193  	if err := ti.setLinkLocal(0); err != nil {
	 194  		t.Skipf("test requires external command: %v", err)
	 195  	}
	 196  	if err := ti.setup(); err != nil {
	 197  		t.Fatal(err)
	 198  	}
	 199  	defer ti.teardown()
	 200  
	 201  	time.Sleep(3 * time.Millisecond)
	 202  
	 203  	// If Listen fails (on Linux with “bind: invalid argument”), zoneCache was
	 204  	// not updated when encountering a nonexistent interface:
	 205  	ln, err := Listen("tcp", "[fe80::1%"+ti.name+"]:0")
	 206  	if err != nil {
	 207  		t.Fatal(err)
	 208  	}
	 209  	ln.Close()
	 210  	if err := ti.teardown(); err != nil {
	 211  		t.Fatal(err)
	 212  	}
	 213  }
	 214  

View as plain text