From e33cfb8ae7ed4ebbfd07bad9d9994f466c6f4b2e Mon Sep 17 00:00:00 2001 From: Cam Date: Fri, 31 May 2019 13:52:36 -0700 Subject: [PATCH] Add processPacket unit tests Add vet and unit test to circleci job --- .circleci/config.yml | 4 +- ping_test.go | 227 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index aa9c855..e156fe4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2.0 jobs: build: docker: - - image: circleci/golang:1.11 + - image: circleci/golang:1.12 working_directory: /go/src/github.com/sparrc/go-ping steps: - checkout @@ -10,6 +10,8 @@ jobs: name: Build and run some basic tests command: | go get ./... + go vet ./... + go test ./... -cover -race go build -race -o ping_linux ./cmd/ping/ping.go sudo ./ping_linux --privileged -c 2 www.google.com sudo ./ping_linux --privileged -c 3 -i 200ms www.google.com diff --git a/ping_test.go b/ping_test.go index 45d5b0a..a337450 100644 --- a/ping_test.go +++ b/ping_test.go @@ -11,6 +11,220 @@ import ( "golang.org/x/net/ipv4" ) +func TestProcessPacket(t *testing.T) { + pinger := makeTestPinger() + shouldBe1 := 0 + // this function should be called + pinger.OnRecv = func(pkt *Packet) { + shouldBe1++ + } + + data := append(timeToBytes(time.Now()), intToBytes(pinger.Tracker)...) + if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 { + data = append(data, bytes.Repeat([]byte{1}, remainSize)...) + } + + body := &icmp.Echo{ + ID: pinger.id, + Seq: pinger.sequence, + Data: data, + } + + msg := &icmp.Message{ + Type: ipv4.ICMPTypeEchoReply, + Code: 0, + Body: body, + } + + msgBytes, _ := msg.Marshal(nil) + + pkt := packet{ + nbytes: len(msgBytes), + bytes: msgBytes, + ttl: 24, + } + + err := pinger.processPacket(&pkt) + AssertNoError(t, err) + AssertTrue(t, shouldBe1 == 1) +} + +func TestProcessPacket_IgnoreNonEchoReplies(t *testing.T) { + pinger := makeTestPinger() + shouldBe0 := 0 + // this function should not be called because the tracker is mismatched + pinger.OnRecv = func(pkt *Packet) { + shouldBe0++ + } + + data := append(timeToBytes(time.Now()), intToBytes(pinger.Tracker)...) + if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 { + data = append(data, bytes.Repeat([]byte{1}, remainSize)...) + } + + body := &icmp.Echo{ + ID: pinger.id, + Seq: pinger.sequence, + Data: data, + } + + msg := &icmp.Message{ + Type: ipv4.ICMPTypeDestinationUnreachable, + Code: 0, + Body: body, + } + + msgBytes, _ := msg.Marshal(nil) + + pkt := packet{ + nbytes: len(msgBytes), + bytes: msgBytes, + ttl: 24, + } + + err := pinger.processPacket(&pkt) + AssertNoError(t, err) + AssertTrue(t, shouldBe0 == 0) +} + +func TestProcessPacket_IDMismatch(t *testing.T) { + pinger := makeTestPinger() + pinger.network = "ip" // ID is only checked on "ip" network + shouldBe0 := 0 + // this function should not be called because the tracker is mismatched + pinger.OnRecv = func(pkt *Packet) { + shouldBe0++ + } + + data := append(timeToBytes(time.Now()), intToBytes(pinger.Tracker)...) + if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 { + data = append(data, bytes.Repeat([]byte{1}, remainSize)...) + } + + body := &icmp.Echo{ + ID: 999999, + Seq: pinger.sequence, + Data: data, + } + + msg := &icmp.Message{ + Type: ipv4.ICMPTypeEchoReply, + Code: 0, + Body: body, + } + + msgBytes, _ := msg.Marshal(nil) + + pkt := packet{ + nbytes: len(msgBytes), + bytes: msgBytes, + ttl: 24, + } + + err := pinger.processPacket(&pkt) + AssertNoError(t, err) + AssertTrue(t, shouldBe0 == 0) +} + +func TestProcessPacket_TrackerMismatch(t *testing.T) { + pinger := makeTestPinger() + shouldBe0 := 0 + // this function should not be called because the tracker is mismatched + pinger.OnRecv = func(pkt *Packet) { + shouldBe0++ + } + + data := append(timeToBytes(time.Now()), intToBytes(999)...) + if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 { + data = append(data, bytes.Repeat([]byte{1}, remainSize)...) + } + + body := &icmp.Echo{ + ID: pinger.id, + Seq: pinger.sequence, + Data: data, + } + + msg := &icmp.Message{ + Type: ipv4.ICMPTypeEchoReply, + Code: 0, + Body: body, + } + + msgBytes, _ := msg.Marshal(nil) + + pkt := packet{ + nbytes: len(msgBytes), + bytes: msgBytes, + ttl: 24, + } + + err := pinger.processPacket(&pkt) + AssertNoError(t, err) + AssertTrue(t, shouldBe0 == 0) +} + +func TestProcessPacket_LargePacket(t *testing.T) { + pinger := makeTestPinger() + pinger.Size = 4096 + + data := append(timeToBytes(time.Now()), intToBytes(pinger.Tracker)...) + if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 { + data = append(data, bytes.Repeat([]byte{1}, remainSize)...) + } + + body := &icmp.Echo{ + ID: pinger.id, + Seq: pinger.sequence, + Data: data, + } + + msg := &icmp.Message{ + Type: ipv4.ICMPTypeEchoReply, + Code: 0, + Body: body, + } + + msgBytes, _ := msg.Marshal(nil) + + pkt := packet{ + nbytes: len(msgBytes), + bytes: msgBytes, + ttl: 24, + } + + err := pinger.processPacket(&pkt) + AssertNoError(t, err) +} + +func TestProcessPacket_PacketTooSmall(t *testing.T) { + pinger := makeTestPinger() + data := []byte("foo") + + body := &icmp.Echo{ + ID: pinger.id, + Seq: pinger.sequence, + Data: data, + } + + msg := &icmp.Message{ + Type: ipv4.ICMPTypeEchoReply, + Code: 0, + Body: body, + } + + msgBytes, _ := msg.Marshal(nil) + + pkt := packet{ + nbytes: len(msgBytes), + bytes: msgBytes, + ttl: 24, + } + + err := pinger.processPacket(&pkt) + AssertError(t, err, "") +} + func TestNewPingerValid(t *testing.T) { p, err := NewPinger("www.google.com") AssertNoError(t, err) @@ -229,6 +443,19 @@ func TestStatisticsLossy(t *testing.T) { } // Test helpers +func makeTestPinger() *Pinger { + pinger, _ := NewPinger("127.0.0.1") + + pinger.ipv4 = true + pinger.addr = "127.0.0.1" + pinger.network = "ip" + pinger.id = 123 + pinger.Tracker = 456 + pinger.Size = 0 + + return pinger +} + func AssertNoError(t *testing.T, err error) { if err != nil { t.Errorf("Expected No Error but got %s, Stack:\n%s",