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