Home | History | Annotate | Download | only in 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 // +build darwin dragonfly freebsd linux netbsd openbsd
      6 
      7 package net
      8 
      9 import (
     10 	"os"
     11 	"os/exec"
     12 	"runtime"
     13 	"testing"
     14 	"time"
     15 )
     16 
     17 type testInterface struct {
     18 	name         string
     19 	local        string
     20 	remote       string
     21 	setupCmds    []*exec.Cmd
     22 	teardownCmds []*exec.Cmd
     23 }
     24 
     25 func (ti *testInterface) setup() error {
     26 	for _, cmd := range ti.setupCmds {
     27 		if err := cmd.Run(); err != nil {
     28 			return err
     29 		}
     30 	}
     31 	return nil
     32 }
     33 
     34 func (ti *testInterface) teardown() error {
     35 	for _, cmd := range ti.teardownCmds {
     36 		if err := cmd.Run(); err != nil {
     37 			return err
     38 		}
     39 	}
     40 	return nil
     41 }
     42 
     43 func TestPointToPointInterface(t *testing.T) {
     44 	if testing.Short() {
     45 		t.Skip("avoid external network")
     46 	}
     47 	if runtime.GOOS == "darwin" {
     48 		t.Skipf("not supported on %s", runtime.GOOS)
     49 	}
     50 	if os.Getuid() != 0 {
     51 		t.Skip("must be root")
     52 	}
     53 
     54 	local, remote := "169.254.0.1", "169.254.0.254"
     55 	ip := ParseIP(remote)
     56 	for i := 0; i < 3; i++ {
     57 		ti := &testInterface{local: local, remote: remote}
     58 		if err := ti.setPointToPoint(5963 + i); err != nil {
     59 			t.Skipf("test requries external command: %v", err)
     60 		}
     61 		if err := ti.setup(); err != nil {
     62 			t.Fatal(err)
     63 		} else {
     64 			time.Sleep(3 * time.Millisecond)
     65 		}
     66 		ift, err := Interfaces()
     67 		if err != nil {
     68 			ti.teardown()
     69 			t.Fatal(err)
     70 		}
     71 		for _, ifi := range ift {
     72 			if ti.name != ifi.Name {
     73 				continue
     74 			}
     75 			ifat, err := ifi.Addrs()
     76 			if err != nil {
     77 				ti.teardown()
     78 				t.Fatal(err)
     79 			}
     80 			for _, ifa := range ifat {
     81 				if ip.Equal(ifa.(*IPNet).IP) {
     82 					ti.teardown()
     83 					t.Fatalf("got %v", ifa)
     84 				}
     85 			}
     86 		}
     87 		if err := ti.teardown(); err != nil {
     88 			t.Fatal(err)
     89 		} else {
     90 			time.Sleep(3 * time.Millisecond)
     91 		}
     92 	}
     93 }
     94 
     95 func TestInterfaceArrivalAndDeparture(t *testing.T) {
     96 	if testing.Short() {
     97 		t.Skip("avoid external network")
     98 	}
     99 	if os.Getuid() != 0 {
    100 		t.Skip("must be root")
    101 	}
    102 
    103 	local, remote := "169.254.0.1", "169.254.0.254"
    104 	ip := ParseIP(remote)
    105 	for i := 0; i < 3; i++ {
    106 		ift1, err := Interfaces()
    107 		if err != nil {
    108 			t.Fatal(err)
    109 		}
    110 		ti := &testInterface{local: local, remote: remote}
    111 		if err := ti.setBroadcast(5682 + i); err != nil {
    112 			t.Skipf("test requires external command: %v", err)
    113 		}
    114 		if err := ti.setup(); err != nil {
    115 			t.Fatal(err)
    116 		} else {
    117 			time.Sleep(3 * time.Millisecond)
    118 		}
    119 		ift2, err := Interfaces()
    120 		if err != nil {
    121 			ti.teardown()
    122 			t.Fatal(err)
    123 		}
    124 		if len(ift2) <= len(ift1) {
    125 			for _, ifi := range ift1 {
    126 				t.Logf("before: %v", ifi)
    127 			}
    128 			for _, ifi := range ift2 {
    129 				t.Logf("after: %v", ifi)
    130 			}
    131 			ti.teardown()
    132 			t.Fatalf("got %v; want gt %v", len(ift2), len(ift1))
    133 		}
    134 		for _, ifi := range ift2 {
    135 			if ti.name != ifi.Name {
    136 				continue
    137 			}
    138 			ifat, err := ifi.Addrs()
    139 			if err != nil {
    140 				ti.teardown()
    141 				t.Fatal(err)
    142 			}
    143 			for _, ifa := range ifat {
    144 				if ip.Equal(ifa.(*IPNet).IP) {
    145 					ti.teardown()
    146 					t.Fatalf("got %v", ifa)
    147 				}
    148 			}
    149 		}
    150 		if err := ti.teardown(); err != nil {
    151 			t.Fatal(err)
    152 		} else {
    153 			time.Sleep(3 * time.Millisecond)
    154 		}
    155 		ift3, err := Interfaces()
    156 		if err != nil {
    157 			t.Fatal(err)
    158 		}
    159 		if len(ift3) >= len(ift2) {
    160 			for _, ifi := range ift2 {
    161 				t.Logf("before: %v", ifi)
    162 			}
    163 			for _, ifi := range ift3 {
    164 				t.Logf("after: %v", ifi)
    165 			}
    166 			t.Fatalf("got %v; want lt %v", len(ift3), len(ift2))
    167 		}
    168 	}
    169 }
    170