Bump MRI upstreams
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / util / FlatBatchUtilTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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 package org.opendaylight.openflowplugin.impl.util;
9
10 import com.google.common.collect.Lists;
11 import java.util.EnumSet;
12 import java.util.List;
13 import java.util.Map;
14 import org.junit.Assert;
15 import org.junit.Test;
16 import org.opendaylight.openflowplugin.impl.services.batch.BatchPlanStep;
17 import org.opendaylight.openflowplugin.impl.services.batch.BatchStepType;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutput;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.failure.ids.aug.FlatBatchFailureFlowIdCaseBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchAddFlowCaseBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchRemoveFlowCaseBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.FlatBatchUpdateFlowCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlow;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.add.flow._case.FlatBatchAddFlowKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlow;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlowBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.remove.flow._case.FlatBatchRemoveFlowKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlow;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlowBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.flow.crud._case.aug.flat.batch.update.flow._case.FlatBatchUpdateFlowKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchAddGroupCaseBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchRemoveGroupCaseBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.FlatBatchUpdateGroupCaseBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroup;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroupBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.add.group._case.FlatBatchAddGroupKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroup;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroupBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.remove.group._case.FlatBatchRemoveGroupKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroup;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroupBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.group.crud._case.aug.flat.batch.update.group._case.FlatBatchUpdateGroupKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchAddMeterCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchRemoveMeterCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.FlatBatchUpdateMeterCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeter;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeterBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.add.meter._case.FlatBatchAddMeterKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeter;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeterBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.remove.meter._case.FlatBatchRemoveMeterKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeter;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeterBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.flat.batch.meter.crud._case.aug.flat.batch.update.meter._case.FlatBatchUpdateMeterKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.BatchChoice;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
64 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
65 import org.opendaylight.yangtools.yang.common.ErrorType;
66 import org.opendaylight.yangtools.yang.common.RpcResult;
67 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
68 import org.opendaylight.yangtools.yang.common.Uint16;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72 /**
73  * Test for {@link FlatBatchUtil}.
74  */
75 public class FlatBatchUtilTest {
76
77     private static final Logger LOG = LoggerFactory.getLogger(FlatBatchUtilTest.class);
78
79     @Test
80     public void testMarkBarriersWhereNeeded_noBarrier() {
81         final List<Batch> batches = Lists.newArrayList(
82                 //general part - no flush required
83                 createBatch(BatchStepType.GROUP_REMOVE),
84                 createBatch(BatchStepType.METER_REMOVE),
85                 createBatch(BatchStepType.FLOW_ADD),
86                 createBatch(BatchStepType.FLOW_REMOVE, 2),
87                 createBatch(BatchStepType.FLOW_ADD),
88                 createBatch(BatchStepType.FLOW_UPDATE),
89                 createBatch(BatchStepType.GROUP_ADD),
90                 createBatch(BatchStepType.GROUP_UPDATE),
91                 createBatch(BatchStepType.METER_ADD),
92                 createBatch(BatchStepType.METER_UPDATE)
93         );
94
95         final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
96         FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
97
98         Assert.assertEquals(10, batchPlan.size());
99         for (int i = 0; i < batchPlan.size(); i++) {
100             final BatchPlanStep planStep = batchPlan.get(i);
101             final boolean barrierBefore = planStep.isBarrierAfter();
102             LOG.debug("checking barrier mark @ {} {} -> {}",
103                     i, planStep.getStepType(), barrierBefore);
104
105             Assert.assertFalse(barrierBefore);
106         }
107     }
108
109     @Test
110     public void testMarkBarriersWhereNeeded_allBarriers() {
111         // need to flush G+/F+
112         checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.FLOW_ADD);
113         // need to flush G+/F*
114         checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.FLOW_UPDATE);
115         // need to flush F-/G-
116         checkBarriersBetween(BatchStepType.FLOW_REMOVE, BatchStepType.GROUP_REMOVE);
117         // need to flush F*/G-
118         checkBarriersBetween(BatchStepType.FLOW_UPDATE, BatchStepType.GROUP_REMOVE);
119
120         // need to flush G+/G+
121         checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.GROUP_ADD);
122         // need to flush G-/G-
123         checkBarriersBetween(BatchStepType.GROUP_REMOVE, BatchStepType.GROUP_REMOVE);
124         // need to flush G*/G+
125         checkBarriersBetween(BatchStepType.GROUP_UPDATE, BatchStepType.GROUP_ADD);
126         // need to flush G*/G-
127         checkBarriersBetween(BatchStepType.GROUP_UPDATE, BatchStepType.GROUP_REMOVE);
128
129         // need to flush M+/F+
130         checkBarriersBetween(BatchStepType.METER_ADD, BatchStepType.FLOW_ADD);
131         // need to flush M+/F*
132         checkBarriersBetween(BatchStepType.METER_ADD, BatchStepType.FLOW_UPDATE);
133         // need to flush F-/M-
134         checkBarriersBetween(BatchStepType.FLOW_REMOVE, BatchStepType.METER_REMOVE);
135         // need to flush F*/M-
136         checkBarriersBetween(BatchStepType.FLOW_UPDATE, BatchStepType.METER_REMOVE);
137     }
138
139     private static void checkBarriersBetween(final BatchStepType typeOfFirst, final BatchStepType typeOfSecond) {
140         final List<Batch> batches = Lists.newArrayList(createBatch(typeOfFirst), createBatch(typeOfSecond));
141         final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
142         FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
143         LOG.debug("checking barrier between {} / {}", typeOfFirst, typeOfSecond);
144         Assert.assertEquals(2, batchPlan.size());
145         Assert.assertTrue("barrier expected between "
146                 + typeOfFirst + " / "
147                 + typeOfSecond, batchPlan.get(0).isBarrierAfter());
148         Assert.assertFalse(batchPlan.get(1).isBarrierAfter());
149     }
150
151     @Test
152     public void testMarkBarriersWhereNeeded_single() {
153         final List<Batch> batches = List.of(
154                 //general part - no flush required
155                 createBatch(BatchStepType.GROUP_REMOVE)
156         );
157
158         final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
159         FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
160
161         Assert.assertEquals(1, batchPlan.size());
162         Assert.assertFalse(batchPlan.get(0).isBarrierAfter());
163     }
164
165     @Test
166     public void testDecideBarrier() {
167         Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.GROUP_ADD), BatchStepType.FLOW_ADD));
168         Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.GROUP_ADD), BatchStepType.FLOW_UPDATE));
169
170         Assert.assertTrue(FlatBatchUtil
171                 .decideBarrier(EnumSet.of(BatchStepType.FLOW_REMOVE), BatchStepType.GROUP_REMOVE));
172         Assert.assertTrue(FlatBatchUtil
173                 .decideBarrier(EnumSet.of(BatchStepType.FLOW_UPDATE), BatchStepType.GROUP_REMOVE));
174
175         Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.METER_ADD), BatchStepType.FLOW_ADD));
176         Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.METER_ADD), BatchStepType.FLOW_UPDATE));
177
178         Assert.assertTrue(FlatBatchUtil
179                 .decideBarrier(EnumSet.of(BatchStepType.FLOW_REMOVE), BatchStepType.METER_REMOVE));
180         Assert.assertTrue(FlatBatchUtil
181                 .decideBarrier(EnumSet.of(BatchStepType.FLOW_UPDATE), BatchStepType.METER_REMOVE));
182     }
183
184     @Test
185     public void testAssembleBatchPlan() {
186         final List<Batch> batches = Lists.newArrayList(
187                 createBatch(BatchStepType.GROUP_ADD),
188                 createBatch(BatchStepType.GROUP_REMOVE, 2),
189                 createBatch(BatchStepType.GROUP_REMOVE),
190                 createBatch(BatchStepType.GROUP_ADD),
191                 createBatch(BatchStepType.GROUP_UPDATE, 3)
192         );
193
194         final List<BatchPlanStep> batchPlanSteps = FlatBatchUtil.assembleBatchPlan(batches);
195         Assert.assertEquals(5, batchPlanSteps.size());
196
197         int index = 0;
198         checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_ADD, 1);
199         checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_REMOVE, 2);
200         checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_REMOVE, 1);
201         checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_ADD, 1);
202         checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_UPDATE, 3);
203     }
204
205     private static void checkSegment(final BatchPlanStep planStep, final BatchStepType stepType, final int expected) {
206         Assert.assertEquals(stepType, planStep.getStepType());
207         Assert.assertEquals(expected, planStep.getTaskBag().size());
208     }
209
210     @Test
211     public void testDetectBatchStepType() {
212         for (BatchStepType stepType : BatchStepType.values()) {
213             LOG.debug("checking detection of: {}", stepType);
214             final Batch batch = createBatch(stepType);
215             final BatchStepType actualType = FlatBatchUtil.detectBatchStepType(batch.getBatchChoice());
216             Assert.assertEquals(stepType, actualType);
217         }
218     }
219
220     private static Batch createBatch(final BatchStepType type) {
221         return createBatch(type, 1);
222     }
223
224     private static Batch createBatch(final BatchStepType type, final int size) {
225         final BatchChoice batchCase;
226         switch (type) {
227             case FLOW_ADD:
228                 batchCase = new FlatBatchAddFlowCaseBuilder()
229                         .setFlatBatchAddFlow(repeatFlatBatchAddFlowIntoList(size))
230                         .build();
231                 break;
232             case FLOW_REMOVE:
233                 batchCase = new FlatBatchRemoveFlowCaseBuilder()
234                         .setFlatBatchRemoveFlow(repeatFlatBatchRemoveFlowIntoList(size))
235                         .build();
236                 break;
237             case FLOW_UPDATE:
238                 batchCase = new FlatBatchUpdateFlowCaseBuilder()
239                         .setFlatBatchUpdateFlow(repeatFlatBatchUpdateFlowIntoList(size))
240                         .build();
241                 break;
242             case GROUP_ADD:
243                 batchCase = new FlatBatchAddGroupCaseBuilder()
244                         .setFlatBatchAddGroup(repeatFlatBatchAddGroupIntoList(size))
245                         .build();
246                 break;
247             case GROUP_REMOVE:
248                 batchCase = new FlatBatchRemoveGroupCaseBuilder()
249                         .setFlatBatchRemoveGroup(repeatFlatBatchRemoveGroupIntoList(size))
250                         .build();
251                 break;
252             case GROUP_UPDATE:
253                 batchCase = new FlatBatchUpdateGroupCaseBuilder()
254                         .setFlatBatchUpdateGroup(repeatFlatBatchUpdateGroupIntoList(size))
255                         .build();
256                 break;
257             case METER_ADD:
258                 batchCase = new FlatBatchAddMeterCaseBuilder()
259                         .setFlatBatchAddMeter(repeatFlatBatchAddMeterIntoList(size))
260                         .build();
261                 break;
262             case METER_REMOVE:
263                 batchCase = new FlatBatchRemoveMeterCaseBuilder()
264                         .setFlatBatchRemoveMeter(repeatFlatBatchRemoveMeterIntoList(size))
265                         .build();
266                 break;
267             case METER_UPDATE:
268                 batchCase = new FlatBatchUpdateMeterCaseBuilder()
269                         .setFlatBatchUpdateMeter(repeatFlatBatchUpdateMeterIntoList(size))
270                         .build();
271                 break;
272             default:
273                 LOG.warn("unsupported batch type: {}", type);
274                 throw new IllegalArgumentException("unsupported batch type: " + type);
275         }
276
277         return new BatchBuilder()
278                 .setBatchOrder(Uint16.ZERO)
279                 .setBatchChoice(batchCase)
280                 .build();
281     }
282
283     private static Map<FlatBatchAddGroupKey, FlatBatchAddGroup> repeatFlatBatchAddGroupIntoList(final int size) {
284         final var list = BindingMap.<FlatBatchAddGroupKey, FlatBatchAddGroup>orderedBuilder(size);
285         for (int i = 0; i < size; i++) {
286             list.add(new FlatBatchAddGroupBuilder().withKey(new FlatBatchAddGroupKey(Uint16.valueOf(i))).build());
287         }
288         return list.build();
289     }
290
291     private static Map<FlatBatchUpdateGroupKey, FlatBatchUpdateGroup> repeatFlatBatchUpdateGroupIntoList(
292             final int size) {
293         final var list = BindingMap.<FlatBatchUpdateGroupKey, FlatBatchUpdateGroup>orderedBuilder(size);
294         for (int i = 0; i < size; i++) {
295             list.add(new FlatBatchUpdateGroupBuilder().withKey(new FlatBatchUpdateGroupKey(Uint16.valueOf(i))).build());
296         }
297         return list.build();
298     }
299
300     private static Map<FlatBatchRemoveGroupKey, FlatBatchRemoveGroup> repeatFlatBatchRemoveGroupIntoList(
301             final int size) {
302         final var list = BindingMap.<FlatBatchRemoveGroupKey, FlatBatchRemoveGroup>orderedBuilder(size);
303         for (int i = 0; i < size; i++) {
304             list.add(new FlatBatchRemoveGroupBuilder().withKey(new FlatBatchRemoveGroupKey(Uint16.valueOf(i))).build());
305         }
306         return list.build();
307     }
308
309     private static Map<FlatBatchAddFlowKey, FlatBatchAddFlow> repeatFlatBatchAddFlowIntoList(final int size) {
310         final var list = BindingMap.<FlatBatchAddFlowKey, FlatBatchAddFlow>orderedBuilder(size);
311         for (int i = 0; i < size; i++) {
312             list.add(new FlatBatchAddFlowBuilder().withKey(new FlatBatchAddFlowKey(Uint16.valueOf(i))).build());
313         }
314         return list.build();
315     }
316
317     private static Map<FlatBatchUpdateFlowKey, FlatBatchUpdateFlow> repeatFlatBatchUpdateFlowIntoList(final int size) {
318         final var list = BindingMap.<FlatBatchUpdateFlowKey, FlatBatchUpdateFlow>orderedBuilder(size);
319         for (int i = 0; i < size; i++) {
320             list.add(new FlatBatchUpdateFlowBuilder().withKey(new FlatBatchUpdateFlowKey(Uint16.valueOf(i))).build());
321         }
322         return list.build();
323     }
324
325     private static Map<FlatBatchRemoveFlowKey, FlatBatchRemoveFlow> repeatFlatBatchRemoveFlowIntoList(final int size) {
326         final var list = BindingMap.<FlatBatchRemoveFlowKey, FlatBatchRemoveFlow>orderedBuilder(size);
327         for (int i = 0; i < size; i++) {
328             list.add(new FlatBatchRemoveFlowBuilder().withKey(new FlatBatchRemoveFlowKey(Uint16.valueOf(i))).build());
329         }
330         return list.build();
331     }
332
333     private static Map<FlatBatchAddMeterKey, FlatBatchAddMeter> repeatFlatBatchAddMeterIntoList(final int size) {
334         final var list = BindingMap.<FlatBatchAddMeterKey, FlatBatchAddMeter>orderedBuilder(size);
335         for (int i = 0; i < size; i++) {
336             list.add(new FlatBatchAddMeterBuilder().withKey(new FlatBatchAddMeterKey(Uint16.valueOf(i))).build());
337         }
338         return list.build();
339     }
340
341     private static Map<FlatBatchUpdateMeterKey, FlatBatchUpdateMeter> repeatFlatBatchUpdateMeterIntoList(
342             final int size) {
343         final var list = BindingMap.<FlatBatchUpdateMeterKey, FlatBatchUpdateMeter>orderedBuilder(size);
344         for (int i = 0; i < size; i++) {
345             list.add(new FlatBatchUpdateMeterBuilder().withKey(new FlatBatchUpdateMeterKey(Uint16.valueOf(i))).build());
346         }
347         return list.build();
348     }
349
350     private static Map<FlatBatchRemoveMeterKey, FlatBatchRemoveMeter> repeatFlatBatchRemoveMeterIntoList(
351             final int size) {
352         final var list = BindingMap.<FlatBatchRemoveMeterKey, FlatBatchRemoveMeter>orderedBuilder(size);
353         for (int i = 0; i < size; i++) {
354             list.add(new FlatBatchRemoveMeterBuilder().withKey(new FlatBatchRemoveMeterKey(Uint16.valueOf(i))).build());
355         }
356         return list.build();
357     }
358
359     @Test
360     public void testMergeJobsResultsFutures() {
361         final BatchFailure batchFailure = new BatchFailureBuilder()
362                 .setBatchOrder(Uint16.valueOf(9))
363                 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
364                         .setFlowId(new FlowId("11"))
365                         .build())
366                 .withKey(new BatchFailureKey(Uint16.ZERO))
367                 .build();
368         final BatchFailure batchFailure_1 = new BatchFailureBuilder()
369                 .setBatchOrder(Uint16.valueOf(9))
370                 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
371                         .setFlowId(new FlowId("11"))
372                         .build())
373                 .withKey(new BatchFailureKey(Uint16.ONE))
374                 .build();
375
376         final ProcessFlatBatchOutput output
377                 = new ProcessFlatBatchOutputBuilder().setBatchFailure(BindingMap.of(batchFailure)).build();
378
379         final ProcessFlatBatchOutput output_1
380                 = new ProcessFlatBatchOutputBuilder().setBatchFailure(BindingMap.of(batchFailure_1)).build();
381
382         final RpcResult<ProcessFlatBatchOutput> rpcResultFailed = RpcResultBuilder.<ProcessFlatBatchOutput>failed()
383                 .withError(ErrorType.APPLICATION, "ut-rpcError")
384                 .withResult(output).build();
385
386         final RpcResult<ProcessFlatBatchOutput> rpcResultFailed_1 = RpcResultBuilder.<ProcessFlatBatchOutput>failed()
387                 .withError(ErrorType.APPLICATION, "ut-rpcError")
388                 .withResult(output_1).build();
389         final RpcResult<ProcessFlatBatchOutput> rpcResultSuccess = RpcResultBuilder.<ProcessFlatBatchOutput>success()
390                 .withResult(new ProcessFlatBatchOutputBuilder().setBatchFailure(Map.of()).build()).build();
391
392         final RpcResult<ProcessFlatBatchOutput> rpcResult1
393                 = FlatBatchUtil.mergeRpcResults().apply(Lists.newArrayList(rpcResultFailed, rpcResultSuccess));
394         Assert.assertEquals(1, rpcResult1.getErrors().size());
395         Assert.assertFalse(rpcResult1.isSuccessful());
396
397         final RpcResult<ProcessFlatBatchOutput> rpcResult2
398                 = FlatBatchUtil.mergeRpcResults().apply(Lists.newArrayList(rpcResultFailed, rpcResultFailed_1));
399         Assert.assertEquals(2, rpcResult2.getErrors().size());
400         Assert.assertFalse(rpcResult2.isSuccessful());
401
402         final RpcResult<ProcessFlatBatchOutput> rpcResult3
403                 = FlatBatchUtil.mergeRpcResults().apply(Lists.newArrayList(rpcResultSuccess, rpcResultSuccess));
404         Assert.assertEquals(0, rpcResult3.getErrors().size());
405         Assert.assertTrue(rpcResult3.isSuccessful());
406     }
407 }