2 * Copyright (c) 2016 Cisco Systems, Inc. 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.util;
11 import com.google.common.collect.Lists;
12 import java.util.ArrayList;
13 import java.util.EnumSet;
14 import java.util.List;
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.FlatBatchAddFlowBuilder;
34 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;
35 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;
36 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;
37 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;
38 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;
39 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;
40 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;
41 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;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailure;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.BatchFailureBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.output.batch.failure.batch.item.id.choice.FlatBatchFailureFlowIdCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
46 import org.opendaylight.yangtools.yang.common.RpcError;
47 import org.opendaylight.yangtools.yang.common.RpcResult;
48 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
53 * Test for {@link FlatBatchUtil}.
55 public class FlatBatchUtilTest {
57 private static final Logger LOG = LoggerFactory.getLogger(FlatBatchUtilTest.class);
60 public void testMarkBarriersWhereNeeded_noBarrier() {
61 final List<Batch> batches = Lists.newArrayList(
62 //general part - no flush required
63 createBatch(BatchStepType.GROUP_REMOVE),
64 createBatch(BatchStepType.METER_REMOVE),
65 createBatch(BatchStepType.FLOW_ADD),
66 createBatch(BatchStepType.FLOW_REMOVE, 2),
67 createBatch(BatchStepType.FLOW_ADD),
68 createBatch(BatchStepType.FLOW_UPDATE),
69 createBatch(BatchStepType.GROUP_ADD),
70 createBatch(BatchStepType.GROUP_UPDATE),
71 createBatch(BatchStepType.METER_ADD),
72 createBatch(BatchStepType.METER_UPDATE)
75 final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
76 FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
78 Assert.assertEquals(10, batchPlan.size());
79 for (int i = 0; i < batchPlan.size(); i++) {
80 final BatchPlanStep planStep = batchPlan.get(i);
81 final boolean barrierBefore = planStep.isBarrierAfter();
82 LOG.debug("checking barrier mark @ {} {} -> {}",
83 i, planStep.getStepType(), barrierBefore);
85 Assert.assertFalse(barrierBefore);
90 public void testMarkBarriersWhereNeeded_allBarriers() {
91 // need to flush G+/F+
92 checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.FLOW_ADD);
93 // need to flush G+/F*
94 checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.FLOW_UPDATE);
95 // need to flush F-/G-
96 checkBarriersBetween(BatchStepType.FLOW_REMOVE, BatchStepType.GROUP_REMOVE);
97 // need to flush F*/G-
98 checkBarriersBetween(BatchStepType.FLOW_UPDATE, BatchStepType.GROUP_REMOVE);
100 // need to flush G+/G+
101 checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.GROUP_ADD);
102 // need to flush G-/G-
103 checkBarriersBetween(BatchStepType.GROUP_REMOVE, BatchStepType.GROUP_REMOVE);
104 // need to flush G*/G+
105 checkBarriersBetween(BatchStepType.GROUP_UPDATE, BatchStepType.GROUP_ADD);
106 // need to flush G*/G-
107 checkBarriersBetween(BatchStepType.GROUP_UPDATE, BatchStepType.GROUP_REMOVE);
109 // need to flush M+/F+
110 checkBarriersBetween(BatchStepType.METER_ADD, BatchStepType.FLOW_ADD);
111 // need to flush M+/F*
112 checkBarriersBetween(BatchStepType.METER_ADD, BatchStepType.FLOW_UPDATE);
113 // need to flush F-/M-
114 checkBarriersBetween(BatchStepType.FLOW_REMOVE, BatchStepType.METER_REMOVE);
115 // need to flush F*/M-
116 checkBarriersBetween(BatchStepType.FLOW_UPDATE, BatchStepType.METER_REMOVE);
119 private void checkBarriersBetween(final BatchStepType typeOfFirst, final BatchStepType typeOfSecond) {
120 final List<Batch> batches = Lists.newArrayList(createBatch(typeOfFirst), createBatch(typeOfSecond));
121 final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
122 FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
123 LOG.debug("checking barrier between {} / {}", typeOfFirst, typeOfSecond);
124 Assert.assertEquals(2, batchPlan.size());
125 Assert.assertTrue("barrier expected between "
126 + typeOfFirst + " / "
127 + typeOfSecond, batchPlan.get(0).isBarrierAfter());
128 Assert.assertFalse(batchPlan.get(1).isBarrierAfter());
132 public void testMarkBarriersWhereNeeded_single() {
133 final List<Batch> batches = Lists.newArrayList(
134 //general part - no flush required
135 createBatch(BatchStepType.GROUP_REMOVE)
138 final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
139 FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
141 Assert.assertEquals(1, batchPlan.size());
142 Assert.assertFalse(batchPlan.get(0).isBarrierAfter());
146 public void testDecideBarrier() {
147 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.GROUP_ADD), BatchStepType.FLOW_ADD));
148 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.GROUP_ADD), BatchStepType.FLOW_UPDATE));
150 Assert.assertTrue(FlatBatchUtil
151 .decideBarrier(EnumSet.of(BatchStepType.FLOW_REMOVE), BatchStepType.GROUP_REMOVE));
152 Assert.assertTrue(FlatBatchUtil
153 .decideBarrier(EnumSet.of(BatchStepType.FLOW_UPDATE), BatchStepType.GROUP_REMOVE));
155 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.METER_ADD), BatchStepType.FLOW_ADD));
156 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.METER_ADD), BatchStepType.FLOW_UPDATE));
158 Assert.assertTrue(FlatBatchUtil
159 .decideBarrier(EnumSet.of(BatchStepType.FLOW_REMOVE), BatchStepType.METER_REMOVE));
160 Assert.assertTrue(FlatBatchUtil
161 .decideBarrier(EnumSet.of(BatchStepType.FLOW_UPDATE), BatchStepType.METER_REMOVE));
165 public void testAssembleBatchPlan() {
166 final List<Batch> batches = Lists.newArrayList(
167 createBatch(BatchStepType.GROUP_ADD),
168 createBatch(BatchStepType.GROUP_REMOVE, 2),
169 createBatch(BatchStepType.GROUP_REMOVE),
170 createBatch(BatchStepType.GROUP_ADD),
171 createBatch(BatchStepType.GROUP_UPDATE, 3)
174 final List<BatchPlanStep> batchPlanSteps = FlatBatchUtil.assembleBatchPlan(batches);
175 Assert.assertEquals(5, batchPlanSteps.size());
178 checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_ADD, 1);
179 checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_REMOVE, 2);
180 checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_REMOVE, 1);
181 checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_ADD, 1);
182 checkSegment(batchPlanSteps.get(index++), BatchStepType.GROUP_UPDATE, 3);
185 private void checkSegment(final BatchPlanStep planStep, final BatchStepType stepType, final int expected) {
186 Assert.assertEquals(stepType, planStep.getStepType());
187 Assert.assertEquals(expected, planStep.getTaskBag().size());
191 public void testDetectBatchStepType() {
192 for (BatchStepType stepType : BatchStepType.values()) {
193 LOG.debug("checking detection of: {}", stepType);
194 final Batch batch = createBatch(stepType);
195 final BatchStepType actualType = FlatBatchUtil.detectBatchStepType(batch.getBatchChoice());
196 Assert.assertEquals(stepType, actualType);
200 private Batch createBatch(BatchStepType type) {
201 return createBatch(type, 1);
204 private Batch createBatch(BatchStepType type, final int size) {
205 final BatchChoice batchCase;
208 batchCase = new FlatBatchAddFlowCaseBuilder()
209 .setFlatBatchAddFlow(repeatIntoList(new FlatBatchAddFlowBuilder().build(), size))
213 batchCase = new FlatBatchRemoveFlowCaseBuilder()
214 .setFlatBatchRemoveFlow(repeatIntoList(new FlatBatchRemoveFlowBuilder().build(), size))
218 batchCase = new FlatBatchUpdateFlowCaseBuilder()
219 .setFlatBatchUpdateFlow(repeatIntoList(new FlatBatchUpdateFlowBuilder().build(), size))
223 batchCase = new FlatBatchAddGroupCaseBuilder()
224 .setFlatBatchAddGroup(repeatIntoList(new FlatBatchAddGroupBuilder().build(), size))
228 batchCase = new FlatBatchRemoveGroupCaseBuilder()
229 .setFlatBatchRemoveGroup(repeatIntoList(new FlatBatchRemoveGroupBuilder().build(), size))
233 batchCase = new FlatBatchUpdateGroupCaseBuilder()
234 .setFlatBatchUpdateGroup(repeatIntoList(new FlatBatchUpdateGroupBuilder().build(), size))
238 batchCase = new FlatBatchAddMeterCaseBuilder()
239 .setFlatBatchAddMeter(repeatIntoList(new FlatBatchAddMeterBuilder().build(), size))
243 batchCase = new FlatBatchRemoveMeterCaseBuilder()
244 .setFlatBatchRemoveMeter(repeatIntoList(new FlatBatchRemoveMeterBuilder().build(), size))
248 batchCase = new FlatBatchUpdateMeterCaseBuilder()
249 .setFlatBatchUpdateMeter(repeatIntoList(new FlatBatchUpdateMeterBuilder().build(), size))
253 LOG.warn("unsupported batch type: {}", type);
254 throw new IllegalArgumentException("unsupported batch type: " + type);
257 return new BatchBuilder()
258 .setBatchChoice(batchCase)
262 private <T> List<T> repeatIntoList(final T element, final int size) {
263 final List<T> list = new ArrayList<>();
264 for (int i = 0; i < size; i++) {
271 public void testMergeJobsResultsFutures() {
272 final BatchFailure batchFailure = new BatchFailureBuilder()
274 .setBatchItemIdChoice(new FlatBatchFailureFlowIdCaseBuilder()
275 .setFlowId(new FlowId("11"))
279 final ProcessFlatBatchOutput output
280 = new ProcessFlatBatchOutputBuilder().setBatchFailure(Lists.newArrayList(batchFailure)).build();
282 final RpcResult<ProcessFlatBatchOutput> rpcResultFailed = RpcResultBuilder.<ProcessFlatBatchOutput>failed()
283 .withError(RpcError.ErrorType.APPLICATION, "ut-rpcError")
284 .withResult(output).build();
285 final RpcResult<ProcessFlatBatchOutput> rpcResultSuccess = RpcResultBuilder.<ProcessFlatBatchOutput>success()
286 .withResult(new ProcessFlatBatchOutputBuilder().setBatchFailure(new ArrayList<>())).build();
288 final RpcResult<ProcessFlatBatchOutput> rpcResult1
289 = FlatBatchUtil.mergeRpcResults().apply(Lists.newArrayList(rpcResultFailed, rpcResultSuccess));
290 Assert.assertEquals(1, rpcResult1.getErrors().size());
291 Assert.assertFalse(rpcResult1.isSuccessful());
293 final RpcResult<ProcessFlatBatchOutput> rpcResult2
294 = FlatBatchUtil.mergeRpcResults().apply(Lists.newArrayList(rpcResultFailed, rpcResultFailed));
295 Assert.assertEquals(2, rpcResult2.getErrors().size());
296 Assert.assertFalse(rpcResult2.isSuccessful());
298 final RpcResult<ProcessFlatBatchOutput> rpcResult3
299 = FlatBatchUtil.mergeRpcResults().apply(Lists.newArrayList(rpcResultSuccess, rpcResultSuccess));
300 Assert.assertEquals(0, rpcResult3.getErrors().size());
301 Assert.assertTrue(rpcResult3.isSuccessful());