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.junit.Assert.assertEquals;
12 import java.util.Collections;
13 import java.util.List;
14 import org.junit.After;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18 import org.mockito.Mock;
19 import org.mockito.Mockito;
20 import org.mockito.runners.MockitoJUnitRunner;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
24 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
25 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
26 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
27 import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
28 import org.opendaylight.openflowplugin.applications.reconciliation.ReconciliationManager;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlow;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import test.mock.util.FRMTest;
54 import test.mock.util.RpcProviderRegistryMock;
55 import test.mock.util.SalFlowServiceMock;
57 @RunWith(MockitoJUnitRunner.class)
58 public class FlowListenerTest extends FRMTest {
59 private ForwardingRulesManagerImpl forwardingRulesManager;
60 private static final NodeId NODE_ID = new NodeId("testnode:1");
61 private static final NodeKey NODE_KEY = new NodeKey(NODE_ID);
62 RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
63 TableKey tableKey = new TableKey((short) 2);
65 ClusterSingletonServiceProvider clusterSingletonService;
67 DeviceMastershipManager deviceMastershipManager;
69 private NotificationProviderService notificationService;
71 private ReconciliationManager reconciliationManager;
75 forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock, getConfig(),
76 clusterSingletonService, notificationService, getConfigurationService(), reconciliationManager);
78 forwardingRulesManager.start();
79 // TODO consider tests rewrite (added because of complicated access)
80 forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
81 Mockito.when(deviceMastershipManager.isDeviceMastered(NODE_ID)).thenReturn(true);
85 public void addTwoFlowsTest() throws Exception {
86 addFlowCapableNode(NODE_KEY);
88 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
89 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
90 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
91 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
92 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
93 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
94 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
96 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
97 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
98 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
99 assertCommit(writeTx.submit());
100 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
101 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
102 assertEquals(1, addFlowCalls.size());
103 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
105 flowKey = new FlowKey(new FlowId("test_Flow2"));
106 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
107 .child(Table.class, tableKey).child(Flow.class, flowKey);
108 flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
109 writeTx = getDataBroker().newWriteOnlyTransaction();
110 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
111 assertCommit(writeTx.submit());
112 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
113 addFlowCalls = salFlowService.getAddFlowCalls();
114 assertEquals(2, addFlowCalls.size());
115 assertEquals("DOM-1", addFlowCalls.get(1).getTransactionUri().getValue());
116 assertEquals(2, addFlowCalls.get(1).getTableId().intValue());
117 assertEquals(flowII, addFlowCalls.get(1).getFlowRef().getValue());
121 public void updateFlowTest() throws Exception {
122 addFlowCapableNode(NODE_KEY);
124 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
125 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
126 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
127 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
128 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
129 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
130 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
132 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
133 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
134 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
135 assertCommit(writeTx.submit());
136 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
137 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
138 assertEquals(1, addFlowCalls.size());
139 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
141 flowKey = new FlowKey(new FlowId("test_Flow"));
142 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
143 .child(Table.class, tableKey).child(Flow.class, flowKey);
144 flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).setOutGroup((long) 5).build();
145 writeTx = getDataBroker().newWriteOnlyTransaction();
146 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
147 assertCommit(writeTx.submit());
148 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
149 List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
150 assertEquals(1, updateFlowCalls.size());
151 assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
152 assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
153 assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getOriginalFlow().isStrict());
154 assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getUpdatedFlow().isStrict());
158 public void updateFlowScopeTest() throws Exception {
159 addFlowCapableNode(NODE_KEY);
161 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
162 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
163 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
164 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
165 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
166 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
167 IpMatch ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short) 4)).build();
168 Match match = new MatchBuilder().setIpMatch(ipMatch).build();
169 Flow flow = new FlowBuilder().setMatch(match).withKey(flowKey).setTableId((short) 2).build();
171 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
172 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
173 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
174 assertCommit(writeTx.submit());
175 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
176 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
177 assertEquals(1, addFlowCalls.size());
178 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
180 flowKey = new FlowKey(new FlowId("test_Flow"));
181 flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY).augmentation(FlowCapableNode.class)
182 .child(Table.class, tableKey).child(Flow.class, flowKey);
183 ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short) 5)).build();
184 match = new MatchBuilder().setIpMatch(ipMatch).build();
185 flow = new FlowBuilder().setMatch(match).withKey(flowKey).setTableId((short) 2).build();
186 writeTx = getDataBroker().newWriteOnlyTransaction();
187 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
188 assertCommit(writeTx.submit());
189 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
190 List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
191 assertEquals(1, updateFlowCalls.size());
192 assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
193 assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
194 assertEquals(ipMatch, updateFlowCalls.get(0).getUpdatedFlow().getMatch().getIpMatch());
198 public void deleteFlowTest() throws Exception {
199 addFlowCapableNode(NODE_KEY);
201 FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
202 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
203 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
204 InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
205 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
206 Table table = new TableBuilder().withKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
207 Flow flow = new FlowBuilder().withKey(flowKey).setTableId((short) 2).build();
209 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
210 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
211 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
212 assertCommit(writeTx.submit());
213 SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
214 List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
215 assertEquals(1, addFlowCalls.size());
216 assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
218 writeTx = getDataBroker().newWriteOnlyTransaction();
219 writeTx.delete(LogicalDatastoreType.CONFIGURATION, flowII);
220 assertCommit(writeTx.submit());
221 salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
222 List<RemoveFlowInput> removeFlowCalls = salFlowService.getRemoveFlowCalls();
223 assertEquals(1, removeFlowCalls.size());
224 assertEquals("DOM-1", removeFlowCalls.get(0).getTransactionUri().getValue());
225 assertEquals(flowII, removeFlowCalls.get(0).getFlowRef().getValue());
226 assertEquals(Boolean.TRUE, removeFlowCalls.get(0).isStrict());
230 public void staleMarkedFlowCreationTest() throws Exception {
232 addFlowCapableNode(NODE_KEY);
234 StaleFlowKey flowKey = new StaleFlowKey(new FlowId("stale_Flow"));
235 InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
236 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
237 InstanceIdentifier<StaleFlow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY)
238 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(StaleFlow.class, flowKey);
239 Table table = new TableBuilder().withKey(tableKey).setStaleFlow(Collections.<StaleFlow>emptyList()).build();
240 StaleFlow flow = new StaleFlowBuilder().withKey(flowKey).setTableId((short) 2).build();
242 WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
243 writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
244 writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
245 assertCommit(writeTx.submit());
249 public void tearDown() throws Exception {
250 forwardingRulesManager.close();