2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 import static org.awaitility.Awaitility.await;
11 import static org.hamcrest.Matchers.equalTo;
12 import static org.junit.Assert.assertEquals;
14 import java.util.Collections;
15 import java.util.List;
16 import org.junit.After;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.junit.runner.RunWith;
20 import org.mockito.Mock;
21 import org.mockito.Mockito;
22 import org.mockito.junit.MockitoJUnitRunner;
23 import org.opendaylight.mdsal.binding.api.WriteTransaction;
24 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
25 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
26 import org.opendaylight.openflowplugin.api.openflow.FlowGroupCacheManager;
27 import org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeServiceManager;
28 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
29 import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
30 import org.opendaylight.openflowplugin.applications.frm.recovery.OpenflowServiceRecoveryHandler;
31 import org.opendaylight.openflowplugin.applications.reconciliation.ReconciliationManager;
32 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlow;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import test.mock.util.FRMTest;
58 import test.mock.util.RpcProviderRegistryMock;
59 import test.mock.util.SalFlowServiceMock;
61 @RunWith(MockitoJUnitRunner.class)
62 public class FlowListenerTest extends FRMTest {
63 private ForwardingRulesManagerImpl forwardingRulesManager;
64 private static final NodeId NODE_ID = new NodeId("testnode:1");
65 private static final NodeKey NODE_KEY = new NodeKey(NODE_ID);
66 RpcProviderRegistryMock rpcProviderRegistryMock = new RpcProviderRegistryMock();
67 TableKey tableKey = new TableKey((short) 2);
69 ClusterSingletonServiceProvider clusterSingletonService;
71 DeviceMastershipManager deviceMastershipManager;
73 private ReconciliationManager reconciliationManager;
75 private OpenflowServiceRecoveryHandler openflowServiceRecoveryHandler;
77 private ServiceRecoveryRegistry serviceRecoveryRegistry;
79 private MastershipChangeServiceManager mastershipChangeServiceManager;
81 private FlowGroupCacheManager flowGroupCacheManager;
85 forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock,
86 rpcProviderRegistryMock, getConfig(), mastershipChangeServiceManager, clusterSingletonService,
87 getConfigurationService(), reconciliationManager, openflowServiceRecoveryHandler,
88 serviceRecoveryRegistry, flowGroupCacheManager);
89 forwardingRulesManager.start();
90 // TODO consider tests rewrite (added because of complicated access)
91 forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
92 Mockito.when(deviceMastershipManager.isDeviceMastered(NODE_ID)).thenReturn(true);
96 public void addTwoFlowsTest() {
97 addFlowCapableNode(NODE_KEY);
99 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
100 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
101 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
102 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
103 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
104 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.emptyList()).build();
105 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
107 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
108 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
109 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
110 assertCommit(writeTx.commit());
111 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
112 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
113 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
114 assertEquals(1, addFlowCalls.size());
115 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
117 flowKey = new FlowKey(new FlowId("test_Flow2"));
118 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
119 .child(Table.class, tableKey).child(Flow.class, flowKey);
120 flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
121 writeTx = getDataBroker().newWriteOnlyTransaction();
122 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
123 assertCommit(writeTx.commit());
124 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
125 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(2));
126 addFlowCalls = salFlowService.getAddFlowCalls();
127 assertEquals(2, addFlowCalls.size());
128 assertEquals("DOM-1", addFlowCalls.get(1).getTransactionUri().getValue());
129 assertEquals(2, addFlowCalls.get(1).getTableId().intValue());
130 assertEquals(flowII, addFlowCalls.get(1).getFlowRef().getValue());
134 public void updateFlowTest() {
135 addFlowCapableNode(NODE_KEY);
137 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
138 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
139 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
140 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
141 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
142 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.emptyList()).build();
143 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
145 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
146 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
147 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
148 assertCommit(writeTx.commit());
149 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
150 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
152 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
153 assertEquals(1, addFlowCalls.size());
154 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
156 flowKey = new FlowKey(new FlowId("test_Flow"));
157 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
158 .child(Table.class, tableKey).child(Flow.class, flowKey);
159 flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).setOutGroup((long) 5).build();
160 writeTx = getDataBroker().newWriteOnlyTransaction();
161 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
162 assertCommit(writeTx.commit());
163 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
164 await().until(listSize(salFlowService.getUpdateFlowCalls()), equalTo(1));
165 List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
166 assertEquals(1, updateFlowCalls.size());
167 assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
168 assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
169 assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getOriginalFlow().isStrict());
170 assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getUpdatedFlow().isStrict());
174 public void updateFlowScopeTest() {
175 addFlowCapableNode(NODE_KEY);
177 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
178 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
179 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
180 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
181 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
182 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.emptyList()).build();
183 IpMatch ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short) 4)).build();
184 Match match = new MatchBuilder().setIpMatch(ipMatch).build();
185 Flow flow = new FlowBuilder().setMatch(match).withKey(flowKey).setTableId((short) 2).build();
187 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
188 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
189 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
190 assertCommit(writeTx.commit());
191 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
192 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
193 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
194 assertEquals(1, addFlowCalls.size());
195 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
197 flowKey = new FlowKey(new FlowId("test_Flow"));
198 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
199 .child(Table.class, tableKey).child(Flow.class, flowKey);
200 ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short) 5)).build();
201 match = new MatchBuilder().setIpMatch(ipMatch).build();
202 flow = new FlowBuilder().setMatch(match).withKey(flowKey).setTableId((short) 2).build();
203 writeTx = getDataBroker().newWriteOnlyTransaction();
204 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
205 assertCommit(writeTx.commit());
206 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
207 await().until(listSize(salFlowService.getUpdateFlowCalls()), equalTo(1));
208 List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
209 assertEquals(1, updateFlowCalls.size());
210 assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
211 assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
212 assertEquals(ipMatch, updateFlowCalls.get(0).getUpdatedFlow().getMatch().getIpMatch());
216 public void deleteFlowTest() {
217 addFlowCapableNode(NODE_KEY);
219 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
220 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
221 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
222 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
223 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
224 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.emptyList()).build();
225 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
227 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
228 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
229 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
230 assertCommit(writeTx.commit());
231 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
232 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
233 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
234 assertEquals(1, addFlowCalls.size());
235 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
237 writeTx = getDataBroker().newWriteOnlyTransaction();
238 writeTx.delete(LogicalDatastoreType.CONFIGURATION, flowII);
239 assertCommit(writeTx.commit());
240 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
241 await().until(listSize(salFlowService.getRemoveFlowCalls()), equalTo(1));
242 List<RemoveFlowInput> removeFlowCalls = salFlowService.getRemoveFlowCalls();
243 assertEquals(1, removeFlowCalls.size());
244 assertEquals("DOM-1", removeFlowCalls.get(0).getTransactionUri().getValue());
245 assertEquals(flowII, removeFlowCalls.get(0).getFlowRef().getValue());
246 assertEquals(Boolean.TRUE, removeFlowCalls.get(0).isStrict());
250 public void staleMarkedFlowCreationTest() {
252 addFlowCapableNode(NODE_KEY);
254 StaleFlowKey flowKey = new StaleFlowKey(new FlowId("stale_Flow"));
255 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
256 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
257 InstanceIdentifier<StaleFlow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
258 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(StaleFlow.class, flowKey);
259 Table table = new TableBuilder().withKey(tableKey).setStaleFlow(Collections.emptyList()).build();
260 StaleFlow flow = new StaleFlowBuilder().withKey(flowKey).setTableId((short) 2).build();
262 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
263 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
264 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
265 assertCommit(writeTx.commit());
269 public void tearDown() throws Exception {
270 forwardingRulesManager.close();