diff --git a/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/DefaultOFAgentTest.java b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/DefaultOFAgentTest.java
new file mode 100644
index 0000000..52f7f53
--- /dev/null
+++ b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/DefaultOFAgentTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.ofagent.impl;
+
+import com.google.common.collect.Sets;
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.ofagent.api.OFAgent;
+import org.onosproject.ofagent.api.OFController;
+
+import java.util.Set;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onosproject.ofagent.api.OFAgent.State.STARTED;
+import static org.onosproject.ofagent.api.OFAgent.State.STOPPED;
+
+/**
+ * Unit test of DefaultOFAgent model entity.
+ */
+public class DefaultOFAgentTest {
+
+    private static final Set<OFController> CONTROLLER_1 = Sets.newHashSet(
+            DefaultOFController.of(
+                    IpAddress.valueOf("192.168.0.3"),
+                    TpPort.tpPort(6653)));
+
+    private static final Set<OFController> CONTROLLER_2 = Sets.newHashSet(
+            DefaultOFController.of(
+                    IpAddress.valueOf("192.168.0.3"),
+                    TpPort.tpPort(6653)),
+            DefaultOFController.of(
+                    IpAddress.valueOf("192.168.0.4"),
+                    TpPort.tpPort(6653)));
+
+    private static final NetworkId NETWORK_1 = NetworkId.networkId(1);
+    private static final NetworkId NETWORK_2 = NetworkId.networkId(2);
+
+    private static final OFAgent OFAGENT = DefaultOFAgent.builder()
+            .networkId(NETWORK_1)
+            .controllers(CONTROLLER_1)
+            .state(STOPPED)
+            .build();
+
+    private static final OFAgent SAME_AS_OFAGENT_1 = DefaultOFAgent.builder()
+            .networkId(NETWORK_1)
+            .controllers(CONTROLLER_2)
+            .state(STOPPED)
+            .build();
+
+    private static final OFAgent SAME_AS_OFAGENT_2 = DefaultOFAgent.builder()
+            .networkId(NETWORK_1)
+            .controllers(CONTROLLER_1)
+            .state(STARTED)
+            .build();
+
+    private static final OFAgent ANOTHER_OFAGENT = DefaultOFAgent.builder()
+            .networkId(NETWORK_2)
+            .controllers(CONTROLLER_1)
+            .state(STOPPED)
+            .build();
+
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultOFAgent.class);
+    }
+
+    @Test
+    public void testEquality() {
+        new EqualsTester()
+                .addEqualityGroup(OFAGENT, SAME_AS_OFAGENT_1, SAME_AS_OFAGENT_2)
+                .addEqualityGroup(ANOTHER_OFAGENT)
+                .testEquals();
+    }
+}
diff --git a/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/OFAgentManagerTest.java b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/OFAgentManagerTest.java
new file mode 100644
index 0000000..52b06f4
--- /dev/null
+++ b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/OFAgentManagerTest.java
@@ -0,0 +1,266 @@
+/*
+ * 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.ofagent.impl;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.event.Event;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.ofagent.api.OFAgent;
+import org.onosproject.ofagent.api.OFAgentEvent;
+import org.onosproject.ofagent.api.OFAgentListener;
+import org.onosproject.ofagent.api.OFController;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.ofagent.api.OFAgent.State.STARTED;
+import static org.onosproject.ofagent.api.OFAgent.State.STOPPED;
+import static org.onosproject.ofagent.api.OFAgentEvent.Type.*;
+
+/**
+ * Junit tests for OFAgent target.
+ */
+public class OFAgentManagerTest {
+
+    private static final ApplicationId APP_ID = new DefaultApplicationId(1, "test");
+    private static final ControllerNode LOCAL_NODE =
+            new DefaultControllerNode(new NodeId("local"), IpAddress.valueOf("127.0.0.1"));
+
+    private static final Set<OFController> CONTROLLER_1 = Sets.newHashSet(
+            DefaultOFController.of(
+                    IpAddress.valueOf("192.168.0.3"),
+                    TpPort.tpPort(6653)));
+
+    private static final Set<OFController> CONTROLLER_2 = Sets.newHashSet(
+            DefaultOFController.of(
+                    IpAddress.valueOf("192.168.0.3"),
+                    TpPort.tpPort(6653)),
+            DefaultOFController.of(
+                    IpAddress.valueOf("192.168.0.4"),
+                    TpPort.tpPort(6653)));
+
+    private static final NetworkId NETWORK_1 = NetworkId.networkId(1);
+    private static final NetworkId NETWORK_2 = NetworkId.networkId(2);
+
+    private static final OFAgent OFAGENT_1 = DefaultOFAgent.builder()
+            .networkId(NETWORK_1)
+            .state(STOPPED)
+            .build();
+
+    private static final OFAgent OFAGENT_1_CTRL_1 = DefaultOFAgent.builder()
+            .networkId(NETWORK_1)
+            .controllers(CONTROLLER_1)
+            .state(STOPPED)
+            .build();
+
+    private static final OFAgent OFAGENT_1_CTRL_2 = DefaultOFAgent.builder()
+            .networkId(NETWORK_1)
+            .controllers(CONTROLLER_2)
+            .state(STOPPED)
+            .build();
+
+    private static final OFAgent OFAGENT_2 = DefaultOFAgent.builder()
+            .networkId(NETWORK_2)
+            .state(STOPPED)
+            .build();
+
+    private final TestOFAgentListener testListener = new TestOFAgentListener();
+    private final CoreService mockCoreService = createMock(CoreService.class);
+    private final LeadershipService mockLeadershipService = createMock(LeadershipService.class);
+    private final VirtualNetworkService mockVirtualNetService = createMock(VirtualNetworkService.class);
+    private final ClusterService mockClusterService = createMock(ClusterService.class);
+
+    private OFAgentManager target;
+    private DistributedOFAgentStore ofAgentStore;
+
+    @Before
+    public void setUp() throws Exception {
+        ofAgentStore = new DistributedOFAgentStore();
+        TestUtils.setField(ofAgentStore, "coreService", createMock(CoreService.class));
+        TestUtils.setField(ofAgentStore, "storageService", new TestStorageService());
+        ofAgentStore.activate();
+
+        expect(mockCoreService.registerApplication(anyObject()))
+                .andReturn(APP_ID)
+                .anyTimes();
+        replay(mockCoreService);
+
+        expect(mockClusterService.getLocalNode())
+                .andReturn(LOCAL_NODE)
+                .anyTimes();
+        replay(mockClusterService);
+
+        expect(mockLeadershipService.runForLeadership(anyObject()))
+                .andReturn(null)
+                .anyTimes();
+        mockLeadershipService.addListener(anyObject());
+        mockLeadershipService.removeListener(anyObject());
+        mockLeadershipService.withdraw(anyObject());
+        replay(mockLeadershipService);
+
+        target = new OFAgentManager();
+        target.coreService = mockCoreService;
+        target.leadershipService = mockLeadershipService;
+        target.virtualNetService = mockVirtualNetService;
+        target.clusterService = mockClusterService;
+        target.ofAgentStore = ofAgentStore;
+        target.addListener(testListener);
+        target.activate();
+    }
+
+    @After
+    public void tearDown() {
+        target.removeListener(testListener);
+        ofAgentStore.deactivate();
+        target.deactivate();
+        ofAgentStore = null;
+        target = null;
+    }
+
+    @Test
+    public void testCreateAndRemoveAgent() {
+        target.createAgent(OFAGENT_1);
+        Set<OFAgent> agents = target.agents();
+        assertEquals("OFAgent set size did not match", 1, agents.size());
+
+        target.createAgent(OFAGENT_2);
+        agents = target.agents();
+        assertEquals("OFAgent set size did not match", 2, agents.size());
+
+        target.removeAgent(NETWORK_1);
+        agents = target.agents();
+        assertEquals("OFAgent set size did not match", 1, agents.size());
+
+        target.removeAgent(NETWORK_2);
+        agents = target.agents();
+        assertEquals("OFAgent set size did not match", 0, agents.size());
+
+        validateEvents(OFAGENT_CREATED, OFAGENT_CREATED, OFAGENT_REMOVED, OFAGENT_REMOVED);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullAgent() {
+        target.createAgent(null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testCreateDuplicateAgent() {
+        target.createAgent(OFAGENT_1);
+        target.createAgent(OFAGENT_1);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testRemoveNullAgent() {
+        target.removeAgent(null);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testRemoveNotFoundAgent() {
+        target.removeAgent(NETWORK_1);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testRemoveStartedAgent() {
+        target.createAgent(OFAGENT_1);
+        target.startAgent(NETWORK_1);
+        target.removeAgent(NETWORK_1);
+    }
+
+    @Test
+    public void testStartAndStopAgent() {
+        target.createAgent(OFAGENT_1);
+        target.startAgent(NETWORK_1);
+        OFAgent ofAgent = target.agent(NETWORK_1);
+        assertEquals("OFAgent state did not match", STARTED, ofAgent.state());
+
+        target.stopAgent(NETWORK_1);
+        ofAgent = target.agent(NETWORK_1);
+        assertEquals("OFAgent state did not match", STOPPED, ofAgent.state());
+
+        validateEvents(OFAGENT_CREATED, OFAGENT_STARTED, OFAGENT_STOPPED);
+    }
+
+    @Test
+    public void testAddController() {
+        target.createAgent(OFAGENT_1);
+        target.updateAgent(OFAGENT_1_CTRL_1);
+        OFAgent ofAgent = target.agent(NETWORK_1);
+        assertEquals("OFAgent controller did not match", CONTROLLER_1, ofAgent.controllers());
+
+        target.updateAgent(OFAGENT_1_CTRL_2);
+        ofAgent = target.agent(NETWORK_1);
+        assertEquals("OFAgent controller did not match", CONTROLLER_2, ofAgent.controllers());
+
+        validateEvents(OFAGENT_CREATED, OFAGENT_CONTROLLER_ADDED, OFAGENT_CONTROLLER_ADDED);
+    }
+
+    @Test
+    public void testRemoveController() {
+        target.createAgent(OFAGENT_1_CTRL_2);
+        target.updateAgent(OFAGENT_1_CTRL_1);
+        OFAgent ofAgent = target.agent(NETWORK_1);
+        assertEquals("OFAgent controller did not match", CONTROLLER_1, ofAgent.controllers());
+
+        target.updateAgent(OFAGENT_1);
+        ofAgent = target.agent(NETWORK_1);
+        assertTrue("OFAgent controller did not match", ofAgent.controllers().isEmpty());
+
+        validateEvents(OFAGENT_CREATED, OFAGENT_CONTROLLER_REMOVED, OFAGENT_CONTROLLER_REMOVED);
+    }
+
+    private void validateEvents(Enum... types) {
+        TestTools.assertAfter(100, () -> {
+            int i = 0;
+            assertEquals("Number of events does not match", types.length, testListener.events.size());
+            for (Event event : testListener.events) {
+                assertEquals("Incorrect event received", types[i], event.type());
+                i++;
+            }
+            testListener.events.clear();
+        });
+    }
+
+    private static class TestOFAgentListener implements OFAgentListener {
+
+        private List<OFAgentEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(OFAgentEvent event) {
+            events.add(event);
+        }
+    }
+}
