From 6ad6edefb15c9ffe418e722c13459ab16a545d2b Mon Sep 17 00:00:00 2001 From: Song Gao Date: Sun, 31 Mar 2019 16:21:00 -0700 Subject: [PATCH] test cleanup --- .gitignore | 1 + ipv4_darwin_test.go | 44 +++++--------------- ipv4_linux_test.go | 96 ++++++++++++++++++++++++-------------------- ipv4_test.go | 55 ++++++++++++++++++++++++- ipv4_windows_test.go | 57 ++++++-------------------- 5 files changed, 129 insertions(+), 124 deletions(-) diff --git a/.gitignore b/.gitignore index 367ccba..22268fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ water.test +water.test.exe diff --git a/ipv4_darwin_test.go b/ipv4_darwin_test.go index c419069..2a5d646 100644 --- a/ipv4_darwin_test.go +++ b/ipv4_darwin_test.go @@ -4,13 +4,14 @@ import ( "net" "os/exec" "testing" - "time" - - "github.com/songgao/water/waterutil" ) -func startPing(t *testing.T, dst net.IP) { - if err := exec.Command("ping", "-c", "4", dst.String()).Start(); err != nil { +func startPing(t *testing.T, dst net.IP, dashB bool) { + params := []string{"-c", "4", dst.String()} + if dashB { + params = append([]string{"-b"}, params...) + } + if err := exec.Command("ping", params...).Start(); err != nil { t.Fatal(err) } } @@ -42,37 +43,10 @@ func TestP2PTUN(t *testing.T) { } defer teardownIfce(t, ifce) - dataCh := make(chan []byte) - errCh := make(chan error) - startRead(t, ifce, dataCh, errCh) + dataCh, errCh := startRead(t, ifce) setupIfce(t, self, remote, ifce.Name()) - startPing(t, remote) + startPing(t, remote, false) - timeout := time.NewTimer(8 * time.Second).C - -readFrame: - for { - select { - case packet := <-dataCh: - if !waterutil.IsIPv4(packet) { - continue readFrame - } - if !waterutil.IPv4Source(packet).Equal(self) { - continue readFrame - } - if !waterutil.IPv4Destination(packet).Equal(remote) { - continue readFrame - } - if waterutil.IPv4Protocol(packet) != waterutil.ICMP { - continue readFrame - } - t.Logf("received broadcast packet: %#v\n", packet) - break readFrame - case err := <-errCh: - t.Fatalf("read error: %v", err) - case <-timeout: - t.Fatal("Waiting for broadcast packet timeout") - } - } + waitForPingOrBust(t, false, false, self, remote, dataCh, errCh) } diff --git a/ipv4_linux_test.go b/ipv4_linux_test.go index 0c81f9c..6544809 100644 --- a/ipv4_linux_test.go +++ b/ipv4_linux_test.go @@ -4,13 +4,14 @@ import ( "net" "os/exec" "testing" - "time" - - "github.com/songgao/water/waterutil" ) -func startBroadcast(t *testing.T, dst net.IP) { - if err := exec.Command("ping", "-b", "-c", "4", dst.String()).Start(); err != nil { +func startPing(t *testing.T, dst net.IP, dashB bool) { + params := []string{"-c", "4", dst.String()} + if dashB { + params = append([]string{"-b"}, params...) + } + if err := exec.Command("ping", params...).Start(); err != nil { t.Fatal(err) } } @@ -46,45 +47,52 @@ func TestBroadcastTAP(t *testing.T) { } defer teardownIfce(t, ifce) + dataCh, errCh := startRead(t, ifce) + setupIfce(t, net.IPNet{IP: self, Mask: mask}, ifce.Name()) - startBroadcast(t, brd) + startPing(t, brd, true) - dataCh := make(chan []byte) - errCh := make(chan error) - startRead(t, ifce, dataCh, errCh) - - timeout := time.NewTimer(8 * time.Second).C - -readFrame: - for { - select { - case buffer := <-dataCh: - ethertype := waterutil.MACEthertype(buffer) - if ethertype != waterutil.IPv4 { - continue readFrame - } - if !waterutil.IsBroadcast(waterutil.MACDestination(buffer)) { - continue readFrame - } - packet := waterutil.MACPayload(buffer) - if !waterutil.IsIPv4(packet) { - continue readFrame - } - if !waterutil.IPv4Source(packet).Equal(self) { - continue readFrame - } - if !waterutil.IPv4Destination(packet).Equal(brd) { - continue readFrame - } - if waterutil.IPv4Protocol(packet) != waterutil.ICMP { - continue readFrame - } - t.Logf("received broadcast frame: %#v\n", buffer) - break readFrame - case err := <-errCh: - t.Fatalf("read error: %v", err) - case <-timeout: - t.Fatal("Waiting for broadcast packet timeout") - } - } + waitForPingOrBust(t, true, true, self, brd, dataCh, errCh) +} + +func TestBroadcastTUN(t *testing.T) { + var ( + self = net.IPv4(10, 0, 42, 1) + mask = net.IPv4Mask(255, 255, 255, 0) + brd = net.IPv4(10, 0, 42, 255) + ) + + ifce, err := New(Config{DeviceType: TUN}) + if err != nil { + t.Fatalf("creating TUN error: %v\n", err) + } + defer teardownIfce(t, ifce) + + dataCh, errCh := startRead(t, ifce) + + setupIfce(t, net.IPNet{IP: self, Mask: mask}, ifce.Name()) + startPing(t, brd, true) + + waitForPingOrBust(t, false, true, self, brd, dataCh, errCh) +} + +func TestUnicastTUN(t *testing.T) { + var ( + self = net.IPv4(10, 0, 42, 1) + mask = net.IPv4Mask(255, 255, 255, 0) + remote = net.IPv4(10, 0, 42, 2) + ) + + ifce, err := New(Config{DeviceType: TUN}) + if err != nil { + t.Fatalf("creating TUN error: %v\n", err) + } + defer teardownIfce(t, ifce) + + dataCh, errCh := startRead(t, ifce) + + setupIfce(t, net.IPNet{IP: self, Mask: mask}, ifce.Name()) + startPing(t, remote, false) + + waitForPingOrBust(t, false, false, self, remote, dataCh, errCh) } diff --git a/ipv4_test.go b/ipv4_test.go index c89cc7e..7a8bf1e 100644 --- a/ipv4_test.go +++ b/ipv4_test.go @@ -1,12 +1,18 @@ package water import ( + "net" "testing" + "time" + + "github.com/songgao/water/waterutil" ) const BUFFERSIZE = 1522 -func startRead(t *testing.T, ifce *Interface, dataCh chan<- []byte, errCh chan<- error) { +func startRead(t *testing.T, ifce *Interface) (dataChan <-chan []byte, errChan <-chan error) { + dataCh := make(chan []byte) + errCh := make(chan error) go func() { for { buffer := make([]byte, BUFFERSIZE) @@ -19,4 +25,51 @@ func startRead(t *testing.T, ifce *Interface, dataCh chan<- []byte, errCh chan<- } } }() + return dataCh, errCh +} + +func waitForPingOrBust(t *testing.T, + isTAP bool, + expectBroadcast bool, + expectSrc net.IP, + expectDest net.IP, + dataCh <-chan []byte, errCh <-chan error) { + waitForPintTimeout := time.NewTimer(8 * time.Second).C +readFrame: + for { + select { + case buffer := <-dataCh: + var packet []byte + if isTAP { + ethertype := waterutil.MACEthertype(buffer) + if ethertype != waterutil.IPv4 { + continue readFrame + } + if expectBroadcast && !waterutil.IsBroadcast(waterutil.MACDestination(buffer)) { + continue readFrame + } + packet = waterutil.MACPayload(buffer) + } else { + packet = buffer + } + if !waterutil.IsIPv4(packet) { + continue readFrame + } + if !waterutil.IPv4Source(packet).Equal(expectSrc) { + continue readFrame + } + if !waterutil.IPv4Destination(packet).Equal(expectDest) { + continue readFrame + } + if waterutil.IPv4Protocol(packet) != waterutil.ICMP { + continue readFrame + } + t.Logf("received broadcast frame: %#v\n", buffer) + break readFrame + case err := <-errCh: + t.Fatalf("read error: %v", err) + case <-waitForPintTimeout: + t.Fatal("Waiting for broadcast packet timeout") + } + } } diff --git a/ipv4_windows_test.go b/ipv4_windows_test.go index c5c617a..e45f174 100644 --- a/ipv4_windows_test.go +++ b/ipv4_windows_test.go @@ -6,13 +6,10 @@ import ( "os/exec" "strings" "testing" - "time" - - "github.com/songgao/water/waterutil" ) -func startBroadcast(t *testing.T, dst net.IP) { - if err := exec.Command("ping", "-n", "2", dst.String()).Start(); err != nil { +func startPing(t *testing.T, dst net.IP, _ bool) { + if err := exec.Command("ping", "-n", "4", dst.String()).Start(); err != nil { t.Fatal(err) } } @@ -29,6 +26,12 @@ func setupIfce(t *testing.T, ipNet net.IPNet, dev string) { } } +func teardownIfce(t *testing.T, ifce *Interface) { + if err := ifce.Close(); err != nil { + t.Fatal(err) + } +} + func TestBroadcastTAP(t *testing.T) { var ( self = net.IPv4(10, 0, 42, 1) @@ -40,46 +43,12 @@ func TestBroadcastTAP(t *testing.T) { if err != nil { t.Fatalf("creating TAP error: %v\n", err) } + defer teardownIfce(t, ifce) + + dataCh, errCh := startRead(t, ifce) setupIfce(t, net.IPNet{IP: self, Mask: mask}, ifce.Name()) - startBroadcast(t, brd) + startPing(t, brd, true) - dataCh := make(chan []byte, 8) - errCh := make(chan error) - startRead(t, ifce, dataCh, errCh) - - timeout := time.NewTimer(8 * time.Second).C - -readFrame: - for { - select { - case buffer := <-dataCh: - ethertype := waterutil.MACEthertype(buffer) - if ethertype != waterutil.IPv4 { - continue readFrame - } - if !waterutil.IsBroadcast(waterutil.MACDestination(buffer)) { - continue readFrame - } - packet := waterutil.MACPayload(buffer) - if !waterutil.IsIPv4(packet) { - continue readFrame - } - if !waterutil.IPv4Source(packet).Equal(self) { - continue readFrame - } - if !waterutil.IPv4Destination(packet).Equal(brd) { - continue readFrame - } - if waterutil.IPv4Protocol(packet) != waterutil.ICMP { - continue readFrame - } - t.Logf("received broadcast frame: %#v\n", buffer) - break readFrame - case err := <-errCh: - t.Fatalf("read error: %v", err) - case <-timeout: - t.Fatal("Waiting for broadcast packet timeout") - } - } + waitForPingOrBust(t, true, true, self, brd, dataCh, errCh) }