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 com.google.common.util.concurrent.AsyncFunction;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.concurrent.Future;
18 import org.junit.After;
19 import org.junit.Assert;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.ArgumentCaptor;
24 import org.mockito.ArgumentMatchers;
25 import org.mockito.Captor;
26 import org.mockito.InOrder;
27 import org.mockito.Mock;
28 import org.mockito.Mockito;
29 import org.mockito.runners.MockitoJUnitRunner;
30 import org.opendaylight.openflowplugin.impl.services.batch.BatchPlanStep;
31 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepJob;
32 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepType;
33 import org.opendaylight.openflowplugin.impl.util.FlatBatchUtil;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.flow._case.FlatBatchAddFlow;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.flow._case.FlatBatchAddFlowBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.group._case.FlatBatchAddGroupBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.add.meter._case.FlatBatchAddMeterBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.flow._case.FlatBatchRemoveFlowBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.group._case.FlatBatchRemoveGroupBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.remove.meter._case.FlatBatchRemoveMeterBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.flow._case.FlatBatchUpdateFlowBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.group._case.FlatBatchUpdateGroupBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.flat.batch.update.meter._case.FlatBatchUpdateMeterBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCaseBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.RemoveFlowsBatchOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.SalFlowsBatchService;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.UpdateFlowsBatchOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchInput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.AddGroupsBatchOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.RemoveGroupsBatchOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.SalGroupsBatchService;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchInput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.UpdateGroupsBatchOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.OriginalBatchedGroupBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.groups.service.rev160315.batch.group.input.update.grouping.UpdatedBatchedGroupBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchInput;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.AddMetersBatchOutputBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchInput;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.RemoveMetersBatchOutputBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.SalMetersBatchService;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchInput;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.UpdateMetersBatchOutputBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.OriginalBatchedMeterBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.meters.service.rev160316.batch.meter.input.update.grouping.UpdatedBatchedMeterBuilder;
99 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
100 import org.opendaylight.yangtools.yang.common.RpcError;
101 import org.opendaylight.yangtools.yang.common.RpcResult;
102 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
105 * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
107 @RunWith(MockitoJUnitRunner.class)
108 public class SalFlatBatchServiceImplTest {
110 private static final NodeId NODE_ID = new NodeId("ut-node-id");
111 private static final InstanceIdentifier<Node> NODE_II = InstanceIdentifier.create(Nodes.class)
112 .child(Node.class, new NodeKey(NODE_ID));
113 private static final NodeRef NODE_REF = new NodeRef(NODE_II);
116 private SalFlowsBatchService salFlowsBatchService;
118 private SalGroupsBatchService salGroupsBatchService;
120 private SalMetersBatchService salMetersBatchService;
122 private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
124 private SalFlatBatchServiceImpl salFlatBatchService;
127 public void setUp() throws Exception {
128 salFlatBatchService =
129 new SalFlatBatchServiceImpl(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
134 public void tearDown() throws Exception {
135 Mockito.verifyNoMoreInteractions(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
139 public void testProcessFlatBatch_allSuccessFinished() throws Exception {
140 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any()))
141 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
142 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.<RemoveFlowsBatchInput>any()))
143 .thenReturn(RpcResultBuilder.success(new RemoveFlowsBatchOutputBuilder().build()).buildFuture());
144 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.<UpdateFlowsBatchInput>any()))
145 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
147 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.<AddGroupsBatchInput>any()))
148 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
149 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.<RemoveGroupsBatchInput>any()))
150 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
151 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.<UpdateGroupsBatchInput>any()))
152 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
154 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.<AddMetersBatchInput>any()))
155 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
156 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.<RemoveMetersBatchInput>any()))
157 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
158 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.<UpdateMetersBatchInput>any()))
159 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
162 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
164 .setBatch(Lists.newArrayList(
165 createFlowAddBatch(0, "f1"),
166 createFlowRemoveBatch(1, "f2"),
167 createFlowUpdateBatch(2, "f3"),
169 createGroupAddBatch(3, 1L),
170 createGroupRemoveBatch(4, 2L),
171 createGroupUpdateBatch(5, 3L),
173 createMeterAddBatch(3, 1L),
174 createMeterRemoveBatch(4, 2L),
175 createMeterUpdateBatch(5, 3L)
177 .setExitOnFirstError(true)
180 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
181 salFlatBatchService.processFlatBatch(batchInput);
182 Assert.assertTrue(rpcResultFuture.isDone());
183 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
184 Assert.assertTrue(rpcResult.isSuccessful());
185 Assert.assertTrue(rpcResult.getErrors().isEmpty());
186 Assert.assertTrue(rpcResult.getResult().getBatchFailure().isEmpty());
188 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
189 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any());
190 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.<RemoveFlowsBatchInput>any());
191 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.<UpdateFlowsBatchInput>any());
193 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.<AddGroupsBatchInput>any());
194 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.<RemoveGroupsBatchInput>any());
195 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.<UpdateGroupsBatchInput>any());
197 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.<AddMetersBatchInput>any());
198 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.<RemoveMetersBatchInput>any());
199 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.<UpdateMetersBatchInput>any());
203 public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
204 prepareFirstFailingMockService();
207 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
209 .setBatch(Lists.newArrayList(
210 createFlowAddBatch(idx++, "f1", 2),
211 createFlowRemoveBatch(idx++, "f2"),
212 createFlowUpdateBatch(idx++, "f3"),
214 createGroupAddBatch(idx++, 1L),
215 createGroupRemoveBatch(idx++, 2L),
216 createGroupUpdateBatch(idx++, 3L),
218 createMeterAddBatch(idx++, 1L),
219 createMeterRemoveBatch(idx++, 2L),
220 createMeterUpdateBatch(idx++, 3L)
222 .setExitOnFirstError(true)
225 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
226 salFlatBatchService.processFlatBatch(batchInput);
227 Assert.assertTrue(rpcResultFuture.isDone());
228 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
229 Assert.assertFalse(rpcResult.isSuccessful());
230 Assert.assertEquals(1, rpcResult.getErrors().size());
231 Assert.assertEquals(1, rpcResult.getResult().getBatchFailure().size());
232 Assert.assertEquals(3, rpcResult.getResult().getBatchFailure().get(0).getBatchOrder().intValue());
234 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
235 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any());
236 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.<RemoveFlowsBatchInput>any());
237 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.<UpdateFlowsBatchInput>any());
238 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.<AddGroupsBatchInput>any());
242 public void testProcessFlatBatch_firstFailedContinue() throws Exception {
243 prepareFirstFailingMockService();
246 ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
248 .setBatch(Lists.newArrayList(
249 createFlowAddBatch(idx++, "f1", 2),
250 createFlowRemoveBatch(idx++, "f2"),
251 createFlowUpdateBatch(idx++, "f3"),
253 createGroupAddBatch(idx++, 1L),
254 createGroupRemoveBatch(idx++, 2L),
255 createGroupUpdateBatch(idx++, 3L),
257 createMeterAddBatch(idx++, 1L),
258 createMeterRemoveBatch(idx++, 2L),
259 createMeterUpdateBatch(idx++, 3L)
261 .setExitOnFirstError(false)
264 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
265 salFlatBatchService.processFlatBatch(batchInput);
266 Assert.assertTrue(rpcResultFuture.isDone());
267 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
268 Assert.assertFalse(rpcResult.isSuccessful());
269 Assert.assertEquals(1, rpcResult.getErrors().size());
270 Assert.assertEquals(1, rpcResult.getResult().getBatchFailure().size());
271 Assert.assertEquals(3, rpcResult.getResult().getBatchFailure().get(0).getBatchOrder().intValue());
273 final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
274 inOrder.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any());
275 inOrder.verify(salFlowsBatchService).removeFlowsBatch(ArgumentMatchers.<RemoveFlowsBatchInput>any());
276 inOrder.verify(salFlowsBatchService).updateFlowsBatch(ArgumentMatchers.<UpdateFlowsBatchInput>any());
278 inOrder.verify(salGroupsBatchService).addGroupsBatch(ArgumentMatchers.<AddGroupsBatchInput>any());
279 inOrder.verify(salGroupsBatchService).removeGroupsBatch(ArgumentMatchers.<RemoveGroupsBatchInput>any());
280 inOrder.verify(salGroupsBatchService).updateGroupsBatch(ArgumentMatchers.<UpdateGroupsBatchInput>any());
282 inOrder.verify(salMetersBatchService).addMetersBatch(ArgumentMatchers.<AddMetersBatchInput>any());
283 inOrder.verify(salMetersBatchService).removeMetersBatch(ArgumentMatchers.<RemoveMetersBatchInput>any());
284 inOrder.verify(salMetersBatchService).updateMetersBatch(ArgumentMatchers.<UpdateMetersBatchInput>any());
287 private void prepareFirstFailingMockService() {
288 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any()))
289 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
290 Mockito.when(salFlowsBatchService.removeFlowsBatch(ArgumentMatchers.<RemoveFlowsBatchInput>any()))
291 .thenReturn(RpcResultBuilder.<RemoveFlowsBatchOutput>failed()
292 .withResult(new RemoveFlowsBatchOutputBuilder()
293 .setBatchFailedFlowsOutput(Lists.newArrayList(
294 new BatchFailedFlowsOutputBuilder()
296 .setFlowId(new FlowId("123"))
299 .withError(RpcError.ErrorType.APPLICATION, "ut-firstFlowAddError")
301 Mockito.when(salFlowsBatchService.updateFlowsBatch(ArgumentMatchers.<UpdateFlowsBatchInput>any()))
302 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
304 Mockito.when(salGroupsBatchService.addGroupsBatch(ArgumentMatchers.<AddGroupsBatchInput>any()))
305 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
306 Mockito.when(salGroupsBatchService.removeGroupsBatch(ArgumentMatchers.<RemoveGroupsBatchInput>any()))
307 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
308 Mockito.when(salGroupsBatchService.updateGroupsBatch(ArgumentMatchers.<UpdateGroupsBatchInput>any()))
309 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
311 Mockito.when(salMetersBatchService.addMetersBatch(ArgumentMatchers.<AddMetersBatchInput>any()))
312 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
313 Mockito.when(salMetersBatchService.removeMetersBatch(ArgumentMatchers.<RemoveMetersBatchInput>any()))
314 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
315 Mockito.when(salMetersBatchService.updateMetersBatch(ArgumentMatchers.<UpdateMetersBatchInput>any()))
316 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
319 private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
320 return createFlowAddBatch(batchOrder, flowIdValue, 1);
323 private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue, int amount) {
324 return new BatchBuilder()
325 .setBatchOrder(batchOrder)
326 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
327 .setFlatBatchAddFlow(repeatInList(new FlatBatchAddFlowBuilder()
328 .setFlowId(new FlowId(flowIdValue))
334 private <T> List<T> repeatInList(final T item, final int amount) {
335 final List<T> list = new ArrayList<>();
336 for (int i = 0; i < amount; i++) {
342 private Batch createFlowRemoveBatch(final int batchOrder, final String flowIdValue) {
343 return new BatchBuilder()
344 .setBatchOrder(batchOrder)
345 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
346 .setFlatBatchRemoveFlow(Collections.singletonList(new FlatBatchRemoveFlowBuilder()
347 .setFlowId(new FlowId(flowIdValue))
353 private Batch createFlowUpdateBatch(final int batchOrder, final String flowIdValue) {
354 return new BatchBuilder()
355 .setBatchOrder(batchOrder)
356 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
357 .setFlatBatchUpdateFlow(Collections.singletonList(new FlatBatchUpdateFlowBuilder()
358 .setFlowId(new FlowId(flowIdValue))
364 private Batch createGroupAddBatch(final int batchOrder, final long groupIdValue) {
365 return new BatchBuilder()
366 .setBatchOrder(batchOrder)
367 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
368 .setFlatBatchAddGroup(Collections.singletonList(new FlatBatchAddGroupBuilder()
369 .setGroupId(new GroupId(groupIdValue))
375 private Batch createGroupRemoveBatch(final int batchOrder, final long groupIdValue) {
376 return new BatchBuilder()
377 .setBatchOrder(batchOrder)
378 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
379 .setFlatBatchRemoveGroup(Collections.singletonList(new FlatBatchRemoveGroupBuilder()
380 .setGroupId(new GroupId(groupIdValue))
386 private Batch createGroupUpdateBatch(final int batchOrder, final long groupIdValue) {
387 return new BatchBuilder()
388 .setBatchOrder(batchOrder)
389 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
390 .setFlatBatchUpdateGroup(Collections.singletonList(new FlatBatchUpdateGroupBuilder()
391 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder()
392 .setGroupId(new GroupId(groupIdValue))
394 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
395 .setGroupId(new GroupId(groupIdValue))
402 private Batch createMeterAddBatch(final int batchOrder, final long groupIdValue) {
403 return new BatchBuilder()
404 .setBatchOrder(batchOrder)
405 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
406 .setFlatBatchAddMeter(Collections.singletonList(new FlatBatchAddMeterBuilder()
407 .setMeterId(new MeterId(groupIdValue))
413 private Batch createMeterRemoveBatch(final int batchOrder, final long groupIdValue) {
414 return new BatchBuilder()
415 .setBatchOrder(batchOrder)
416 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
417 .setFlatBatchRemoveMeter(Collections.singletonList(new FlatBatchRemoveMeterBuilder()
418 .setMeterId(new MeterId(groupIdValue))
424 private Batch createMeterUpdateBatch(final int batchOrder, final long groupIdValue) {
425 return new BatchBuilder()
426 .setBatchOrder(batchOrder)
427 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
428 .setFlatBatchUpdateMeter(Collections.singletonList(new FlatBatchUpdateMeterBuilder()
429 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder()
430 .setMeterId(new MeterId(groupIdValue))
432 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
433 .setMeterId(new MeterId(groupIdValue))
441 public void testExecuteBatchPlan() throws Exception {
442 BatchStepJob batchStepJob1 = Mockito.mock(BatchStepJob.class);
443 BatchStepJob batchStepJob2 = Mockito.mock(BatchStepJob.class);
444 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function1 =
445 Mockito.mock(AsyncFunction.class);
446 AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function2 =
447 Mockito.mock(AsyncFunction.class);
448 Mockito.when(batchStepJob1.getStepFunction()).thenReturn(function1);
449 Mockito.when(batchStepJob2.getStepFunction()).thenReturn(function2);
450 BatchPlanStep batchPlanStep1 = new BatchPlanStep(BatchStepType.GROUP_ADD);
451 batchPlanStep1.setBarrierAfter(true);
452 BatchPlanStep batchPlanStep2 = new BatchPlanStep(BatchStepType.FLOW_ADD);
453 batchPlanStep1.setBarrierAfter(false);
454 Mockito.when(batchStepJob1.getPlanStep()).thenReturn(batchPlanStep1);
455 Mockito.when(batchStepJob2.getPlanStep()).thenReturn(batchPlanStep2);
457 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> succeededChainOutput =
458 FlatBatchUtil.createEmptyRpcBatchResultFuture(true);
459 final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> failedChainOutput =
460 RpcResultBuilder.<ProcessFlatBatchOutput>failed()
461 .withError(RpcError.ErrorType.APPLICATION, "ut-chainError")
462 .withResult(createFlatBatchOutput(createFlowBatchFailure(0, "f1"),
463 createFlowBatchFailure(1, "f2")))
466 Mockito.when(batchStepJob1.getStepFunction().apply(ArgumentMatchers.<RpcResult<ProcessFlatBatchOutput>>any()))
467 .thenReturn(succeededChainOutput);
468 Mockito.when(batchStepJob2.getStepFunction().apply(ArgumentMatchers.<RpcResult<ProcessFlatBatchOutput>>any()))
469 .thenReturn(failedChainOutput);
471 final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
472 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
473 salFlatBatchService.executeBatchPlan(batchChainElements);
475 Assert.assertTrue(rpcResultFuture.isDone());
476 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
477 Assert.assertFalse(rpcResult.isSuccessful());
478 Assert.assertEquals(1, rpcResult.getErrors().size());
479 Assert.assertEquals(2, rpcResult.getResult().getBatchFailure().size());
480 Assert.assertEquals("f2",
481 ((FlatBatchFailureFlowIdCase) rpcResult.getResult().getBatchFailure().get(1).getBatchItemIdChoice())
482 .getFlowId().getValue());
485 private BatchFailure createFlowBatchFailure(final int batchOrder, final String flowIdValue) {
486 return new BatchFailureBuilder()
487 .setBatchOrder(batchOrder)
488 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
489 .setFlowId(new FlowId(flowIdValue))
494 private ProcessFlatBatchOutput createFlatBatchOutput(BatchFailure... batchFailures) {
495 return new ProcessFlatBatchOutputBuilder()
496 .setBatchFailure(Lists.newArrayList(batchFailures))
501 public void testPrepareBatchPlan_success() throws Exception {
502 final FlatBatchAddFlow flatBatchAddFlow = new FlatBatchAddFlowBuilder()
503 .setFlowId(new FlowId("f1"))
505 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
506 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow, flatBatchAddFlow));
507 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep);
509 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
511 Assert.assertEquals(1, batchChain.size());
513 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any()))
514 .thenReturn(RpcResultBuilder
515 .success(new AddFlowsBatchOutputBuilder().build())
518 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
519 salFlatBatchService.executeBatchPlan(batchChain);
520 Assert.assertTrue(rpcResultFuture.isDone());
521 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
522 Assert.assertTrue(rpcResult.isSuccessful());
523 Assert.assertEquals(0, rpcResult.getErrors().size());
524 Assert.assertEquals(0, rpcResult.getResult().getBatchFailure().size());
526 Mockito.verify(salFlowsBatchService).addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any());
530 public void testPrepareBatchPlan_failure() throws Exception {
531 final FlatBatchAddFlow flatBatchAddFlow = new FlatBatchAddFlowBuilder()
532 .setFlowId(new FlowId("f1"))
534 final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
535 batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow, flatBatchAddFlow));
537 final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
539 final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
541 Assert.assertEquals(2, batchChain.size());
543 Mockito.when(salFlowsBatchService.addFlowsBatch(ArgumentMatchers.<AddFlowsBatchInput>any()))
544 .thenReturn(RpcResultBuilder
545 .<AddFlowsBatchOutput>failed()
546 .withResult(new AddFlowsBatchOutputBuilder()
547 .setBatchFailedFlowsOutput(Lists.newArrayList(
548 new BatchFailedFlowsOutputBuilder()
550 .setFlowId(new FlowId("f1"))
552 new BatchFailedFlowsOutputBuilder()
554 .setFlowId(new FlowId("f2"))
557 .withError(RpcError.ErrorType.APPLICATION, "ut-addFlowBatchError")
560 final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture =
561 salFlatBatchService.executeBatchPlan(batchChain);
562 Assert.assertTrue(rpcResultFuture.isDone());
563 final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
564 Assert.assertFalse(rpcResult.isSuccessful());
565 Assert.assertEquals(2, rpcResult.getErrors().size());
566 Assert.assertEquals(4, rpcResult.getResult().getBatchFailure().size());
568 Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
569 Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());