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
8 package org.opendaylight.openflowplugin.applications.frsync.impl.strategy;
10 import com.google.common.collect.Lists;
11 import com.google.common.collect.Range;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
17 import org.junit.Assert;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.junit.runner.RunWith;
21 import org.mockito.ArgumentCaptor;
22 import org.mockito.ArgumentMatchers;
23 import org.mockito.Captor;
24 import org.mockito.Mock;
25 import org.mockito.Mockito;
26 import org.mockito.runners.MockitoJUnitRunner;
27 import org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox;
28 import org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.ProcessFlatBatchOutputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.SalFlatBatchService;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.Batch;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.BatchBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddFlowCaseBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCase;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddGroupCaseBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchAddMeterCaseBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveFlowCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveGroupCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchRemoveMeterCase;
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.FlatBatchUpdateFlowCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateFlowCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateGroupCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flat.batch.service.rev160321.process.flat.batch.input.batch.batch.choice.FlatBatchUpdateMeterCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
62 import org.opendaylight.yangtools.yang.common.RpcResult;
63 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
66 * Test for {@link SyncPlanPushStrategyFlatBatchImpl}.
68 @RunWith(MockitoJUnitRunner.class)
69 public class SyncPlanPushStrategyFlatBatchImplTest {
71 private static final NodeId NODE_ID = new NodeId("ut-node-id");
72 private static final InstanceIdentifier<FlowCapableNode> NODE_IDENT = InstanceIdentifier.create(Nodes.class)
73 .child(Node.class, new NodeKey(NODE_ID))
74 .augmentation(FlowCapableNode.class);
76 private SalFlatBatchService flatBatchService;
78 private TableForwarder tableForwarder;
80 private ArgumentCaptor<ProcessFlatBatchInput> processFlatBatchInputCpt;
82 private final List<ItemSyncBox<Group>> groupsToAddOrUpdate;
83 private final List<ItemSyncBox<Group>> groupsToRemove;
84 private final ItemSyncBox<Meter> metersToAddOrUpdate;
85 private final ItemSyncBox<Meter> metersToRemove;
86 private final Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate;
87 private final Map<TableKey, ItemSyncBox<Flow>> flowsToRemove;
88 private List<Batch> batchBag;
90 private SyncPlanPushStrategyFlatBatchImpl syncPlanPushStrategy;
92 public SyncPlanPushStrategyFlatBatchImplTest() {
93 groupsToAddOrUpdate = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
94 DiffInputFactory.createGroupSyncBoxWithUpdates(4, 5, 6));
95 groupsToRemove = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
96 DiffInputFactory.createGroupSyncBox(4, 5, 6));
98 metersToAddOrUpdate = DiffInputFactory.createMeterSyncBoxWithUpdates(1, 2, 3);
99 metersToRemove = DiffInputFactory.createMeterSyncBox(1, 2, 3);
101 flowsToAddOrUpdate = new HashMap<>();
102 flowsToAddOrUpdate.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
103 flowsToAddOrUpdate.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBoxWithUpdates("4", "5", "6"));
104 flowsToRemove = new HashMap<>();
105 flowsToRemove.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
106 flowsToRemove.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBox("4", "5", "6"));
111 public void setUp() {
112 syncPlanPushStrategy = new SyncPlanPushStrategyFlatBatchImpl();
113 syncPlanPushStrategy.setFlatBatchService(flatBatchService);
114 syncPlanPushStrategy.setTableForwarder(tableForwarder);
116 batchBag = new ArrayList<>();
120 public void testExecuteSyncStrategy() throws Exception {
121 final SynchronizationDiffInput diffInput = new SynchronizationDiffInput(NODE_IDENT,
122 groupsToAddOrUpdate, metersToAddOrUpdate, flowsToAddOrUpdate,
123 flowsToRemove, metersToRemove, groupsToRemove);
125 Mockito.when(flatBatchService.processFlatBatch(ArgumentMatchers.any()))
126 .thenReturn(RpcResultBuilder.success(new ProcessFlatBatchOutputBuilder().build()).buildFuture());
128 final SyncCrudCounters counters = new SyncCrudCounters();
129 final ListenableFuture<RpcResult<Void>> rpcResult = syncPlanPushStrategy.executeSyncStrategy(
130 RpcResultBuilder.<Void>success().buildFuture(), diffInput, counters);
132 Mockito.verify(flatBatchService).processFlatBatch(processFlatBatchInputCpt.capture());
134 final ProcessFlatBatchInput processFlatBatchInput = processFlatBatchInputCpt.getValue();
135 Assert.assertFalse(processFlatBatchInput.isExitOnFirstError());
136 Assert.assertEquals(13, processFlatBatchInput.getBatch().size());
138 Assert.assertTrue(rpcResult.isDone());
139 Assert.assertTrue(rpcResult.get().isSuccessful());
141 Assert.assertEquals(6, counters.getFlowCrudCounts().getAdded());
142 Assert.assertEquals(3, counters.getFlowCrudCounts().getUpdated());
143 Assert.assertEquals(6, counters.getFlowCrudCounts().getRemoved());
145 Assert.assertEquals(6, counters.getGroupCrudCounts().getAdded());
146 Assert.assertEquals(3, counters.getGroupCrudCounts().getUpdated());
147 Assert.assertEquals(6, counters.getGroupCrudCounts().getRemoved());
149 Assert.assertEquals(3, counters.getMeterCrudCounts().getAdded());
150 Assert.assertEquals(3, counters.getMeterCrudCounts().getUpdated());
151 Assert.assertEquals(3, counters.getMeterCrudCounts().getRemoved());
155 public void testAssembleRemoveFlows() {
156 final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleRemoveFlows(batchBag, 0, flowsToRemove);
158 Assert.assertEquals(6, lastOrder);
159 Assert.assertEquals(2, batchBag.size());
160 Assert.assertEquals(FlatBatchRemoveFlowCase.class, batchBag.get(0).getBatchChoice().implementedInterface());
161 Assert.assertEquals(3, ((FlatBatchRemoveFlowCase) batchBag.get(0).getBatchChoice())
162 .getFlatBatchRemoveFlow().size());
163 Assert.assertEquals(FlatBatchRemoveFlowCase.class, batchBag.get(1).getBatchChoice().implementedInterface());
164 Assert.assertEquals(3, ((FlatBatchRemoveFlowCase) batchBag.get(1).getBatchChoice())
165 .getFlatBatchRemoveFlow().size());
169 public void testAssembleAddOrUpdateGroups() {
170 final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleAddOrUpdateGroups(
171 batchBag, 0, groupsToAddOrUpdate);
173 Assert.assertEquals(9, lastOrder);
174 Assert.assertEquals(3, batchBag.size());
175 Assert.assertEquals(FlatBatchAddGroupCase.class, batchBag.get(0).getBatchChoice().implementedInterface());
176 Assert.assertEquals(3, ((FlatBatchAddGroupCase) batchBag.get(0).getBatchChoice())
177 .getFlatBatchAddGroup().size());
178 Assert.assertEquals(FlatBatchAddGroupCase.class, batchBag.get(1).getBatchChoice().implementedInterface());
179 Assert.assertEquals(3, ((FlatBatchAddGroupCase) batchBag.get(1).getBatchChoice())
180 .getFlatBatchAddGroup().size());
181 Assert.assertEquals(FlatBatchUpdateGroupCase.class, batchBag.get(2).getBatchChoice().implementedInterface());
182 Assert.assertEquals(3, ((FlatBatchUpdateGroupCase) batchBag.get(2).getBatchChoice())
183 .getFlatBatchUpdateGroup().size());
187 public void testAssembleRemoveGroups() {
188 final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleRemoveGroups(batchBag, 0, groupsToRemove);
190 Assert.assertEquals(6, lastOrder);
191 Assert.assertEquals(2, batchBag.size());
192 Assert.assertEquals(FlatBatchRemoveGroupCase.class, batchBag.get(0).getBatchChoice().implementedInterface());
193 Assert.assertEquals(3, ((FlatBatchRemoveGroupCase) batchBag.get(0).getBatchChoice())
194 .getFlatBatchRemoveGroup().size());
195 Assert.assertEquals(FlatBatchRemoveGroupCase.class, batchBag.get(1).getBatchChoice().implementedInterface());
196 Assert.assertEquals(3, ((FlatBatchRemoveGroupCase) batchBag.get(1).getBatchChoice())
197 .getFlatBatchRemoveGroup().size());
201 public void testAssembleAddOrUpdateMeters() {
202 final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleAddOrUpdateMeters(
203 batchBag, 0, metersToAddOrUpdate);
205 Assert.assertEquals(6, lastOrder);
206 Assert.assertEquals(2, batchBag.size());
207 Assert.assertEquals(FlatBatchAddMeterCase.class, batchBag.get(0).getBatchChoice().implementedInterface());
208 Assert.assertEquals(3, ((FlatBatchAddMeterCase) batchBag.get(0).getBatchChoice())
209 .getFlatBatchAddMeter().size());
210 Assert.assertEquals(FlatBatchUpdateMeterCase.class, batchBag.get(1).getBatchChoice().implementedInterface());
211 Assert.assertEquals(3, ((FlatBatchUpdateMeterCase) batchBag.get(1).getBatchChoice())
212 .getFlatBatchUpdateMeter().size());
216 public void testAssembleRemoveMeters() {
217 final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleRemoveMeters(batchBag, 0, metersToRemove);
219 Assert.assertEquals(3, lastOrder);
220 Assert.assertEquals(1, batchBag.size());
221 Assert.assertEquals(FlatBatchRemoveMeterCase.class, batchBag.get(0).getBatchChoice().implementedInterface());
222 Assert.assertEquals(3, ((FlatBatchRemoveMeterCase) batchBag.get(0).getBatchChoice())
223 .getFlatBatchRemoveMeter().size());
227 public void testAssembleAddOrUpdateFlows() {
228 final int lastOrder = SyncPlanPushStrategyFlatBatchImpl.assembleAddOrUpdateFlows(
229 batchBag, 0, flowsToAddOrUpdate);
231 Assert.assertEquals(9, lastOrder);
232 Assert.assertEquals(3, batchBag.size());
233 Assert.assertEquals(FlatBatchAddFlowCase.class, batchBag.get(0).getBatchChoice().implementedInterface());
234 Assert.assertEquals(3, ((FlatBatchAddFlowCase) batchBag.get(0).getBatchChoice())
235 .getFlatBatchAddFlow().size());
236 Assert.assertEquals(FlatBatchUpdateFlowCase.class, batchBag.get(1).getBatchChoice().implementedInterface());
237 Assert.assertEquals(3, ((FlatBatchUpdateFlowCase) batchBag.get(1).getBatchChoice())
238 .getFlatBatchUpdateFlow().size());
239 Assert.assertEquals(FlatBatchAddFlowCase.class, batchBag.get(2).getBatchChoice().implementedInterface());
240 Assert.assertEquals(3, ((FlatBatchAddFlowCase) batchBag.get(2).getBatchChoice())
241 .getFlatBatchAddFlow().size());
245 public void testDecrementCounters() {
246 final SyncCrudCounters counters = new SyncCrudCounters();
247 counters.getFlowCrudCounts().setAdded(100);
248 counters.getFlowCrudCounts().setUpdated(100);
249 counters.getFlowCrudCounts().setRemoved(100);
251 counters.getGroupCrudCounts().setAdded(100);
252 counters.getGroupCrudCounts().setUpdated(100);
253 counters.getGroupCrudCounts().setRemoved(100);
255 counters.getMeterCrudCounts().setAdded(100);
256 counters.getMeterCrudCounts().setUpdated(100);
257 counters.getMeterCrudCounts().setRemoved(100);
259 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchAddFlowCaseBuilder().build(), counters);
260 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchUpdateFlowCaseBuilder().build(), counters);
261 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchRemoveFlowCaseBuilder().build(), counters);
263 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchAddGroupCaseBuilder().build(), counters);
264 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchUpdateGroupCaseBuilder().build(), counters);
265 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchRemoveGroupCaseBuilder().build(), counters);
267 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchAddMeterCaseBuilder().build(), counters);
268 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchUpdateMeterCaseBuilder().build(), counters);
269 SyncPlanPushStrategyFlatBatchImpl.decrementCounters(new FlatBatchRemoveMeterCaseBuilder().build(), counters);
271 Assert.assertEquals(99, counters.getFlowCrudCounts().getAdded());
272 Assert.assertEquals(99, counters.getFlowCrudCounts().getUpdated());
273 Assert.assertEquals(99, counters.getFlowCrudCounts().getRemoved());
275 Assert.assertEquals(99, counters.getGroupCrudCounts().getAdded());
276 Assert.assertEquals(99, counters.getGroupCrudCounts().getUpdated());
277 Assert.assertEquals(99, counters.getGroupCrudCounts().getRemoved());
279 Assert.assertEquals(99, counters.getMeterCrudCounts().getAdded());
280 Assert.assertEquals(99, counters.getMeterCrudCounts().getUpdated());
281 Assert.assertEquals(99, counters.getMeterCrudCounts().getRemoved());
285 public void testMapBatchesToRanges() {
286 final List<Batch> inputBatchBag = Lists.newArrayList(
287 new BatchBuilder().setBatchOrder(0).build(),
288 new BatchBuilder().setBatchOrder(5).build(),
289 new BatchBuilder().setBatchOrder(9).build(),
290 new BatchBuilder().setBatchOrder(15).build()
292 final Map<Range<Integer>, Batch> rangeBatchMap =
293 SyncPlanPushStrategyFlatBatchImpl.mapBatchesToRanges(inputBatchBag, 42);
295 Assert.assertEquals(4, rangeBatchMap.size());
297 final int[] lower = new int[]{0, 5, 9, 15};
298 final int[] upper = new int[]{4, 8, 14, 41};
299 for (Map.Entry<Range<Integer>, Batch> rangeBatchEntry : rangeBatchMap.entrySet()) {
300 Assert.assertEquals(lower[idx], rangeBatchEntry.getKey().lowerEndpoint().intValue());
301 Assert.assertEquals(upper[idx], rangeBatchEntry.getKey().upperEndpoint().intValue());
302 Assert.assertSame(inputBatchBag.get(idx), rangeBatchEntry.getValue());