Refactor HostIP predicate algorithm

- Remove string decode logic. It's not really helping to find the
  conflict ports, and it's expensive to do encoding/decoding
- Not to parse the container ports information in predicate meta, use
  straight []*v1.ContainerPort
- Use better data structure to search port conflict based on ip
  addresses
- Collect scattered source code into common place
This commit is contained in:
Yongkun Anfernee Gui
2017-11-16 15:43:06 -08:00
parent 8a9954d471
commit 68c2c79362
11 changed files with 398 additions and 370 deletions

View File

@@ -93,3 +93,213 @@ func TestSortableList(t *testing.T) {
}
}
}
type hostPortInfoParam struct {
protocol, ip string
port int32
}
func TestHostPortInfo_AddRemove(t *testing.T) {
tests := []struct {
desc string
added []hostPortInfoParam
removed []hostPortInfoParam
length int
}{
{
desc: "normal add case",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 79},
{"UDP", "127.0.0.1", 80},
{"TCP", "127.0.0.1", 81},
{"TCP", "127.0.0.1", 82},
// this might not make sense in real case, but the struct doesn't forbid it.
{"TCP", "0.0.0.0", 79},
{"UDP", "0.0.0.0", 80},
{"TCP", "0.0.0.0", 81},
{"TCP", "0.0.0.0", 82},
{"TCP", "0.0.0.0", 0},
{"TCP", "0.0.0.0", -1},
},
length: 8,
},
{
desc: "empty ip and protocol add should work",
added: []hostPortInfoParam{
{"", "127.0.0.1", 79},
{"UDP", "127.0.0.1", 80},
{"", "127.0.0.1", 81},
{"", "127.0.0.1", 82},
{"", "", 79},
{"UDP", "", 80},
{"", "", 81},
{"", "", 82},
{"", "", 0},
{"", "", -1},
},
length: 8,
},
{
desc: "normal remove case",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 79},
{"UDP", "127.0.0.1", 80},
{"TCP", "127.0.0.1", 81},
{"TCP", "127.0.0.1", 82},
{"TCP", "0.0.0.0", 79},
{"UDP", "0.0.0.0", 80},
{"TCP", "0.0.0.0", 81},
{"TCP", "0.0.0.0", 82},
},
removed: []hostPortInfoParam{
{"TCP", "127.0.0.1", 79},
{"UDP", "127.0.0.1", 80},
{"TCP", "127.0.0.1", 81},
{"TCP", "127.0.0.1", 82},
{"TCP", "0.0.0.0", 79},
{"UDP", "0.0.0.0", 80},
{"TCP", "0.0.0.0", 81},
{"TCP", "0.0.0.0", 82},
},
length: 0,
},
{
desc: "empty ip and protocol remove should work",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 79},
{"UDP", "127.0.0.1", 80},
{"TCP", "127.0.0.1", 81},
{"TCP", "127.0.0.1", 82},
{"TCP", "0.0.0.0", 79},
{"UDP", "0.0.0.0", 80},
{"TCP", "0.0.0.0", 81},
{"TCP", "0.0.0.0", 82},
},
removed: []hostPortInfoParam{
{"", "127.0.0.1", 79},
{"", "127.0.0.1", 81},
{"", "127.0.0.1", 82},
{"UDP", "127.0.0.1", 80},
{"", "", 79},
{"", "", 81},
{"", "", 82},
{"UDP", "", 80},
},
length: 0,
},
}
for _, test := range tests {
hp := make(HostPortInfo)
for _, param := range test.added {
hp.Add(param.ip, param.protocol, param.port)
}
for _, param := range test.removed {
hp.Remove(param.ip, param.protocol, param.port)
}
if hp.Len() != test.length {
t.Errorf("%v failed: expect length %d; got %d", test.desc, test.length, hp.Len())
t.Error(hp)
}
}
}
func TestHostPortInfo_Check(t *testing.T) {
tests := []struct {
desc string
added []hostPortInfoParam
check hostPortInfoParam
expect bool
}{
{
desc: "empty check should check 0.0.0.0 and TCP",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 80},
},
check: hostPortInfoParam{"", "", 81},
expect: false,
},
{
desc: "empty check should check 0.0.0.0 and TCP (conflicted)",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 80},
},
check: hostPortInfoParam{"", "", 80},
expect: true,
},
{
desc: "empty port check should pass",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 80},
},
check: hostPortInfoParam{"", "", 0},
expect: false,
},
{
desc: "0.0.0.0 should check all registered IPs",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 80},
},
check: hostPortInfoParam{"TCP", "0.0.0.0", 80},
expect: true,
},
{
desc: "0.0.0.0 with different protocol should be allowed",
added: []hostPortInfoParam{
{"UDP", "127.0.0.1", 80},
},
check: hostPortInfoParam{"TCP", "0.0.0.0", 80},
expect: false,
},
{
desc: "0.0.0.0 with different port should be allowed",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 79},
{"TCP", "127.0.0.1", 81},
{"TCP", "127.0.0.1", 82},
},
check: hostPortInfoParam{"TCP", "0.0.0.0", 80},
expect: false,
},
{
desc: "normal ip should check all registered 0.0.0.0",
added: []hostPortInfoParam{
{"TCP", "0.0.0.0", 80},
},
check: hostPortInfoParam{"TCP", "127.0.0.1", 80},
expect: true,
},
{
desc: "normal ip with different port/protocol should be allowed (0.0.0.0)",
added: []hostPortInfoParam{
{"TCP", "0.0.0.0", 79},
{"UDP", "0.0.0.0", 80},
{"TCP", "0.0.0.0", 81},
{"TCP", "0.0.0.0", 82},
},
check: hostPortInfoParam{"TCP", "127.0.0.1", 80},
expect: false,
},
{
desc: "normal ip with different port/protocol should be allowed",
added: []hostPortInfoParam{
{"TCP", "127.0.0.1", 79},
{"UDP", "127.0.0.1", 80},
{"TCP", "127.0.0.1", 81},
{"TCP", "127.0.0.1", 82},
},
check: hostPortInfoParam{"TCP", "127.0.0.1", 80},
expect: false,
},
}
for _, test := range tests {
hp := make(HostPortInfo)
for _, param := range test.added {
hp.Add(param.ip, param.protocol, param.port)
}
if hp.CheckConflict(test.check.ip, test.check.protocol, test.check.port) != test.expect {
t.Errorf("%v failed, expected %t; got %t", test.desc, test.expect, !test.expect)
}
}
}