func TestPingerSetDF(t *testing.T) { if skipRawSocketTests() { t.Skip("Test skipped due to non-root") } pinger := &Pinger{ DF: true, Size: 1800, } pinger.AddIPs([]string{"8.8.8.8"}) res, err := pinger.Start() require.NoError(t, err) require.NotNil(t, res) go func() { for pr := range res { glog.Debugf("%v", pr) } }() select { case <-time.Tick(time.Duration(len(pinger.IPs())) * time.Second): } pinger.Stop() }
func TestPingerStartMultiple(t *testing.T) { if skipRawSocketTests() { t.Skip("Test skipped due to non-root") } pinger := &Pinger{} pinger.AddIPs([]string{"127.0.0.1"}) for i := 0; i < 5; i++ { done := make(chan struct{}) cnt := 0 res, err := pinger.Start() require.NoError(t, err) require.NotNil(t, res) go func() { for pr := range res { glog.Debugf("%v", pr) cnt++ } close(done) }() select { case <-time.Tick(time.Duration(len(pinger.IPs())) * time.Second): require.FailNow(t, "Test timed out") case <-done: require.Equal(t, len(pinger.IPs()), cnt) } pinger.Stop() } }
func TestPingerPing(t *testing.T) { if skipRawSocketTests() { t.Skip("Test skipped due to non-root") } pr, err := Ping("127.0.0.1") require.NoError(t, err) glog.Debugf("%v", pr) }
func TestParseIPv4Success(t *testing.T) { for i, ip := range ips { glog.Debugf("Parsing %d %s", i, ip) res, err := ParseIP(ip) require.NoError(t, err) m := make(map[[4]byte]bool) for _, ip2 := range res { var tmp [4]byte copy(tmp[:], ip2.To4()) m[tmp] = true } require.Equal(t, results[i], m) } }
func TestEnglishVocOutput(t *testing.T) { inscan, infile := openFile("voc.txt") outscan, outfile := openFile("output.txt") defer infile.Close() defer outfile.Close() for inscan.Scan() { if !outscan.Scan() { break } word := inscan.Text() expect := outscan.Text() //glog.Debugf("word=%q, expect=%q", word, expect) actual := Stem(word) if actual != expect { glog.Debugf("word=%q, actual=%q != expect=%q", word, actual, expect) } assert.Equal(t, expect, actual) } }
func (this *Pinger) sendMessage(m *icmp.Message, wh *ipv4.Header) error { select { case <-this.done: return nil default: } var ( wb []byte tempDelay time.Duration // how long to sleep on accept failure ticker = time.NewTicker(this.Interval) ) for i, dst := range this.IPs() { if i != 0 { <-ticker.C } binary.BigEndian.PutUint64(this.payload, uint64(time.Now().UnixNano())) wb, err := this.marshalMessage(m, wb) if err != nil { glog.Errorf("Error creating ICMP payload: %v", err) continue } wh.TotalLen = ipv4.HeaderLen + len(wb) wh.Dst = dst glog.Debugf("Pinging %s", wh.Dst) this.mu.Lock() this.results[wh.Dst.String()] = nil this.mu.Unlock() if err := this.rconn.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { return err } if err := this.rconn.WriteTo(wh, wb, nil); err != nil { select { case <-this.done: return nil default: } // Borrowed from go1.3.3/src/pkg/net/http/server.go:1699 if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } glog.Errorf("write error: %v; retrying in %v", err, tempDelay) time.Sleep(tempDelay) continue // out of the IP list, wait for next tick } return err } } if err := this.rconn.SetReadDeadline(time.Now().Add(this.MaxRTT)); err != nil { return err } return nil }
func (this *Pinger) receiver() { defer func() { // Let's recover from panic if r := recover(); r != nil { glog.Errorf("Recovering from panic: %v", r) } this.wg.Done() close(this.reschan) this.Stop() }() rb := make([]byte, ipv4.HeaderLen+icmpHeaderSize+this.Size) var tempDelay time.Duration // how long to sleep on accept failure loop: for { rh, b, _, err := this.rconn.ReadFrom(rb) if err != nil { select { case <-this.done: break loop default: } // Borrowed from go1.3.3/src/pkg/net/http/server.go:1699 if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := this.MaxRTT; tempDelay > max { tempDelay = max } glog.Errorf("Accept error: %v; retrying in %v", err, tempDelay) time.Sleep(tempDelay) continue } break loop } m, err := icmp.ParseMessage(ProtocolICMP, b) if err != nil { // Hm...bad message? continue } if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho { // On Linux we must handle own sent packets. continue } if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 { glog.Errorf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) continue } // Echo Reply er, ok := m.Body.(*icmp.Echo) if !ok { glog.Errorf("Error type requireing m.Body to *icmp.Echo") continue } if er.ID != int(this.pid) || er.Seq > int(this.seqnum) { glog.Debugf("%d != %d, %d != %d", er.ID, this.pid, er.Seq, this.seqnum) continue } rtt := time.Since(time.Unix(0, int64(binary.BigEndian.Uint64(er.Data)))) src := make(net.IP, len(rh.Src)) copy(src, rh.Src) dst := make(net.IP, len(rh.Dst)) copy(dst, rh.Dst) pr := &PingResult{ TOS: rh.TOS, TTL: rh.TTL, Type: m.Type, Code: m.Code, ID: er.ID, Seq: er.Seq, RTT: rtt, Src: src, Dst: dst, Size: len(er.Data), } this.mu.Lock() this.results[src.String()] = pr this.mu.Unlock() this.reschan <- pr } for ip, pr := range this.results { if pr == nil { this.reschan <- &PingResult{ Src: net.ParseIP(ip), ID: int(this.pid), Seq: int(this.seqnum), Err: fmt.Errorf("%s: Request timed out for seq %d", ip, this.seqnum), } } } }