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