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