Files
weave-scope/probe/endpoint/conntrack_test.go
2015-08-28 09:19:56 +00:00

144 lines
2.9 KiB
Go

package endpoint_test
import (
"bufio"
"encoding/xml"
"io"
"testing"
"time"
"github.com/weaveworks/scope/common/exec"
. "github.com/weaveworks/scope/probe/endpoint"
"github.com/weaveworks/scope/test"
testExec "github.com/weaveworks/scope/test/exec"
)
func makeFlow(id int64, srcIP, dstIP string, srcPort, dstPort int, ty, state string) Flow {
return Flow{
XMLName: xml.Name{
Local: "flow",
},
Type: ty,
Metas: []Meta{
{
XMLName: xml.Name{
Local: "meta",
},
Direction: "original",
Layer3: Layer3{
XMLName: xml.Name{
Local: "layer3",
},
SrcIP: srcIP,
DstIP: dstIP,
},
Layer4: Layer4{
XMLName: xml.Name{
Local: "layer4",
},
SrcPort: srcPort,
DstPort: dstPort,
Proto: TCP,
},
},
{
XMLName: xml.Name{
Local: "meta",
},
Direction: "independent",
ID: id,
State: state,
Layer3: Layer3{
XMLName: xml.Name{
Local: "layer3",
},
},
Layer4: Layer4{
XMLName: xml.Name{
Local: "layer4",
},
},
},
},
}
}
func TestConntracker(t *testing.T) {
oldExecCmd, oldConntrackPresent := exec.Command, ConntrackModulePresent
defer func() { exec.Command, ConntrackModulePresent = oldExecCmd, oldConntrackPresent }()
ConntrackModulePresent = func() bool {
return true
}
reader, writer := io.Pipe()
exec.Command = func(name string, args ...string) exec.Cmd {
return testExec.NewMockCmd(reader)
}
conntracker, err := NewConntracker()
if err != nil {
t.Fatal(err)
}
bw := bufio.NewWriter(writer)
if _, err := bw.WriteString(XMLHeader); err != nil {
t.Fatal(err)
}
if _, err := bw.WriteString(ConntrackOpenTag); err != nil {
t.Fatal(err)
}
if err := bw.Flush(); err != nil {
t.Fatal(err)
}
have := func() interface{} {
result := []Flow{}
conntracker.WalkFlows(func(f Flow) {
f.Original = nil
f.Reply = nil
f.Independent = nil
result = append(result, f)
})
return result
}
ts := 100 * time.Millisecond
// First, assert we have no flows
test.Poll(t, ts, []Flow{}, have)
// Now add some flows
xmlEncoder := xml.NewEncoder(bw)
writeFlow := func(f Flow) {
if err := xmlEncoder.Encode(f); err != nil {
t.Fatal(err)
}
if _, err := bw.WriteString("\n"); err != nil {
t.Fatal(err)
}
if err := bw.Flush(); err != nil {
t.Fatal(err)
}
}
flow1 := makeFlow(1, "1.2.3.4", "2.3.4.5", 2, 3, New, "")
writeFlow(flow1)
test.Poll(t, ts, []Flow{flow1}, have)
// Now check when we remove the flow, we still get it in the next Walk
flow1.Type = Destroy
writeFlow(flow1)
test.Poll(t, ts, []Flow{flow1}, have)
test.Poll(t, ts, []Flow{}, have)
// This time we're not going to remove it, but put it in state TIME_WAIT
flow1.Type = New
writeFlow(flow1)
test.Poll(t, ts, []Flow{flow1}, have)
flow1.Metas[1].State = TimeWait
writeFlow(flow1)
test.Poll(t, ts, []Flow{flow1}, have)
test.Poll(t, ts, []Flow{}, have)
}