Merge "Fix connection when slave role request is unsupported"
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / services / sal / SalFlatBatchServiceImplTest.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 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.Captor;
25 import org.mockito.InOrder;
26 import org.mockito.Matchers;
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;
103
104 /**
105  * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
106  */
107 @RunWith(MockitoJUnitRunner.class)
108 public class SalFlatBatchServiceImplTest {
109
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);
114
115     @Mock
116     private SalFlowsBatchService salFlowsBatchService;
117     @Mock
118     private SalGroupsBatchService salGroupsBatchService;
119     @Mock
120     private SalMetersBatchService salMetersBatchService;
121     @Captor
122     private ArgumentCaptor<AddFlowsBatchInput> addFlowsBatchInputCpt;
123
124     private SalFlatBatchServiceImpl salFlatBatchService;
125
126     @Before
127     public void setUp() throws Exception {
128         salFlatBatchService = new SalFlatBatchServiceImpl(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
129
130     }
131
132     @After
133     public void tearDown() throws Exception {
134         Mockito.verifyNoMoreInteractions(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
135     }
136
137     @Test
138     public void testProcessFlatBatch_allSuccessFinished() throws Exception {
139         Mockito.when(salFlowsBatchService.addFlowsBatch(Matchers.<AddFlowsBatchInput>any()))
140                 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
141         Mockito.when(salFlowsBatchService.removeFlowsBatch(Matchers.<RemoveFlowsBatchInput>any()))
142                 .thenReturn(RpcResultBuilder.success(new RemoveFlowsBatchOutputBuilder().build()).buildFuture());
143         Mockito.when(salFlowsBatchService.updateFlowsBatch(Matchers.<UpdateFlowsBatchInput>any()))
144                 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
145
146         Mockito.when(salGroupsBatchService.addGroupsBatch(Matchers.<AddGroupsBatchInput>any()))
147                 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
148         Mockito.when(salGroupsBatchService.removeGroupsBatch(Matchers.<RemoveGroupsBatchInput>any()))
149                 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
150         Mockito.when(salGroupsBatchService.updateGroupsBatch(Matchers.<UpdateGroupsBatchInput>any()))
151                 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
152
153         Mockito.when(salMetersBatchService.addMetersBatch(Matchers.<AddMetersBatchInput>any()))
154                 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
155         Mockito.when(salMetersBatchService.removeMetersBatch(Matchers.<RemoveMetersBatchInput>any()))
156                 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
157         Mockito.when(salMetersBatchService.updateMetersBatch(Matchers.<UpdateMetersBatchInput>any()))
158                 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
159
160
161         ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
162                 .setNode(NODE_REF)
163                 .setBatch(Lists.newArrayList(
164                         createFlowAddBatch(0, "f1"),
165                         createFlowRemoveBatch(1, "f2"),
166                         createFlowUpdateBatch(2, "f3"),
167
168                         createGroupAddBatch(3, 1L),
169                         createGroupRemoveBatch(4, 2L),
170                         createGroupUpdateBatch(5, 3L),
171
172                         createMeterAddBatch(3, 1L),
173                         createMeterRemoveBatch(4, 2L),
174                         createMeterUpdateBatch(5, 3L)
175                 ))
176                 .setExitOnFirstError(true)
177                 .build();
178
179         final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = salFlatBatchService.processFlatBatch(batchInput);
180         Assert.assertTrue(rpcResultFuture.isDone());
181         final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
182         Assert.assertTrue(rpcResult.isSuccessful());
183         Assert.assertTrue(rpcResult.getErrors().isEmpty());
184         Assert.assertTrue(rpcResult.getResult().getBatchFailure().isEmpty());
185
186         final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
187         inOrder.verify(salFlowsBatchService).addFlowsBatch(Matchers.<AddFlowsBatchInput>any());
188         inOrder.verify(salFlowsBatchService).removeFlowsBatch(Matchers.<RemoveFlowsBatchInput>any());
189         inOrder.verify(salFlowsBatchService).updateFlowsBatch(Matchers.<UpdateFlowsBatchInput>any());
190
191         inOrder.verify(salGroupsBatchService).addGroupsBatch(Matchers.<AddGroupsBatchInput>any());
192         inOrder.verify(salGroupsBatchService).removeGroupsBatch(Matchers.<RemoveGroupsBatchInput>any());
193         inOrder.verify(salGroupsBatchService).updateGroupsBatch(Matchers.<UpdateGroupsBatchInput>any());
194
195         inOrder.verify(salMetersBatchService).addMetersBatch(Matchers.<AddMetersBatchInput>any());
196         inOrder.verify(salMetersBatchService).removeMetersBatch(Matchers.<RemoveMetersBatchInput>any());
197         inOrder.verify(salMetersBatchService).updateMetersBatch(Matchers.<UpdateMetersBatchInput>any());
198     }
199
200     @Test
201     public void testProcessFlatBatch_firstFailedInterrupted() throws Exception {
202         prepareFirstFailingMockService();
203
204         int idx = 0;
205         ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
206                 .setNode(NODE_REF)
207                 .setBatch(Lists.newArrayList(
208                         createFlowAddBatch(idx++, "f1", 2),
209                         createFlowRemoveBatch(idx++, "f2"),
210                         createFlowUpdateBatch(idx++, "f3"),
211
212                         createGroupAddBatch(idx++, 1L),
213                         createGroupRemoveBatch(idx++, 2L),
214                         createGroupUpdateBatch(idx++, 3L),
215
216                         createMeterAddBatch(idx++, 1L),
217                         createMeterRemoveBatch(idx++, 2L),
218                         createMeterUpdateBatch(idx++, 3L)
219                 ))
220                 .setExitOnFirstError(true)
221                 .build();
222
223         final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = salFlatBatchService.processFlatBatch(batchInput);
224         Assert.assertTrue(rpcResultFuture.isDone());
225         final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
226         Assert.assertFalse(rpcResult.isSuccessful());
227         Assert.assertEquals(1, rpcResult.getErrors().size());
228         Assert.assertEquals(1, rpcResult.getResult().getBatchFailure().size());
229         Assert.assertEquals(3, rpcResult.getResult().getBatchFailure().get(0).getBatchOrder().intValue());
230
231         final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
232         inOrder.verify(salFlowsBatchService).addFlowsBatch(Matchers.<AddFlowsBatchInput>any());
233         inOrder.verify(salFlowsBatchService).removeFlowsBatch(Matchers.<RemoveFlowsBatchInput>any());
234         inOrder.verify(salFlowsBatchService).updateFlowsBatch(Matchers.<UpdateFlowsBatchInput>any());
235         inOrder.verify(salGroupsBatchService).addGroupsBatch(Matchers.<AddGroupsBatchInput>any());
236     }
237
238     @Test
239     public void testProcessFlatBatch_firstFailedContinue() throws Exception {
240         prepareFirstFailingMockService();
241
242         int idx = 0;
243         ProcessFlatBatchInput batchInput = new ProcessFlatBatchInputBuilder()
244                 .setNode(NODE_REF)
245                 .setBatch(Lists.newArrayList(
246                         createFlowAddBatch(idx++, "f1", 2),
247                         createFlowRemoveBatch(idx++, "f2"),
248                         createFlowUpdateBatch(idx++, "f3"),
249
250                         createGroupAddBatch(idx++, 1L),
251                         createGroupRemoveBatch(idx++, 2L),
252                         createGroupUpdateBatch(idx++, 3L),
253
254                         createMeterAddBatch(idx++, 1L),
255                         createMeterRemoveBatch(idx++, 2L),
256                         createMeterUpdateBatch(idx++, 3L)
257                 ))
258                 .setExitOnFirstError(false)
259                 .build();
260
261         final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = salFlatBatchService.processFlatBatch(batchInput);
262         Assert.assertTrue(rpcResultFuture.isDone());
263         final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
264         Assert.assertFalse(rpcResult.isSuccessful());
265         Assert.assertEquals(1, rpcResult.getErrors().size());
266         Assert.assertEquals(1, rpcResult.getResult().getBatchFailure().size());
267         Assert.assertEquals(3, rpcResult.getResult().getBatchFailure().get(0).getBatchOrder().intValue());
268
269         final InOrder inOrder = Mockito.inOrder(salFlowsBatchService, salGroupsBatchService, salMetersBatchService);
270         inOrder.verify(salFlowsBatchService).addFlowsBatch(Matchers.<AddFlowsBatchInput>any());
271         inOrder.verify(salFlowsBatchService).removeFlowsBatch(Matchers.<RemoveFlowsBatchInput>any());
272         inOrder.verify(salFlowsBatchService).updateFlowsBatch(Matchers.<UpdateFlowsBatchInput>any());
273
274         inOrder.verify(salGroupsBatchService).addGroupsBatch(Matchers.<AddGroupsBatchInput>any());
275         inOrder.verify(salGroupsBatchService).removeGroupsBatch(Matchers.<RemoveGroupsBatchInput>any());
276         inOrder.verify(salGroupsBatchService).updateGroupsBatch(Matchers.<UpdateGroupsBatchInput>any());
277
278         inOrder.verify(salMetersBatchService).addMetersBatch(Matchers.<AddMetersBatchInput>any());
279         inOrder.verify(salMetersBatchService).removeMetersBatch(Matchers.<RemoveMetersBatchInput>any());
280         inOrder.verify(salMetersBatchService).updateMetersBatch(Matchers.<UpdateMetersBatchInput>any());
281     }
282
283     private void prepareFirstFailingMockService() {
284         Mockito.when(salFlowsBatchService.addFlowsBatch(Matchers.<AddFlowsBatchInput>any()))
285                 .thenReturn(RpcResultBuilder.success(new AddFlowsBatchOutputBuilder().build()).buildFuture());
286         Mockito.when(salFlowsBatchService.removeFlowsBatch(Matchers.<RemoveFlowsBatchInput>any()))
287                 .thenReturn(RpcResultBuilder.<RemoveFlowsBatchOutput>failed()
288                         .withResult(new RemoveFlowsBatchOutputBuilder()
289                                 .setBatchFailedFlowsOutput(Lists.newArrayList(
290                                         new BatchFailedFlowsOutputBuilder()
291                                                 .setBatchOrder(1)
292                                                 .setFlowId(new FlowId("123"))
293                                                 .build()))
294                                 .build())
295                         .withError(RpcError.ErrorType.APPLICATION, "ut-firstFlowAddError")
296                         .buildFuture());
297         Mockito.when(salFlowsBatchService.updateFlowsBatch(Matchers.<UpdateFlowsBatchInput>any()))
298                 .thenReturn(RpcResultBuilder.success(new UpdateFlowsBatchOutputBuilder().build()).buildFuture());
299
300         Mockito.when(salGroupsBatchService.addGroupsBatch(Matchers.<AddGroupsBatchInput>any()))
301                 .thenReturn(RpcResultBuilder.success(new AddGroupsBatchOutputBuilder().build()).buildFuture());
302         Mockito.when(salGroupsBatchService.removeGroupsBatch(Matchers.<RemoveGroupsBatchInput>any()))
303                 .thenReturn(RpcResultBuilder.success(new RemoveGroupsBatchOutputBuilder().build()).buildFuture());
304         Mockito.when(salGroupsBatchService.updateGroupsBatch(Matchers.<UpdateGroupsBatchInput>any()))
305                 .thenReturn(RpcResultBuilder.success(new UpdateGroupsBatchOutputBuilder().build()).buildFuture());
306
307         Mockito.when(salMetersBatchService.addMetersBatch(Matchers.<AddMetersBatchInput>any()))
308                 .thenReturn(RpcResultBuilder.success(new AddMetersBatchOutputBuilder().build()).buildFuture());
309         Mockito.when(salMetersBatchService.removeMetersBatch(Matchers.<RemoveMetersBatchInput>any()))
310                 .thenReturn(RpcResultBuilder.success(new RemoveMetersBatchOutputBuilder().build()).buildFuture());
311         Mockito.when(salMetersBatchService.updateMetersBatch(Matchers.<UpdateMetersBatchInput>any()))
312                 .thenReturn(RpcResultBuilder.success(new UpdateMetersBatchOutputBuilder().build()).buildFuture());
313     }
314
315     private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue) {
316         return createFlowAddBatch(batchOrder, flowIdValue, 1);
317     }
318
319     private Batch createFlowAddBatch(final int batchOrder, final String flowIdValue, int amount) {
320         return new BatchBuilder()
321                 .setBatchOrder(batchOrder)
322                 .setBatchChoice(new FlatBatchAddFlowCaseBuilder()
323                         .setFlatBatchAddFlow(repeatInList(new FlatBatchAddFlowBuilder()
324                                 .setFlowId(new FlowId(flowIdValue))
325                                 .build(), amount))
326                         .build())
327                 .build();
328     }
329
330     private <T> List<T> repeatInList(final T item, final int amount) {
331         final List<T> list = new ArrayList<>();
332         for (int i = 0; i < amount; i++) {
333             list.add(item);
334         }
335         return list;
336     }
337
338     private Batch createFlowRemoveBatch(final int batchOrder, final String flowIdValue) {
339         return new BatchBuilder()
340                 .setBatchOrder(batchOrder)
341                 .setBatchChoice(new FlatBatchRemoveFlowCaseBuilder()
342                         .setFlatBatchRemoveFlow(Collections.singletonList(new FlatBatchRemoveFlowBuilder()
343                                 .setFlowId(new FlowId(flowIdValue))
344                                 .build()))
345                         .build())
346                 .build();
347     }
348
349     private Batch createFlowUpdateBatch(final int batchOrder, final String flowIdValue) {
350         return new BatchBuilder()
351                 .setBatchOrder(batchOrder)
352                 .setBatchChoice(new FlatBatchUpdateFlowCaseBuilder()
353                         .setFlatBatchUpdateFlow(Collections.singletonList(new FlatBatchUpdateFlowBuilder()
354                                 .setFlowId(new FlowId(flowIdValue))
355                                 .build()))
356                         .build())
357                 .build();
358     }
359
360     private Batch createGroupAddBatch(final int batchOrder, final long groupIdValue) {
361         return new BatchBuilder()
362                 .setBatchOrder(batchOrder)
363                 .setBatchChoice(new FlatBatchAddGroupCaseBuilder()
364                         .setFlatBatchAddGroup(Collections.singletonList(new FlatBatchAddGroupBuilder()
365                                 .setGroupId(new GroupId(groupIdValue))
366                                 .build()))
367                         .build())
368                 .build();
369     }
370
371     private Batch createGroupRemoveBatch(final int batchOrder, final long groupIdValue) {
372         return new BatchBuilder()
373                 .setBatchOrder(batchOrder)
374                 .setBatchChoice(new FlatBatchRemoveGroupCaseBuilder()
375                         .setFlatBatchRemoveGroup(Collections.singletonList(new FlatBatchRemoveGroupBuilder()
376                                 .setGroupId(new GroupId(groupIdValue))
377                                 .build()))
378                         .build())
379                 .build();
380     }
381
382     private Batch createGroupUpdateBatch(final int batchOrder, final long groupIdValue) {
383         return new BatchBuilder()
384                 .setBatchOrder(batchOrder)
385                 .setBatchChoice(new FlatBatchUpdateGroupCaseBuilder()
386                         .setFlatBatchUpdateGroup(Collections.singletonList(new FlatBatchUpdateGroupBuilder()
387                                 .setOriginalBatchedGroup(new OriginalBatchedGroupBuilder()
388                                         .setGroupId(new GroupId(groupIdValue))
389                                         .build())
390                                 .setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder()
391                                         .setGroupId(new GroupId(groupIdValue))
392                                         .build())
393                                 .build()))
394                         .build())
395                 .build();
396     }
397
398     private Batch createMeterAddBatch(final int batchOrder, final long groupIdValue) {
399         return new BatchBuilder()
400                 .setBatchOrder(batchOrder)
401                 .setBatchChoice(new FlatBatchAddMeterCaseBuilder()
402                         .setFlatBatchAddMeter(Collections.singletonList(new FlatBatchAddMeterBuilder()
403                                 .setMeterId(new MeterId(groupIdValue))
404                                 .build()))
405                         .build())
406                 .build();
407     }
408
409     private Batch createMeterRemoveBatch(final int batchOrder, final long groupIdValue) {
410         return new BatchBuilder()
411                 .setBatchOrder(batchOrder)
412                 .setBatchChoice(new FlatBatchRemoveMeterCaseBuilder()
413                         .setFlatBatchRemoveMeter(Collections.singletonList(new FlatBatchRemoveMeterBuilder()
414                                 .setMeterId(new MeterId(groupIdValue))
415                                 .build()))
416                         .build())
417                 .build();
418     }
419
420     private Batch createMeterUpdateBatch(final int batchOrder, final long groupIdValue) {
421         return new BatchBuilder()
422                 .setBatchOrder(batchOrder)
423                 .setBatchChoice(new FlatBatchUpdateMeterCaseBuilder()
424                         .setFlatBatchUpdateMeter(Collections.singletonList(new FlatBatchUpdateMeterBuilder()
425                                 .setOriginalBatchedMeter(new OriginalBatchedMeterBuilder()
426                                         .setMeterId(new MeterId(groupIdValue))
427                                         .build())
428                                 .setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder()
429                                         .setMeterId(new MeterId(groupIdValue))
430                                         .build())
431                                 .build()))
432                         .build())
433                 .build();
434     }
435
436     @Test
437     public void testExecuteBatchPlan() throws Exception {
438         BatchStepJob batchStepJob1 = Mockito.mock(BatchStepJob.class);
439         BatchStepJob batchStepJob2 = Mockito.mock(BatchStepJob.class);
440         AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function1 = Mockito.mock(AsyncFunction.class);
441         AsyncFunction<RpcResult<ProcessFlatBatchOutput>, RpcResult<ProcessFlatBatchOutput>> function2 = Mockito.mock(AsyncFunction.class);
442         Mockito.when(batchStepJob1.getStepFunction()).thenReturn(function1);
443         Mockito.when(batchStepJob2.getStepFunction()).thenReturn(function2);
444         BatchPlanStep batchPlanStep1 = new BatchPlanStep(BatchStepType.GROUP_ADD);
445         batchPlanStep1.setBarrierAfter(true);
446         BatchPlanStep batchPlanStep2 = new BatchPlanStep(BatchStepType.FLOW_ADD);
447         batchPlanStep1.setBarrierAfter(false);
448         Mockito.when(batchStepJob1.getPlanStep()).thenReturn(batchPlanStep1);
449         Mockito.when(batchStepJob2.getPlanStep()).thenReturn(batchPlanStep2);
450
451         final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> succeededChainOutput = FlatBatchUtil.createEmptyRpcBatchResultFuture(true);
452         final ListenableFuture<RpcResult<ProcessFlatBatchOutput>> failedChainOutput =
453                 RpcResultBuilder.<ProcessFlatBatchOutput>failed()
454                         .withError(RpcError.ErrorType.APPLICATION, "ut-chainError")
455                         .withResult(createFlatBatchOutput(createFlowBatchFailure(0, "f1"), createFlowBatchFailure(1, "f2")))
456                         .buildFuture();
457
458         Mockito.when(batchStepJob1.getStepFunction().apply(Matchers.<RpcResult<ProcessFlatBatchOutput>>any()))
459                 .thenReturn(succeededChainOutput);
460         Mockito.when(batchStepJob2.getStepFunction().apply(Matchers.<RpcResult<ProcessFlatBatchOutput>>any()))
461                 .thenReturn(failedChainOutput);
462
463         final List<BatchStepJob> batchChainElements = Lists.newArrayList(batchStepJob1, batchStepJob2);
464         final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = salFlatBatchService.executeBatchPlan(batchChainElements);
465
466         Assert.assertTrue(rpcResultFuture.isDone());
467         final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
468         Assert.assertFalse(rpcResult.isSuccessful());
469         Assert.assertEquals(1, rpcResult.getErrors().size());
470         Assert.assertEquals(2, rpcResult.getResult().getBatchFailure().size());
471         Assert.assertEquals("f2", ((FlatBatchFailureFlowIdCase) rpcResult.getResult().getBatchFailure().get(1).getBatchItemIdChoice()).getFlowId().getValue());
472     }
473
474     private BatchFailure createFlowBatchFailure(final int batchOrder, final String flowIdValue) {
475         return new BatchFailureBuilder()
476                 .setBatchOrder(batchOrder)
477                 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
478                         .setFlowId(new FlowId(flowIdValue))
479                         .build())
480                 .build();
481     }
482
483     private ProcessFlatBatchOutput createFlatBatchOutput(BatchFailure... batchFailures) {
484         return new ProcessFlatBatchOutputBuilder()
485                 .setBatchFailure(Lists.newArrayList(batchFailures))
486                 .build();
487     }
488
489     @Test
490     public void testPrepareBatchPlan_success() throws Exception {
491         final FlatBatchAddFlow flatBatchAddFlow = new FlatBatchAddFlowBuilder()
492                 .setFlowId(new FlowId("f1"))
493                 .build();
494         final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
495         batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow, flatBatchAddFlow));
496         final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep);
497
498         final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
499
500         Assert.assertEquals(1, batchChain.size());
501
502         Mockito.when(salFlowsBatchService.addFlowsBatch(Matchers.<AddFlowsBatchInput>any()))
503                 .thenReturn(RpcResultBuilder
504                         .success(new AddFlowsBatchOutputBuilder().build())
505                         .buildFuture());
506
507         final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = salFlatBatchService.executeBatchPlan(batchChain);
508         Assert.assertTrue(rpcResultFuture.isDone());
509         final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
510         Assert.assertTrue(rpcResult.isSuccessful());
511         Assert.assertEquals(0, rpcResult.getErrors().size());
512         Assert.assertEquals(0, rpcResult.getResult().getBatchFailure().size());
513
514         Mockito.verify(salFlowsBatchService).addFlowsBatch(Matchers.<AddFlowsBatchInput>any());
515     }
516
517     @Test
518     public void testPrepareBatchPlan_failure() throws Exception {
519         final FlatBatchAddFlow flatBatchAddFlow = new FlatBatchAddFlowBuilder()
520                 .setFlowId(new FlowId("f1"))
521                 .build();
522         final BatchPlanStep batchPlanStep = new BatchPlanStep(BatchStepType.FLOW_ADD);
523         batchPlanStep.getTaskBag().addAll(Lists.newArrayList(flatBatchAddFlow, flatBatchAddFlow));
524
525         final List<BatchPlanStep> batchPlan = Lists.newArrayList(batchPlanStep, batchPlanStep);
526
527         final List<BatchStepJob> batchChain = salFlatBatchService.prepareBatchChain(batchPlan, NODE_REF, true);
528
529         Assert.assertEquals(2, batchChain.size());
530
531         Mockito.when(salFlowsBatchService.addFlowsBatch(Matchers.<AddFlowsBatchInput>any()))
532                 .thenReturn(RpcResultBuilder
533                         .<AddFlowsBatchOutput>failed()
534                         .withResult(new AddFlowsBatchOutputBuilder()
535                                 .setBatchFailedFlowsOutput(Lists.newArrayList(
536                                         new BatchFailedFlowsOutputBuilder()
537                                                 .setBatchOrder(0)
538                                                 .setFlowId(new FlowId("f1"))
539                                                 .build(),
540                                         new BatchFailedFlowsOutputBuilder()
541                                                 .setBatchOrder(1)
542                                                 .setFlowId(new FlowId("f2"))
543                                                 .build()))
544                                 .build())
545                         .withError(RpcError.ErrorType.APPLICATION, "ut-addFlowBatchError")
546                         .buildFuture());
547
548         final Future<RpcResult<ProcessFlatBatchOutput>> rpcResultFuture = salFlatBatchService.executeBatchPlan(batchChain);
549         Assert.assertTrue(rpcResultFuture.isDone());
550         final RpcResult<ProcessFlatBatchOutput> rpcResult = rpcResultFuture.get();
551         Assert.assertFalse(rpcResult.isSuccessful());
552         Assert.assertEquals(2, rpcResult.getErrors().size());
553         Assert.assertEquals(4, rpcResult.getResult().getBatchFailure().size());
554
555         Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
556         Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());
557     }
558 }