DeviceState changes
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / device / DeviceContextImplTest.java
index 58e85ca002a09479ca5771ae4b9c6e0ee13a2ed9..31e8ffe3b93e6a80ecc140989e24784e79162c1b 100644 (file)
@@ -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<Object, Object> 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<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);
-        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<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;
-            }
+        Mockito.doAnswer(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;
-            }
+        Mockito.doAnswer(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);
         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<Nodes> 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<Nodes> 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();
+    }
 }