import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.inOrder;
import org.opendaylight.netconf.sal.restconf.impl.PutResult;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
import org.opendaylight.netconf.sal.streams.listeners.ListenerAdapter;
import org.opendaylight.netconf.sal.streams.listeners.NotificationListenerAdapter;
import org.opendaylight.netconf.sal.streams.listeners.Notificator;
* @author Thomas Pantelis
*/
public class BrokerFacadeTest {
-
- @Mock
- DOMDataBroker domDataBroker;
-
- @Mock
- DOMNotificationService domNotification;
-
- @Mock
- ConsumerSession context;
-
- @Mock
- DOMRpcService mockRpcService;
-
- @Mock
- DOMMountPoint mockMountInstance;
-
- BrokerFacade brokerFacade = BrokerFacade.getInstance();
-
- NormalizedNode<?, ?> dummyNode = createDummyNode("test:module", "2014-01-09", "interfaces");
- CheckedFuture<Optional<NormalizedNode<?, ?>>,ReadFailedException> dummyNodeInFuture = wrapDummyNode(this.dummyNode);
-
- QName qname = TestUtils.buildQName("interfaces","test:module", "2014-01-09");
-
- SchemaPath type = SchemaPath.create(true, this.qname);
-
- YangInstanceIdentifier instanceID = YangInstanceIdentifier.builder().node(this.qname).build();
-
- @Mock
- DOMDataReadOnlyTransaction rTransaction;
-
- @Mock
- DOMDataWriteTransaction wTransaction;
-
- @Mock
- DOMDataReadWriteTransaction rwTransaction;
+ @Mock private DOMDataBroker domDataBroker;
+ @Mock private DOMNotificationService domNotification;
+ @Mock private ConsumerSession context;
+ @Mock private DOMRpcService mockRpcService;
+ @Mock private DOMMountPoint mockMountInstance;
+
+ private final BrokerFacade brokerFacade = BrokerFacade.getInstance();
+ private final NormalizedNode<?, ?> dummyNode = createDummyNode("test:module", "2014-01-09", "interfaces");
+ private final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> dummyNodeInFuture =
+ wrapDummyNode(dummyNode);
+ private final QName qname = TestUtils.buildQName("interfaces","test:module", "2014-01-09");
+ private final SchemaPath type = SchemaPath.create(true, qname);
+ private final YangInstanceIdentifier instanceID = YangInstanceIdentifier.builder().node(qname).build();
+
+ @Mock private DOMDataReadOnlyTransaction rTransaction;
+ @Mock private DOMDataWriteTransaction wTransaction;
+ @Mock private DOMDataReadWriteTransaction rwTransaction;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- // TODO it is started before every test method
this.brokerFacade.setDomDataBroker(this.domDataBroker);
this.brokerFacade.setDomNotificationService(this.domNotification);
this.brokerFacade.setRpcService(this.mockRpcService);
ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext("/full-versions/test-module"));
}
- private CheckedFuture<Optional<NormalizedNode<?, ?>>,ReadFailedException> wrapDummyNode(
+ private CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> wrapDummyNode(
final NormalizedNode<?, ?> dummyNode) {
- return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>> of(dummyNode));
+ return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>> of(dummyNode));
}
- private CheckedFuture<Boolean,ReadFailedException> wrapExistence(final Boolean exists) {
- return Futures.immediateCheckedFuture(exists);
+ private CheckedFuture<Boolean, ReadFailedException> wrapExistence(final Boolean exists) {
+ return Futures.immediateCheckedFuture(exists);
}
-
/**
* Value of this node shouldn't be important for testing purposes
*/
final CheckedFuture<DOMRpcResult, DOMRpcException> future = Futures.immediateCheckedFuture(expResult);
when(this.mockRpcService.invokeRpc(this.type, this.dummyNode)).thenReturn(future);
- final CheckedFuture<DOMRpcResult, DOMRpcException> actualFuture = this.brokerFacade.invokeRpc(
- this.type, this.dummyNode);
+ final CheckedFuture<DOMRpcResult, DOMRpcException> actualFuture = this.brokerFacade
+ .invokeRpc(this.type, this.dummyNode);
assertNotNull("Future is null", actualFuture);
final DOMRpcResult actualResult = actualFuture.get();
assertSame("invokeRpc", expResult, actualResult);
final Optional<NormalizedNode<?, ?>> optionalMock = mock(Optional.class);
when(optionalMock.get()).thenReturn(null);
+
final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readFuture = Futures
.immediateCheckedFuture(optionalMock);
- when(this.rwTransaction.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)))
- .thenReturn(readFuture);
+ when(this.rwTransaction.read(LogicalDatastoreType.CONFIGURATION, this.instanceID)).thenReturn(readFuture);
final PutResult result = this.brokerFacade.commitConfigurationDataPut(mock(SchemaContext.class),
this.instanceID, this.dummyNode);
+
final Future<Void> actualFuture = result.getFutureOfPutData();
assertSame("commitConfigurationDataPut", expFuture, actualFuture);
@SuppressWarnings("unchecked")
final CheckedFuture<Void, TransactionCommitFailedException> expFuture = mock(CheckedFuture.class);
- when(this.rwTransaction.exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
- wrapExistence(false));
-
+ when(this.rwTransaction.exists(LogicalDatastoreType.CONFIGURATION, this.instanceID))
+ .thenReturn(wrapExistence(false));
when(this.rwTransaction.submit()).thenReturn(expFuture);
@Test(expected = RestconfDocumentedException.class)
public void testCommitConfigurationDataPostAlreadyExists() {
final CheckedFuture<Boolean, ReadFailedException> successFuture = Futures.immediateCheckedFuture(Boolean.TRUE);
- when(this.rwTransaction.exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class))).thenReturn(
- successFuture);
+ when(this.rwTransaction.exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class)))
+ .thenReturn(successFuture);
try {
// Schema context is only necessary for ensuring parent structure
- this.brokerFacade.commitConfigurationDataPost((SchemaContext)null, this.instanceID, this.dummyNode);
+ this.brokerFacade.commitConfigurationDataPost((SchemaContext) null, this.instanceID, this.dummyNode);
} catch (final RestconfDocumentedException e) {
assertEquals("getErrorTag", RestconfError.ErrorTag.DATA_EXISTS, e.getErrors().get(0).getErrorTag());
throw e;
}
}
+ /**
+ * Positive test of delete operation when data to delete exits. Returned value and order of steps are validated.
+ */
@Test
- public void testCommitConfigurationDataDelete() {
+ public void testCommitConfigurationDataDelete() throws Exception {
+ // assume that data to delete exists
+ prepareDataForDelete(true);
+
+ // expected result
@SuppressWarnings("unchecked")
final CheckedFuture<Void, TransactionCommitFailedException> expFuture = mock(CheckedFuture.class);
+ when(this.rwTransaction.submit()).thenReturn(expFuture);
- when(this.wTransaction.submit()).thenReturn(expFuture);
-
+ // test
final CheckedFuture<Void, TransactionCommitFailedException> actualFuture = this.brokerFacade
.commitConfigurationDataDelete(this.instanceID);
+ // verify result and interactions
assertSame("commitConfigurationDataDelete", expFuture, actualFuture);
- final InOrder inOrder = inOrder(this.domDataBroker, this.wTransaction);
- inOrder.verify(this.domDataBroker).newWriteOnlyTransaction();
- inOrder.verify(this.wTransaction).delete(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
- inOrder.verify(this.wTransaction).submit();
+ // check exists, delete, submit
+ final InOrder inOrder = inOrder(this.domDataBroker, this.rwTransaction);
+ inOrder.verify(this.rwTransaction).exists(LogicalDatastoreType.CONFIGURATION, this.instanceID);
+ inOrder.verify(this.rwTransaction).delete(LogicalDatastoreType.CONFIGURATION, this.instanceID);
+ inOrder.verify(this.rwTransaction).submit();
+ }
+
+ /**
+ * Negative test of delete operation when data to delete does not exist. Error 404 should be returned.
+ */
+ @Test
+ public void testCommitConfigurationDataDeleteNoData() throws Exception {
+ // assume that data to delete does not exist
+ prepareDataForDelete(false);
+
+ // try to delete and expect 404 error
+ try {
+ this.brokerFacade.commitConfigurationDataDelete(this.instanceID);
+ fail("Delete operation should fail due to missing data");
+ } catch (final RestconfDocumentedException e) {
+ assertEquals(ErrorType.PROTOCOL, e.getErrors().get(0).getErrorType());
+ assertEquals(ErrorTag.DATA_MISSING, e.getErrors().get(0).getErrorTag());
+ assertEquals(404, e.getErrors().get(0).getErrorTag().getStatusCode());
+ }
+ }
+
+ /**
+ * Prepare conditions to test delete operation. Data to delete exists or does not exist according to value of
+ * {@code assumeDataExists} parameter.
+ * @param assumeDataExists
+ */
+ private void prepareDataForDelete(final boolean assumeDataExists) {
+ when(this.rwTransaction.exists(LogicalDatastoreType.CONFIGURATION, this.instanceID))
+ .thenReturn(Futures.immediateCheckedFuture(new Boolean(assumeDataExists)));
}
- @SuppressWarnings("unchecked")
@Test
public void testRegisterToListenDataChanges() {
final ListenerAdapter listener = Notificator.createListener(this.instanceID, "stream");
+ @SuppressWarnings("unchecked")
final ListenerRegistration<DOMDataChangeListener> mockRegistration = mock(ListenerRegistration.class);
- when(this.domDataBroker.registerDataChangeListener(
- any(LogicalDatastoreType.class), eq(this.instanceID), eq(listener), eq(DataChangeScope.BASE)))
- .thenReturn(mockRegistration);
+ when(this.domDataBroker.registerDataChangeListener(any(LogicalDatastoreType.class), eq(this.instanceID),
+ eq(listener), eq(DataChangeScope.BASE))).thenReturn(mockRegistration);
- this.brokerFacade.registerToListenDataChanges(LogicalDatastoreType.CONFIGURATION, DataChangeScope.BASE, listener);
+ this.brokerFacade.registerToListenDataChanges(
+ LogicalDatastoreType.CONFIGURATION, DataChangeScope.BASE, listener);
- verify(this.domDataBroker).registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, this.instanceID, listener,
- DataChangeScope.BASE);
+ verify(this.domDataBroker).registerDataChangeListener(
+ LogicalDatastoreType.CONFIGURATION, this.instanceID, listener, DataChangeScope.BASE);
assertEquals("isListening", true, listener.isListening());
- this.brokerFacade.registerToListenDataChanges(LogicalDatastoreType.CONFIGURATION,
- DataChangeScope.BASE, listener);
+ this.brokerFacade.registerToListenDataChanges(
+ LogicalDatastoreType.CONFIGURATION, DataChangeScope.BASE, listener);
verifyNoMoreInteractions(this.domDataBroker);
}
// mock registration
final ListenerRegistration<NotificationListenerAdapter> registration = mock(ListenerRegistration.class);
- when(domNotification.registerNotificationListener(listener, listener.getSchemaPath()))
+ when(this.domNotification.registerNotificationListener(listener, listener.getSchemaPath()))
.thenReturn(registration);
// test to register listener for the first time
- brokerFacade.registerToListenNotification(listener);
+ this.brokerFacade.registerToListenNotification(listener);
assertEquals("Registration was not successful", true, listener.isListening());
// try to register for the second time
- brokerFacade.registerToListenNotification(listener);
+ this.brokerFacade.registerToListenNotification(listener);
assertEquals("Registration was not successful", true, listener.isListening());
// registrations should be invoked only once
- verify(domNotification, times(1)).registerNotificationListener(listener, listener.getSchemaPath());
+ verify(this.domNotification, times(1)).registerNotificationListener(listener, listener.getSchemaPath());
// close and remove test notification listener
listener.close();