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;
17 import org.junit.After;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.junit.runner.RunWith;
21 import org.mockito.Mock;
22 import org.mockito.Mockito;
23 import org.mockito.runners.MockitoJUnitRunner;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
27 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
28 import org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeServiceManager;
29 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
30 import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
31 import org.opendaylight.openflowplugin.applications.frm.recovery.OpenflowServiceRecoveryHandler;
32 import org.opendaylight.openflowplugin.applications.reconciliation.ReconciliationManager;
33 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlow;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import test.mock.util.FRMTest;
59 import test.mock.util.RpcProviderRegistryMock;
60 import test.mock.util.SalFlowServiceMock;
62 @RunWith(MockitoJUnitRunner.class)
63 public class FlowListenerTest extends FRMTest {
64 private ForwardingRulesManagerImpl forwardingRulesManager;
65 private static final NodeId NODE_ID = new NodeId("testnode:1");
66 private static final NodeKey NODE_KEY = new NodeKey(NODE_ID);
67 RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
68 TableKey tableKey = new TableKey((short) 2);
70 ClusterSingletonServiceProvider clusterSingletonService;
72 DeviceMastershipManager deviceMastershipManager;
74 private ReconciliationManager reconciliationManager;
76 private OpenflowServiceRecoveryHandler openflowServiceRecoveryHandler;
78 private ServiceRecoveryRegistry serviceRecoveryRegistry;
80 private MastershipChangeServiceManager mastershipChangeServiceManager;
84 forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock, getConfig(),
85 mastershipChangeServiceManager, clusterSingletonService, getConfigurationService(),
86 reconciliationManager, openflowServiceRecoveryHandler, serviceRecoveryRegistry);
88 forwardingRulesManager.start();
89 // TODO consider tests rewrite (added because of complicated access)
90 forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
91 Mockito.when(deviceMastershipManager.isDeviceMastered(NODE_ID)).thenReturn(true);
95 public void addTwoFlowsTest() throws Exception {
96 addFlowCapableNode(NODE_KEY);
98 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
99 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
100 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
101 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
102 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
103 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
104 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
106 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
107 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
108 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
109 assertCommit(writeTx.submit());
110 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
111 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
112 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
113 assertEquals(1, addFlowCalls.size());
114 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
116 flowKey = new FlowKey(new FlowId("test_Flow2"));
117 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
118 .child(Table.class, tableKey).child(Flow.class, flowKey);
119 flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
120 writeTx = getDataBroker().newWriteOnlyTransaction();
121 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
122 assertCommit(writeTx.submit());
123 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
124 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(2));
125 addFlowCalls = salFlowService.getAddFlowCalls();
126 assertEquals(2, addFlowCalls.size());
127 assertEquals("DOM-1", addFlowCalls.get(1).getTransactionUri().getValue());
128 assertEquals(2, addFlowCalls.get(1).getTableId().intValue());
129 assertEquals(flowII, addFlowCalls.get(1).getFlowRef().getValue());
133 public void updateFlowTest() throws Exception {
134 addFlowCapableNode(NODE_KEY);
136 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
137 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
138 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
139 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
140 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
141 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
142 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
144 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
145 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
146 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
147 assertCommit(writeTx.submit());
148 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
149 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
151 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
152 assertEquals(1, addFlowCalls.size());
153 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
155 flowKey = new FlowKey(new FlowId("test_Flow"));
156 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
157 .child(Table.class, tableKey).child(Flow.class, flowKey);
158 flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).setOutGroup((long) 5).build();
159 writeTx = getDataBroker().newWriteOnlyTransaction();
160 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
161 assertCommit(writeTx.submit());
162 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
163 await().until(listSize(salFlowService.getUpdateFlowCalls()), equalTo(1));
164 List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
165 assertEquals(1, updateFlowCalls.size());
166 assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
167 assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
168 assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getOriginalFlow().isStrict());
169 assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getUpdatedFlow().isStrict());
173 public void updateFlowScopeTest() throws Exception {
174 addFlowCapableNode(NODE_KEY);
176 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
177 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
178 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
179 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
180 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
181 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
182 IpMatch ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short) 4)).build();
183 Match match = new MatchBuilder().setIpMatch(ipMatch).build();
184 Flow flow = new FlowBuilder().setMatch(match).withKey(flowKey).setTableId((short) 2).build();
186 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
187 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
188 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
189 assertCommit(writeTx.submit());
190 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
191 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
192 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
193 assertEquals(1, addFlowCalls.size());
194 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
196 flowKey = new FlowKey(new FlowId("test_Flow"));
197 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
198 .child(Table.class, tableKey).child(Flow.class, flowKey);
199 ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short) 5)).build();
200 match = new MatchBuilder().setIpMatch(ipMatch).build();
201 flow = new FlowBuilder().setMatch(match).withKey(flowKey).setTableId((short) 2).build();
202 writeTx = getDataBroker().newWriteOnlyTransaction();
203 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
204 assertCommit(writeTx.submit());
205 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
206 await().until(listSize(salFlowService.getUpdateFlowCalls()), equalTo(1));
207 List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
208 assertEquals(1, updateFlowCalls.size());
209 assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
210 assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
211 assertEquals(ipMatch, updateFlowCalls.get(0).getUpdatedFlow().getMatch().getIpMatch());
215 public void deleteFlowTest() throws Exception {
216 addFlowCapableNode(NODE_KEY);
218 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
219 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
220 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
221 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
222 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
223 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
224 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
226 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
227 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
228 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
229 assertCommit(writeTx.submit());
230 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
231 await().until(listSize(salFlowService.getAddFlowCalls()), equalTo(1));
232 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
233 assertEquals(1, addFlowCalls.size());
234 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
236 writeTx = getDataBroker().newWriteOnlyTransaction();
237 writeTx.delete(LogicalDatastoreType.CONFIGURATION, flowII);
238 assertCommit(writeTx.submit());
239 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
240 await().until(listSize(salFlowService.getRemoveFlowCalls()), equalTo(1));
241 List<RemoveFlowInput> removeFlowCalls = salFlowService.getRemoveFlowCalls();
242 assertEquals(1, removeFlowCalls.size());
243 assertEquals("DOM-1", removeFlowCalls.get(0).getTransactionUri().getValue());
244 assertEquals(flowII, removeFlowCalls.get(0).getFlowRef().getValue());
245 assertEquals(Boolean.TRUE, removeFlowCalls.get(0).isStrict());
249 public void staleMarkedFlowCreationTest() throws Exception {
251 addFlowCapableNode(NODE_KEY);
253 StaleFlowKey flowKey = new StaleFlowKey(new FlowId("stale_Flow"));
254 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
255 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
256 InstanceIdentifier<StaleFlow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
257 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(StaleFlow.class, flowKey);
258 Table table = new TableBuilder().withKey(tableKey).setStaleFlow(Collections.<StaleFlow>emptyList()).build();
259 StaleFlow flow = new StaleFlowBuilder().withKey(flowKey).setTableId((short) 2).build();
261 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
262 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
263 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
264 assertCommit(writeTx.submit());
268 public void tearDown() throws Exception {
269 forwardingRulesManager.close();