Switch to MD-SAL APIs
[openflowplugin.git] / applications / forwardingrules-sync / src / test / java / org / opendaylight / openflowplugin / applications / frsync / impl / strategy / SyncPlanPushStrategyIncrementalImplTest.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.applications.frsync.impl.strategy;
9
10 import com.google.common.collect.Lists;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.LinkedHashMap;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.concurrent.Future;
18 import org.junit.Assert;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.ArgumentCaptor;
23 import org.mockito.ArgumentMatchers;
24 import org.mockito.Captor;
25 import org.mockito.InOrder;
26 import org.mockito.Mock;
27 import org.mockito.Mockito;
28 import org.mockito.junit.MockitoJUnitRunner;
29 import org.mockito.stubbing.Answer;
30 import org.opendaylight.mdsal.binding.api.DataBroker;
31 import org.opendaylight.openflowplugin.applications.frsync.impl.DSInputFactory;
32 import org.opendaylight.openflowplugin.applications.frsync.util.ItemSyncBox;
33 import org.opendaylight.openflowplugin.applications.frsync.util.SyncCrudCounters;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesBuilder;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import org.opendaylight.yangtools.yang.common.RpcResult;
62 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
63
64 /**
65  * Test for {@link SyncPlanPushStrategyIncrementalImpl}.
66  */
67 @RunWith(MockitoJUnitRunner.class)
68 public class SyncPlanPushStrategyIncrementalImplTest {
69
70     private static final NodeId NODE_ID = new NodeId("unit-nodeId");
71     private static final InstanceIdentifier<FlowCapableNode> NODE_IDENT = InstanceIdentifier.create(Nodes.class)
72             .child(Node.class, new NodeKey(NODE_ID)).augmentation(FlowCapableNode.class);
73
74     private SyncPlanPushStrategyIncrementalImpl syncPlanPushStrategy;
75
76     @Mock
77     private DataBroker db;
78     @Mock
79     private GroupForwarder groupCommitter;
80     @Mock
81     private FlowForwarder flowCommitter;
82     @Mock
83     private MeterForwarder meterCommitter;
84     @Mock
85     private TableForwarder tableCommitter;
86     @Mock
87     private FlowCapableTransactionService flowCapableTxService;
88
89     @Captor
90     private ArgumentCaptor<Group> groupCaptor;
91     @Captor
92     private ArgumentCaptor<Group> groupUpdateCaptor;
93     @Captor
94     private ArgumentCaptor<Flow> flowCaptor;
95     @Captor
96     private ArgumentCaptor<Flow> flowUpdateCaptor;
97     @Captor
98     private ArgumentCaptor<Meter> meterCaptor;
99     @Captor
100     private ArgumentCaptor<Meter> meterUpdateCaptor;
101     @Captor
102     private ArgumentCaptor<TableFeatures> tableFeaturesCaptor;
103
104     private SyncCrudCounters counters;
105
106     private final List<ItemSyncBox<Group>> groupsToAddOrUpdate;
107     private final List<ItemSyncBox<Group>> groupsToRemove;
108     private final ItemSyncBox<Meter> metersToAddOrUpdate;
109     private final ItemSyncBox<Meter> metersToRemove;
110     private final Map<TableKey, ItemSyncBox<Flow>> flowsToAddOrUpdate;
111     private final Map<TableKey, ItemSyncBox<Flow>> flowsToRemove;
112
113     public SyncPlanPushStrategyIncrementalImplTest() {
114         groupsToAddOrUpdate = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
115                 DiffInputFactory.createGroupSyncBoxWithUpdates(4, 5, 6));
116         groupsToRemove = Lists.newArrayList(DiffInputFactory.createGroupSyncBox(1, 2, 3),
117                 DiffInputFactory.createGroupSyncBox(4, 5, 6));
118
119         metersToAddOrUpdate = DiffInputFactory.createMeterSyncBoxWithUpdates(1, 2, 3);
120         metersToRemove = DiffInputFactory.createMeterSyncBox(1, 2, 3);
121
122         flowsToAddOrUpdate = new HashMap<>();
123         flowsToAddOrUpdate.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
124         flowsToAddOrUpdate.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBoxWithUpdates("4", "5", "6"));
125         flowsToRemove = new HashMap<>();
126         flowsToRemove.put(new TableKey((short) 0), DiffInputFactory.createFlowSyncBox("1", "2", "3"));
127         flowsToRemove.put(new TableKey((short) 1), DiffInputFactory.createFlowSyncBox("4", "5", "6"));
128     }
129
130     @Test
131     public void testExecuteSyncStrategy() throws Exception {
132         final SynchronizationDiffInput diffInput = new SynchronizationDiffInput(NODE_IDENT,
133                 groupsToAddOrUpdate, metersToAddOrUpdate, flowsToAddOrUpdate, flowsToRemove,
134                 metersToRemove, groupsToRemove);
135
136         final SyncCrudCounters syncCounters = new SyncCrudCounters();
137         final ListenableFuture<RpcResult<Void>> rpcResult = syncPlanPushStrategy.executeSyncStrategy(
138                 RpcResultBuilder.<Void>success().buildFuture(), diffInput, syncCounters);
139
140         Mockito.verify(groupCommitter, Mockito.times(6)).add(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
141                 ArgumentMatchers.<Group>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
142         Mockito.verify(groupCommitter, Mockito.times(3)).update(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
143                 ArgumentMatchers.<Group>any(), ArgumentMatchers.<Group>any(),
144                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
145         Mockito.verify(groupCommitter, Mockito.times(6)).remove(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
146                 ArgumentMatchers.<Group>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
147         Mockito.verify(flowCommitter, Mockito.times(6)).add(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
148                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
149         Mockito.verify(flowCommitter, Mockito.times(3)).update(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
150                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.<Flow>any(),
151                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
152         Mockito.verify(flowCommitter, Mockito.times(6)).remove(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
153                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
154         Mockito.verify(meterCommitter, Mockito.times(3)).add(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
155                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
156         Mockito.verify(meterCommitter, Mockito.times(3)).update(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
157                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.<Meter>any(),
158                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
159         Mockito.verify(meterCommitter, Mockito.times(3)).remove(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
160                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
161
162         Assert.assertTrue(rpcResult.isDone());
163         Assert.assertTrue(rpcResult.get().isSuccessful());
164
165         Assert.assertEquals(6, syncCounters.getFlowCrudCounts().getAdded());
166         Assert.assertEquals(3, syncCounters.getFlowCrudCounts().getUpdated());
167         Assert.assertEquals(6, syncCounters.getFlowCrudCounts().getRemoved());
168
169         Assert.assertEquals(6, syncCounters.getGroupCrudCounts().getAdded());
170         Assert.assertEquals(3, syncCounters.getGroupCrudCounts().getUpdated());
171         Assert.assertEquals(6, syncCounters.getGroupCrudCounts().getRemoved());
172
173         Assert.assertEquals(3, syncCounters.getMeterCrudCounts().getAdded());
174         Assert.assertEquals(3, syncCounters.getMeterCrudCounts().getUpdated());
175         Assert.assertEquals(3, syncCounters.getMeterCrudCounts().getRemoved());
176     }
177
178     @Before
179     public void setUp() throws Exception {
180         Mockito.when(flowCapableTxService.sendBarrier(ArgumentMatchers.<SendBarrierInput>any()))
181                 .thenReturn(RpcResultBuilder.success((SendBarrierOutput) null).buildFuture());
182
183         Mockito.doAnswer(createSalServiceFutureAnswer()).when(groupCommitter).add(
184                 ArgumentMatchers.<InstanceIdentifier<Group>>any(), ArgumentMatchers.<Group>any(),
185                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
186         Mockito.doAnswer(createSalServiceFutureAnswer()).when(groupCommitter).update(
187                 ArgumentMatchers.<InstanceIdentifier<Group>>any(), ArgumentMatchers.<Group>any(),
188                 ArgumentMatchers.<Group>any(),
189                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
190         Mockito.doAnswer(createSalServiceFutureAnswer()).when(groupCommitter).remove(
191                 ArgumentMatchers.<InstanceIdentifier<Group>>any(), ArgumentMatchers.<Group>any(),
192                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
193
194         Mockito.doAnswer(createSalServiceFutureAnswer()).when(flowCommitter).add(
195                 ArgumentMatchers.<InstanceIdentifier<Flow>>any(), ArgumentMatchers.<Flow>any(),
196                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
197         Mockito.doAnswer(createSalServiceFutureAnswer()).when(flowCommitter).update(
198                 ArgumentMatchers.<InstanceIdentifier<Flow>>any(), ArgumentMatchers.<Flow>any(),
199                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
200         Mockito.doAnswer(createSalServiceFutureAnswer()).when(flowCommitter).remove(
201                 ArgumentMatchers.<InstanceIdentifier<Flow>>any(), ArgumentMatchers.<Flow>any(),
202                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
203
204         Mockito.doAnswer(createSalServiceFutureAnswer()).when(meterCommitter).add(
205                 ArgumentMatchers.<InstanceIdentifier<Meter>>any(), ArgumentMatchers.<Meter>any(),
206                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
207         Mockito.doAnswer(createSalServiceFutureAnswer()).when(meterCommitter).update(
208                 ArgumentMatchers.<InstanceIdentifier<Meter>>any(), ArgumentMatchers.<Meter>any(),
209                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
210         Mockito.doAnswer(createSalServiceFutureAnswer()).when(meterCommitter).remove(
211                 ArgumentMatchers.<InstanceIdentifier<Meter>>any(), ArgumentMatchers.<Meter>any(),
212                 ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
213
214         Mockito.doAnswer(createSalServiceFutureAnswer()).when(tableCommitter).update(
215                 ArgumentMatchers.<InstanceIdentifier<TableFeatures>>any(), ArgumentMatchers.<TableFeatures>any(),
216                 ArgumentMatchers.<TableFeatures>any(), ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any());
217
218         syncPlanPushStrategy = new SyncPlanPushStrategyIncrementalImpl()
219                 .setMeterForwarder(meterCommitter)
220                 .setTableForwarder(tableCommitter)
221                 .setGroupForwarder(groupCommitter)
222                 .setFlowForwarder(flowCommitter)
223                 .setTransactionService(flowCapableTxService);
224
225         counters = new SyncCrudCounters();
226     }
227
228     private <O> Answer<Future<RpcResult<O>>> createSalServiceFutureAnswer() {
229         return invocation -> RpcResultBuilder.<O>success().buildFuture();
230     }
231
232     @Test
233     public void testAddMissingFlows() throws Exception {
234         Mockito.when(flowCommitter.add(ArgumentMatchers.<InstanceIdentifier<Flow>>any(), flowCaptor.capture(),
235                 ArgumentMatchers.same(NODE_IDENT)))
236                 .thenReturn(RpcResultBuilder.success(new AddFlowOutputBuilder().build()).buildFuture());
237
238         final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
239         flowBox.getItemsToPush().add(DSInputFactory.createFlow("f3", 3));
240         flowBox.getItemsToPush().add(DSInputFactory.createFlow("f4", 4));
241
242         final Map<TableKey, ItemSyncBox<Flow>> flowBoxMap = new LinkedHashMap<>();
243         flowBoxMap.put(new TableKey((short) 0), flowBox);
244
245         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingFlows(
246                 NODE_ID, NODE_IDENT, flowBoxMap, counters);
247
248         Assert.assertTrue(result.isDone());
249         Assert.assertTrue(result.get().isSuccessful());
250
251         final List<Flow> flowCaptorAllValues = flowCaptor.getAllValues();
252         Assert.assertEquals(2, flowCaptorAllValues.size());
253         Assert.assertEquals("f3", flowCaptorAllValues.get(0).getId().getValue());
254         Assert.assertEquals("f4", flowCaptorAllValues.get(1).getId().getValue());
255
256         final InOrder inOrderFlow = Mockito.inOrder(flowCapableTxService, flowCommitter);
257         inOrderFlow.verify(flowCommitter, Mockito.times(2)).add(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
258                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.eq(NODE_IDENT));
259         //TODO: uncomment when enabled in impl
260 //        inOrderFlow.verify(flowCapableTxService).sendBarrier(Matchers.<SendBarrierInput>any());
261         inOrderFlow.verifyNoMoreInteractions();
262     }
263
264     @Test
265     public void testRemoveRedundantFlows() throws Exception {
266         Mockito.when(flowCommitter.remove(ArgumentMatchers.<InstanceIdentifier<Flow>>any(), flowCaptor.capture(),
267                 ArgumentMatchers.same(NODE_IDENT)))
268                 .thenReturn(RpcResultBuilder.success(new RemoveFlowOutputBuilder().build()).buildFuture());
269
270         final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
271         flowBox.getItemsToPush().add(DSInputFactory.createFlow("f3", 3));
272         flowBox.getItemsToPush().add(DSInputFactory.createFlow("f4", 4));
273
274         final Map<TableKey, ItemSyncBox<Flow>> flowBoxMap = new LinkedHashMap<>();
275         flowBoxMap.put(new TableKey((short) 0), flowBox);
276
277         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.removeRedundantFlows(
278                 NODE_ID, NODE_IDENT, flowBoxMap, counters);
279
280         Assert.assertTrue(result.isDone());
281         Assert.assertTrue(result.get().isSuccessful());
282
283         final List<Flow> flowCaptorAllValues = flowCaptor.getAllValues();
284         Assert.assertEquals(2, flowCaptorAllValues.size());
285         Assert.assertEquals("f3", flowCaptorAllValues.get(0).getId().getValue());
286         Assert.assertEquals("f4", flowCaptorAllValues.get(1).getId().getValue());
287
288         final InOrder inOrderFlow = Mockito.inOrder(flowCapableTxService, flowCommitter);
289         inOrderFlow.verify(flowCommitter, Mockito.times(2)).remove(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
290                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.eq(NODE_IDENT));
291         inOrderFlow.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
292         inOrderFlow.verifyNoMoreInteractions();
293     }
294
295
296     @Test
297     public void testAddMissingFlows_withUpdate() throws Exception {
298         Mockito.when(flowCommitter.add(ArgumentMatchers.<InstanceIdentifier<Flow>>any(), flowCaptor.capture(),
299                 ArgumentMatchers.same(NODE_IDENT)))
300                 .thenReturn(RpcResultBuilder.success(new AddFlowOutputBuilder().build()).buildFuture());
301
302         Mockito.when(flowCommitter.update(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
303                 flowUpdateCaptor.capture(), flowUpdateCaptor.capture(),
304                 ArgumentMatchers.same(NODE_IDENT)))
305                 .thenReturn(RpcResultBuilder.success(new UpdateFlowOutputBuilder().build()).buildFuture());
306
307         final ItemSyncBox<Flow> flowBox = new ItemSyncBox<>();
308         flowBox.getItemsToPush().add(DSInputFactory.createFlow("f3", 3));
309         flowBox.getItemsToPush().add(DSInputFactory.createFlow("f4", 4));
310         flowBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
311                 DSInputFactory.createFlow("f1", 1), DSInputFactory.createFlowWithInstruction("f1", 1)));
312
313         final Map<TableKey, ItemSyncBox<Flow>> flowBoxMap = new LinkedHashMap<>();
314         flowBoxMap.put(new TableKey((short) 0), flowBox);
315
316
317         //TODO: replace null
318         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingFlows(
319                 NODE_ID, NODE_IDENT, flowBoxMap, counters);
320
321         Assert.assertTrue(result.isDone());
322         Assert.assertTrue(result.get().isSuccessful());
323
324         final List<Flow> flowCaptorAllValues = flowCaptor.getAllValues();
325         Assert.assertEquals(2, flowCaptorAllValues.size());
326         Assert.assertEquals("f3", flowCaptorAllValues.get(0).getId().getValue());
327         Assert.assertEquals("f4", flowCaptorAllValues.get(1).getId().getValue());
328
329         final List<Flow> flowUpdateCaptorAllValues = flowUpdateCaptor.getAllValues();
330         Assert.assertEquals(2, flowUpdateCaptorAllValues.size());
331         Assert.assertEquals("f1", flowUpdateCaptorAllValues.get(0).getId().getValue());
332         Assert.assertEquals("f1", flowUpdateCaptorAllValues.get(1).getId().getValue());
333
334         final InOrder inOrderFlow = Mockito.inOrder(flowCapableTxService, flowCommitter);
335         // add f3, f4
336         inOrderFlow.verify(flowCommitter, Mockito.times(2)).add(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
337                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.eq(NODE_IDENT));
338         // update f1
339         inOrderFlow.verify(flowCommitter).update(ArgumentMatchers.<InstanceIdentifier<Flow>>any(),
340                 ArgumentMatchers.<Flow>any(), ArgumentMatchers.<Flow>any(), ArgumentMatchers.eq(NODE_IDENT));
341         //TODO: uncomment when enabled in impl
342 //        inOrderFlow.verify(flowCapableTxService).sendBarrier(Matchers.<SendBarrierInput>any());
343
344         inOrderFlow.verifyNoMoreInteractions();
345     }
346
347     @Test
348     public void testAddMissingMeters() throws Exception {
349         Mockito.when(meterCommitter.add(ArgumentMatchers.<InstanceIdentifier<Meter>>any(), meterCaptor.capture(),
350                 ArgumentMatchers.same(NODE_IDENT)))
351                 .thenReturn(RpcResultBuilder.success(new AddMeterOutputBuilder().build()).buildFuture());
352
353         final ItemSyncBox<Meter> meterSyncBox = new ItemSyncBox<>();
354         meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(2L));
355         meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(4L));
356
357         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingMeters(
358                 NODE_ID, NODE_IDENT, meterSyncBox, counters);
359
360         Assert.assertTrue(result.isDone());
361         Assert.assertTrue(result.get().isSuccessful());
362
363         final List<Meter> metercaptorAllValues = meterCaptor.getAllValues();
364         Assert.assertEquals(2, metercaptorAllValues.size());
365         Assert.assertEquals(2L, metercaptorAllValues.get(0).getMeterId().getValue().longValue());
366         Assert.assertEquals(4L, metercaptorAllValues.get(1).getMeterId().getValue().longValue());
367
368         final InOrder inOrderMeter = Mockito.inOrder(flowCapableTxService, meterCommitter);
369         inOrderMeter.verify(meterCommitter, Mockito.times(2)).add(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
370                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.eq(NODE_IDENT));
371         //TODO: uncomment when enabled in impl
372 //        inOrderMeter.verify(flowCapableTxService).sendBarrier(Matchers.<SendBarrierInput>any());
373         inOrderMeter.verifyNoMoreInteractions();
374     }
375
376     @Test
377     public void testAddMissingMeters_withUpdate() throws Exception {
378         Mockito.when(meterCommitter.add(ArgumentMatchers.<InstanceIdentifier<Meter>>any(), meterCaptor.capture(),
379                 ArgumentMatchers.same(NODE_IDENT)))
380                 .thenReturn(RpcResultBuilder.success(new AddMeterOutputBuilder().build()).buildFuture());
381
382         Mockito.when(meterCommitter.update(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
383                 meterUpdateCaptor.capture(), meterUpdateCaptor.capture(), ArgumentMatchers.same(NODE_IDENT)))
384                 .thenReturn(RpcResultBuilder.success(new UpdateMeterOutputBuilder().build()).buildFuture());
385
386         final ItemSyncBox<Meter> meterSyncBox = new ItemSyncBox<>();
387         meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(2L));
388         meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(4L));
389         meterSyncBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
390                 DSInputFactory.createMeter(1L), DSInputFactory.createMeterWithBody(1L)));
391
392         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingMeters(
393                 NODE_ID, NODE_IDENT, meterSyncBox, counters);
394
395         Assert.assertTrue(result.isDone());
396         Assert.assertTrue(result.get().isSuccessful());
397
398         final List<Meter> meterCaptorAllValues = meterCaptor.getAllValues();
399         Assert.assertEquals(2, meterCaptorAllValues.size());
400         Assert.assertEquals(2L, meterCaptorAllValues.get(0).getMeterId().getValue().longValue());
401         Assert.assertEquals(4L, meterCaptorAllValues.get(1).getMeterId().getValue().longValue());
402
403
404         final List<Meter> meterUpdateCaptorAllValues = meterUpdateCaptor.getAllValues();
405         Assert.assertEquals(2, meterUpdateCaptorAllValues.size());
406         Assert.assertEquals(1L, meterUpdateCaptorAllValues.get(0).getMeterId().getValue().longValue());
407         Assert.assertEquals(1L, meterUpdateCaptorAllValues.get(1).getMeterId().getValue().longValue());
408
409         final InOrder inOrderMeters = Mockito.inOrder(flowCapableTxService, meterCommitter);
410         inOrderMeters.verify(meterCommitter, Mockito.times(2)).add(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
411                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.eq(NODE_IDENT));
412         inOrderMeters.verify(meterCommitter).update(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
413                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.<Meter>any(), ArgumentMatchers.eq(NODE_IDENT));
414         //TODO: uncomment when enabled in impl
415 //        inOrderMeters.verify(flowCapableTxService).sendBarrier(Matchers.<SendBarrierInput>any());
416
417         inOrderMeters.verifyNoMoreInteractions();
418     }
419
420     @Test
421     public void testRemoveRedundantMeters() throws Exception {
422         Mockito.when(meterCommitter.remove(ArgumentMatchers.<InstanceIdentifier<Meter>>any(), meterCaptor.capture(),
423                 ArgumentMatchers.same(NODE_IDENT)))
424                 .thenReturn(RpcResultBuilder.success(new RemoveMeterOutputBuilder().build()).buildFuture());
425
426         final ItemSyncBox<Meter> meterSyncBox = new ItemSyncBox<>();
427         meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(2L));
428         meterSyncBox.getItemsToPush().add(DSInputFactory.createMeter(4L));
429         meterSyncBox.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
430                 DSInputFactory.createMeter(1L), DSInputFactory.createMeterWithBody(1L)));
431
432         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.removeRedundantMeters(
433                 NODE_ID, NODE_IDENT, meterSyncBox, counters);
434
435         Assert.assertTrue(result.isDone());
436         Assert.assertTrue(result.get().isSuccessful());
437
438         final List<Meter> metercaptorAllValues = meterCaptor.getAllValues();
439         Assert.assertEquals(2, metercaptorAllValues.size());
440         Assert.assertEquals(2L, metercaptorAllValues.get(0).getMeterId().getValue().longValue());
441         Assert.assertEquals(4L, metercaptorAllValues.get(1).getMeterId().getValue().longValue());
442
443         final InOrder inOrderMeter = Mockito.inOrder(flowCapableTxService, meterCommitter);
444         inOrderMeter.verify(meterCommitter, Mockito.times(2)).remove(ArgumentMatchers.<InstanceIdentifier<Meter>>any(),
445                 ArgumentMatchers.<Meter>any(), ArgumentMatchers.eq(NODE_IDENT));
446         //TODO: uncomment when enabled in impl
447 //        inOrderMeter.verify(flowCapableTxService).sendBarrier(Matchers.<SendBarrierInput>any());
448         inOrderMeter.verifyNoMoreInteractions();
449     }
450
451     @Test
452     public void testAddMissingGroups() throws Exception {
453         Mockito.when(groupCommitter.add(ArgumentMatchers.<InstanceIdentifier<Group>>any(), groupCaptor.capture(),
454                 ArgumentMatchers.same(NODE_IDENT)))
455                 .thenReturn(RpcResultBuilder.success(new AddGroupOutputBuilder().build()).buildFuture());
456
457         ItemSyncBox<Group> groupBox1 = new ItemSyncBox<>();
458         groupBox1.getItemsToPush().add(DSInputFactory.createGroup(2L));
459
460         ItemSyncBox<Group> groupBox2 = new ItemSyncBox<>();
461         groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(3L, 2L));
462         groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(4L, 2L));
463
464         ItemSyncBox<Group> groupBox3 = new ItemSyncBox<>();
465         groupBox3.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(5L, 3L, 4L));
466
467         final List<ItemSyncBox<Group>> groupBoxLot = Lists.newArrayList(groupBox1, groupBox2, groupBox3);
468
469         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingGroups(
470                 NODE_ID, NODE_IDENT, groupBoxLot, counters);
471
472         Assert.assertTrue(result.isDone());
473         Assert.assertTrue(result.get().isSuccessful());
474
475         final List<Group> groupCaptorAllValues = groupCaptor.getAllValues();
476         Assert.assertEquals(4, groupCaptorAllValues.size());
477         Assert.assertEquals(2L, groupCaptorAllValues.get(0).getGroupId().getValue().longValue());
478         Assert.assertEquals(3L, groupCaptorAllValues.get(1).getGroupId().getValue().longValue());
479         Assert.assertEquals(4L, groupCaptorAllValues.get(2).getGroupId().getValue().longValue());
480         Assert.assertEquals(5L, groupCaptorAllValues.get(3).getGroupId().getValue().longValue());
481
482         final InOrder inOrderGroups = Mockito.inOrder(flowCapableTxService, groupCommitter);
483         // add 2
484         inOrderGroups.verify(groupCommitter).add(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
485                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
486         inOrderGroups.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
487         // add 3, 4
488         inOrderGroups.verify(groupCommitter, Mockito.times(2)).add(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
489                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
490         inOrderGroups.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
491         // add 5
492         inOrderGroups.verify(groupCommitter).add(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
493                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
494         inOrderGroups.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
495
496         inOrderGroups.verifyNoMoreInteractions();
497     }
498
499     @Test
500     public void testAddMissingGroups_withUpdate() throws Exception {
501         Mockito.when(groupCommitter.add(ArgumentMatchers.<InstanceIdentifier<Group>>any(), groupCaptor.capture(),
502                 ArgumentMatchers.same(NODE_IDENT)))
503                 .thenReturn(RpcResultBuilder.success(new AddGroupOutputBuilder().build()).buildFuture());
504
505         Mockito.when(groupCommitter.update(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
506                 groupUpdateCaptor.capture(), groupUpdateCaptor.capture(),
507                 ArgumentMatchers.same(NODE_IDENT)))
508                 .thenReturn(RpcResultBuilder.success(new UpdateGroupOutputBuilder().build()).buildFuture());
509
510         ItemSyncBox<Group> groupBox1 = new ItemSyncBox<>();
511         groupBox1.getItemsToPush().add(DSInputFactory.createGroup(2L));
512         groupBox1.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
513                 DSInputFactory.createGroup(1L), DSInputFactory.createGroupWithAction(1L)));
514
515         ItemSyncBox<Group> groupBox2 = new ItemSyncBox<>();
516         groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(3L, 2L));
517         groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(4L, 2L));
518
519         ItemSyncBox<Group> groupBox3 = new ItemSyncBox<>();
520         groupBox3.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(5L, 3L, 4L));
521
522         final List<ItemSyncBox<Group>> groupBoxLot = Lists.newArrayList(groupBox1, groupBox2, groupBox3);
523         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.addMissingGroups(
524                 NODE_ID, NODE_IDENT, groupBoxLot, counters);
525
526         Assert.assertTrue(result.isDone());
527         Assert.assertTrue(result.get().isSuccessful());
528
529         final List<Group> groupCaptorAllValues = groupCaptor.getAllValues();
530         Assert.assertEquals(4, groupCaptorAllValues.size());
531         Assert.assertEquals(2L, groupCaptorAllValues.get(0).getGroupId().getValue().longValue());
532         Assert.assertEquals(3L, groupCaptorAllValues.get(1).getGroupId().getValue().longValue());
533         Assert.assertEquals(4L, groupCaptorAllValues.get(2).getGroupId().getValue().longValue());
534         Assert.assertEquals(5L, groupCaptorAllValues.get(3).getGroupId().getValue().longValue());
535
536         final List<Group> groupUpdateCaptorAllValues = groupUpdateCaptor.getAllValues();
537         Assert.assertEquals(2, groupUpdateCaptorAllValues.size());
538         Assert.assertEquals(1L, groupUpdateCaptorAllValues.get(0).getGroupId().getValue().longValue());
539         Assert.assertEquals(1L, groupUpdateCaptorAllValues.get(1).getGroupId().getValue().longValue());
540
541         final InOrder inOrderGroups = Mockito.inOrder(flowCapableTxService, groupCommitter);
542
543         // add 2, update 1
544         inOrderGroups.verify(groupCommitter).add(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
545                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
546         inOrderGroups.verify(groupCommitter).update(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
547                 ArgumentMatchers.<Group>any(), ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
548         inOrderGroups.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
549
550         // add 3, 4
551         inOrderGroups.verify(groupCommitter, Mockito.times(2)).add(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
552                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
553         inOrderGroups.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
554         // add 5
555         inOrderGroups.verify(groupCommitter).add(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
556                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
557         inOrderGroups.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
558
559         inOrderGroups.verifyNoMoreInteractions();
560     }
561
562     @Test
563     public void testRemoveRedundantGroups() throws Exception {
564         Mockito.when(groupCommitter.remove(ArgumentMatchers.<InstanceIdentifier<Group>>any(), groupCaptor.capture(),
565                 ArgumentMatchers.same(NODE_IDENT)))
566                 .thenReturn(RpcResultBuilder.success(new RemoveGroupOutputBuilder().build()).buildFuture());
567
568         ItemSyncBox<Group> groupBox1 = new ItemSyncBox<>();
569         groupBox1.getItemsToPush().add(DSInputFactory.createGroup(2L));
570         groupBox1.getItemsToUpdate().add(new ItemSyncBox.ItemUpdateTuple<>(
571                 DSInputFactory.createGroup(1L), DSInputFactory.createGroupWithAction(1L)));
572
573         ItemSyncBox<Group> groupBox2 = new ItemSyncBox<>();
574         groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(3L, 2L));
575         groupBox2.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(4L, 2L));
576
577         ItemSyncBox<Group> groupBox3 = new ItemSyncBox<>();
578         groupBox3.getItemsToPush().add(DSInputFactory.createGroupWithPreconditions(5L, 3L, 4L));
579
580         final List<ItemSyncBox<Group>> groupBoxLot = Lists.newArrayList(groupBox1, groupBox2, groupBox3);
581         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.removeRedundantGroups(
582                 NODE_ID, NODE_IDENT, groupBoxLot, counters);
583
584         Assert.assertTrue(result.isDone());
585         Assert.assertTrue(result.get().isSuccessful());
586
587         final List<Group> groupCaptorAllValues = groupCaptor.getAllValues();
588         Assert.assertEquals(4, groupCaptorAllValues.size());
589         Assert.assertEquals(5L, groupCaptorAllValues.get(0).getGroupId().getValue().longValue());
590         Assert.assertEquals(3L, groupCaptorAllValues.get(1).getGroupId().getValue().longValue());
591         Assert.assertEquals(4L, groupCaptorAllValues.get(2).getGroupId().getValue().longValue());
592         Assert.assertEquals(2L, groupCaptorAllValues.get(3).getGroupId().getValue().longValue());
593
594         final InOrder inOrderGroup = Mockito.inOrder(flowCapableTxService, groupCommitter);
595         // remove 5
596         inOrderGroup.verify(groupCommitter).remove(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
597                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
598         inOrderGroup.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
599         // remove 3, 4
600         inOrderGroup.verify(groupCommitter, Mockito.times(2)).remove(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
601                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
602         inOrderGroup.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
603         // remove 2
604         inOrderGroup.verify(groupCommitter).remove(ArgumentMatchers.<InstanceIdentifier<Group>>any(),
605                 ArgumentMatchers.<Group>any(), ArgumentMatchers.eq(NODE_IDENT));
606         inOrderGroup.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
607
608         inOrderGroup.verifyNoMoreInteractions();
609     }
610
611     @Test
612     public void testUpdateTableFeatures() throws Exception {
613         Mockito.lenient().when(tableCommitter.update(ArgumentMatchers.<InstanceIdentifier<TableFeatures>>any(),
614                 ArgumentMatchers.isNull(TableFeatures.class), tableFeaturesCaptor.capture(),
615                 ArgumentMatchers.same(NODE_IDENT)))
616                 .thenReturn(RpcResultBuilder.success(new UpdateTableOutputBuilder().build()).buildFuture());
617
618         final FlowCapableNode operational = new FlowCapableNodeBuilder()
619                 .setTable(Collections.singletonList(new TableBuilder()
620                         .setId((short) 1)
621                         .build()))
622                 .setTableFeatures(Collections.singletonList(new TableFeaturesBuilder()
623                         .setName("test table features")
624                         .setTableId((short) 1)
625                         .build()))
626                 .build();
627
628         final ListenableFuture<RpcResult<Void>> result = syncPlanPushStrategy.updateTableFeatures(
629                 NODE_IDENT, operational);
630
631         Assert.assertTrue(result.isDone());
632         Assert.assertTrue(result.get().isSuccessful());
633
634         final List<TableFeatures> groupCaptorAllValues = tableFeaturesCaptor.getAllValues();
635         //TODO: uncomment when enabled in impl
636 //        Assert.assertEquals(1, groupCaptorAllValues.size());
637 //        Assert.assertEquals("test table features", groupCaptorAllValues.get(0).getName());
638 //        Assert.assertEquals(1, groupCaptorAllValues.get(0).getTableId().intValue());
639
640         Mockito.verify(flowCapableTxService).sendBarrier(ArgumentMatchers.<SendBarrierInput>any());
641     }
642 }