+
+ @Test
+ public void testOnDataTreeChangedReconcileButStaticsGatheringNotSuccessful() {
+ Mockito.when(reconciliationRegistry.isRegistered(NODE_ID)).thenReturn(true);
+ operationalUpdate();
+ Mockito.when(operationalNode.augmentation(FlowCapableStatisticsGatheringStatus.class))
+ .thenReturn(statisticsGatheringStatus);
+ Mockito.when(statisticsGatheringStatus.getSnapshotGatheringStatusEnd()).thenReturn(snapshotGatheringStatusEnd);
+ Mockito.when(snapshotGatheringStatusEnd.isSucceeded()).thenReturn(false);
+
+ nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+ Mockito.verifyZeroInteractions(reactor);
+ }
+
+ @Test
+ public void testOnDataTreeChangedReconcileAndFreshOperationalNotPresent() throws ParseException {
+ Mockito.when(reconciliationRegistry.isRegistered(NODE_ID)).thenReturn(true);
+ operationalUpdate();
+ prepareFreshOperational(false);
+
+ nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+ Mockito.verifyZeroInteractions(reactor);
+ }
+
+ @Test
+ public void testOnDataTreeChangedReconcileAndFreshOperationalPresent() throws Exception {
+ Mockito.when(reconciliationRegistry.isRegistered(NODE_ID)).thenReturn(true);
+ operationalUpdate();
+ prepareFreshOperational(true);
+ final SyncupEntry syncupEntry = loadConfigDSAndPrepareSyncupEntry(
+ configNode, configDS, fcOperationalNode, operationalDS);
+
+ nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+ Mockito.verify(reactor).syncup(fcNodePath, syncupEntry);
+ Mockito.verify(roTx).close();
+ }
+
+
+ @Test
+ public void testOnDataTreeChangedReconcileAndFreshOperationalNotPresentButAdd() throws ParseException {
+ Mockito.when(reconciliationRegistry.isRegistered(NODE_ID)).thenReturn(true);
+ operationalAdd();
+ prepareFreshOperational(false);
+ final SyncupEntry syncupEntry = loadConfigDSAndPrepareSyncupEntry(
+ configNode, configDS, fcOperationalNode, operationalDS);
+
+ nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+ Mockito.verify(reactor).syncup(fcNodePath, syncupEntry);
+ Mockito.verify(roTx).close();
+ }
+
+ @Test
+ public void testOnDataTreeChangedReconcileAndConfigNotPresent() throws Exception {
+ // Related to bug 5920 -> https://bugs.opendaylight.org/show_bug.cgi?id=5920
+ Mockito.when(reconciliationRegistry.isRegistered(NODE_ID)).thenReturn(true);
+ operationalUpdate();
+ prepareFreshOperational(true);
+
+ Mockito.when(roTx.read(LogicalDatastoreType.CONFIGURATION, fcNodePath))
+ .thenReturn(Futures.immediateCheckedFuture(Optional.absent()));
+
+ nodeListenerOperational.onDataTreeChanged(Collections.singleton(dataTreeModification));
+
+ Mockito.verify(reconciliationRegistry).unregisterIfRegistered(NODE_ID);
+ Mockito.verifyZeroInteractions(reactor);
+ Mockito.verify(roTx).close();
+ }
+
+ private void prepareFreshOperational(final boolean afterRegistration) throws ParseException {
+ Mockito.when(operationalNode.augmentation(FlowCapableStatisticsGatheringStatus.class))
+ .thenReturn(statisticsGatheringStatus);
+ Mockito.when(statisticsGatheringStatus.getSnapshotGatheringStatusEnd()).thenReturn(snapshotGatheringStatusEnd);
+ Mockito.when(snapshotGatheringStatusEnd.isSucceeded()).thenReturn(true);
+ Mockito.when(snapshotGatheringStatusEnd.getEnd()).thenReturn(Mockito.mock(DateAndTime.class));
+ final String timestampBefore = "0000-12-12T01:01:01.000-07:00";
+ final String timestampAfter = "9999-12-12T01:01:01.000-07:00";
+ if (afterRegistration) {
+ Mockito.when(snapshotGatheringStatusEnd.getEnd().getValue()).thenReturn(timestampAfter);
+ Mockito.when(reconciliationRegistry.getRegistrationTimestamp(NODE_ID))
+ .thenReturn(simpleDateFormat.parse(timestampBefore));
+ } else {
+ Mockito.when(snapshotGatheringStatusEnd.getEnd().getValue()).thenReturn(timestampBefore);
+ Mockito.when(reconciliationRegistry.getRegistrationTimestamp(NODE_ID))
+ .thenReturn(simpleDateFormat.parse(timestampAfter));
+ }
+ }
+
+ private void operationalAdd() {
+ Mockito.when(operationalModification.getDataBefore()).thenReturn(null);
+ Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+ }
+
+ private void operationalUpdate() {
+ Mockito.when(operationalModification.getDataBefore()).thenReturn(operationalNode);
+ Mockito.when(operationalModification.getDataAfter()).thenReturn(operationalNode);
+ }
+
+ private SyncupEntry loadConfigDSAndPrepareSyncupEntry(final FlowCapableNode after,
+ final LogicalDatastoreType dsTypeAfter, final FlowCapableNode before,
+ final LogicalDatastoreType dsTypeBefore) {
+ Mockito.when(roTx.read(LogicalDatastoreType.CONFIGURATION, fcNodePath))
+ .thenReturn(Futures.immediateCheckedFuture(Optional.of(configNode)));
+ final SyncupEntry syncupEntry = new SyncupEntry(after, dsTypeAfter, before, dsTypeBefore);
+ Mockito.when(reactor.syncup(ArgumentMatchers.<InstanceIdentifier<FlowCapableNode>>any(),
+ Mockito.eq(syncupEntry))).thenReturn(Futures.immediateFuture(Boolean.TRUE));
+ return syncupEntry;
+ }