diff --git a/apps/openstacknode/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java b/apps/openstacknode/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
new file mode 100644
index 0000000..aadec13
--- /dev/null
+++ b/apps/openstacknode/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
@@ -0,0 +1,1062 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstacknode.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.LeadershipServiceAdapter;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeDescription;
+import org.onosproject.net.behaviour.BridgeName;
+import org.onosproject.net.behaviour.ControllerInfo;
+import org.onosproject.net.behaviour.DefaultBridgeDescription;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.behaviour.InterfaceConfig;
+import org.onosproject.net.behaviour.PatchDescription;
+import org.onosproject.net.behaviour.TunnelDescription;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.DeviceAdminService;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceInterfaceDescription;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.openstacknode.api.NodeState;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbController;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
+import static org.onosproject.net.Device.Type.CONTROLLER;
+import static org.onosproject.net.Device.Type.SWITCH;
+import static org.onosproject.net.device.DeviceEvent.Type.*;
+import static org.onosproject.openstacknode.api.Constants.*;
+import static org.onosproject.openstacknode.api.NodeState.*;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
+
+/**
+ * Unit test for DefaultOpenstackNodeHandler.
+ */
+public class DefaultOpenstackNodeHandlerTest {
+
+    private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
+    private static final String ERR_STATE_NOT_MATCH = "Node state did not match";
+    private static final NodeId LOCAL_NODE_ID = new NodeId("local");
+    private static final ControllerNode LOCAL_CTRL =
+            new DefaultControllerNode(LOCAL_NODE_ID, IpAddress.valueOf("127.0.0.1"));
+
+    private static final BridgeDescription ROUT_BRIDGE = DefaultBridgeDescription.builder()
+            .name(ROUTER_BRIDGE)
+            .failMode(BridgeDescription.FailMode.SECURE)
+            .disableInBand()
+            .build();
+
+    private static final PortDescription PATCH_ROUT = new DefaultPortDescription(
+            PortNumber.portNumber(1),
+            true,
+            DefaultAnnotations.builder()
+                    .set(PORT_NAME, PATCH_ROUT_BRIDGE)
+                    .build()
+    );
+
+    private static final String COMPUTE_1_HOSTNAME = "compute_1";
+    private static final String COMPUTE_2_HOSTNAME = "compute_2";
+    private static final String COMPUTE_3_HOSTNAME = "compute_3";
+    private static final String COMPUTE_4_HOSTNAME = "compute_4";
+    private static final String GATEWAY_1_HOSTNAME = "gateway_1";
+    private static final String GATEWAY_2_HOSTNAME = "gateway_2";
+    private static final String GATEWAY_3_HOSTNAME = "gateway_3";
+    private static final String GATEWAY_4_HOSTNAME = "gateway_4";
+
+    private static final IpAddress COMPUTE_1_IP = IpAddress.valueOf("10.100.0.1");
+    private static final IpAddress COMPUTE_2_IP = IpAddress.valueOf("10.100.0.2");
+    private static final IpAddress COMPUTE_3_IP = IpAddress.valueOf("10.100.0.3");
+    private static final IpAddress COMPUTE_4_IP = IpAddress.valueOf("10.100.0.4");
+    private static final IpAddress GATEWAY_1_IP = IpAddress.valueOf("10.100.0.5");
+    private static final IpAddress GATEWAY_2_IP = IpAddress.valueOf("10.100.0.6");
+    private static final IpAddress GATEWAY_3_IP = IpAddress.valueOf("10.100.0.7");
+    private static final IpAddress GATEWAY_4_IP = IpAddress.valueOf("10.100.0.8");
+
+    private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE);
+    private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE);
+    private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE);
+    private static final Device COMPUTE_4_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE);
+    private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE);
+    private static final Device GATEWAY_1_ROUT_DEVICE = createOpenFlowDevice(6, ROUTER_BRIDGE);
+    private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(7, INTEGRATION_BRIDGE);
+    private static final Device GATEWAY_2_ROUT_DEVICE = createOpenFlowDevice(8, ROUTER_BRIDGE);
+    private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(9, INTEGRATION_BRIDGE);
+    private static final Device GATEWAY_3_ROUT_DEVICE = createOpenFlowDevice(10, ROUTER_BRIDGE);
+    private static final Device GATEWAY_4_INTG_DEVICE = createOpenFlowDevice(11, INTEGRATION_BRIDGE);
+    private static final Device GATEWAY_4_ROUT_DEVICE = createOpenFlowDevice(12, ROUTER_BRIDGE);
+
+    private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP);
+    private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP);
+    private static final Device COMPUTE_3_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_3_IP);
+    private static final Device COMPUTE_4_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_4_IP);
+    private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP);
+    private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP);
+
+    private static final OpenstackNode COMPUTE_1 = createNode(
+            COMPUTE_1_HOSTNAME,
+            COMPUTE,
+            COMPUTE_1_INTG_DEVICE,
+            COMPUTE_1_IP,
+            INIT
+    );
+
+    private static final OpenstackNode COMPUTE_2 = createNode(
+            COMPUTE_2_HOSTNAME,
+            COMPUTE,
+            COMPUTE_2_INTG_DEVICE,
+            COMPUTE_2_IP,
+            DEVICE_CREATED
+    );
+
+    private static final OpenstackNode COMPUTE_3 = createNode(
+            COMPUTE_3_HOSTNAME,
+            COMPUTE,
+            COMPUTE_3_INTG_DEVICE,
+            COMPUTE_3_IP,
+            PORT_CREATED
+    );
+
+    private static final OpenstackNode COMPUTE_4 = createNode(
+            COMPUTE_4_HOSTNAME,
+            COMPUTE,
+            COMPUTE_4_INTG_DEVICE,
+            COMPUTE_4_IP,
+            COMPLETE
+    );
+
+    private static final OpenstackNode GATEWAY_1 = createNode(
+            GATEWAY_1_HOSTNAME,
+            GATEWAY,
+            GATEWAY_1_INTG_DEVICE,
+            GATEWAY_1_ROUT_DEVICE,
+            GATEWAY_1_IP,
+            INIT
+    );
+
+    private static final OpenstackNode GATEWAY_2 = createNode(
+            GATEWAY_2_HOSTNAME,
+            GATEWAY,
+            GATEWAY_2_INTG_DEVICE,
+            GATEWAY_2_ROUT_DEVICE,
+            GATEWAY_2_IP,
+            DEVICE_CREATED
+    );
+
+    private static final OpenstackNode GATEWAY_3 = createNode(
+            GATEWAY_3_HOSTNAME,
+            GATEWAY,
+            GATEWAY_3_INTG_DEVICE,
+            GATEWAY_3_ROUT_DEVICE,
+            GATEWAY_3_IP,
+            PORT_CREATED
+    );
+
+    private static final OpenstackNode GATEWAY_4 = createNode(
+            GATEWAY_4_HOSTNAME,
+            GATEWAY,
+            GATEWAY_4_INTG_DEVICE,
+            GATEWAY_4_ROUT_DEVICE,
+            GATEWAY_4_IP,
+            COMPLETE
+    );
+
+    private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService();
+
+    private TestOpenstackNodeManager testNodeManager;
+    private DefaultOpenstackNodeHandler target;
+
+    @Before
+    public void setUp() throws Exception {
+        DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class);
+        mockDeviceAdminService.removeDevice(anyObject());
+        replay(mockDeviceAdminService);
+
+        OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class);
+        expect(mockOvsdbClient.isConnected())
+                .andReturn(true)
+                .anyTimes();
+        replay(mockOvsdbClient);
+
+        OvsdbController mockOvsdbController = createMock(OvsdbController.class);
+        expect(mockOvsdbController.getOvsdbClient(anyObject()))
+                .andReturn(mockOvsdbClient)
+                .anyTimes();
+        replay(mockOvsdbController);
+
+        testNodeManager = new TestOpenstackNodeManager();
+        target = new DefaultOpenstackNodeHandler();
+
+        target.coreService = new TestCoreService();
+        target.leadershipService = new TestLeadershipService();
+        target.clusterService = new TestClusterService();
+        target.deviceService = TEST_DEVICE_SERVICE;
+        target.deviceAdminService = mockDeviceAdminService;
+        target.ovsdbController = mockOvsdbController;
+        target.groupService = new TestGroupService();
+        target.osNodeService = testNodeManager;
+        target.osNodeAdminService = testNodeManager;
+        target.componentConfigService = new TestComponentConfigService();
+        TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService());
+        target.activate();
+    }
+
+    @After
+    public void tearDown() {
+        TEST_DEVICE_SERVICE.clear();
+        target.deactivate();
+        target = null;
+        testNodeManager = null;
+    }
+
+    /**
+     * Checks if the compute node state changes from INIT to DEVICE_CREATED
+     * after processing INIT state.
+     */
+    @Test
+    public void testComputeNodeProcessNodeInitState() {
+        testNodeManager.createNode(COMPUTE_1);
+        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE);
+
+        assertEquals(ERR_STATE_NOT_MATCH, INIT,
+                testNodeManager.node(COMPUTE_1_HOSTNAME).state());
+        target.processInitState(COMPUTE_1);
+        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
+                testNodeManager.node(COMPUTE_1_HOSTNAME).state());
+    }
+
+    /**
+     * Checks if the gateway node state changes from INIT to DEVICE_CREATED
+     * after processing INIT state.
+     */
+    @Test
+    public void testGatewayNodeProcessNodeInitState() {
+        testNodeManager.createNode(GATEWAY_1);
+        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE);
+
+        assertEquals(ERR_STATE_NOT_MATCH, INIT,
+                testNodeManager.node(GATEWAY_1_HOSTNAME).state());
+        target.processInitState(GATEWAY_1);
+        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
+                testNodeManager.node(GATEWAY_1_HOSTNAME).state());
+    }
+
+    /**
+     * Checks if the compute node state changes from DEVICE_CREATED to
+     * PORT_CREATED after processing DEVICE_CREATED state.
+     */
+    @Test
+    public void testComputeNodeProcessDeviceCreatedState() {
+        testNodeManager.createNode(COMPUTE_2);
+        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE);
+        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE);
+
+        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
+                testNodeManager.node(COMPUTE_2_HOSTNAME).state());
+        target.processDeviceCreatedState(COMPUTE_2);
+        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
+                testNodeManager.node(COMPUTE_2_HOSTNAME).state());
+    }
+
+    /**
+     * Checks if the gateway node state changes from DEVICE_CREATED to
+     * PORT_CREATED after processing DEVICE_CREATED state.
+     */
+    @Test
+    public void testGatewayNodeProcessDeviceCreatedState() {
+        testNodeManager.createNode(GATEWAY_2);
+        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE);
+        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE);
+
+        assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
+                testNodeManager.node(GATEWAY_2_HOSTNAME).state());
+        target.processDeviceCreatedState(GATEWAY_2);
+        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
+                testNodeManager.node(GATEWAY_2_HOSTNAME).state());
+    }
+
+    /**
+     * Checks if the compute node state changes from PORT_CREATED to
+     * COMPLETE after processing PORT_CREATED state.
+     */
+    @Test
+    public void testComputeNodeProcessPortCreatedState() {
+        testNodeManager.createNode(COMPUTE_3);
+        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_3_OVSDB_DEVICE.id(), COMPUTE_3_OVSDB_DEVICE);
+        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_3_INTG_DEVICE.id(), COMPUTE_3_INTG_DEVICE);
+        TEST_DEVICE_SERVICE.portList.add(createPort(COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));
+
+        testNodeManager.createNode(GATEWAY_4);
+        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_4_INTG_DEVICE.id(), GATEWAY_4_INTG_DEVICE);
+
+        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
+                testNodeManager.node(COMPUTE_3_HOSTNAME).state());
+        target.processPortCreatedState(COMPUTE_3);
+        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
+                testNodeManager.node(COMPUTE_3_HOSTNAME).state());
+    }
+
+    /**
+     * Checks if the gateway node state changes from PORT_CREATED to
+     * COMPLETE after processing PORT_CREATED state.
+     */
+    @Test
+    public void testGatewayNodeProcessPortCreatedState() {
+        testNodeManager.createNode(COMPUTE_4);
+        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_4_OVSDB_DEVICE.id(), COMPUTE_4_OVSDB_DEVICE);
+        TEST_DEVICE_SERVICE.devMap.put(COMPUTE_4_INTG_DEVICE.id(), COMPUTE_4_INTG_DEVICE);
+        TEST_DEVICE_SERVICE.portList.add(createPort(COMPUTE_4_INTG_DEVICE, DEFAULT_TUNNEL));
+
+        testNodeManager.createNode(GATEWAY_3);
+        TEST_DEVICE_SERVICE.devMap.put(GATEWAY_3_INTG_DEVICE.id(), GATEWAY_4_INTG_DEVICE);
+
+        assertEquals(ERR_STATE_NOT_MATCH, PORT_CREATED,
+                testNodeManager.node(GATEWAY_3_HOSTNAME).state());
+        target.processPortCreatedState(GATEWAY_3);
+        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
+                testNodeManager.node(GATEWAY_3_HOSTNAME).state());
+    }
+
+    /**
+     * Checks if the compute node state changes from COMPLETE to INCOMPLETE
+     * when integration bridge is disconnected.
+     */
+    @Test
+    public void testBackToIncompleteWhenBrIntDisconnected() {
+        testNodeManager.createNode(COMPUTE_4);
+
+        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
+                testNodeManager.node(COMPUTE_4_HOSTNAME).state());
+        TEST_DEVICE_SERVICE.removeDevice(COMPUTE_4_INTG_DEVICE);
+        assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
+                testNodeManager.node(COMPUTE_4_HOSTNAME).state());
+    }
+
+    /**
+     * Checks if the compute node state changes from COMPLETE to INCOMPLETE
+     * when vxlan port is removed from integration bridge.
+     */
+    @Test
+    public void testBackToIncompleteWhenVxlanRemoved() {
+        testNodeManager.createNode(COMPUTE_4);
+
+        assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
+                testNodeManager.node(COMPUTE_4_HOSTNAME).state());
+        TEST_DEVICE_SERVICE.removePort(COMPUTE_4_INTG_DEVICE, createPort(
+                COMPUTE_4_INTG_DEVICE, DEFAULT_TUNNEL));
+        assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
+                testNodeManager.node(COMPUTE_4_HOSTNAME).state());
+
+    }
+
+    private static Device createOvsdbDevice(IpAddress ovsdbIp) {
+        return new TestDevice(new ProviderId("of", "foo"),
+                DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()),
+                CONTROLLER,
+                "manufacturer",
+                "hwVersion",
+                "swVersion",
+                "serialNumber",
+                new ChassisId(1));
+    }
+
+    private static Device createOpenFlowDevice(long devIdNum, String type) {
+        return new TestDevice(new ProviderId("of", "foo"),
+                DeviceId.deviceId(String.format("of:%016d", devIdNum)),
+                SWITCH,
+                type,
+                "hwVersion",
+                "swVersion",
+                "serialNumber",
+                new ChassisId(1));
+    }
+
+    private static Port createPort(Device device, String portName) {
+        return new DefaultPort(device,
+                PortNumber.portNumber(1),
+                true,
+                DefaultAnnotations.builder().set(PORT_NAME, portName).build());
+    }
+
+    private static OpenstackNode createNode(String hostname,
+                                            OpenstackNode.NodeType type,
+                                            Device intgBridge,
+                                            IpAddress ipAddr,
+                                            NodeState state) {
+        return new TestOpenstackNode(
+                hostname,
+                type,
+                intgBridge.id(),
+                null,
+                ipAddr,
+                ipAddr,
+                null, state);
+    }
+
+    private static OpenstackNode createNode(String hostname,
+                                            OpenstackNode.NodeType type,
+                                            Device intgBridge,
+                                            Device routerBridge,
+                                            IpAddress ipAddr,
+                                            NodeState state) {
+        return new TestOpenstackNode(
+                hostname,
+                type,
+                intgBridge.id(),
+                routerBridge.id(),
+                ipAddr,
+                ipAddr,
+                null, state);
+    }
+
+    private static final class TestDevice extends DefaultDevice {
+        private TestDevice(ProviderId providerId,
+                           DeviceId id,
+                           Type type,
+                           String manufacturer,
+                           String hwVersion,
+                           String swVersion,
+                           String serialNumber,
+                           ChassisId chassisId,
+                           Annotations... annotations) {
+            super(providerId,
+                    id,
+                    type,
+                    manufacturer,
+                    hwVersion,
+                    swVersion,
+                    serialNumber,
+                    chassisId,
+                    annotations);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <B extends Behaviour> B as(Class<B> projectionClass) {
+            if (projectionClass.equals(BridgeConfig.class)) {
+                return (B) new TestBridgeConfig();
+            } else if (projectionClass.equals(InterfaceConfig.class)) {
+                return (B) new TestInterfaceConfig();
+            } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) {
+                ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class);
+                expect(treatmentResolver.getExtensionInstruction(anyObject()))
+                        .andReturn(new TestExtensionTreatment())
+                        .anyTimes();
+                replay(treatmentResolver);
+                return (B) treatmentResolver;
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        public <B extends Behaviour> boolean is(Class<B> projectionClass) {
+            return true;
+        }
+    }
+
+    private static final class TestOpenstackNode extends DefaultOpenstackNode {
+        private TestOpenstackNode(String hostname,
+                                  NodeType type,
+                                  DeviceId intgBridge,
+                                  DeviceId routerBridge,
+                                  IpAddress managementIp,
+                                  IpAddress dataIp,
+                                  String vlanIntf,
+                                  NodeState state) {
+            super(hostname,
+                    type,
+                    intgBridge,
+                    routerBridge,
+                    managementIp,
+                    dataIp,
+                    vlanIntf,
+                    state);
+        }
+
+        @Override
+        public PortNumber tunnelPortNum() {
+            return PortNumber.portNumber(1);
+        }
+
+        @Override
+        public PortNumber vlanPortNum() {
+            return PortNumber.portNumber(1);
+        }
+
+        @Override
+        public PortNumber patchPortNum() {
+            return PortNumber.portNumber(1);
+        }
+
+        @Override
+        public MacAddress vlanPortMac() {
+            return MacAddress.NONE;
+        }
+    }
+
+    private static class TestOpenstackNodeManager implements OpenstackNodeService, OpenstackNodeAdminService {
+        Map<String, OpenstackNode> osNodeMap = Maps.newHashMap();
+        List<OpenstackNodeListener> listeners = Lists.newArrayList();
+
+        @Override
+        public Set<OpenstackNode> nodes() {
+            return ImmutableSet.copyOf(osNodeMap.values());
+        }
+
+        @Override
+        public Set<OpenstackNode> nodes(OpenstackNode.NodeType type) {
+            return osNodeMap.values().stream()
+                    .filter(osNode -> osNode.type() == type)
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<OpenstackNode> completeNodes() {
+            return osNodeMap.values().stream()
+                    .filter(osNode -> osNode.state() == COMPLETE)
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<OpenstackNode> completeNodes(OpenstackNode.NodeType type) {
+            return osNodeMap.values().stream()
+                    .filter(osNode -> osNode.type() == type && osNode.state() == COMPLETE)
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public OpenstackNode node(String hostname) {
+            return osNodeMap.get(hostname);
+        }
+
+        @Override
+        public OpenstackNode node(DeviceId deviceId) {
+            return osNodeMap.values().stream()
+                    .filter(osNode -> Objects.equals(osNode.intgBridge(), deviceId) ||
+                            Objects.equals(osNode.ovsdb(), deviceId) ||
+                            Objects.equals(osNode.routerBridge(), deviceId))
+                    .findFirst().orElse(null);
+        }
+
+        @Override
+        public void addListener(OpenstackNodeListener listener) {
+            listeners.add(listener);
+        }
+
+        @Override
+        public void removeListener(OpenstackNodeListener listener) {
+            listeners.remove(listener);
+        }
+
+        @Override
+        public void createNode(OpenstackNode osNode) {
+            osNodeMap.put(osNode.hostname(), osNode);
+        }
+
+        @Override
+        public void updateNode(OpenstackNode osNode) {
+            osNodeMap.put(osNode.hostname(), osNode);
+        }
+
+        @Override
+        public OpenstackNode removeNode(String hostname) {
+            return null;
+        }
+    }
+
+    private static class TestDeviceService extends DeviceServiceAdapter {
+        Map<DeviceId, Device> devMap = Maps.newHashMap();
+        List<Port> portList = Lists.newArrayList();
+        List<DeviceListener> listeners = Lists.newArrayList();
+
+        @Override
+        public void addListener(DeviceListener listener) {
+            listeners.add(listener);
+        }
+
+        @Override
+        public void removeListener(DeviceListener listener) {
+            listeners.remove(listener);
+        }
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            return devMap.get(deviceId);
+        }
+
+        @Override
+        public List<Port> getPorts(DeviceId deviceId) {
+            return this.portList.stream()
+                    .filter(p -> p.element().id().equals(deviceId))
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        public boolean isAvailable(DeviceId deviceId) {
+            return devMap.containsKey(deviceId);
+        }
+
+        void addDevice(Device device) {
+            devMap.put(device.id(), device);
+            DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device);
+            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
+        }
+
+        void removeDevice(Device device) {
+            devMap.remove(device.id());
+            DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device);
+            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
+        }
+
+        void addPort(Device device, Port port) {
+            portList.add(port);
+            DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port);
+            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
+        }
+
+        void removePort(Device device, Port port) {
+            portList.remove(port);
+            DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port);
+            listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
+        }
+
+        void clear() {
+            this.listeners.clear();
+            this.devMap.clear();
+            this.portList.clear();
+        }
+    }
+
+    private static class TestBridgeConfig implements BridgeConfig {
+
+        @Override
+        public DriverData data() {
+            return null;
+        }
+
+        @Override
+        public void setData(DriverData data) {
+
+        }
+
+        @Override
+        public DriverHandler handler() {
+            return null;
+        }
+
+        @Override
+        public void setHandler(DriverHandler handler) {
+
+        }
+
+        @Override
+        public void addBridge(BridgeName bridgeName) {
+
+        }
+
+        @Override
+        public void addBridge(BridgeName bridgeName, String dpid, String exPortName) {
+
+        }
+
+        @Override
+        public boolean addBridge(BridgeName bridgeName, String dpid, List<ControllerInfo> controllers) {
+            return false;
+        }
+
+        @Override
+        public boolean addBridge(BridgeDescription bridge) {
+            TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"),
+                    DeviceId.deviceId("of:" + bridge.datapathId().get()),
+                    SWITCH,
+                    bridge.name(),
+                    "hwVersion",
+                    "swVersion",
+                    "serialNumber",
+                    new ChassisId(1)));
+            return true;
+        }
+
+        @Override
+        public void deleteBridge(BridgeName bridgeName) {
+
+        }
+
+        @Override
+        public Collection<BridgeDescription> getBridges() {
+            return ImmutableSet.of(ROUT_BRIDGE);
+        }
+
+        @Override
+        public void addPort(BridgeName bridgeName, String portName) {
+
+        }
+
+        @Override
+        public void deletePort(BridgeName bridgeName, String portName) {
+
+        }
+
+        @Override
+        public Collection<PortDescription> getPorts() {
+            return ImmutableSet.of(PATCH_ROUT);
+        }
+
+        @Override
+        public Set<PortNumber> getPortNumbers() {
+            return null;
+        }
+
+        @Override
+        public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
+            return null;
+        }
+    }
+
+    private static class TestInterfaceConfig implements InterfaceConfig {
+
+        @Override
+        public DriverData data() {
+            return null;
+        }
+
+        @Override
+        public void setData(DriverData data) {
+
+        }
+
+        @Override
+        public DriverHandler handler() {
+            return null;
+        }
+
+        @Override
+        public void setHandler(DriverHandler handler) {
+
+        }
+
+        @Override
+        public boolean addAccessInterface(DeviceId deviceId, String intf, VlanId vlanId) {
+            return false;
+        }
+
+        @Override
+        public boolean addAccessMode(String intf, VlanId vlanId) {
+            return false;
+        }
+
+        @Override
+        public boolean removeAccessInterface(DeviceId deviceId, String intf) {
+            return false;
+        }
+
+        @Override
+        public boolean removeAccessMode(String intf) {
+            return false;
+        }
+
+        @Override
+        public boolean addTrunkInterface(DeviceId deviceId, String intf, List<VlanId> vlanIds) {
+            return false;
+        }
+
+        @Override
+        public boolean addTrunkMode(String intf, List<VlanId> vlanIds) {
+            return false;
+        }
+
+        @Override
+        public boolean removeTrunkInterface(DeviceId deviceId, String intf) {
+            return false;
+        }
+
+        @Override
+        public boolean removeTrunkMode(String intf) {
+            return false;
+        }
+
+        @Override
+        public boolean addRateLimit(String intf, short limit) {
+            return false;
+        }
+
+        @Override
+        public boolean removeRateLimit(String intf) {
+            return false;
+        }
+
+        @Override
+        public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) {
+            TEST_DEVICE_SERVICE.devMap.values().stream()
+                    .filter(device -> device.type() == SWITCH &&
+                            device.manufacturer().equals(INTEGRATION_BRIDGE))
+                    .forEach(device -> {
+                        TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf));
+                    });
+            return true;
+        }
+
+        @Override
+        public boolean removeTunnelMode(String intf) {
+            return false;
+        }
+
+        @Override
+        public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) {
+            if (ifaceName.equals(PATCH_INTG_BRIDGE)) {
+                TEST_DEVICE_SERVICE.devMap.values().stream()
+                        .filter(device -> device.type() == SWITCH &&
+                                device.manufacturer().equals(INTEGRATION_BRIDGE))
+                        .forEach(device -> {
+                            TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
+                        });
+            } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) {
+                TEST_DEVICE_SERVICE.devMap.values().stream()
+                        .filter(device -> device.type() == SWITCH &&
+                                device.manufacturer().equals(ROUTER_BRIDGE))
+                        .forEach(device -> {
+                            TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
+                        });
+            }
+            return true;
+        }
+
+        @Override
+        public boolean removePatchMode(String ifaceName) {
+            return false;
+        }
+
+        @Override
+        public List<DeviceInterfaceDescription> getInterfaces(DeviceId deviceId) {
+            return null;
+        }
+
+        @Override
+        public List<DeviceInterfaceDescription> getInterfaces() {
+            return null;
+        }
+    }
+
+    private static class TestGroupService implements GroupService {
+        Map<GroupKey, Group> groupMap = Maps.newHashMap();
+        Map<GroupKey, GroupBuckets> groupBucketsMap = Maps.newHashMap();
+        List<GroupListener> listeners = Lists.newArrayList();
+
+        @Override
+        public void addListener(GroupListener listener) {
+            listeners.add(listener);
+        }
+
+        @Override
+        public void removeListener(GroupListener listener) {
+            listeners.remove(listener);
+        }
+
+        @Override
+        public void addGroup(GroupDescription groupDesc) {
+            DefaultGroup group = new DefaultGroup(GroupId.valueOf(groupDesc.givenGroupId()), groupDesc);
+            group.setState(Group.GroupState.ADDED);
+            groupMap.put(groupDesc.appCookie(), group);
+            groupBucketsMap.put(groupDesc.appCookie(), groupDesc.buckets());
+
+            GroupEvent event = new GroupEvent(GroupEvent.Type.GROUP_ADDED, group);
+            listeners.stream().filter(listener -> listener.isRelevant(event))
+                    .forEach(listener -> listener.event(event));
+        }
+
+        @Override
+        public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
+            return groupMap.get(appCookie);
+        }
+
+        @Override
+        public void addBucketsToGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
+                                      GroupKey newCookie, ApplicationId appId) {
+
+        }
+
+        @Override
+        public void removeBucketsFromGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
+                                           GroupKey newCookie, ApplicationId appId) {
+
+        }
+
+        @Override
+        public void purgeGroupEntries(DeviceId deviceId) {
+
+        }
+
+        @Override
+        public void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId) {
+
+        }
+
+        @Override
+        public Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId) {
+            return null;
+        }
+
+        @Override
+        public Iterable<Group> getGroups(DeviceId deviceId) {
+            return null;
+        }
+
+        @Override
+        public void setBucketsForGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
+                                       GroupKey newCookie, ApplicationId appId) {
+            groupBucketsMap.put(newCookie, buckets);
+            GroupEvent event = new GroupEvent(GroupEvent.Type.GROUP_UPDATED, groupMap.get(newCookie));
+            listeners.stream().filter(listener -> listener.isRelevant(event))
+                    .forEach(listener -> listener.event(event));
+        }
+
+    }
+
+    private static class TestExtensionTreatment implements ExtensionTreatment {
+        Ip4Address tunnelDst;
+
+        @Override
+        public ExtensionTreatmentType type() {
+            return null;
+        }
+
+        @Override
+        public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+            tunnelDst = (Ip4Address) value;
+        }
+
+        @Override
+        public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
+            return null;
+        }
+
+        @Override
+        public List<String> getProperties() {
+            return null;
+        }
+
+        @Override
+        public byte[] serialize() {
+            return new byte[0];
+        }
+
+        @Override
+        public void deserialize(byte[] data) {
+
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            TestExtensionTreatment that = (TestExtensionTreatment) obj;
+            return Objects.equals(tunnelDst, that.tunnelDst);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(tunnelDst);
+        }
+    }
+
+    private static class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId getAppId(String name) {
+            return TEST_APP_ID;
+        }
+    }
+
+    private static class TestLeadershipService extends LeadershipServiceAdapter {
+
+        @Override
+        public NodeId getLeader(String path) {
+            return LOCAL_NODE_ID;
+        }
+    }
+
+    private static class TestClusterService extends ClusterServiceAdapter {
+
+        @Override
+        public ControllerNode getLocalNode() {
+            return LOCAL_CTRL;
+        }
+    }
+
+    private class TestComponentConfigService extends ComponentConfigAdapter {
+
+    }
+}
