package org.opendaylight.openflowplugin.impl.device;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import io.netty.util.HashedWheelTimer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider;
-import org.opendaylight.openflowplugin.api.openflow.connection.ThrottledNotificationsOfferer;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
+import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.api.openflow.device.exception.DeviceDataException;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMask;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder;
-import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Mock
MessageIntelligenceAgency messageIntelligenceAgency;
@Mock
- ThrottledNotificationsOfferer throttledConnectionsHolder;
- @Mock
OutboundQueueProvider outboundQueueProvider;
+ @Mock
+ ConnectionAdapter connectionAdapter;
+ @Mock
+ KeyedInstanceIdentifier<Node, NodeKey> nodeKeyIdent;
+ @Mock
+ TranslatorLibrary translatorLibrary;
+ @Mock
+ Registration registration;
+
+ private final AtomicLong atomicLong = new AtomicLong(0);
- private AtomicLong atomicLong = new AtomicLong(0);
@Before
public void setUp() {
+ final CheckedFuture<Optional<Node>, ReadFailedException> noExistNodeFuture = Futures.immediateCheckedFuture(Optional.<Node>absent());
+ Mockito.when(rTx.read(LogicalDatastoreType.OPERATIONAL, nodeKeyIdent)).thenReturn(noExistNodeFuture);
+ Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
Mockito.when(dataBroker.createTransactionChain(Mockito.any(TransactionChainManager.class))).thenReturn(txChainFactory);
- txChainManager = new TransactionChainManager(dataBroker, timer, 5L, 5L);
+ Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeKeyIdent);
+ txChainManager = new TransactionChainManager(dataBroker, connectionContext, registration);
final SettableFuture<RpcResult<GetAsyncReply>> settableFuture = SettableFuture.create();
final SettableFuture<RpcResult<MultipartReply>> settableFutureMultiReply = SettableFuture.create();
Mockito.when(requestContext.getFuture()).thenReturn(settableFuture);
+ Mockito.doAnswer(new Answer<Object>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object answer(final InvocationOnMock invocation) {
+ settableFuture.set((RpcResult<GetAsyncReply>) invocation.getArguments()[0]);
+ return null;
+ }
+ }).when(requestContext).setResult(any(RpcResult.class));
+
Mockito.when(requestContextMultiReply.getFuture()).thenReturn(settableFutureMultiReply);
+ Mockito.doAnswer(new Answer<Object>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object answer(final InvocationOnMock invocation) {
+ settableFutureMultiReply.set((RpcResult<MultipartReply>) invocation.getArguments()[0]);
+ return null;
+ }
+ }).when(requestContextMultiReply).setResult(any(RpcResult.class));
Mockito.when(txChainFactory.newWriteOnlyTransaction()).thenReturn(wTx);
Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
Mockito.when(connectionContext.getOutboundQueueProvider()).thenReturn(outboundQueueProvider);
- deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, timer, messageIntelligenceAgency,throttledConnectionsHolder);
+ Mockito.when(connectionContext.getConnectionAdapter()).thenReturn(connectionAdapter);
+ deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, timer, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, txChainManager);
xid = new Xid(atomicLong.incrementAndGet());
xidMulti = new Xid(atomicLong.incrementAndGet());
}
@Test(expected = NullPointerException.class)
- public void testDeviceContextImplConstructorNullConnectionContext() {
- new DeviceContextImpl(null, deviceState, dataBroker, timer, messageIntelligenceAgency,throttledConnectionsHolder);
+ public void testDeviceContextImplConstructorNullDataBroker() throws Exception {
+ new DeviceContextImpl(connectionContext, deviceState, null, timer, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, txChainManager).close();
}
@Test(expected = NullPointerException.class)
- public void testDeviceContextImplConstructorNullDataBroker() {
- new DeviceContextImpl(connectionContext, deviceState, null, timer, messageIntelligenceAgency,throttledConnectionsHolder);
+ public void testDeviceContextImplConstructorNullDeviceState() throws Exception {
+ new DeviceContextImpl(connectionContext, null, dataBroker, timer, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, txChainManager).close();
}
@Test(expected = NullPointerException.class)
- public void testDeviceContextImplConstructorNullDeviceState() {
- new DeviceContextImpl(connectionContext, null, dataBroker, timer, messageIntelligenceAgency,throttledConnectionsHolder);
- }
-
- @Test(expected = NullPointerException.class)
- public void testDeviceContextImplConstructorNullTimer() {
- new DeviceContextImpl(null, deviceState, dataBroker, null, messageIntelligenceAgency,throttledConnectionsHolder);
+ public void testDeviceContextImplConstructorNullTimer() throws Exception {
+ new DeviceContextImpl(null, deviceState, dataBroker, null, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, txChainManager).close();
}
@Test
Assert.assertEquals(rTx, readTx);
}
- private static GetAsyncOutput createAsyncOutput(final Xid xid) {
- final GetAsyncOutputBuilder asyncOutputBuilder = new GetAsyncOutputBuilder();
- asyncOutputBuilder.setFlowRemovedMask(Collections.<FlowRemovedMask>emptyList());
- asyncOutputBuilder.setPacketInMask(Collections.<PacketInMask>emptyList());
- asyncOutputBuilder.setPortStatusMask(Collections.<PortStatusMask>emptyList());
- asyncOutputBuilder.setVersion(OFConstants.OFP_VERSION_1_3);
- asyncOutputBuilder.setXid(xid.getValue());
- return asyncOutputBuilder.build();
- }
-
- @Test
- public void testProcessReply() {
- final GetAsyncOutput asyncOutput = createAsyncOutput(xid);
- LOG.info("Hooking RequestContext");
- deviceContext.hookRequestCtx(xid, requestContext);
- Assert.assertEquals(requestContext, deviceContext.lookupRequest(xid));
-
- Assert.assertFalse(requestContext.getFuture().isDone());
- LOG.info("Sending reply from device");
- deviceContext.processReply(asyncOutput);
- Assert.assertTrue(requestContext.getFuture().isDone());
-
- LOG.info("Checking RequestContext.future");
- try {
- final Object object = requestContext.getFuture().get(1L, TimeUnit.SECONDS);
- final RpcResult<OfHeader> rpcResult = (RpcResult<OfHeader>) object;
- final GetAsyncOutput getAsyncOutput = (GetAsyncOutput) rpcResult.getResult();
- assertEquals(asyncOutput.getVersion(), getAsyncOutput.getVersion());
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- LOG.error("Test failed when checking RequestContext.future", e);
- fail("fail");
- }
- Assert.assertTrue(deviceContext.getNumberOfOutstandingRequests() == 0);
- }
-
- private static Error createError(final Xid xid) {
- final ErrorMessageBuilder errorMessageBuilder = new ErrorMessageBuilder();
- errorMessageBuilder.setCode(42);
- errorMessageBuilder.setCodeString("42");
- errorMessageBuilder.setXid(xid.getValue());
- return errorMessageBuilder.build();
- }
-
- @Test
- public void testProcessReplyError() {
- LOG.info("Hooking RequestContext");
- deviceContext.hookRequestCtx(xid, requestContext);
- Assert.assertEquals(requestContext, deviceContext.lookupRequest(xid));
-
- Assert.assertFalse(requestContext.getFuture().isDone());
- LOG.info("Sending error reply from device");
- final Error error = createError(xid);
- deviceContext.processReply(error);
- Assert.assertTrue(requestContext.getFuture().isDone());
-
- LOG.info("Checking RequestContext.future");
- try {
- final Object object = requestContext.getFuture().get(1L, TimeUnit.SECONDS);
- final RpcResult<OfHeader> rpcResult = (RpcResult<OfHeader>) object;
- Assert.assertFalse(rpcResult.isSuccessful());
- final List<RpcError> errors = (List<RpcError>) rpcResult.getErrors();
- Assert.assertTrue(errors.get(0).getCause() instanceof DeviceDataException);
- final DeviceDataException cause = (DeviceDataException) errors.get(0).getCause();
- Assert.assertEquals(error, cause.getError());
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- LOG.error("Test failed when checking RequestContext.future", e);
- fail("fail");
- }
- Assert.assertTrue(deviceContext.getNumberOfOutstandingRequests() == 0);
- }
-
- @Test
- public void testProcessReplyList() {
- LOG.info("Hooking RequestContext");
- deviceContext.hookRequestCtx(xidMulti, requestContextMultiReply);
- Assert.assertEquals(requestContextMultiReply, deviceContext.lookupRequest(xidMulti));
-
- Assert.assertFalse(requestContextMultiReply.getFuture().isDone());
- LOG.info("Sending reply from device");
- deviceContext.processReply(xidMulti, createMultipartReplyList(xidMulti));
- Assert.assertTrue(requestContextMultiReply.getFuture().isDone());
-
- LOG.info("Checking RequestContext.future");
- try {
- final Object object = requestContextMultiReply.getFuture().get(1L, TimeUnit.SECONDS);
- final RpcResult<List<OfHeader>> rpcResult = (RpcResult<List<OfHeader>>) object;
- final List<OfHeader> multipartReplies = rpcResult.getResult();
- final List<MultipartReply> expectedMpReplies = createMultipartReplyList(xidMulti);
- assertEquals(expectedMpReplies, multipartReplies);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- LOG.error("Test failed when checking RequestContext.future", e);
- fail("fail");
- }
- Assert.assertTrue(deviceContext.getNumberOfOutstandingRequests() == 0);
- }
-
- private static List<MultipartReply> createMultipartReplyList(final Xid xid) {
- final MultipartReplyDesc descValue = new MultipartReplyDescBuilder().setHwDesc("hw-test-value").build();
- final MultipartReplyDescCase replyBody = new MultipartReplyDescCaseBuilder()
- .setMultipartReplyDesc(descValue).build();
- final List<MultipartReply> multipartReplies = new ArrayList<>();
- multipartReplies.add(new MultipartReplyMessageBuilder()
- .setMultipartReplyBody(replyBody)
- .setXid(xid.getValue())
- .setFlags(new MultipartRequestFlags(false))
- .build());
- multipartReplies.add(new MultipartReplyMessageBuilder()
- .setMultipartReplyBody(replyBody)
- .setXid(xid.getValue())
- .setFlags(new MultipartRequestFlags(true))
- .build());
- return multipartReplies;
- }
-
- @Test
- public void testProcessException() {
- LOG.info("Hooking RequestContext");
- deviceContext.hookRequestCtx(xid, requestContext);
- Assert.assertEquals(requestContext, deviceContext.lookupRequest(xid));
-
- Assert.assertFalse(requestContext.getFuture().isDone());
-
- LOG.info("Sending reply from device");
- deviceContext.processException(xid, new DeviceDataException("Some freakin' error", new NullPointerException()));
- Assert.assertTrue(requestContext.getFuture().isDone());
-
- LOG.info("Checking RequestContext.future");
- try {
- final Object object = requestContext.getFuture().get(1L, TimeUnit.SECONDS);
- final RpcResult<OfHeader> rpcResult = (RpcResult<OfHeader>) object;
- Assert.assertFalse(rpcResult.isSuccessful());
- final List<RpcError> errors = (List<RpcError>) rpcResult.getErrors();
- Assert.assertTrue(errors.get(0).getCause() instanceof DeviceDataException);
- final DeviceDataException cause = (DeviceDataException) errors.get(0).getCause();
- Assert.assertTrue(cause.getCause() instanceof NullPointerException);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- LOG.error("Test failed when checking RequestContext.future", e);
- fail("fail");
- }
- Assert.assertTrue(deviceContext.getNumberOfOutstandingRequests() == 0);
- }
}