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.process.flat.batch.input.Batch;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.BatchChoice;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCaseBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
31 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;
32 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;
33 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;
34 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;
35 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;
36 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;
37 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;
38 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;
39 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;
40 import org.opendaylight.yangtools.yang.common.RpcError;
41 import org.opendaylight.yangtools.yang.common.RpcResult;
42 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * Test for {@link FlatBatchUtil}.
49 public class FlatBatchUtilTest {
51 private static final Logger LOG = LoggerFactory.getLogger(FlatBatchUtilTest.class);
54 public void testMarkBarriersWhereNeeded_noBarrier() throws Exception {
55 final List<Batch> batches = Lists.newArrayList(
56 //general part - no flush required
57 createBatch(BatchStepType.GROUP_REMOVE),
58 createBatch(BatchStepType.METER_REMOVE),
59 createBatch(BatchStepType.FLOW_ADD),
60 createBatch(BatchStepType.FLOW_REMOVE, 2),
61 createBatch(BatchStepType.FLOW_ADD),
62 createBatch(BatchStepType.FLOW_UPDATE),
63 createBatch(BatchStepType.GROUP_ADD),
64 createBatch(BatchStepType.GROUP_UPDATE),
65 createBatch(BatchStepType.METER_ADD),
66 createBatch(BatchStepType.METER_UPDATE)
69 final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
70 FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
72 Assert.assertEquals(10, batchPlan.size());
73 for (int i = 0; i < batchPlan.size(); i++) {
74 final BatchPlanStep planStep = batchPlan.get(i);
75 final boolean barrierBefore = planStep.isBarrierAfter();
76 LOG.debug("checking barrier mark @ {} {} -> {}",
77 i, planStep.getStepType(), barrierBefore);
79 Assert.assertFalse(barrierBefore);
84 public void testMarkBarriersWhereNeeded_allBarriers() throws Exception {
85 // need to flush G+/F+
86 checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.FLOW_ADD);
87 // need to flush G+/F*
88 checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.FLOW_UPDATE);
89 // need to flush F-/G-
90 checkBarriersBetween(BatchStepType.FLOW_REMOVE, BatchStepType.GROUP_REMOVE);
91 // need to flush F*/G-
92 checkBarriersBetween(BatchStepType.FLOW_UPDATE, BatchStepType.GROUP_REMOVE);
94 // need to flush G+/G+
95 checkBarriersBetween(BatchStepType.GROUP_ADD, BatchStepType.GROUP_ADD);
96 // need to flush G-/G-
97 checkBarriersBetween(BatchStepType.GROUP_REMOVE, BatchStepType.GROUP_REMOVE);
98 // need to flush G*/G+
99 checkBarriersBetween(BatchStepType.GROUP_UPDATE, BatchStepType.GROUP_ADD);
100 // need to flush G*/G-
101 checkBarriersBetween(BatchStepType.GROUP_UPDATE, BatchStepType.GROUP_REMOVE);
103 // need to flush M+/F+
104 checkBarriersBetween(BatchStepType.METER_ADD, BatchStepType.FLOW_ADD);
105 // need to flush M+/F*
106 checkBarriersBetween(BatchStepType.METER_ADD, BatchStepType.FLOW_UPDATE);
107 // need to flush F-/M-
108 checkBarriersBetween(BatchStepType.FLOW_REMOVE, BatchStepType.METER_REMOVE);
109 // need to flush F*/M-
110 checkBarriersBetween(BatchStepType.FLOW_UPDATE, BatchStepType.METER_REMOVE);
113 private void checkBarriersBetween(final BatchStepType typeOfFirst, final BatchStepType typeOfSecond) {
114 final List<Batch> batches = Lists.newArrayList(createBatch(typeOfFirst), createBatch(typeOfSecond));
115 final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
116 FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
117 LOG.debug("checking barrier between {} / {}", typeOfFirst, typeOfSecond);
118 Assert.assertEquals(2, batchPlan.size());
119 Assert.assertTrue("barrier expected between " + typeOfFirst + " / " + typeOfSecond, batchPlan.get(0).isBarrierAfter());
120 Assert.assertFalse(batchPlan.get(1).isBarrierAfter());
124 public void testMarkBarriersWhereNeeded_single() throws Exception {
125 final List<Batch> batches = Lists.newArrayList(
126 //general part - no flush required
127 createBatch(BatchStepType.GROUP_REMOVE)
130 final List<BatchPlanStep> batchPlan = FlatBatchUtil.assembleBatchPlan(batches);
131 FlatBatchUtil.markBarriersWhereNeeded(batchPlan);
133 Assert.assertEquals(1, batchPlan.size());
134 Assert.assertFalse(batchPlan.get(0).isBarrierAfter());
138 public void testDecideBarrier() throws Exception {
139 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.GROUP_ADD), BatchStepType.FLOW_ADD));
140 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.GROUP_ADD), BatchStepType.FLOW_UPDATE));
142 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.FLOW_REMOVE), BatchStepType.GROUP_REMOVE));
143 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.FLOW_UPDATE), BatchStepType.GROUP_REMOVE));
145 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.METER_ADD), BatchStepType.FLOW_ADD));
146 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.METER_ADD), BatchStepType.FLOW_UPDATE));
148 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.FLOW_REMOVE), BatchStepType.METER_REMOVE));
149 Assert.assertTrue(FlatBatchUtil.decideBarrier(EnumSet.of(BatchStepType.FLOW_UPDATE), BatchStepType.METER_REMOVE));
153 public void testAssembleBatchPlan() throws Exception {
154 final List<Batch> batches = Lists.newArrayList(
155 createBatch(BatchStepType.GROUP_ADD),
156 createBatch(BatchStepType.GROUP_REMOVE, 2),
157 createBatch(BatchStepType.GROUP_REMOVE),
158 createBatch(BatchStepType.GROUP_ADD),
159 createBatch(BatchStepType.GROUP_UPDATE, 3)
162 final List<BatchPlanStep> batchPlanSteps = FlatBatchUtil.assembleBatchPlan(batches);
163 Assert.assertEquals(5, batchPlanSteps.size());
166 checkSegment(batchPlanSteps.get(i++), BatchStepType.GROUP_ADD, 1);
167 checkSegment(batchPlanSteps.get(i++), BatchStepType.GROUP_REMOVE, 2);
168 checkSegment(batchPlanSteps.get(i++), BatchStepType.GROUP_REMOVE, 1);
169 checkSegment(batchPlanSteps.get(i++), BatchStepType.GROUP_ADD, 1);
170 checkSegment(batchPlanSteps.get(i++), BatchStepType.GROUP_UPDATE, 3);
173 private void checkSegment(final BatchPlanStep planStep, final BatchStepType stepType, final int expected) {
174 Assert.assertEquals(stepType, planStep.getStepType());
175 Assert.assertEquals(expected, planStep.getTaskBag().size());
179 public void testDetectBatchStepType() throws Exception {
180 for (BatchStepType stepType : BatchStepType.values()) {
181 LOG.debug("checking detection of: {}", stepType);
182 final Batch batch = createBatch(stepType);
183 final BatchStepType actualType = FlatBatchUtil.detectBatchStepType(batch.getBatchChoice());
184 Assert.assertEquals(stepType, actualType);
188 private Batch createBatch(BatchStepType type) {
189 return createBatch(type, 1);
192 private Batch createBatch(BatchStepType type, final int size) {
193 final BatchChoice batchCase;
196 batchCase = new FlatBatchAddFlowCaseBuilder()
197 .setFlatBatchAddFlow(repeatIntoList(new FlatBatchAddFlowBuilder().build(), size))
201 batchCase = new FlatBatchRemoveFlowCaseBuilder()
202 .setFlatBatchRemoveFlow(repeatIntoList(new FlatBatchRemoveFlowBuilder().build(), size))
206 batchCase = new FlatBatchUpdateFlowCaseBuilder()
207 .setFlatBatchUpdateFlow(repeatIntoList(new FlatBatchUpdateFlowBuilder().build(), size))
211 batchCase = new FlatBatchAddGroupCaseBuilder()
212 .setFlatBatchAddGroup(repeatIntoList(new FlatBatchAddGroupBuilder().build(), size))
216 batchCase = new FlatBatchRemoveGroupCaseBuilder()
217 .setFlatBatchRemoveGroup(repeatIntoList(new FlatBatchRemoveGroupBuilder().build(), size))
221 batchCase = new FlatBatchUpdateGroupCaseBuilder()
222 .setFlatBatchUpdateGroup(repeatIntoList(new FlatBatchUpdateGroupBuilder().build(), size))
226 batchCase = new FlatBatchAddMeterCaseBuilder()
227 .setFlatBatchAddMeter(repeatIntoList(new FlatBatchAddMeterBuilder().build(), size))
231 batchCase = new FlatBatchRemoveMeterCaseBuilder()
232 .setFlatBatchRemoveMeter(repeatIntoList(new FlatBatchRemoveMeterBuilder().build(), size))
236 batchCase = new FlatBatchUpdateMeterCaseBuilder()
237 .setFlatBatchUpdateMeter(repeatIntoList(new FlatBatchUpdateMeterBuilder().build(), size))
241 LOG.warn("unsupported batch type: {}", type);
242 throw new IllegalArgumentException("unsupported batch type: " + type);
245 return new BatchBuilder()
246 .setBatchChoice(batchCase)
250 private <T> List<T> repeatIntoList(final T element, final int size) {
251 final List<T> list = new ArrayList<>();
252 for (int i = 0; i < size; i++) {
259 public void testMergeRpcResults() throws Exception {
260 final RpcResult<String> rpcResultFailed = RpcResultBuilder.<String>failed()
261 .withError(RpcError.ErrorType.APPLICATION, "ut-rpcError").build();
262 final RpcResult<String> rpcResultSuccess = RpcResultBuilder.<String>success().build();
264 final RpcResult<String> rpcResult1 = FlatBatchUtil.mergeRpcResults(rpcResultFailed, rpcResultSuccess).build();
265 Assert.assertEquals(1, rpcResult1.getErrors().size());
266 Assert.assertFalse(rpcResult1.isSuccessful());
268 final RpcResult<String> rpcResult2 = FlatBatchUtil.mergeRpcResults(rpcResultFailed, rpcResultFailed).build();
269 Assert.assertEquals(2, rpcResult2.getErrors().size());
270 Assert.assertFalse(rpcResult2.isSuccessful());
272 final RpcResult<String> rpcResult3 = FlatBatchUtil.mergeRpcResults(rpcResultSuccess, rpcResultSuccess).build();
273 Assert.assertEquals(0, rpcResult3.getErrors().size());
274 Assert.assertTrue(rpcResult3.isSuccessful());