diff --git a/apps/network-troubleshoot/core/src/test/java/org/onosproject/fnl/impl/DefaultCheckLoopTest.java b/apps/network-troubleshoot/core/src/test/java/org/onosproject/fnl/impl/DefaultCheckLoopTest.java
new file mode 100644
index 0000000..3c72a09
--- /dev/null
+++ b/apps/network-troubleshoot/core/src/test/java/org/onosproject/fnl/impl/DefaultCheckLoopTest.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2015-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.fnl.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.fnl.intf.NetworkAnomaly;
+import org.onosproject.fnl.intf.NetworkDiagnostic;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Link;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.link.LinkService;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.onlab.packet.EthType.EtherType.IPV4;
+import static org.onlab.packet.TpPort.tpPort;
+import static org.onosproject.net.DefaultAnnotations.EMPTY;
+import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.net.Link.Type.DIRECT;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.net.flow.FlowEntry.FlowEntryState.ADDED;
+import static org.onosproject.net.provider.ProviderId.NONE;
+
+/**
+ * Unit Tests for DefaultCheckLoop class.
+ */
+public class DefaultCheckLoopTest {
+
+    private NetworkDiagnostic defaultCheckLoop;
+
+    private DeviceService ds;
+    private HostService hs;
+    private FlowRuleService frs;
+    private LinkService ls;
+
+    private List<Device> devices;
+    private List<Host> hosts;
+    private Map<DeviceId, Set<Link>> egressLinks;
+    private Map<DeviceId, List<FlowEntry>> flowEntries;
+
+
+    private static final DeviceId DEVICE_ID_A = DeviceId.deviceId("of:000000000000000A");
+    private static final DeviceId DEVICE_ID_B = DeviceId.deviceId("of:000000000000000B");
+    private static final DeviceId DEVICE_ID_C = DeviceId.deviceId("of:000000000000000C");
+    private static final DeviceId DEVICE_ID_D = DeviceId.deviceId("of:000000000000000D");
+    private static final DeviceId DEVICE_ID_E = DeviceId.deviceId("of:E000000000000000");
+    private static final DeviceId DEVICE_ID_F = DeviceId.deviceId("of:F000000000000000");
+    private static final DeviceId DEVICE_ID_G = DeviceId.deviceId("of:A000000000000000");
+
+    private static final String HOSTID_EXAMPLE = "12:34:56:78:9A:BC/1355";
+    private static final long FLOWRULE_COOKIE_EXAMPLE = 708;
+    private static final int FLOWRULE_PRIORITY_EXAMPLE = 738;
+
+
+    @Before
+    public void setUp() {
+        ds = EasyMock.createMock(DeviceService.class);
+        hs = EasyMock.createMock(HostService.class);
+        frs = EasyMock.createMock(FlowRuleService.class);
+        ls = EasyMock.createMock(LinkService.class);
+
+        defaultCheckLoop = new DefaultCheckLoop(ds, hs, frs, ls);
+    }
+
+    @After
+    public void tearDown() {
+        // do nothing
+    }
+
+    @Test
+    public void testFindLoops() {
+        produceTopoDevices();
+        produceTopoHosts();
+        produceTopoLinks();
+        produceFlowEntries();
+
+        initMock();
+
+        Set<NetworkAnomaly> loops = defaultCheckLoop.findAnomalies();
+        assertThat(loops, hasSize(1));
+    }
+
+    private void initMock() {
+        expect(ds.getDevices()).andReturn(devices).anyTimes();
+        replay(ds);
+
+        expect(hs.getHosts()).andReturn(hosts).anyTimes();
+        replay(hs);
+
+        // --- init flow rule service ---
+
+        expect(frs.getFlowEntries(DEVICE_ID_A))
+                .andReturn(flowEntries.get(DEVICE_ID_A)).anyTimes();
+        expect(frs.getFlowEntries(DEVICE_ID_B))
+                .andReturn(flowEntries.get(DEVICE_ID_B)).anyTimes();
+        expect(frs.getFlowEntries(DEVICE_ID_C))
+                .andReturn(flowEntries.get(DEVICE_ID_C)).anyTimes();
+        expect(frs.getFlowEntries(DEVICE_ID_D))
+                .andReturn(flowEntries.get(DEVICE_ID_D)).anyTimes();
+        expect(frs.getFlowEntries(DEVICE_ID_E))
+                .andReturn(flowEntries.get(DEVICE_ID_E)).anyTimes();
+        expect(frs.getFlowEntries(DEVICE_ID_F))
+                .andReturn(flowEntries.get(DEVICE_ID_F)).anyTimes();
+        expect(frs.getFlowEntries(DEVICE_ID_G))
+                .andReturn(flowEntries.get(DEVICE_ID_G)).anyTimes();
+        replay(frs);
+
+        // --- init link service ---
+
+        expect(ls.getDeviceEgressLinks(DEVICE_ID_A))
+                .andReturn(egressLinks.get(DEVICE_ID_A)).anyTimes();
+        expect(ls.getDeviceEgressLinks(DEVICE_ID_B))
+                .andReturn(egressLinks.get(DEVICE_ID_B)).anyTimes();
+        expect(ls.getDeviceEgressLinks(DEVICE_ID_C))
+                .andReturn(egressLinks.get(DEVICE_ID_C)).anyTimes();
+        expect(ls.getDeviceEgressLinks(DEVICE_ID_D))
+                .andReturn(egressLinks.get(DEVICE_ID_D)).anyTimes();
+        expect(ls.getDeviceEgressLinks(DEVICE_ID_E))
+                .andReturn(egressLinks.get(DEVICE_ID_E)).anyTimes();
+        expect(ls.getDeviceEgressLinks(DEVICE_ID_F))
+                .andReturn(egressLinks.get(DEVICE_ID_F)).anyTimes();
+        expect(ls.getDeviceEgressLinks(DEVICE_ID_G))
+                .andReturn(egressLinks.get(DEVICE_ID_G)).anyTimes();
+        replay(ls);
+    }
+
+    private void produceTopoDevices() {
+        devices = new ArrayList<>();
+        devices.add(produceOneDevice(DEVICE_ID_A));
+        devices.add(produceOneDevice(DEVICE_ID_B));
+        devices.add(produceOneDevice(DEVICE_ID_C));
+        devices.add(produceOneDevice(DEVICE_ID_D));
+        devices.add(produceOneDevice(DEVICE_ID_E));
+        devices.add(produceOneDevice(DEVICE_ID_F));
+        devices.add(produceOneDevice(DEVICE_ID_G));
+    }
+
+    private Device produceOneDevice(DeviceId dpid) {
+        return new DefaultDevice(NONE, dpid,
+                Device.Type.SWITCH, "", "", "", "", new ChassisId(),
+                EMPTY);
+    }
+
+    private void produceTopoHosts() {
+        hosts = new ArrayList<>();
+        hosts.add(produceOneHost(DEVICE_ID_A, 3));
+        hosts.add(produceOneHost(DEVICE_ID_B, 3));
+        hosts.add(produceOneHost(DEVICE_ID_D, 3));
+        hosts.add(produceOneHost(DEVICE_ID_F, 2));
+        hosts.add(produceOneHost(DEVICE_ID_F, 3));
+        hosts.add(produceOneHost(DEVICE_ID_G, 1));
+        hosts.add(produceOneHost(DEVICE_ID_G, 3));
+    }
+
+    private Host produceOneHost(DeviceId dpid, int port) {
+        return new DefaultHost(NONE, HostId.hostId(HOSTID_EXAMPLE),
+                MacAddress.valueOf(0), VlanId.vlanId(),
+                new HostLocation(dpid, portNumber(port), 1),
+                ImmutableSet.of(), EMPTY);
+    }
+
+    private void produceTopoLinks() {
+        egressLinks = new HashMap<>();
+
+        Set<Link> el = new HashSet<>();
+        el.add(produceOneEgressLink(DEVICE_ID_A, 1, DEVICE_ID_B, 1));
+        el.add(produceOneEgressLink(DEVICE_ID_A, 2, DEVICE_ID_D, 2));
+        egressLinks.put(DEVICE_ID_A, el);
+
+        el = new HashSet<>();
+        el.add(produceOneEgressLink(DEVICE_ID_B, 1, DEVICE_ID_A, 1));
+        el.add(produceOneEgressLink(DEVICE_ID_B, 2, DEVICE_ID_C, 2));
+        egressLinks.put(DEVICE_ID_B, el);
+
+        el = new HashSet<>();
+        el.add(produceOneEgressLink(DEVICE_ID_C, 1, DEVICE_ID_D, 1));
+        el.add(produceOneEgressLink(DEVICE_ID_C, 2, DEVICE_ID_B, 2));
+        el.add(produceOneEgressLink(DEVICE_ID_C, 3, DEVICE_ID_E, 3));
+        egressLinks.put(DEVICE_ID_C, el);
+
+        el = new HashSet<>();
+        el.add(produceOneEgressLink(DEVICE_ID_D, 1, DEVICE_ID_C, 1));
+        el.add(produceOneEgressLink(DEVICE_ID_D, 2, DEVICE_ID_A, 2));
+        egressLinks.put(DEVICE_ID_D, el);
+
+        el = new HashSet<>();
+        el.add(produceOneEgressLink(DEVICE_ID_E, 1, DEVICE_ID_F, 1));
+        el.add(produceOneEgressLink(DEVICE_ID_E, 2, DEVICE_ID_G, 2));
+        el.add(produceOneEgressLink(DEVICE_ID_E, 3, DEVICE_ID_C, 3));
+        egressLinks.put(DEVICE_ID_E, el);
+
+        el = new HashSet<>();
+        el.add(produceOneEgressLink(DEVICE_ID_F, 1, DEVICE_ID_E, 1));
+        egressLinks.put(DEVICE_ID_F, el);
+
+        el = new HashSet<>();
+        el.add(produceOneEgressLink(DEVICE_ID_G, 2, DEVICE_ID_E, 2));
+        egressLinks.put(DEVICE_ID_G, el);
+    }
+
+    private Link produceOneEgressLink(DeviceId srcId, int srcPort, DeviceId dstId, int dstPort) {
+        return DefaultLink.builder()
+                .providerId(NONE)
+                .src(new ConnectPoint(srcId, portNumber(srcPort)))
+                .dst(new ConnectPoint(dstId, portNumber(dstPort)))
+                .type(DIRECT)
+                .state(ACTIVE)
+                .build();
+    }
+
+    private void produceFlowEntries() {
+        flowEntries = new HashMap<>();
+
+        List<FlowEntry> fe = new ArrayList<>();
+        fe.add(produceOneFlowEntry(DEVICE_ID_A, 2));
+        flowEntries.put(DEVICE_ID_A, fe);
+
+        fe = new ArrayList<>();
+        fe.add(produceOneFlowEntry(DEVICE_ID_D, 1));
+        flowEntries.put(DEVICE_ID_D, fe);
+
+        fe = new ArrayList<>();
+        fe.add(produceOneFlowEntry(DEVICE_ID_C, 2));
+        flowEntries.put(DEVICE_ID_C, fe);
+
+        fe = new ArrayList<>();
+        fe.add(produceOneFlowEntry(DEVICE_ID_B, 1));
+        flowEntries.put(DEVICE_ID_B, fe);
+
+        flowEntries.put(DEVICE_ID_E, new ArrayList<>());
+        flowEntries.put(DEVICE_ID_F, new ArrayList<>());
+        flowEntries.put(DEVICE_ID_G, new ArrayList<>());
+
+    }
+
+    private FlowEntry produceOneFlowEntry(DeviceId dpid, int outPort) {
+
+        TrafficSelector.Builder sb = DefaultTrafficSelector.builder()
+                .matchEthType(IPV4.ethType().toShort())
+                .matchIPDst(IpPrefix.valueOf("10.0.0.0/8"))
+                .matchIPProtocol(IPv4.PROTOCOL_TCP)
+                .matchTcpDst(tpPort(22));
+
+        TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder()
+                .setOutput(portNumber(outPort));
+
+        return new DefaultFlowEntry(DefaultFlowRule.builder()
+                .withPriority(FLOWRULE_PRIORITY_EXAMPLE).forDevice(dpid).forTable(0)
+                .withCookie(FLOWRULE_COOKIE_EXAMPLE)
+                .withSelector(sb.build()).withTreatment(tb.build())
+                .makePermanent().build(), ADDED);
+    }
+}
