Bug 6110: Fixed bugs in statistics manager due to race condition.
[openflowplugin.git] / applications / forwardingrules-manager / src / test / java / test / mock / FlowListenerTest.java
1 /**
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package test.mock;
9
10 import static org.junit.Assert.assertEquals;
11
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.RpcProviderRegistry;
24 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
25 import org.opendaylight.openflowplugin.applications.frm.impl.DeviceMastershipManager;
26 import org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlow;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.StaleFlowKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import test.mock.util.FRMTest;
52 import test.mock.util.RpcProviderRegistryMock;
53 import test.mock.util.SalFlowServiceMock;
54
55 @RunWith(MockitoJUnitRunner.class)
56 public class FlowListenerTest extends FRMTest {
57     private ForwardingRulesManagerImpl forwardingRulesManager;
58     private final static NodeId NODE_ID = new NodeId("testnode:1");
59     private final static NodeKey s1Key = new NodeKey(NODE_ID);
60     RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
61     TableKey tableKey = new TableKey((short) 2);
62     @Mock
63     ClusterSingletonServiceProvider clusterSingletonService;
64     @Mock
65     DeviceMastershipManager deviceMastershipManager;
66
67     @Before
68     public void setUp() {
69         forwardingRulesManager = new ForwardingRulesManagerImpl(
70                 getDataBroker(),
71                 rpcProviderRegistryMock,
72                 getConfig(),
73                 clusterSingletonService);
74         forwardingRulesManager.start();
75         // TODO consider tests rewrite (added because of complicated access)
76         forwardingRulesManager.setDeviceMastershipManager(deviceMastershipManager);
77         Mockito.when(deviceMastershipManager.isDeviceMastered(NODE_ID)).thenReturn(true);
78     }
79
80     @Test
81     public void addTwoFlowsTest() throws Exception {
82         addFlowCapableNode(s1Key);
83
84         FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
85         InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
86                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
87         InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
88                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
89         Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
90         Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
91
92         WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
93         writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
94         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
95         assertCommit(writeTx.submit());
96         SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
97         List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
98         assertEquals(1, addFlowCalls.size());
99         assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
100
101         flowKey = new FlowKey(new FlowId("test_Flow2"));
102         flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
103                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
104         flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
105         writeTx = getDataBroker().newWriteOnlyTransaction();
106         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
107         assertCommit(writeTx.submit());
108         salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
109         addFlowCalls = salFlowService.getAddFlowCalls();
110         assertEquals(2, addFlowCalls.size());
111         assertEquals("DOM-1", addFlowCalls.get(1).getTransactionUri().getValue());
112         assertEquals(2, addFlowCalls.get(1).getTableId().intValue());
113         assertEquals(flowII, addFlowCalls.get(1).getFlowRef().getValue());
114 }
115
116     @Test
117     public void updateFlowTest() throws Exception {
118         addFlowCapableNode(s1Key);
119
120         FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
121         InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
122                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
123         InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
124                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
125         Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
126         Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
127
128         WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
129         writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
130         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
131         assertCommit(writeTx.submit());
132         SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
133         List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
134         assertEquals(1, addFlowCalls.size());
135         assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
136
137         flowKey = new FlowKey(new FlowId("test_Flow"));
138         flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
139                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
140         flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).setOutGroup((long) 5).build();
141         writeTx = getDataBroker().newWriteOnlyTransaction();
142         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
143         assertCommit(writeTx.submit());
144         salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
145         List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
146         assertEquals(1, updateFlowCalls.size());
147         assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
148         assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
149         assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getOriginalFlow().isStrict());
150         assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getUpdatedFlow().isStrict());
151     }
152
153     @Test
154     public void updateFlowScopeTest() throws Exception {
155         addFlowCapableNode(s1Key);
156
157         FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
158         InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
159                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
160         InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
161                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
162         Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
163         IpMatch ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short)4)).build();
164         Match match = new MatchBuilder().setIpMatch(ipMatch).build();
165         Flow flow = new FlowBuilder().setMatch(match).setKey(flowKey).setTableId((short) 2).build();
166
167         WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
168         writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
169         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
170         assertCommit(writeTx.submit());
171         SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
172         List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
173         assertEquals(1, addFlowCalls.size());
174         assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
175
176         flowKey = new FlowKey(new FlowId("test_Flow"));
177         flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
178                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
179         ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short)5)).build();
180         match = new MatchBuilder().setIpMatch(ipMatch).build();
181         flow = new FlowBuilder().setMatch(match).setKey(flowKey).setTableId((short) 2).build();
182         writeTx = getDataBroker().newWriteOnlyTransaction();
183         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
184         assertCommit(writeTx.submit());
185         salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
186         List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
187         assertEquals(1, updateFlowCalls.size());
188         assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
189         assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
190         assertEquals(ipMatch, updateFlowCalls.get(0).getUpdatedFlow().getMatch().getIpMatch());
191     }
192
193     @Test
194     public void deleteFlowTest() throws Exception {
195         addFlowCapableNode(s1Key);
196
197         FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
198         InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
199                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
200         InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
201                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
202         Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
203         Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
204
205         WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
206         writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
207         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
208         assertCommit(writeTx.submit());
209         SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
210         List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
211         assertEquals(1, addFlowCalls.size());
212         assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
213
214         writeTx = getDataBroker().newWriteOnlyTransaction();
215         writeTx.delete(LogicalDatastoreType.CONFIGURATION, flowII);
216         assertCommit(writeTx.submit());
217         salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
218         List<RemoveFlowInput> removeFlowCalls = salFlowService.getRemoveFlowCalls();
219         assertEquals(1, removeFlowCalls.size());
220         assertEquals("DOM-1", removeFlowCalls.get(0).getTransactionUri().getValue());
221         assertEquals(flowII, removeFlowCalls.get(0).getFlowRef().getValue());
222         assertEquals(Boolean.TRUE, removeFlowCalls.get(0).isStrict());
223     }
224
225
226     @Test
227     public void staleMarkedFlowCreationTest() throws Exception{
228
229         addFlowCapableNode(s1Key);
230
231         StaleFlowKey flowKey = new StaleFlowKey(new FlowId("stale_Flow"));
232         InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
233                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
234         InstanceIdentifier<StaleFlow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
235                 .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(StaleFlow.class, flowKey);
236         Table table = new TableBuilder().setKey(tableKey).setStaleFlow(Collections.<StaleFlow>emptyList()).build();
237         StaleFlow flow = new StaleFlowBuilder().setKey(flowKey).setTableId((short) 2).build();
238
239         WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
240         writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
241         writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
242         assertCommit(writeTx.submit());
243     }
244
245     @After
246     public void tearDown() throws Exception {
247         forwardingRulesManager.close();
248     }
249
250 }