2 * Copyright (c) 2017 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowplugin.impl.services.sal;
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.types.rev131026.flow.MatchBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchOutput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlows;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.add.flows.batch.input.BatchAddFlowsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.OriginalBatchedFlowBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.input.update.grouping.UpdatedBatchedFlowBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlows;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.remove.flows.batch.input.BatchRemoveFlowsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlows;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.update.flows.batch.input.BatchUpdateFlowsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.opendaylight.yangtools.yang.common.RpcError;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
65 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
70 * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlowsBatchServiceImpl}.
72 @RunWith(MockitoJUnitRunner.class)
73 public class SalFlowsBatchServiceImplTest {
75 private static final Logger LOG = LoggerFactory.getLogger(SalFlowsBatchServiceImplTest.class);
77 public static final NodeId NODE_ID = new NodeId("ut-dummy-node");
78 public static final NodeKey NODE_KEY = new NodeKey(NODE_ID);
79 public static final NodeRef NODE_REF = new NodeRef(InstanceIdentifier.create(Nodes.class).child(Node.class, NODE_KEY));
82 private SalFlowService salFlowService;
84 private FlowCapableTransactionService transactionService;
86 private ArgumentCaptor<RemoveFlowInput> removeFlowInputCpt;
88 private ArgumentCaptor<UpdateFlowInput> updateFlowInputCpt;
90 private ArgumentCaptor<AddFlowInput> addFlowInputCpt;
92 private SalFlowsBatchServiceImpl salFlowsBatchService;
93 public static final String FLOW_ID_VALUE_1 = "ut-dummy-flow1";
94 public static final String FLOW_ID_VALUE_2 = "ut-dummy-flow2";
97 public void setUp() throws Exception {
98 salFlowsBatchService = new SalFlowsBatchServiceImpl(salFlowService, transactionService);
100 Mockito.when(transactionService.sendBarrier(Matchers.<SendBarrierInput>any()))
101 .thenReturn(RpcResultBuilder.<Void>success().buildFuture());
105 public void tearDown() throws Exception {
106 Mockito.verifyNoMoreInteractions(salFlowService, transactionService);
110 public void testRemoveFlowsBatch_success() throws Exception {
111 Mockito.when(salFlowService.removeFlow(Matchers.<RemoveFlowInput>any()))
112 .thenReturn(RpcResultBuilder.success(new RemoveFlowOutputBuilder().build())
115 final String flow1IdValue = "ut-dummy-flow1";
116 final String flow2IdValue = "ut-dummy-flow2";
117 final BatchRemoveFlows batchFlow1 = createEmptyBatchRemoveFlow(flow1IdValue, 42);
118 final BatchRemoveFlows batchFlow2 = createEmptyBatchRemoveFlow(flow2IdValue, 43);
120 final RemoveFlowsBatchInput input = new RemoveFlowsBatchInputBuilder()
122 .setBarrierAfter(true)
123 .setBatchRemoveFlows(Lists.newArrayList(batchFlow1, batchFlow2))
126 final Future<RpcResult<RemoveFlowsBatchOutput>> resultFuture = salFlowsBatchService.removeFlowsBatch(input);
128 Assert.assertTrue(resultFuture.isDone());
129 final RpcResult<RemoveFlowsBatchOutput> rpcResult = resultFuture.get();
130 Assert.assertTrue(rpcResult.isSuccessful());
131 final RemoveFlowsBatchOutput result = rpcResult.getResult();
132 Assert.assertEquals(0, result.getBatchFailedFlowsOutput().size());
134 final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
136 inOrder.verify(salFlowService, Mockito.times(2)).removeFlow(removeFlowInputCpt.capture());
137 final List<RemoveFlowInput> allValues = removeFlowInputCpt.getAllValues();
138 Assert.assertEquals(2, allValues.size());
139 Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
140 Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
142 inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
146 public void testRemoveFlowsBatch_failed() throws Exception {
147 Mockito.when(salFlowService.removeFlow(Matchers.<RemoveFlowInput>any()))
148 .thenReturn(RpcResultBuilder.<RemoveFlowOutput>failed()
149 .withError(RpcError.ErrorType.APPLICATION, "flow-remove-fail-1")
152 final BatchRemoveFlows batchFlow1 = createEmptyBatchRemoveFlow(FLOW_ID_VALUE_1, 42);
153 final BatchRemoveFlows batchFlow2 = createEmptyBatchRemoveFlow(FLOW_ID_VALUE_2, 43);
155 final RemoveFlowsBatchInput input = new RemoveFlowsBatchInputBuilder()
157 .setBarrierAfter(true)
158 .setBatchRemoveFlows(Lists.newArrayList(batchFlow1, batchFlow2))
161 final Future<RpcResult<RemoveFlowsBatchOutput>> resultFuture = salFlowsBatchService.removeFlowsBatch(input);
163 Assert.assertTrue(resultFuture.isDone());
164 final RpcResult<RemoveFlowsBatchOutput> rpcResult = resultFuture.get();
165 Assert.assertFalse(rpcResult.isSuccessful());
166 final RemoveFlowsBatchOutput result = rpcResult.getResult();
167 Assert.assertEquals(2, result.getBatchFailedFlowsOutput().size());
168 Assert.assertEquals(FLOW_ID_VALUE_1, result.getBatchFailedFlowsOutput().get(0).getFlowId().getValue());
169 Assert.assertEquals(FLOW_ID_VALUE_2, result.getBatchFailedFlowsOutput().get(1).getFlowId().getValue());
171 final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
173 inOrder.verify(salFlowService, Mockito.times(2)).removeFlow(removeFlowInputCpt.capture());
174 final List<RemoveFlowInput> allValues = removeFlowInputCpt.getAllValues();
175 Assert.assertEquals(2, allValues.size());
176 Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
177 Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
179 inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
182 private static BatchAddFlows createEmptyBatchAddFlow(final String flowIdValue, final int priority) {
183 return new BatchAddFlowsBuilder()
184 .setFlowId(new FlowId(flowIdValue))
185 .setPriority(priority)
186 .setMatch(new MatchBuilder().build())
187 .setTableId((short) 0)
191 private static BatchRemoveFlows createEmptyBatchRemoveFlow(final String flowIdValue, final int priority) {
192 return new BatchRemoveFlowsBuilder()
193 .setFlowId(new FlowId(flowIdValue))
194 .setPriority(priority)
195 .setMatch(new MatchBuilder().build())
196 .setTableId((short) 0)
200 private static BatchUpdateFlows createEmptyBatchUpdateFlow(final String flowIdValue, final int priority) {
201 final BatchAddFlows emptyOriginalFlow = createEmptyBatchAddFlow(flowIdValue, priority);
202 final BatchAddFlows emptyUpdatedFlow = createEmptyBatchAddFlow(flowIdValue, priority + 1);
203 return new BatchUpdateFlowsBuilder()
204 .setFlowId(new FlowId(flowIdValue))
205 .setOriginalBatchedFlow(new OriginalBatchedFlowBuilder(emptyOriginalFlow).build())
206 .setUpdatedBatchedFlow(new UpdatedBatchedFlowBuilder(emptyUpdatedFlow).build())
211 public void testAddFlowsBatch_success() throws Exception {
212 Mockito.when(salFlowService.addFlow(Matchers.<AddFlowInput>any()))
213 .thenReturn(RpcResultBuilder.success(new AddFlowOutputBuilder().build()).buildFuture());
215 final AddFlowsBatchInput input = new AddFlowsBatchInputBuilder()
217 .setBarrierAfter(true)
218 .setBatchAddFlows(Lists.newArrayList(
219 createEmptyBatchAddFlow("ut-dummy-flow1", 42),
220 createEmptyBatchAddFlow("ut-dummy-flow2", 43)))
223 final Future<RpcResult<AddFlowsBatchOutput>> resultFuture = salFlowsBatchService.addFlowsBatch(input);
225 Assert.assertTrue(resultFuture.isDone());
226 Assert.assertTrue(resultFuture.get().isSuccessful());
228 final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
230 inOrder.verify(salFlowService, Mockito.times(2)).addFlow(addFlowInputCpt.capture());
231 final List<AddFlowInput> allValues = addFlowInputCpt.getAllValues();
232 Assert.assertEquals(2, allValues.size());
233 Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
234 Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
236 inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
240 public void testAddFlowsBatch_failed() throws Exception {
241 Mockito.when(salFlowService.addFlow(Matchers.<AddFlowInput>any()))
242 .thenReturn(RpcResultBuilder.<AddFlowOutput>failed().withError(RpcError.ErrorType.APPLICATION, "ut-groupAddError")
245 final AddFlowsBatchInput input = new AddFlowsBatchInputBuilder()
247 .setBarrierAfter(true)
248 .setBatchAddFlows(Lists.newArrayList(
249 createEmptyBatchAddFlow(FLOW_ID_VALUE_1, 42),
250 createEmptyBatchAddFlow(FLOW_ID_VALUE_2, 43)))
253 final Future<RpcResult<AddFlowsBatchOutput>> resultFuture = salFlowsBatchService.addFlowsBatch(input);
255 Assert.assertTrue(resultFuture.isDone());
256 Assert.assertFalse(resultFuture.get().isSuccessful());
257 Assert.assertEquals(2, resultFuture.get().getResult().getBatchFailedFlowsOutput().size());
258 Assert.assertEquals(FLOW_ID_VALUE_1, resultFuture.get().getResult().getBatchFailedFlowsOutput().get(0).getFlowId().getValue());
259 Assert.assertEquals(FLOW_ID_VALUE_2, resultFuture.get().getResult().getBatchFailedFlowsOutput().get(1).getFlowId().getValue());
260 Assert.assertEquals(2, resultFuture.get().getErrors().size());
262 final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
264 inOrder.verify(salFlowService, Mockito.times(2)).addFlow(addFlowInputCpt.capture());
265 final List<AddFlowInput> allValues = addFlowInputCpt.getAllValues();
266 Assert.assertEquals(2, allValues.size());
267 Assert.assertEquals(42, allValues.get(0).getPriority().longValue());
268 Assert.assertEquals(43, allValues.get(1).getPriority().longValue());
270 inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
274 public void testUpdateFlowsBatch_success() throws Exception {
275 Mockito.when(salFlowService.updateFlow(Matchers.<UpdateFlowInput>any()))
276 .thenReturn(RpcResultBuilder.success(new UpdateFlowOutputBuilder().build()).buildFuture());
278 final UpdateFlowsBatchInput input = new UpdateFlowsBatchInputBuilder()
280 .setBarrierAfter(true)
281 .setBatchUpdateFlows(Lists.newArrayList(
282 createEmptyBatchUpdateFlow(FLOW_ID_VALUE_1, 42),
283 createEmptyBatchUpdateFlow(FLOW_ID_VALUE_2, 44)))
286 final Future<RpcResult<UpdateFlowsBatchOutput>> resultFuture = salFlowsBatchService.updateFlowsBatch(input);
288 Assert.assertTrue(resultFuture.isDone());
289 Assert.assertTrue(resultFuture.get().isSuccessful());
291 final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
293 inOrder.verify(salFlowService, Mockito.times(2)).updateFlow(updateFlowInputCpt.capture());
294 final List<UpdateFlowInput> allValues = updateFlowInputCpt.getAllValues();
295 Assert.assertEquals(2, allValues.size());
296 Assert.assertEquals(42, allValues.get(0).getOriginalFlow().getPriority().longValue());
297 Assert.assertEquals(43, allValues.get(0).getUpdatedFlow().getPriority().longValue());
298 Assert.assertEquals(44, allValues.get(1).getOriginalFlow().getPriority().longValue());
299 Assert.assertEquals(45, allValues.get(1).getUpdatedFlow().getPriority().longValue());
301 inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
305 public void testUpdateFlowsBatch_failure() throws Exception {
306 Mockito.when(salFlowService.updateFlow(Matchers.<UpdateFlowInput>any()))
307 .thenReturn(RpcResultBuilder.<UpdateFlowOutput>failed().withError(RpcError.ErrorType.APPLICATION, "ut-flowUpdateError")
310 final UpdateFlowsBatchInput input = new UpdateFlowsBatchInputBuilder()
312 .setBarrierAfter(true)
313 .setBatchUpdateFlows(Lists.newArrayList(
314 createEmptyBatchUpdateFlow(FLOW_ID_VALUE_1, 42),
315 createEmptyBatchUpdateFlow(FLOW_ID_VALUE_2, 44)))
318 final Future<RpcResult<UpdateFlowsBatchOutput>> resultFuture = salFlowsBatchService.updateFlowsBatch(input);
320 Assert.assertTrue(resultFuture.isDone());
321 Assert.assertFalse(resultFuture.get().isSuccessful());
322 Assert.assertFalse(resultFuture.get().isSuccessful());
323 Assert.assertEquals(2, resultFuture.get().getResult().getBatchFailedFlowsOutput().size());
324 Assert.assertEquals(FLOW_ID_VALUE_1, resultFuture.get().getResult().getBatchFailedFlowsOutput().get(0).getFlowId().getValue());
325 Assert.assertEquals(FLOW_ID_VALUE_2, resultFuture.get().getResult().getBatchFailedFlowsOutput().get(1).getFlowId().getValue());
326 Assert.assertEquals(2, resultFuture.get().getErrors().size());
328 final InOrder inOrder = Mockito.inOrder(salFlowService, transactionService);
329 inOrder.verify(salFlowService, Mockito.times(2)).updateFlow(updateFlowInputCpt.capture());
330 final List<UpdateFlowInput> allValues = updateFlowInputCpt.getAllValues();
331 Assert.assertEquals(2, allValues.size());
332 Assert.assertEquals(42, allValues.get(0).getOriginalFlow().getPriority().longValue());
333 Assert.assertEquals(43, allValues.get(0).getUpdatedFlow().getPriority().longValue());
334 Assert.assertEquals(44, allValues.get(1).getOriginalFlow().getPriority().longValue());
335 Assert.assertEquals(45, allValues.get(1).getUpdatedFlow().getPriority().longValue());
337 inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());