OPNFLWPLUG-1010 Adopt mdsal changes proposed through weather item TSC-99
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / services / sal / SalFlowsBatchServiceImplTest.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowplugin.impl.services.sal;
10
11 import com.google.common.collect.Lists;
12 import java.util.List;
13 import java.util.concurrent.Future;
14 import org.junit.After;
15 import org.junit.Assert;
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.junit.runner.RunWith;
19 import org.mockito.ArgumentCaptor;
20 import org.mockito.Captor;
21 import org.mockito.InOrder;
22 import org.mockito.Matchers;
23 import org.mockito.Mock;
24 import org.mockito.Mockito;
25 import org.mockito.runners.MockitoJUnitRunner;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierOutput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInputBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchOutput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlows;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlowsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.OriginalBatchedFlowBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.UpdatedBatchedFlowBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlows;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlowsBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlows;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlowsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
63 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
64 import org.opendaylight.yangtools.yang.common.RpcError;
65 import org.opendaylight.yangtools.yang.common.RpcResult;
66 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70 /**
71  * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlowsBatchServiceImpl}.
72  */
73 @RunWith(MockitoJUnitRunner.class)
74 public class SalFlowsBatchServiceImplTest {
75
76     private static final Logger LOG = LoggerFactory.getLogger(SalFlowsBatchServiceImplTest.class);
77
78     public static final NodeId NODE_ID = new NodeId("ut-dummy-node");
79     public static final NodeKey NODE_KEY = new NodeKey(NODE_ID);
80     public static final NodeRef NODE_REF =
81             new NodeRef(InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY));
82
83     @Mock
84     private SalFlowService salFlowService;
85     @Mock
86     private FlowCapableTransactionService transactionService;
87     @Captor
88     private ArgumentCaptor<RemoveFlowInput> removeFlowInputCpt;
89     @Captor
90     private ArgumentCaptor<UpdateFlowInput> updateFlowInputCpt;
91     @Captor
92     private ArgumentCaptor<AddFlowInput> addFlowInputCpt;
93
94     private SalFlowsBatchServiceImpl salFlowsBatchService;
95     public static final String FLOW_ID_VALUE_1 = "ut-dummy-flow1";
96     public static final String FLOW_ID_VALUE_2 = "ut-dummy-flow2";
97
98     @Before
99     public void setUp() throws Exception {
100         salFlowsBatchService = new SalFlowsBatchServiceImpl(salFlowService, transactionService);
101
102         Mockito.when(transactionService.sendBarrier(Matchers.<SendBarrierInput>any()))
103                 .thenReturn(RpcResultBuilder.<SendBarrierOutput>success().buildFuture());
104     }
105
106     @After
107     public void tearDown() throws Exception {
108         Mockito.verifyNoMoreInteractions(salFlowService, transactionService);
109     }
110
111     @Test
112     public void testRemoveFlowsBatch_success() throws Exception {
113         Mockito.when(salFlowService.removeFlow(Matchers.<RemoveFlowInput>any()))
114                 .thenReturn(RpcResultBuilder.success(new RemoveFlowOutputBuilder().build())
115                         .buildFuture());
116
117         final String flow1IdValue = "ut-dummy-flow1";
118         final String flow2IdValue = "ut-dummy-flow2";
119         final BatchRemoveFlows batchFlow1 = createEmptyBatchRemoveFlow(flow1IdValue, 42);
120         final BatchRemoveFlows batchFlow2 = createEmptyBatchRemoveFlow(flow2IdValue, 43);
121
122         final RemoveFlowsBatchInput input = new RemoveFlowsBatchInputBuilder()
123                 .setNode(NODE_REF)
124                 .setBarrierAfter(true)
125                 .setBatchRemoveFlows(Lists.newArrayList(batchFlow1, batchFlow2))
126                 .build();
127
128         final Future<RpcResult<RemoveFlowsBatchOutput>> resultFuture = salFlowsBatchService.removeFlowsBatch(input);
129
130         Assert.assertTrue(resultFuture.isDone());
131         final RpcResult<RemoveFlowsBatchOutput> rpcResult = resultFuture.get();
132         Assert.assertTrue(rpcResult.isSuccessful());
133         final RemoveFlowsBatchOutput result = rpcResult.getResult();
134         Assert.assertEquals(0, result.getBatchFailedFlowsOutput().size());
135
136         final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
137
138         inOrder.verify(salFlowService, Mockito.times(2)).removeFlow(removeFlowInputCpt.capture());
139         final List<RemoveFlowInput> allValues = removeFlowInputCpt.getAllValues();
140         Assert.assertEquals(2, allValues.size());
141         Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
142         Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
143
144         inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
145     }
146
147     @Test
148     public void testRemoveFlowsBatch_failed() throws Exception {
149         Mockito.when(salFlowService.removeFlow(Matchers.<RemoveFlowInput>any()))
150                 .thenReturn(RpcResultBuilder.<RemoveFlowOutput>failed()
151                         .withError(RpcError.ErrorType.APPLICATION, "flow-remove-fail-1")
152                         .buildFuture());
153
154         final BatchRemoveFlows batchFlow1 = createEmptyBatchRemoveFlow(FLOW_ID_VALUE_1, 42);
155         final BatchRemoveFlows batchFlow2 = createEmptyBatchRemoveFlow(FLOW_ID_VALUE_2, 43);
156
157         final RemoveFlowsBatchInput input = new RemoveFlowsBatchInputBuilder()
158                 .setNode(NODE_REF)
159                 .setBarrierAfter(true)
160                 .setBatchRemoveFlows(Lists.newArrayList(batchFlow1, batchFlow2))
161                 .build();
162
163         final Future<RpcResult<RemoveFlowsBatchOutput>> resultFuture = salFlowsBatchService.removeFlowsBatch(input);
164
165         Assert.assertTrue(resultFuture.isDone());
166         final RpcResult<RemoveFlowsBatchOutput> rpcResult = resultFuture.get();
167         Assert.assertFalse(rpcResult.isSuccessful());
168         final RemoveFlowsBatchOutput result = rpcResult.getResult();
169         Assert.assertEquals(2, result.getBatchFailedFlowsOutput().size());
170         Assert.assertEquals(FLOW_ID_VALUE_1, result.getBatchFailedFlowsOutput().get(0).getFlowId().getValue());
171         Assert.assertEquals(FLOW_ID_VALUE_2, result.getBatchFailedFlowsOutput().get(1).getFlowId().getValue());
172
173         final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
174
175         inOrder.verify(salFlowService, Mockito.times(2)).removeFlow(removeFlowInputCpt.capture());
176         final List<RemoveFlowInput> allValues = removeFlowInputCpt.getAllValues();
177         Assert.assertEquals(2, allValues.size());
178         Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
179         Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
180
181         inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
182     }
183
184     private static BatchAddFlows createEmptyBatchAddFlow(final String flowIdValue, final int priority) {
185         return new BatchAddFlowsBuilder()
186                 .setFlowId(new FlowId(flowIdValue))
187                 .setPriority(priority)
188                 .setMatch(new MatchBuilder().build())
189                 .setTableId((short) 0)
190                 .build();
191     }
192
193     private static BatchRemoveFlows createEmptyBatchRemoveFlow(final String flowIdValue, final int priority) {
194         return new BatchRemoveFlowsBuilder()
195                 .setFlowId(new FlowId(flowIdValue))
196                 .setPriority(priority)
197                 .setMatch(new MatchBuilder().build())
198                 .setTableId((short) 0)
199                 .build();
200     }
201
202     private static BatchUpdateFlows createEmptyBatchUpdateFlow(final String flowIdValue, final int priority) {
203         final BatchAddFlows emptyOriginalFlow = createEmptyBatchAddFlow(flowIdValue, priority);
204         final BatchAddFlows emptyUpdatedFlow = createEmptyBatchAddFlow(flowIdValue, priority + 1);
205         return new BatchUpdateFlowsBuilder()
206                 .setFlowId(new FlowId(flowIdValue))
207                 .setOriginalBatchedFlow(new OriginalBatchedFlowBuilder(emptyOriginalFlow).build())
208                 .setUpdatedBatchedFlow(new UpdatedBatchedFlowBuilder(emptyUpdatedFlow).build())
209                 .build();
210     }
211
212     @Test
213     public void testAddFlowsBatch_success() throws Exception {
214         Mockito.when(salFlowService.addFlow(Matchers.<AddFlowInput>any()))
215                 .thenReturn(RpcResultBuilder.success(new AddFlowOutputBuilder().build()).buildFuture());
216
217         final AddFlowsBatchInput input = new AddFlowsBatchInputBuilder()
218                 .setNode(NODE_REF)
219                 .setBarrierAfter(true)
220                 .setBatchAddFlows(Lists.newArrayList(
221                         createEmptyBatchAddFlow("ut-dummy-flow1", 42),
222                         createEmptyBatchAddFlow("ut-dummy-flow2", 43)))
223                 .build();
224
225         final Future<RpcResult<AddFlowsBatchOutput>> resultFuture = salFlowsBatchService.addFlowsBatch(input);
226
227         Assert.assertTrue(resultFuture.isDone());
228         Assert.assertTrue(resultFuture.get().isSuccessful());
229
230         final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
231
232         inOrder.verify(salFlowService, Mockito.times(2)).addFlow(addFlowInputCpt.capture());
233         final List<AddFlowInput> allValues = addFlowInputCpt.getAllValues();
234         Assert.assertEquals(2, allValues.size());
235         Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
236         Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
237
238         inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
239     }
240
241     @Test
242     public void testAddFlowsBatch_failed() throws Exception {
243         Mockito.when(salFlowService.addFlow(Matchers.<AddFlowInput>any()))
244                 .thenReturn(RpcResultBuilder
245                         .<AddFlowOutput>failed().withError(RpcError.ErrorType.APPLICATION, "ut-groupAddError")
246                         .buildFuture());
247
248         final AddFlowsBatchInput input = new AddFlowsBatchInputBuilder()
249                 .setNode(NODE_REF)
250                 .setBarrierAfter(true)
251                 .setBatchAddFlows(Lists.newArrayList(
252                         createEmptyBatchAddFlow(FLOW_ID_VALUE_1, 42),
253                         createEmptyBatchAddFlow(FLOW_ID_VALUE_2, 43)))
254                 .build();
255
256         final Future<RpcResult<AddFlowsBatchOutput>> resultFuture = salFlowsBatchService.addFlowsBatch(input);
257
258         Assert.assertTrue(resultFuture.isDone());
259         Assert.assertFalse(resultFuture.get().isSuccessful());
260         Assert.assertEquals(2, resultFuture.get().getResult().getBatchFailedFlowsOutput().size());
261         Assert.assertEquals(FLOW_ID_VALUE_1,
262                 resultFuture.get().getResult().getBatchFailedFlowsOutput().get(0).getFlowId().getValue());
263         Assert.assertEquals(FLOW_ID_VALUE_2,
264                 resultFuture.get().getResult().getBatchFailedFlowsOutput().get(1).getFlowId().getValue());
265         Assert.assertEquals(2, resultFuture.get().getErrors().size());
266
267         final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
268
269         inOrder.verify(salFlowService, Mockito.times(2)).addFlow(addFlowInputCpt.capture());
270         final List<AddFlowInput> allValues = addFlowInputCpt.getAllValues();
271         Assert.assertEquals(2, allValues.size());
272         Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
273         Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
274
275         inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
276     }
277
278     @Test
279     public void testUpdateFlowsBatch_success() throws Exception {
280         Mockito.when(salFlowService.updateFlow(Matchers.<UpdateFlowInput>any()))
281                 .thenReturn(RpcResultBuilder.success(new UpdateFlowOutputBuilder().build()).buildFuture());
282
283         final UpdateFlowsBatchInput input = new UpdateFlowsBatchInputBuilder()
284                 .setNode(NODE_REF)
285                 .setBarrierAfter(true)
286                 .setBatchUpdateFlows(Lists.newArrayList(
287                         createEmptyBatchUpdateFlow(FLOW_ID_VALUE_1, 42),
288                         createEmptyBatchUpdateFlow(FLOW_ID_VALUE_2, 44)))
289                 .build();
290
291         final Future<RpcResult<UpdateFlowsBatchOutput>> resultFuture = salFlowsBatchService.updateFlowsBatch(input);
292
293         Assert.assertTrue(resultFuture.isDone());
294         Assert.assertTrue(resultFuture.get().isSuccessful());
295
296         final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
297
298         inOrder.verify(salFlowService, Mockito.times(2)).updateFlow(updateFlowInputCpt.capture());
299         final List<UpdateFlowInput> allValues = updateFlowInputCpt.getAllValues();
300         Assert.assertEquals(2, allValues.size());
301         Assert.assertEquals(42, allValues.get(0).getOriginalFlow().getPriority().longValue());
302         Assert.assertEquals(43, allValues.get(0).getUpdatedFlow().getPriority().longValue());
303         Assert.assertEquals(44, allValues.get(1).getOriginalFlow().getPriority().longValue());
304         Assert.assertEquals(45, allValues.get(1).getUpdatedFlow().getPriority().longValue());
305
306         inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
307     }
308
309     @Test
310     public void testUpdateFlowsBatch_failure() throws Exception {
311         Mockito.when(salFlowService.updateFlow(Matchers.<UpdateFlowInput>any()))
312                 .thenReturn(RpcResultBuilder.<UpdateFlowOutput>failed()
313                         .withError(RpcError.ErrorType.APPLICATION, "ut-flowUpdateError")
314                         .buildFuture());
315
316         final UpdateFlowsBatchInput input = new UpdateFlowsBatchInputBuilder()
317                 .setNode(NODE_REF)
318                 .setBarrierAfter(true)
319                 .setBatchUpdateFlows(Lists.newArrayList(
320                         createEmptyBatchUpdateFlow(FLOW_ID_VALUE_1, 42),
321                         createEmptyBatchUpdateFlow(FLOW_ID_VALUE_2, 44)))
322                 .build();
323
324         final Future<RpcResult<UpdateFlowsBatchOutput>> resultFuture = salFlowsBatchService.updateFlowsBatch(input);
325
326         Assert.assertTrue(resultFuture.isDone());
327         Assert.assertFalse(resultFuture.get().isSuccessful());
328         Assert.assertFalse(resultFuture.get().isSuccessful());
329         Assert.assertEquals(2, resultFuture.get().getResult().getBatchFailedFlowsOutput().size());
330         Assert.assertEquals(FLOW_ID_VALUE_1,
331                 resultFuture.get().getResult().getBatchFailedFlowsOutput().get(0).getFlowId().getValue());
332         Assert.assertEquals(FLOW_ID_VALUE_2,
333                 resultFuture.get().getResult().getBatchFailedFlowsOutput().get(1).getFlowId().getValue());
334         Assert.assertEquals(2, resultFuture.get().getErrors().size());
335
336         final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
337         inOrder.verify(salFlowService, Mockito.times(2)).updateFlow(updateFlowInputCpt.capture());
338         final List<UpdateFlowInput> allValues = updateFlowInputCpt.getAllValues();
339         Assert.assertEquals(2, allValues.size());
340         Assert.assertEquals(42, allValues.get(0).getOriginalFlow().getPriority().longValue());
341         Assert.assertEquals(43, allValues.get(0).getUpdatedFlow().getPriority().longValue());
342         Assert.assertEquals(44, allValues.get(1).getOriginalFlow().getPriority().longValue());
343         Assert.assertEquals(45, allValues.get(1).getUpdatedFlow().getPriority().longValue());
344
345         inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
346     }
347 }