X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin-impl%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fimpl%2Fdevice%2FDeviceContextImplTest.java;h=31e8ffe3b93e6a80ecc140989e24784e79162c1b;hb=6e2627630ebabb37526133a13deeb62adcc85d35;hp=58e85ca002a09479ca5771ae4b9c6e0ee13a2ed9;hpb=5ebd1e5fcefacfdfc230d8c21145011f9c88340a;p=openflowplugin.git diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java index 58e85ca002..31e8ffe3b9 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java @@ -10,11 +10,14 @@ package org.opendaylight.openflowplugin.impl.device; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; + import com.google.common.base.Optional; import com.google.common.collect.Lists; import com.google.common.util.concurrent.CheckedFuture; @@ -28,7 +31,6 @@ import java.net.InetSocketAddress; import java.util.concurrent.atomic.AtomicLong; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; @@ -46,10 +48,12 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; 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.openflowjava.protocol.api.keys.MessageTypeKey; import org.opendaylight.openflowplugin.api.OFConstants; import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; import org.opendaylight.openflowplugin.api.openflow.connection.OutboundQueueProvider; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; import org.opendaylight.openflowplugin.api.openflow.device.DeviceState; import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; @@ -64,13 +68,18 @@ import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKe import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry; import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry; import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource; +import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener; +import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava; +import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider; import org.opendaylight.openflowplugin.impl.registry.flow.FlowDescriptorFactory; import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory; import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.ExperimenterMessageFromDev; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; @@ -86,20 +95,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; 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.common.types.rev130731.Capabilities; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.*; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketIn; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived; +import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole; import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -130,6 +134,8 @@ public class DeviceContextImplTest { @Mock DeviceState deviceState; @Mock + GetFeaturesOutput featuresOutput; + @Mock DataBroker dataBroker; @Mock WriteTransaction wTx; @@ -159,56 +165,61 @@ public class DeviceContextImplTest { private MessageTranslator messageTranslatorFlowRemoved; @Mock private LifecycleConductor lifecycleConductor; + @Mock + private DeviceInfo deviceInfo; private InOrder inOrderDevState; private final AtomicLong atomicLong = new AtomicLong(0); + private DeviceContext deviceContextSpy; + @Before public void setUp() { final CheckedFuture, ReadFailedException> noExistNodeFuture = Futures.immediateCheckedFuture(Optional.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); - Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeKeyIdent); - Mockito.when(deviceState.getNodeId()).thenReturn(nodeId); -// txChainManager = new TransactionChainManager(dataBroker, deviceState); + Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeKeyIdent); + Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId); + Mockito.when(deviceInfo.getDatapathId()).thenReturn(BigInteger.TEN); final SettableFuture> settableFuture = SettableFuture.create(); final SettableFuture> settableFutureMultiReply = SettableFuture.create(); Mockito.when(requestContext.getFuture()).thenReturn(settableFuture); - Mockito.doAnswer(new Answer() { - @SuppressWarnings("unchecked") - @Override - public Object answer(final InvocationOnMock invocation) { - settableFuture.set((RpcResult) invocation.getArguments()[0]); - return null; - } + Mockito.doAnswer(invocation -> { + settableFuture.set((RpcResult) invocation.getArguments()[0]); + return null; }).when(requestContext).setResult(any(RpcResult.class)); Mockito.when(requestContextMultiReply.getFuture()).thenReturn(settableFutureMultiReply); - Mockito.doAnswer(new Answer() { - @SuppressWarnings("unchecked") - @Override - public Object answer(final InvocationOnMock invocation) { - settableFutureMultiReply.set((RpcResult) invocation.getArguments()[0]); - return null; - } + Mockito.doAnswer(invocation -> { + settableFutureMultiReply.set((RpcResult) 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); Mockito.when(connectionContext.getConnectionAdapter()).thenReturn(connectionAdapter); - - Mockito.when(deviceState.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); - Mockito.when(messageTranslatorPacketReceived.translate(any(Object.class), any(DeviceContext.class), any(Object.class))).thenReturn(mock(PacketReceived.class)); - Mockito.when(messageTranslatorFlowCapableNodeConnector.translate(any(Object.class), any(DeviceContext.class), any(Object.class))).thenReturn(mock(FlowCapableNodeConnector.class)); + Mockito.when(connectionContext.getDeviceInfo()).thenReturn(deviceInfo); + final FeaturesReply mockedFeaturesReply = mock(FeaturesReply.class); + when(connectionContext.getFeatures()).thenReturn(mockedFeaturesReply); + when(connectionContext.getFeatures().getCapabilities()).thenReturn(mock(Capabilities.class)); + + Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); + Mockito.when(featuresOutput.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID); + Mockito.when(featuresOutput.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); + Mockito.when(messageTranslatorPacketReceived.translate(any(Object.class), any(DeviceInfo.class), any(Object.class))).thenReturn(mock(PacketReceived.class)); + Mockito.when(messageTranslatorFlowCapableNodeConnector.translate(any(Object.class), any(DeviceInfo.class), any(Object.class))).thenReturn(mock(FlowCapableNodeConnector.class)); Mockito.when(translatorLibrary.lookupTranslator(eq(new TranslatorKey(OFConstants.OFP_VERSION_1_3, PacketIn.class.getName())))).thenReturn(messageTranslatorPacketReceived); Mockito.when(translatorLibrary.lookupTranslator(eq(new TranslatorKey(OFConstants.OFP_VERSION_1_3, PortGrouping.class.getName())))).thenReturn(messageTranslatorFlowCapableNodeConnector); Mockito.when(translatorLibrary.lookupTranslator(eq(new TranslatorKey(OFConstants.OFP_VERSION_1_3, org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved.class.getName())))) .thenReturn(messageTranslatorFlowRemoved); + Mockito.when(lifecycleConductor.getMessageIntelligenceAgency()).thenReturn(messageIntelligenceAgency); + + deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, false); - deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, false); + deviceContextSpy = Mockito.spy(deviceContext); xid = new Xid(atomicLong.incrementAndGet()); xidMulti = new Xid(atomicLong.incrementAndGet()); @@ -216,42 +227,45 @@ public class DeviceContextImplTest { @Test(expected = NullPointerException.class) public void testDeviceContextImplConstructorNullDataBroker() throws Exception { - new DeviceContextImpl(connectionContext, deviceState, null, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, false).close(); + new DeviceContextImpl(connectionContext, deviceState, null, lifecycleConductor, outboundQueueProvider, translatorLibrary, false).close(); } @Test(expected = NullPointerException.class) public void testDeviceContextImplConstructorNullDeviceState() throws Exception { - new DeviceContextImpl(connectionContext, null, dataBroker, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, false).close(); + new DeviceContextImpl(connectionContext, null, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, false).close(); } @Test(expected = NullPointerException.class) public void testDeviceContextImplConstructorNullTimer() throws Exception { - new DeviceContextImpl(null, deviceState, dataBroker, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, false).close(); + new DeviceContextImpl(null, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, false).close(); } @Test public void testGetDeviceState() { final DeviceState deviceSt = deviceContext.getDeviceState(); assertNotNull(deviceSt); - Assert.assertEquals(deviceState, deviceSt); + assertEquals(deviceState, deviceSt); } @Test public void testGetReadTransaction() { final ReadTransaction readTx = deviceContext.getReadTransaction(); assertNotNull(readTx); - Assert.assertEquals(rTx, readTx); + assertEquals(rTx, readTx); } /** - * FIXME: Need to change the test on behalf the clustering transaction chain manager changes * @throws Exception */ - @Ignore @Test public void testInitialSubmitTransaction() throws Exception { + Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); + final InstanceIdentifier dummyII = InstanceIdentifier.create(Nodes.class); + deviceContext.getTransactionChainManager().activateTransactionManager() ; + deviceContext.getTransactionChainManager().enableSubmit(); + deviceContext.addDeleteToTxChain(LogicalDatastoreType.CONFIGURATION, dummyII); deviceContext.initialSubmitTransaction(); - verify(txChainManager).initialSubmitWriteTransaction(); + verify(wTx).submit(); } @Test @@ -266,6 +280,17 @@ public class DeviceContextImplTest { final ConnectionContext pickedConnectiobContexts = deviceContext.getAuxiliaryConnectiobContexts(DUMMY_COOKIE); assertEquals(mockedConnectionContext, pickedConnectiobContexts); } + @Test + public void testRemoveAuxiliaryConnectionContext() { + final ConnectionContext mockedConnectionContext = addDummyAuxiliaryConnectionContext(); + + final ConnectionAdapter mockedAuxConnectionAdapter = mock(ConnectionAdapter.class); + when(mockedConnectionContext.getConnectionAdapter()).thenReturn(mockedAuxConnectionAdapter); + + assertNotNull(deviceContext.getAuxiliaryConnectiobContexts(DUMMY_COOKIE)); + deviceContext.removeAuxiliaryConnectionContext(mockedConnectionContext); + assertNull(deviceContext.getAuxiliaryConnectiobContexts(DUMMY_COOKIE)); + } private ConnectionContext addDummyAuxiliaryConnectionContext() { final ConnectionContext mockedConnectionContext = prepareConnectionContext(); @@ -282,26 +307,25 @@ public class DeviceContextImplTest { } /** - * FIXME: Need to change the test on behalf the clustering transaction chain manager changes * @throws Exception */ - @Ignore @Test public void testAddDeleteToTxChain() throws Exception{ final InstanceIdentifier dummyII = InstanceIdentifier.create(Nodes.class); + deviceContext.getTransactionChainManager().activateTransactionManager() ; + deviceContext.getTransactionChainManager().enableSubmit(); deviceContext.addDeleteToTxChain(LogicalDatastoreType.CONFIGURATION, dummyII); - verify(txChainManager).addDeleteOperationTotTxChain(eq(LogicalDatastoreType.CONFIGURATION), eq(dummyII)); + verify(wTx).delete(eq(LogicalDatastoreType.CONFIGURATION), eq(dummyII)); } /** - * FIXME: Need to change the test on behalf the clustering transaction chain manager changes * @throws Exception */ - @Ignore @Test public void testSubmitTransaction() throws Exception { - deviceContext.submitTransaction(); - verify(txChainManager).submitWriteTransaction(); + deviceContext.getTransactionChainManager().activateTransactionManager() ; + deviceContext.getTransactionChainManager().enableSubmit(); + assertTrue(deviceContext.submitTransaction()); } @Test @@ -328,6 +352,13 @@ public class DeviceContextImplTest { assertNotNull(deviceMeterRegistry); } + @Test + public void testGetRpcContext() { + final RpcContext rpcContext = mock(RpcContext.class); + deviceContext.setRpcContext(rpcContext); + assertNotNull(deviceContext.getRpcContext()); + } + @Test public void testProcessReply() { final Error mockedError = mock(Error.class); @@ -384,7 +415,7 @@ public class DeviceContextImplTest { when(connectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter); final NodeId dummyNodeId = new NodeId("dummyNodeId"); - when(deviceState.getNodeId()).thenReturn(dummyNodeId); + when(deviceInfo.getNodeId()).thenReturn(dummyNodeId); final ConnectionContext mockedAuxiliaryConnectionContext = prepareConnectionContext(); deviceContext.addAuxiliaryConnectionContext(mockedAuxiliaryConnectionContext); @@ -433,7 +464,7 @@ public class DeviceContextImplTest { } @Test - public void testPortStatusMessage() { + public void testPortStatusMessage() throws Exception{ final PortStatusMessage mockedPortStatusMessage = mock(PortStatusMessage.class); final Class dummyClass = Class.class; when(mockedPortStatusMessage.getImplementedInterface()).thenReturn(dummyClass); @@ -441,10 +472,10 @@ public class DeviceContextImplTest { final GetFeaturesOutput mockedFeature = mock(GetFeaturesOutput.class); when(mockedFeature.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID); - when(deviceState.getFeatures()).thenReturn(mockedFeature); when(mockedPortStatusMessage.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3); when(mockedPortStatusMessage.getReason()).thenReturn(PortReason.OFPPRADD); + when(mockedPortStatusMessage.getPortNo()).thenReturn(42L); OpenflowPortsUtil.init(); deviceContext.processPortStatusMessage(mockedPortStatusMessage); @@ -459,8 +490,9 @@ public class DeviceContextImplTest { .setPriority(42) .setCookie(new FlowCookie(BigInteger.ONE)) .setMatch(new MatchBuilder().build()); + final NotificationPublishService mockedNotificationPublishService = mock(NotificationPublishService.class); - Mockito.when(messageTranslatorFlowRemoved.translate(any(Object.class), any(DeviceContext.class), any(Object.class))) + Mockito.when(messageTranslatorFlowRemoved.translate(any(Object.class), any(DeviceInfo.class), any(Object.class))) .thenReturn(flowRemovedMdsalBld.build()); // insert flow+flowId into local registry @@ -483,20 +515,61 @@ public class DeviceContextImplTest { .child(Table.class, new TableKey((short) 0)) .child(Flow.class, new FlowKey(new FlowId("ut-ofp:f456"))); + deviceContext.setNotificationPublishService(mockedNotificationPublishService); deviceContext.processFlowRemovedMessage(flowRemovedBld.build()); Mockito.verify(itemLifecycleListener).onRemoved(flowToBeRemovedPath); } + @Test + public void testProcessExperimenterMessage() { + final ConvertorMessageFromOFJava mockedMessageConverter = mock(ConvertorMessageFromOFJava.class); + final ExtensionConverterProvider mockedExtensionConverterProvider = mock(ExtensionConverterProvider.class); + when(mockedExtensionConverterProvider.getMessageConverter(any(MessageTypeKey.class))).thenReturn(mockedMessageConverter); + + final ExperimenterDataOfChoice mockedExperimenterDataOfChoice = mock(ExperimenterDataOfChoice.class); + final ExperimenterMessage experimenterMessage = new ExperimenterMessageBuilder() + .setExperimenterDataOfChoice(mockedExperimenterDataOfChoice).build(); + + final NotificationPublishService mockedNotificationPublishService = mock(NotificationPublishService.class); + + deviceContext.setNotificationPublishService(mockedNotificationPublishService); + deviceContext.setExtensionConverterProvider(mockedExtensionConverterProvider); + deviceContext.processExperimenterMessage(experimenterMessage); + + verify(mockedNotificationPublishService).offerNotification(any(ExperimenterMessageFromDev.class)); + } + @Test public void testOnDeviceDisconnected() throws Exception { final DeviceTerminationPhaseHandler deviceContextClosedHandler = mock(DeviceTerminationPhaseHandler.class); -// Mockito.verify(deviceState).setValid(false); -// Mockito.verify(deviceContextClosedHandler).onDeviceContextClosed(deviceContext); - Assert.assertEquals(0, deviceContext.getDeviceFlowRegistry().getAllFlowDescriptors().size()); - Assert.assertEquals(0, deviceContext.getDeviceGroupRegistry().getAllGroupIds().size()); - Assert.assertEquals(0, deviceContext.getDeviceMeterRegistry().getAllMeterIds().size()); + assertEquals(0, deviceContext.getDeviceFlowRegistry().getAllFlowDescriptors().size()); + assertEquals(0, deviceContext.getDeviceGroupRegistry().getAllGroupIds().size()); + assertEquals(0, deviceContext.getDeviceMeterRegistry().getAllMeterIds().size()); } + @Test + public void testOnClusterRoleChange() throws Exception { + // test role.equals(oldRole) + Assert.assertNull(deviceContextSpy.onClusterRoleChange(OfpRole.BECOMEMASTER, OfpRole.BECOMEMASTER).get()); + + // test call transactionChainManager.deactivateTransactionManager() + Assert.assertNull(deviceContextSpy.onClusterRoleChange(OfpRole.BECOMESLAVE, OfpRole.NOCHANGE).get()); + + // test call MdSalRegistrationUtils.unregisterServices(rpcContext) + final RpcContext rpcContext = mock(RpcContext.class); + deviceContextSpy.setRpcContext(rpcContext); + Assert.assertNull(deviceContextSpy.onClusterRoleChange(OfpRole.BECOMESLAVE, OfpRole.NOCHANGE).get()); + + final StatisticsContext statisticsContext = mock(StatisticsContext.class); + deviceContextSpy.setStatisticsContext(statisticsContext); + + deviceContextSpy.onClusterRoleChange(OfpRole.NOCHANGE, OfpRole.BECOMEMASTER); + verify(deviceContextSpy).onDeviceTakeClusterLeadership(); + + Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); + deviceContextSpy.onClusterRoleChange(OfpRole.NOCHANGE, OfpRole.BECOMESLAVE); + verify(deviceContextSpy).onDeviceLostClusterLeadership(); + } }