[VOL-1035] Flow decomposition tests and code cleanup
Change-Id: Ie739160772e515721ab45a4bcffbb9ce7764b2e3
diff --git a/rw_core/flow_decomposition/flow_decomposer_test.go b/rw_core/flow_decomposition/flow_decomposer_test.go
index b2ba777..6c7d7fa 100644
--- a/rw_core/flow_decomposition/flow_decomposer_test.go
+++ b/rw_core/flow_decomposition/flow_decomposer_test.go
@@ -27,15 +27,10 @@
"testing"
)
-const (
- maxOnuOnPort4 int = 1
- maxOnuOnPort5 int = 1
-)
-
func init() {
- log.AddPackage(log.JSON, log.DebugLevel, nil)
+ log.AddPackage(log.JSON, log.WarnLevel, nil)
log.UpdateAllLoggers(log.Fields{"instanceId": "flow-descomposition"})
- log.SetAllLogLevel(log.DebugLevel)
+ log.SetAllLogLevel(log.WarnLevel)
}
type testDeviceManager struct {
@@ -50,8 +45,8 @@
Root: true,
ParentId: "logical_device",
Ports: []*voltha.Port{
- &voltha.Port{PortNo: 1, Label: "pon"},
- &voltha.Port{PortNo: 2, Label: "nni"},
+ {PortNo: 1, Label: "pon"},
+ {PortNo: 2, Label: "nni"},
},
}
tdm.devices["onu1"] = &voltha.Device{
@@ -59,8 +54,8 @@
Root: false,
ParentId: "olt",
Ports: []*voltha.Port{
- &voltha.Port{PortNo: 1, Label: "pon"},
- &voltha.Port{PortNo: 2, Label: "uni"},
+ {PortNo: 1, Label: "pon"},
+ {PortNo: 2, Label: "uni"},
},
}
tdm.devices["onu2"] = &voltha.Device{
@@ -68,8 +63,8 @@
Root: false,
ParentId: "olt",
Ports: []*voltha.Port{
- &voltha.Port{PortNo: 1, Label: "pon"},
- &voltha.Port{PortNo: 2, Label: "uni"},
+ {PortNo: 1, Label: "pon"},
+ {PortNo: 2, Label: "uni"},
},
}
tdm.devices["onu3"] = &voltha.Device{
@@ -77,8 +72,8 @@
Root: false,
ParentId: "olt",
Ports: []*voltha.Port{
- &voltha.Port{PortNo: 1, Label: "pon"},
- &voltha.Port{PortNo: 2, Label: "uni"},
+ {PortNo: 1, Label: "pon"},
+ {PortNo: 2, Label: "uni"},
},
}
tdm.devices["onu4"] = &voltha.Device{
@@ -86,8 +81,8 @@
Root: false,
ParentId: "olt",
Ports: []*voltha.Port{
- &voltha.Port{PortNo: 1, Label: "pon"},
- &voltha.Port{PortNo: 2, Label: "uni"},
+ {PortNo: 1, Label: "pon"},
+ {PortNo: 2, Label: "uni"},
},
}
return &tdm
@@ -97,7 +92,7 @@
if d, ok := tdm.devices[deviceId]; ok {
return d, nil
}
- return nil, errors.New("Absent")
+ return nil, errors.New("ABSENT.")
}
type testFlowDecomposer struct {
@@ -127,12 +122,12 @@
//DOWNSTREAM ROUTES
tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 1}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "onu1",
Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
@@ -140,36 +135,36 @@
}
tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 2}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "onu2",
Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 3}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "onu3",
Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 4}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "onu4",
Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
@@ -179,48 +174,48 @@
//UPSTREAM DATA PLANE
tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 10}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu1",
Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 10}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu2",
Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 10}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu3",
Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 10}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu4",
Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
@@ -231,48 +226,48 @@
// openflow port 0 means absence of a port - go/protobuf interpretation
tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 0}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu1",
Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 0}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu2",
Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 0}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu3",
Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
},
}
tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 0}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "onu4",
Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
},
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
@@ -282,17 +277,17 @@
// DOWNSTREAM NEXT TABLE BASED
tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 0}] = []graph.RouteHop{
- graph.RouteHop{
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
},
- graph.RouteHop{}, // 2nd hop is not known yet
+ {}, // 2nd hop is not known yet
}
tfd.routes[graph.OFPortLink{Ingress: 0, Egress: 10}] = []graph.RouteHop{
- graph.RouteHop{}, // 1st hop is wildcard
- graph.RouteHop{
+ {}, // 1st hop is wildcard
+ {
DeviceID: "olt",
Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
@@ -395,7 +390,7 @@
if len(excludePort) == 1 {
exclPort = excludePort[0]
}
- for portno, _ := range tfd.logicalPorts {
+ for portno := range tfd.logicalPorts {
if portno != exclPort {
lPorts = append(lPorts, portno)
}
@@ -445,9 +440,9 @@
groups := ofp.FlowGroups{}
tfd := newTestFlowDecomposer(newTestDeviceManager())
- device_rules := tfd.fd.DecomposeRules(tfd, flows, groups)
- onu1FlowAndGroup := device_rules.Rules["onu1"]
- oltFlowAndGroup := device_rules.Rules["olt"]
+ deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
+ onu1FlowAndGroup := deviceRules.Rules["onu1"]
+ oltFlowAndGroup := deviceRules.Rules["olt"]
assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
assert.Equal(t, 2, oltFlowAndGroup.Flows.Len())
@@ -525,9 +520,9 @@
groups := ofp.FlowGroups{}
tfd := newTestFlowDecomposer(newTestDeviceManager())
- device_rules := tfd.fd.DecomposeRules(tfd, flows, groups)
- onu1FlowAndGroup := device_rules.Rules["onu1"]
- oltFlowAndGroup := device_rules.Rules["olt"]
+ deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
+ onu1FlowAndGroup := deviceRules.Rules["onu1"]
+ oltFlowAndGroup := deviceRules.Rules["olt"]
assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
assert.Equal(t, 2, oltFlowAndGroup.Flows.Len())
@@ -586,80 +581,227 @@
assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
}
-//func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
-//
-// var fa *fu.FlowArgs
-// fa = &fu.FlowArgs{
-// KV: fu.OfpFlowModArgs{"priority": 500, "table_id":1},
-// MatchFields: []*ofp.OfpOxmOfbField{
-// InPort(1),
-// VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
-// VlanPcp(0),
-// },
-// Actions: []*ofp.OfpAction{
-// SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
-// },
-// }
-//
-// var fa2 *fu.FlowArgs
-// fa2 = &fu.FlowArgs{
-// KV: fu.OfpFlowModArgs{"priority": 500},
-// MatchFields: []*ofp.OfpOxmOfbField{
-// InPort(1),
-// VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
-// VlanPcp(0),
-// },
-// Actions: []*ofp.OfpAction{
-// PushVlan(0x8100),
-// SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
-// SetField(VlanPcp(0)),
-// Output(10),
-// },
-// }
-//
-// flows := ofp.Flows{Items:[]*ofp.OfpFlowStats{MkFlowStat(fa), MkFlowStat(fa2)}}
-// groups := ofp.FlowGroups{}
-// tfd := newTestFlowDecomposer(newTestDeviceManager())
-//
-// device_rules := tfd.fd.DecomposeRules(tfd, flows, groups)
-// onu1FlowAndGroup := device_rules.Rules["onu1"]
-// oltFlowAndGroup := device_rules.Rules["olt"]
-// assert.Equal(t, 2, onu1FlowAndGroup.Flows.Len())
-// assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
-// assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
-// assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
-//
-// fa = &fu.FlowArgs{
-// KV: fu.OfpFlowModArgs{"priority": 500},
-// MatchFields: []*ofp.OfpOxmOfbField{
-// InPort(2),
-// VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
-// VlanPcp(0),
-// },
-// Actions: []*ofp.OfpAction{
-// SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
-// Output(1),
-// },
-// }
-// expectedOnu1Flow := MkFlowStat(fa)
-// derivedFlow := onu1FlowAndGroup.GetFlow(1)
-// assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
-//
-// fa = &fu.FlowArgs{
-// KV: fu.OfpFlowModArgs{"priority": 500},
-// MatchFields: []*ofp.OfpOxmOfbField{
-// InPort(1),
-// VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
-// VlanPcp(0),
-// },
-// Actions: []*ofp.OfpAction{
-// PushVlan(0x8100),
-// SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
-// SetField(VlanPcp(0)),
-// Output(2),
-// },
-// }
-// expectedOltFlow := MkFlowStat(fa)
-// derivedFlow = oltFlowAndGroup.GetFlow(0)
-// assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
-//}
+func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
+
+ var fa *fu.FlowArgs
+ fa = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(1),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+ },
+ }
+
+ var fa2 *fu.FlowArgs
+ fa2 = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(1),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ PushVlan(0x8100),
+ SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
+ SetField(VlanPcp(0)),
+ Output(10),
+ },
+ }
+
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{MkFlowStat(fa), MkFlowStat(fa2)}}
+ groups := ofp.FlowGroups{}
+ tfd := newTestFlowDecomposer(newTestDeviceManager())
+
+ deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
+ onu1FlowAndGroup := deviceRules.Rules["onu1"]
+ oltFlowAndGroup := deviceRules.Rules["olt"]
+ assert.Equal(t, 2, onu1FlowAndGroup.Flows.Len())
+ assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
+ assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
+ assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
+
+ fa = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(2),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+ Output(1),
+ },
+ }
+ expectedOnu1Flow := MkFlowStat(fa)
+ derivedFlow := onu1FlowAndGroup.GetFlow(1)
+ assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
+
+ fa = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(1),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ PushVlan(0x8100),
+ SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
+ SetField(VlanPcp(0)),
+ Output(2),
+ },
+ }
+ expectedOltFlow := MkFlowStat(fa)
+ derivedFlow = oltFlowAndGroup.GetFlow(0)
+ assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
+}
+
+func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
+ var fa1 *fu.FlowArgs
+ fa1 = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(10),
+ Metadata_ofp((1000 << 32) | 1),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ PopVlan(),
+ },
+ }
+
+ var fa2 *fu.FlowArgs
+ fa2 = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(10),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
+ Output(1),
+ },
+ }
+
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{MkFlowStat(fa1), MkFlowStat(fa2)}}
+ groups := ofp.FlowGroups{}
+ tfd := newTestFlowDecomposer(newTestDeviceManager())
+
+ deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
+ onu1FlowAndGroup := deviceRules.Rules["onu1"]
+ oltFlowAndGroup := deviceRules.Rules["olt"]
+ assert.Equal(t, 2, onu1FlowAndGroup.Flows.Len())
+ assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
+ assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
+ assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
+
+ fa1 = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(2),
+ Metadata_ofp(1000),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ PopVlan(),
+ Output(1),
+ },
+ }
+ expectedOltFlow := MkFlowStat(fa1)
+ derivedFlow := oltFlowAndGroup.GetFlow(0)
+ assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
+
+ fa1 = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(1),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
+ VlanPcp(0),
+ },
+ Actions: []*ofp.OfpAction{
+ SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
+ Output(2),
+ },
+ }
+ expectedOnu1Flow := MkFlowStat(fa1)
+ derivedFlow = onu1FlowAndGroup.GetFlow(1)
+ assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
+}
+
+func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
+ var fa *fu.FlowArgs
+ fa = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(10),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
+ VlanPcp(0),
+ EthType(0x800),
+ Ipv4Dst(0xe00a0a0a),
+ },
+ Actions: []*ofp.OfpAction{
+ Group(10),
+ },
+ }
+
+ var ga *fu.GroupArgs
+ ga = &fu.GroupArgs{
+ GroupId: 10,
+ Buckets: []*ofp.OfpBucket{
+ {Actions: []*ofp.OfpAction{
+ PopVlan(),
+ Output(1),
+ },
+ },
+ },
+ }
+
+ flows := ofp.Flows{Items: []*ofp.OfpFlowStats{MkFlowStat(fa)}}
+ groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{MkGroupStat(ga)}}
+ tfd := newTestFlowDecomposer(newTestDeviceManager())
+
+ deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
+ onu1FlowAndGroup := deviceRules.Rules["onu1"]
+ oltFlowAndGroup := deviceRules.Rules["olt"]
+ assert.Equal(t, 2, onu1FlowAndGroup.Flows.Len())
+ assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
+ assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
+ assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
+
+ fa = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(2),
+ VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
+ VlanPcp(0),
+ EthType(0x800),
+ Ipv4Dst(0xe00a0a0a),
+ },
+ Actions: []*ofp.OfpAction{
+ PopVlan(),
+ Output(1),
+ },
+ }
+ expectedOltFlow := MkFlowStat(fa)
+ derivedFlow := oltFlowAndGroup.GetFlow(0)
+ assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
+
+ fa = &fu.FlowArgs{
+ KV: fu.OfpFlowModArgs{"priority": 500},
+ MatchFields: []*ofp.OfpOxmOfbField{
+ InPort(1),
+ EthType(0x800),
+ Ipv4Dst(0xe00a0a0a),
+ },
+ Actions: []*ofp.OfpAction{
+ Output(2),
+ },
+ }
+ expectedOnu1Flow := MkFlowStat(fa)
+ derivedFlow = onu1FlowAndGroup.GetFlow(1)
+ assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
+}