mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-16 20:11:09 +00:00
126 lines
2.9 KiB
Go
126 lines
2.9 KiB
Go
package sniff_test
|
|
|
|
import (
|
|
"io"
|
|
"net"
|
|
"reflect"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/gopacket"
|
|
|
|
"github.com/weaveworks/scope/probe/sniff"
|
|
"github.com/weaveworks/scope/report"
|
|
"github.com/weaveworks/scope/test"
|
|
)
|
|
|
|
func TestSnifferShutdown(t *testing.T) {
|
|
var (
|
|
hostID = "abcd"
|
|
src = newMockSource([]byte{}, nil)
|
|
on = time.Millisecond
|
|
off = time.Millisecond
|
|
s = sniff.New(hostID, report.Networks{}, src, on, off)
|
|
)
|
|
|
|
// Stopping the source should terminate the sniffer.
|
|
src.Close()
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
// Try to get a report from the sniffer. It should block forever, as the
|
|
// loop goroutine should have exited.
|
|
report := make(chan struct{})
|
|
go func() { _, _ = s.Report(); close(report) }()
|
|
select {
|
|
case <-time.After(time.Millisecond):
|
|
case <-report:
|
|
t.Errorf("shouldn't get report after Close")
|
|
}
|
|
}
|
|
|
|
func TestMerge(t *testing.T) {
|
|
var (
|
|
hostID = "xyz"
|
|
src = newMockSource([]byte{}, nil)
|
|
on = time.Millisecond
|
|
off = time.Millisecond
|
|
rpt = report.MakeReport()
|
|
p = sniff.Packet{
|
|
SrcIP: "1.0.0.0",
|
|
SrcPort: "1000",
|
|
DstIP: "2.0.0.0",
|
|
DstPort: "2000",
|
|
Network: 512,
|
|
Transport: 256,
|
|
}
|
|
|
|
_, ipnet, _ = net.ParseCIDR(p.SrcIP + "/24") // ;)
|
|
localNets = report.Networks([]*net.IPNet{ipnet})
|
|
)
|
|
sniff.New(hostID, localNets, src, on, off).Merge(p, &rpt)
|
|
|
|
var (
|
|
srcEndpointNodeID = report.MakeEndpointNodeID(hostID, p.SrcIP, p.SrcPort)
|
|
dstEndpointNodeID = report.MakeEndpointNodeID(hostID, p.DstIP, p.DstPort)
|
|
)
|
|
if want, have := (report.Topology{
|
|
Nodes: report.Nodes{
|
|
srcEndpointNodeID: report.MakeNode().WithEdge(dstEndpointNodeID, report.EdgeMetadata{
|
|
EgressPacketCount: newu64(1),
|
|
EgressByteCount: newu64(256),
|
|
}),
|
|
dstEndpointNodeID: report.MakeNode(),
|
|
},
|
|
}), rpt.Endpoint; !reflect.DeepEqual(want, have) {
|
|
t.Errorf("%s", test.Diff(want, have))
|
|
}
|
|
|
|
var (
|
|
srcAddressNodeID = report.MakeAddressNodeID(hostID, p.SrcIP)
|
|
dstAddressNodeID = report.MakeAddressNodeID(hostID, p.DstIP)
|
|
)
|
|
if want, have := (report.Topology{
|
|
Nodes: report.Nodes{
|
|
srcAddressNodeID: report.MakeNode().WithEdge(dstAddressNodeID, report.EdgeMetadata{
|
|
EgressPacketCount: newu64(1),
|
|
EgressByteCount: newu64(512),
|
|
}),
|
|
dstAddressNodeID: report.MakeNode(),
|
|
},
|
|
}), rpt.Address; !reflect.DeepEqual(want, have) {
|
|
t.Errorf("%s", test.Diff(want, have))
|
|
}
|
|
}
|
|
|
|
type mockSource struct {
|
|
mtx sync.RWMutex
|
|
data []byte
|
|
err error
|
|
}
|
|
|
|
func newMockSource(data []byte, err error) *mockSource {
|
|
return &mockSource{
|
|
data: data,
|
|
err: err,
|
|
}
|
|
}
|
|
|
|
func (s *mockSource) ZeroCopyReadPacketData() ([]byte, gopacket.CaptureInfo, error) {
|
|
s.mtx.RLock()
|
|
defer s.mtx.RUnlock()
|
|
return s.data, gopacket.CaptureInfo{
|
|
Timestamp: time.Now(),
|
|
CaptureLength: len(s.data),
|
|
Length: len(s.data),
|
|
}, s.err
|
|
}
|
|
|
|
func (s *mockSource) Close() {
|
|
s.mtx.Lock()
|
|
defer s.mtx.Unlock()
|
|
s.err = io.EOF
|
|
}
|
|
|
|
func newu64(value uint64) *uint64 { return &value }
|