2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package io.fd.honeycomb.translate.impl.write.registry;
19 import static org.hamcrest.Matchers.hasSize;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertThat;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24 import static org.mockito.Matchers.any;
25 import static org.mockito.Mockito.doThrow;
26 import static org.mockito.Mockito.inOrder;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.verifyNoMoreInteractions;
31 import static org.mockito.Mockito.verifyZeroInteractions;
32 import static org.mockito.Mockito.when;
34 import com.google.common.base.Optional;
35 import com.google.common.collect.HashMultimap;
36 import com.google.common.collect.ImmutableMap;
37 import com.google.common.collect.ImmutableMultimap;
38 import com.google.common.collect.Lists;
39 import com.google.common.collect.Multimap;
40 import com.google.common.collect.Sets;
41 import io.fd.honeycomb.translate.util.DataObjects;
42 import io.fd.honeycomb.translate.util.DataObjects.DataObject1;
43 import io.fd.honeycomb.translate.util.DataObjects.DataObject2;
44 import io.fd.honeycomb.translate.write.DataObjectUpdate;
45 import io.fd.honeycomb.translate.write.WriteContext;
46 import io.fd.honeycomb.translate.write.WriteFailedException;
47 import io.fd.honeycomb.translate.write.Writer;
48 import io.fd.honeycomb.translate.write.registry.UpdateFailedException;
49 import io.fd.honeycomb.translate.write.registry.WriterRegistry;
50 import java.util.Collection;
51 import java.util.Collections;
52 import java.util.List;
53 import javax.annotation.Nonnull;
54 import javax.annotation.Nullable;
55 import org.junit.Before;
56 import org.junit.Test;
57 import org.mockito.InOrder;
58 import org.mockito.Mock;
59 import org.mockito.MockitoAnnotations;
60 import org.mockito.stubbing.Answer;
61 import org.opendaylight.yangtools.yang.binding.DataObject;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
65 public class FlatWriterRegistryTest {
68 private Writer<DataObject1> writer1;
70 private Writer<DataObject2> writer2;
72 private Writer<DataObjects.DataObject3> writer3;
74 private Writer<DataObjects.DataObject1ChildK> writer4;
76 private WriteContext ctx;
78 private WriteContext revertWriteContext;
81 public void setUp() throws Exception {
82 MockitoAnnotations.initMocks(this);
83 when(writer1.getManagedDataObjectType()).thenReturn(DataObject1.IID);
84 when(writer2.getManagedDataObjectType()).thenReturn(DataObject2.IID);
85 when(writer3.getManagedDataObjectType()).thenReturn(DataObjects.DataObject3.IID);
86 when(writer4.getManagedDataObjectType()).thenReturn(DataObjects.DataObject1ChildK.IID);
87 // TODO - HONEYCOMB-412 - thenCallRealMethod doest work with default methods
88 // https://stackoverflow.com/questions/27663252/can-you-make-mockito-1-10-17-work-with-default-methods-in-interfaces
89 when(writer1.canProcess(any())).thenAnswer(answerWithImpl());
90 when(writer2.canProcess(any())).thenAnswer(answerWithImpl());
91 when(writer3.canProcess(any())).thenAnswer(answerWithImpl());
92 when(writer4.canProcess(any())).thenAnswer(answerWithImpl());
95 private static Answer<Object> answerWithImpl() {
96 return invocationOnMock -> new CheckedMockWriter(Writer.class.cast(invocationOnMock.getMock())).canProcess(
97 InstanceIdentifier.class.cast(invocationOnMock.getArguments()[0]));
101 public void testSubtreeWriterUpdateAggregation() throws Exception {
102 Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
104 when(ctx.readAfter(DataObject1.IID)).thenReturn(Optional.of(mock(DataObject1.class)));
105 when(ctx.readBefore(DataObject1.IID)).thenReturn(Optional.of(mock(DataObject1.class)));
107 Writer<?> writer = SubtreeWriter.createForWriter(Collections.singleton(DataObjects.DataObject1ChildK.IID), writer1);
109 InstanceIdentifier<DataObjects.DataObject1ChildK> update1Id = DataObject1.IID.child(DataObjects.DataObject1ChildK.class, new DataObjects.DataObject1ChildKey());
110 InstanceIdentifier<DataObjects.DataObject1ChildK> update2Id = DataObject1.IID.child(DataObjects.DataObject1ChildK.class, new DataObjects.DataObject1ChildKey());
111 updates.putAll(DataObjects.DataObject1ChildK.IID,
113 DataObjectUpdate.create(update1Id, mock(DataObjects.DataObject1ChildK.class), mock(DataObjects.DataObject1ChildK.class)),
114 DataObjectUpdate.create(update2Id, mock(DataObjects.DataObject1ChildK.class), mock(DataObjects.DataObject1ChildK.class))));
116 Collection<DataObjectUpdate> parentDataObjectUpdate = FlatWriterRegistry.getParentDataObjectUpdate(ctx, updates, writer);
117 // Just a single update, since there are 2 child updates for a container, they get reduced
118 assertEquals(1, parentDataObjectUpdate.size());
122 public void testSubtreeWriterUpdateAggregationForList() throws Exception {
123 Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
125 KeyedInstanceIdentifier<DataObjects.DataObject1ChildK, DataObjects.DataObject1ChildKey> parentKeyedId1 =
126 DataObject1.IID.child(DataObjects.DataObject1ChildK.class, new DataObjects.DataObject1ChildKey());
127 KeyedInstanceIdentifier<DataObjects.DataObject1ChildK, DataObjects.DataObject1ChildKey> parentKeyedId2 =
128 DataObject1.IID.child(DataObjects.DataObject1ChildK.class, new DataObjects.DataObject1ChildKey());
130 when(ctx.readBefore(parentKeyedId1)).thenReturn(Optional.of(mock(DataObjects.DataObject1ChildK.class)));
131 when(ctx.readAfter(parentKeyedId1)).thenReturn(Optional.of(mock(DataObjects.DataObject1ChildK.class)));
132 when(ctx.readBefore(parentKeyedId2)).thenReturn(Optional.of(mock(DataObjects.DataObject1ChildK.class)));
133 when(ctx.readAfter(parentKeyedId2)).thenReturn(Optional.of(mock(DataObjects.DataObject1ChildK.class)));
135 Writer<?> writer = SubtreeWriter.createForWriter(Sets.newHashSet(
136 InstanceIdentifier.create(DataObjects.DataObject1ChildK.class).child(DataObjects.DataObject1ChildK.DataObject1ChildKNested.class),
137 InstanceIdentifier.create(DataObjects.DataObject1ChildK.class).child(DataObjects.DataObject1ChildK.DataObject1ChildKNested2.class)),
140 InstanceIdentifier<DataObjects.DataObject1ChildK.DataObject1ChildKNested> updateList1Id = parentKeyedId1.child(DataObjects.DataObject1ChildK.DataObject1ChildKNested.class);
141 InstanceIdentifier<DataObjects.DataObject1ChildK.DataObject1ChildKNested> updateList2Id = parentKeyedId2.child(DataObjects.DataObject1ChildK.DataObject1ChildKNested.class);
142 updates.putAll(DataObjects.DataObject1ChildK.DataObject1ChildKNested.IID,
144 DataObjectUpdate.create(updateList1Id, mock(DataObjects.DataObject1ChildK.DataObject1ChildKNested.class), mock(DataObjects.DataObject1ChildK.DataObject1ChildKNested.class)),
145 DataObjectUpdate.create(updateList2Id, mock(DataObjects.DataObject1ChildK.DataObject1ChildKNested.class), mock(DataObjects.DataObject1ChildK.DataObject1ChildKNested.class))));
147 Collection<DataObjectUpdate> parentDataObjectUpdate = FlatWriterRegistry.getParentDataObjectUpdate(ctx, updates, writer);
148 // 2 updates for 2 different list items
149 assertEquals(2, parentDataObjectUpdate.size());
153 public void testMultipleUpdatesForSingleWriter() throws Exception {
154 final FlatWriterRegistry flatWriterRegistry =
155 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
157 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
158 final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
159 final InstanceIdentifier<DataObject1> iid2 = InstanceIdentifier.create(DataObject1.class);
160 final DataObject1 dataObject = mock(DataObject1.class);
161 updates.put(DataObject1.IID, DataObjectUpdate.create(iid, dataObject, dataObject));
162 updates.put(DataObject1.IID, DataObjectUpdate.create(iid2, dataObject, dataObject));
163 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
165 verify(writer1).processModification(iid, dataObject, dataObject, ctx);
166 verify(writer1).processModification(iid2, dataObject, dataObject, ctx);
167 // Invoked when registry is being created
168 verifyNoMoreInteractions(writer1);
169 verifyZeroInteractions(writer2);
173 public void testMultipleUpdatesForMultipleWriters() throws Exception {
174 final FlatWriterRegistry flatWriterRegistry =
175 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
177 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
178 final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
179 final DataObject1 dataObject = mock(DataObject1.class);
180 updates.put(DataObject1.IID, DataObjectUpdate.create(iid, dataObject, dataObject));
181 final InstanceIdentifier<DataObject2> iid2 = InstanceIdentifier.create(DataObject2.class);
182 final DataObject2 dataObject2 = mock(DataObject2.class);
183 updates.put(DataObject2.IID, DataObjectUpdate.create(iid2, dataObject2, dataObject2));
184 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
186 final InOrder inOrder = inOrder(writer1, writer2);
187 inOrder.verify(writer1).processModification(iid, dataObject, dataObject, ctx);
188 inOrder.verify(writer2).processModification(iid2, dataObject2, dataObject2, ctx);
190 // TODO - HONEYCOMB-412 -reintroduce verifyNoMoreInteractions and remove manual verify
191 // we are really interested just in invocations of processModification(),so adding specific verify to check that
192 verify(writer1,times(1)).processModification(any(),any(),any(),any());
193 verify(writer2,times(1)).processModification(any(),any(),any(),any());
194 //verifyNoMoreInteractions(writer1);
195 //verifyNoMoreInteractions(writer2);
199 public void testMultipleDeletesForMultipleWriters() throws Exception {
200 final FlatWriterRegistry flatWriterRegistry =
201 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
203 final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> deletes = HashMultimap.create();
204 final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
205 final DataObject1 dataObject = mock(DataObject1.class);
206 deletes.put(DataObject1.IID, ((DataObjectUpdate.DataObjectDelete) DataObjectUpdate.create(iid, dataObject, null)));
207 final InstanceIdentifier<DataObject2> iid2 = InstanceIdentifier.create(DataObject2.class);
208 final DataObject2 dataObject2 = mock(DataObject2.class);
210 DataObject2.IID, ((DataObjectUpdate.DataObjectDelete) DataObjectUpdate.create(iid2, dataObject2, null)));
211 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(ImmutableMultimap.of(), deletes), ctx);
213 final InOrder inOrder = inOrder(writer1, writer2);
214 // Reversed order of invocation, first writer2 and then writer1
215 inOrder.verify(writer2).processModification(iid2, dataObject2, null, ctx);
216 inOrder.verify(writer1).processModification(iid, dataObject, null, ctx);
218 // TODO - HONEYCOMB-412 -reintroduce verifyNoMoreInteractions and remove manual verify
219 // we are really interested just in invocations of processModification(),so adding specific verify to check that
220 verify(writer1,times(1)).processModification(any(),any(),any(),any());
221 verify(writer2,times(1)).processModification(any(),any(),any(),any());
222 //verifyNoMoreInteractions(writer1);
223 //verifyNoMoreInteractions(writer2);
227 public void testMultipleUpdatesAndDeletesForMultipleWriters() throws Exception {
228 final FlatWriterRegistry flatWriterRegistry =
229 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
231 final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> deletes = HashMultimap.create();
232 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
233 final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
234 final DataObject1 dataObject = mock(DataObject1.class);
236 deletes.put(DataObject1.IID, ((DataObjectUpdate.DataObjectDelete) DataObjectUpdate.create(iid, dataObject, null)));
238 updates.put(DataObject1.IID, DataObjectUpdate.create(iid, dataObject, dataObject));
239 final InstanceIdentifier<DataObject2> iid2 = InstanceIdentifier.create(DataObject2.class);
240 final DataObject2 dataObject2 = mock(DataObject2.class);
243 DataObject2.IID, ((DataObjectUpdate.DataObjectDelete) DataObjectUpdate.create(iid2, dataObject2, null)));
245 updates.put(DataObject2.IID, DataObjectUpdate.create(iid2, dataObject2, dataObject2));
246 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, deletes), ctx);
248 final InOrder inOrder = inOrder(writer1, writer2);
249 // Reversed order of invocation, first writer2 and then writer1 for deletes
250 inOrder.verify(writer2).processModification(iid2, dataObject2, null, ctx);
251 inOrder.verify(writer1).processModification(iid, dataObject, null, ctx);
252 // Then also updates are processed
253 inOrder.verify(writer1).processModification(iid, dataObject, dataObject, ctx);
254 inOrder.verify(writer2).processModification(iid2, dataObject2, dataObject2, ctx);
256 // TODO - HONEYCOMB-412 -reintroduce verifyNoMoreInteractions and remove manual verify
257 // we are really interested just in invocations of processModification(),so adding specific verify to check that
258 verify(writer1,times(2)).processModification(any(),any(),any(),any());
259 verify(writer2,times(2)).processModification(any(),any(),any(),any());
260 //verifyNoMoreInteractions(writer1);
261 //verifyNoMoreInteractions(writer2);
264 @Test(expected = IllegalArgumentException.class)
265 public void testMultipleUpdatesOneMissing() throws Exception {
266 final FlatWriterRegistry flatWriterRegistry =
267 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1));
269 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
270 addUpdate(updates, DataObject1.class);
271 addUpdate(updates, DataObject2.class);
272 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
276 public void testMultipleUpdatesFirstFailing() throws Exception {
277 final FlatWriterRegistry flatWriterRegistry =
278 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
280 // Writer1 always fails
281 doThrow(new RuntimeException()).when(writer1)
282 .processModification(any(InstanceIdentifier.class), any(DataObject.class), any(DataObject.class), any(WriteContext.class));
284 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
285 addUpdate(updates, DataObject1.class);
286 addUpdate(updates, DataObject2.class);
289 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
290 fail("Bulk update should have failed on writer1 with UpdateFailedException");
291 } catch (UpdateFailedException e) {
292 assertThat(e.getProcessed(), hasSize(0));// very first update failed
297 public void testMultipleUpdatesSecondFailing() throws Exception {
298 final FlatWriterRegistry flatWriterRegistry =
299 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
301 // Writer2 always fails
302 doThrow(new RuntimeException()).when(writer2)
303 .processModification(any(InstanceIdentifier.class), any(DataObject.class), any(DataObject.class), any(WriteContext.class));
305 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
306 addUpdate(updates, DataObject1.class);
307 addUpdate(updates, DataObject2.class);
310 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
311 fail("Bulk update should have failed on writer1 with UpdateFailedException");
312 } catch (UpdateFailedException e) {
313 final List<DataObjectUpdate> alreadyProcessed = e.getProcessed();
314 assertThat(alreadyProcessed, hasSize(1));// very first update failed
315 assertEquals(updateData(DataObject1.class, DataObject1.IID),
316 e.getProcessed().iterator().next());
321 public void testMultipleUpdatesLastFailing() throws Exception {
322 final FlatWriterRegistry flatWriterRegistry =
323 new FlatWriterRegistry(
324 ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2, DataObjects.DataObject3.IID, writer3));
326 // Writer1 always fails
327 doThrow(new RuntimeException()).when(writer3)
328 .processModification(any(InstanceIdentifier.class), any(DataObject.class), any(DataObject.class), any(WriteContext.class));
330 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
331 addUpdate(updates, DataObject1.class);
332 addUpdate(updates, DataObject2.class);
333 addUpdate(updates, DataObjects.DataObject3.class);
336 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
337 fail("Bulk update should have failed on writer1 with UpdateFailedException");
338 } catch (UpdateFailedException e) {
339 final List<DataObjectUpdate> alreadyProcessed = e.getProcessed();
340 assertEquals(2, alreadyProcessed.size());
341 assertTrue(alreadyProcessed.contains(updateData(DataObject1.class, DataObject1.IID)));
342 assertTrue(alreadyProcessed.contains(updateData(DataObject2.class, DataObject2.IID)));
347 public void testMutlipleUpdatesWithOneKeyedContainer() throws Exception {
348 final FlatWriterRegistry flatWriterRegistry =
349 new FlatWriterRegistry(
350 ImmutableMap.of(DataObject1.IID, writer1, DataObjects.DataObject1ChildK.IID, writer4));
352 // Writer1 always fails
353 doThrow(new RuntimeException()).when(writer1)
354 .processModification(any(InstanceIdentifier.class), any(DataObject.class), any(DataObject.class),
355 any(WriteContext.class));
357 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
358 addKeyedUpdate(updates, DataObjects.DataObject1ChildK.class);
359 addUpdate(updates, DataObject1.class);
361 flatWriterRegistry.processModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
362 fail("Bulk update should have failed on writer1 with UpdateFailedException");
363 } catch (UpdateFailedException e) {
364 assertTrue(e.getProcessed().isEmpty());
368 @Test(expected = IllegalArgumentException.class)
369 public void testValidateMissingWriter() throws Exception {
370 final FlatWriterRegistry flatWriterRegistry =
371 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1));
373 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
374 addUpdate(updates, DataObject1.class);
375 addUpdate(updates, DataObject2.class);
376 flatWriterRegistry.validateModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
380 public void testValidateSingleWriter() throws Exception {
381 final FlatWriterRegistry flatWriterRegistry =
382 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
384 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
385 final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
386 final InstanceIdentifier<DataObject1> iid2 = InstanceIdentifier.create(DataObject1.class);
387 final DataObject1 dataObject = mock(DataObject1.class);
388 updates.put(DataObject1.IID, DataObjectUpdate.create(iid, dataObject, dataObject));
389 updates.put(DataObject1.IID, DataObjectUpdate.create(iid2, dataObject, dataObject));
391 .validateModifications(new WriterRegistry.DataObjectUpdates(updates, ImmutableMultimap.of()), ctx);
393 verify(writer1).validate(iid, dataObject, dataObject, ctx);
394 verify(writer1).validate(iid2, dataObject, dataObject, ctx);
395 // Invoked when registry is being created
396 verifyNoMoreInteractions(writer1);
397 verifyZeroInteractions(writer2);
401 public void testValidateMultipleWriters() throws Exception {
402 final FlatWriterRegistry flatWriterRegistry =
403 new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2));
405 final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> deletes = HashMultimap.create();
406 final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates = HashMultimap.create();
407 final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
408 final DataObject1 dataObject = mock(DataObject1.class);
410 deletes.put(DataObject1.IID,
411 ((DataObjectUpdate.DataObjectDelete) DataObjectUpdate.create(iid, dataObject, null)));
413 updates.put(DataObject1.IID, DataObjectUpdate.create(iid, null, dataObject));
414 final InstanceIdentifier<DataObject2> iid2 = InstanceIdentifier.create(DataObject2.class);
415 final DataObject2 dataObject2 = mock(DataObject2.class);
417 deletes.put(DataObject2.IID,
418 ((DataObjectUpdate.DataObjectDelete) DataObjectUpdate.create(iid2, dataObject2, null)));
420 updates.put(DataObject2.IID, DataObjectUpdate.create(iid2, dataObject2, dataObject2));
421 flatWriterRegistry.validateModifications(new WriterRegistry.DataObjectUpdates(updates, deletes), ctx);
424 verify(writer1).validate(iid, dataObject, null, ctx);
425 verify(writer1).validate(iid, null, dataObject, ctx);
426 verify(writer2).validate(iid2, dataObject2, null, ctx);
427 verify(writer2).validate(iid2, dataObject2, dataObject2, ctx);
429 verifyNoMoreInteractions(writer1);
430 verifyNoMoreInteractions(writer2);
433 private <D extends DataObject> void addKeyedUpdate(final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates,
434 final Class<D> type) throws Exception {
435 final InstanceIdentifier<D> iid = (InstanceIdentifier<D>) type.getDeclaredField("IID").get(null);
436 final InstanceIdentifier<D> keyedIid = (InstanceIdentifier<D>) type.getDeclaredField("INTERNALLY_KEYED_IID").get(null);
437 updates.put(iid, DataObjectUpdate.create(keyedIid, mock(type), mock(type)));
440 private <D extends DataObject> void addUpdate(final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates,
441 final Class<D> type) throws Exception {
442 final InstanceIdentifier<D> iid = (InstanceIdentifier<D>) type.getDeclaredField("IID").get(null);
443 updates.put(iid, updateData(type, iid));
446 private static <D extends DataObject> DataObjectUpdate updateData(final Class<D> type,
447 final InstanceIdentifier<D> iid) {
448 return DataObjectUpdate.create(iid, mock(type), mock(type));
451 //TODO - HONEYCOMB-412 - remove after
453 * Used to utilize default implementation of canProcess()
455 static class CheckedMockWriter implements Writer{
457 private final Writer mockedWriter;
459 CheckedMockWriter(final Writer mockedWriter) {
460 this.mockedWriter = mockedWriter;
464 public void processModification(@Nonnull final InstanceIdentifier id, @Nullable final DataObject dataBefore,
465 @Nullable final DataObject dataAfter, @Nonnull final WriteContext ctx)
466 throws WriteFailedException {
467 mockedWriter.processModification(id,dataBefore,dataAfter,ctx);
471 public boolean supportsDirectUpdate() {
472 return mockedWriter.supportsDirectUpdate();
477 public InstanceIdentifier getManagedDataObjectType() {
478 return mockedWriter.getManagedDataObjectType();