You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by pe...@apache.org on 2018/04/17 02:40:11 UTC

[incubator-skywalking] branch master updated: apm collector ui module testcase completed (#1079)

This is an automated email from the ASF dual-hosted git repository.

pengys pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new f62381c  apm collector ui module testcase completed (#1079)
f62381c is described below

commit f62381c4947b3491febdc8c281c06d0833e1c916
Author: lican <29...@qq.com>
AuthorDate: Tue Apr 17 10:40:06 2018 +0800

    apm collector ui module testcase completed (#1079)
    
    * empty service testcase
    
    * complete GraphQLHandlerTest
    
    * some test completed
    
    * apm-collector-ui testcase completed
---
 .../apm/collector/core/module/MockModule.java      |  67 +++++++
 .../collector/ui/DelegatingServletInputStream.java |  75 ++++++++
 .../ui/jetty/UIModuleJettyProviderTest.java        |  79 ++++++++
 .../ui/jetty/UIModuleJettyRegistrationTest.java    |  43 +++++
 .../ui/jetty/handler/GraphQLHandlerTest.java       | 104 +++++++++++
 .../handler/naming/UIJettyNamingHandlerTest.java   |  65 +++++++
 .../handler/naming/UIJettyNamingListenerTest.java  |  50 +++++
 .../apm/collector/ui/service/AlarmServiceTest.java | 191 +++++++++++++++++++
 .../ui/service/ApplicationServiceTest.java         | 173 +++++++++++++++++
 .../ui/service/ApplicationTopologyServiceTest.java | 106 +++++++++++
 .../ui/service/ClusterTopologyServiceTest.java     | 106 +++++++++++
 .../ui/service/NetworkAddressServiceTest.java      |  66 +++++++
 .../ui/service/SecondBetweenServiceTest.java       |  70 +++++++
 .../ui/service/SegmentTopServiceTest.java          |  93 +++++++++
 .../collector/ui/service/ServerServiceTest.java    | 208 +++++++++++++++++++++
 .../ui/service/ServiceNameServiceTest.java         | 134 +++++++++++++
 .../ui/service/ServiceTopologyServiceTest.java     | 138 ++++++++++++++
 .../apm/collector/ui/service/SpanServiceTest.java  |  84 +++++++++
 .../ui/service/TimeSynchronousServiceTest.java     |  55 ++++++
 .../collector/ui/service/TopologyBuilderTest.java  | 156 ++++++++++++++++
 .../ui/service/TraceStackServiceTest.java          | 104 +++++++++++
 21 files changed, 2167 insertions(+)

diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/core/module/MockModule.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/core/module/MockModule.java
new file mode 100644
index 0000000..06105d5
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/core/module/MockModule.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.core.module;
+
+import com.google.common.collect.Lists;
+import org.apache.skywalking.apm.collector.jetty.manager.service.JettyManagerService;
+import org.apache.skywalking.apm.collector.server.jetty.JettyServer;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.util.LinkedList;
+
+import static org.mockito.Matchers.*;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class MockModule extends Module {
+
+    public MockModule() throws ServiceNotProvidedException {
+        ModuleProvider moduleProvider = Mockito.mock(ModuleProvider.class);
+        LinkedList<ModuleProvider> linkedList = Lists.newLinkedList();
+        linkedList.add(moduleProvider);
+        Whitebox.setInternalState(this, "loadedProviders", linkedList);
+        when(moduleProvider.getService(any())).then(invocation -> {
+            Class argumentAt = invocation.getArgumentAt(0, Class.class);
+            Object mock = Mockito.mock(argumentAt);
+            if (mock instanceof JettyManagerService) {
+                when(((JettyManagerService) mock).createIfAbsent(anyString(), anyInt(), anyString())).then(invocation1 -> {
+                    JettyServer jettyServer = new JettyServer("127.0.0.1", 10805, "/");
+                    jettyServer.initialize();
+                    return jettyServer;
+                });
+
+            }
+            return mock;
+        });
+    }
+
+    @Override
+    public String name() {
+        return null;
+    }
+
+    @Override
+    public Class[] services() {
+        return new Class[0];
+    }
+
+
+}
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/DelegatingServletInputStream.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/DelegatingServletInputStream.java
new file mode 100644
index 0000000..d5c016e
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/DelegatingServletInputStream.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui;
+
+import org.junit.Assert;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author lican
+ */
+public class DelegatingServletInputStream extends ServletInputStream {
+
+    private final InputStream sourceStream;
+
+
+    /**
+     * Create a DelegatingServletInputStream for the given source stream.
+     * @param sourceStream the source stream (never <code>null</code>)
+     */
+    public DelegatingServletInputStream(InputStream sourceStream) {
+        Assert.assertNotNull("Source InputStream must not be null",sourceStream);
+        this.sourceStream = sourceStream;
+    }
+
+    /**
+     * Return the underlying source stream (never <code>null</code>).
+     */
+    public final InputStream getSourceStream() {
+        return this.sourceStream;
+    }
+
+
+    public int read() throws IOException {
+        return this.sourceStream.read();
+    }
+
+    public void close() throws IOException {
+        super.close();
+        this.sourceStream.close();
+    }
+
+    @Override
+    public boolean isFinished() {
+        return false;
+    }
+
+    @Override
+    public boolean isReady() {
+        return false;
+    }
+
+    @Override
+    public void setReadListener(ReadListener readListener) {
+
+    }
+}
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/UIModuleJettyProviderTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/UIModuleJettyProviderTest.java
new file mode 100644
index 0000000..86d27ce
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/UIModuleJettyProviderTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.jetty;
+
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import static org.mockito.Matchers.anyString;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class UIModuleJettyProviderTest {
+    private UIModuleJettyProvider uiModuleJettyProvider;
+
+    @Before
+    public void setUp() {
+        uiModuleJettyProvider = new UIModuleJettyProvider();
+        ModuleManager moduleManager = Mockito.mock(ModuleManager.class);
+        Whitebox.setInternalState(uiModuleJettyProvider, "manager", moduleManager);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+    }
+
+    @Test
+    public void name() {
+        Assert.assertEquals(uiModuleJettyProvider.name(), "jetty");
+    }
+
+    @Test
+    public void module() {
+        Assert.assertNotNull(uiModuleJettyProvider.module());
+    }
+
+    @Test
+    public void createConfigBeanIfAbsent() {
+        Assert.assertNotNull(uiModuleJettyProvider.createConfigBeanIfAbsent());
+    }
+
+    @Test
+    public void prepare() {
+        uiModuleJettyProvider.prepare();
+    }
+
+    @Test
+    public void start() {
+        uiModuleJettyProvider.start();
+    }
+
+    @Test
+    public void notifyAfterCompleted() {
+        uiModuleJettyProvider.notifyAfterCompleted();
+    }
+
+    @Test
+    public void requiredModules() {
+        Assert.assertTrue(uiModuleJettyProvider.requiredModules().length > 0);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/UIModuleJettyRegistrationTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/UIModuleJettyRegistrationTest.java
new file mode 100644
index 0000000..6f3ee94
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/UIModuleJettyRegistrationTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.jetty;
+
+import org.apache.skywalking.apm.collector.cluster.ModuleRegistration;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author lican
+ */
+public class UIModuleJettyRegistrationTest {
+
+    private UIModuleJettyRegistration uiModuleJettyRegistration;
+
+    @Before
+    public void setUp() throws Exception {
+        uiModuleJettyRegistration = new UIModuleJettyRegistration("127.0.0.1", 8080, "/");
+    }
+
+    @Test
+    public void buildValue() {
+        ModuleRegistration.Value value = uiModuleJettyRegistration.buildValue();
+        Assert.assertEquals(value.getHostPort(), "127.0.0.1:8080");
+
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/GraphQLHandlerTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/GraphQLHandlerTest.java
new file mode 100644
index 0000000..4e3251d
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/GraphQLHandlerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.jetty.handler;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import graphql.ExecutionInput;
+import graphql.ExecutionResultImpl;
+import graphql.GraphQL;
+import graphql.GraphQLError;
+import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
+import org.apache.skywalking.apm.collector.ui.DelegatingServletInputStream;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author lican
+ */
+public class GraphQLHandlerTest {
+
+    private GraphQLHandler graphQLHandler;
+    private GraphQL graphQL;
+    private String mockParams = "{\"query\":\"query\" }";
+    private static final String DATA = "data";
+    private static final String ERRORS = "errors";
+    private Map<String, String> stringStringMap = Collections.singletonMap("something", "test");
+
+
+    @Before
+    public void setUp() {
+        //test if the constructor is well
+        graphQLHandler = new GraphQLHandler(null);
+        //stub graphQL
+        graphQL = Mockito.mock(GraphQL.class);
+        Whitebox.setInternalState(graphQLHandler, "graphQL", graphQL);
+    }
+
+    @Test
+    public void pathSpec() {
+        Assert.assertEquals("/graphql", graphQLHandler.pathSpec());
+    }
+
+    @Test
+    public void doGet() throws ArgumentsParseException {
+        HttpServletRequest req = mock(HttpServletRequest.class);
+        when(req.getParameter(anyString())).then(invocation -> mockParams);
+        when(graphQL.execute((ExecutionInput) anyObject())).then(invocation -> new ExecutionResultImpl(stringStringMap, null, Collections.emptyMap()));
+        JsonElement jsonElement = graphQLHandler.doGet(req);
+        Assert.assertNotNull(((JsonObject) jsonElement).get(DATA));
+    }
+
+    @Test
+    public void doPost() throws IOException, ArgumentsParseException {
+        HttpServletRequest req = mock(HttpServletRequest.class);
+        when(req.getInputStream()).then(invocation -> new DelegatingServletInputStream(new ByteArrayInputStream(mockParams.getBytes())));
+        when(graphQL.execute((ExecutionInput) anyObject())).then(invocation -> new ExecutionResultImpl(stringStringMap, null, Collections.emptyMap()));
+        JsonElement jsonElement = graphQLHandler.doPost(req);
+        Assert.assertNotNull(((JsonObject) jsonElement).get(DATA));
+        Assert.assertNull(((JsonObject) jsonElement).get(ERRORS));
+        when(graphQL.execute((ExecutionInput) anyObject())).then(invocation -> {
+            GraphQLError graphQLError = Mockito.mock(GraphQLError.class);
+            return new ExecutionResultImpl(stringStringMap, Collections.singletonList(graphQLError), Collections.emptyMap());
+        });
+        jsonElement = graphQLHandler.doPost(req);
+        Assert.assertNotNull(((JsonObject) jsonElement).get(ERRORS));
+        //test exception;
+        when(graphQL.execute((ExecutionInput) anyObject())).then(invocation -> {
+            throw new IllegalArgumentException("unit test exception when execute");
+        });
+        jsonElement = graphQLHandler.doPost(req);
+        Assert.assertNotNull(((JsonObject) jsonElement).get(ERRORS));
+
+
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingHandlerTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingHandlerTest.java
new file mode 100644
index 0000000..1bfc84f
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingHandlerTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.jetty.handler.naming;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import org.apache.skywalking.apm.collector.server.jetty.ArgumentsParseException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.servlet.http.HttpServletRequest;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * @author lican
+ */
+public class UIJettyNamingHandlerTest {
+
+    private UIJettyNamingHandler uiJettyNamingHandler;
+
+    @Before
+    public void setUp() {
+        UIJettyNamingListener uiJettyNamingListener = new UIJettyNamingListener();
+        uiJettyNamingListener.addAddress("127.0.0.1:10800");
+        uiJettyNamingHandler = new UIJettyNamingHandler(uiJettyNamingListener);
+    }
+
+    @Test
+    public void pathSpec() {
+        Assert.assertEquals(uiJettyNamingHandler.pathSpec(), "/ui/jetty");
+    }
+
+    @Test
+    public void doGet() throws ArgumentsParseException {
+        HttpServletRequest request = mock(HttpServletRequest.class);
+        JsonElement jsonElement = uiJettyNamingHandler.doGet(request);
+        Assert.assertTrue(jsonElement instanceof JsonArray);
+        Assert.assertTrue(((JsonArray) jsonElement).size() > 0);
+
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void doPost() throws ArgumentsParseException {
+        HttpServletRequest request = mock(HttpServletRequest.class);
+        uiJettyNamingHandler.doPost(request);
+
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingListenerTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingListenerTest.java
new file mode 100644
index 0000000..76cf334
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/jetty/handler/naming/UIJettyNamingListenerTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.jetty.handler.naming;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author lican
+ */
+public class UIJettyNamingListenerTest {
+
+    private UIJettyNamingListener uiJettyNamingListener;
+
+    @Before
+    public void setUp() throws Exception {
+        uiJettyNamingListener = new UIJettyNamingListener();
+    }
+
+    @Test
+    public void path() {
+        Assert.assertEquals("/ui/jetty", uiJettyNamingListener.path());
+    }
+
+    @Test
+    public void serverJoinNotify() {
+        uiJettyNamingListener.serverJoinNotify(null);
+    }
+
+    @Test
+    public void serverQuitNotify() {
+        uiJettyNamingListener.serverQuitNotify(null);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/AlarmServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/AlarmServiceTest.java
new file mode 100644
index 0000000..e590ee7
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/AlarmServiceTest.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import org.apache.skywalking.apm.collector.cache.service.ApplicationCacheService;
+import org.apache.skywalking.apm.collector.cache.service.ServiceNameCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.*;
+import org.apache.skywalking.apm.collector.storage.table.register.Application;
+import org.apache.skywalking.apm.collector.storage.table.register.Instance;
+import org.apache.skywalking.apm.collector.storage.table.register.ServiceName;
+import org.apache.skywalking.apm.collector.storage.ui.alarm.Alarm;
+import org.apache.skywalking.apm.collector.storage.ui.alarm.AlarmItem;
+import org.apache.skywalking.apm.collector.storage.ui.alarm.AlarmType;
+import org.apache.skywalking.apm.collector.storage.ui.alarm.CauseType;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.overview.AlarmTrend;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.Collections;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class AlarmServiceTest {
+
+    private AlarmService alarmService;
+
+    private IInstanceUIDAO instanceDAO;
+    private IApplicationAlarmUIDAO applicationAlarmUIDAO;
+    private IApplicationMappingUIDAO applicationMappingUIDAO;
+    private IInstanceAlarmUIDAO instanceAlarmUIDAO;
+    private IServiceAlarmUIDAO serviceAlarmUIDAO;
+    private IApplicationAlarmListUIDAO applicationAlarmListUIDAO;
+    private ApplicationCacheService applicationCacheService;
+    private ServiceNameCacheService serviceNameCacheService;
+    private Duration duration;
+
+    @Before
+    public void setUp() {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        alarmService = new AlarmService(moduleManager);
+        instanceDAO = mock(IInstanceUIDAO.class);
+        applicationAlarmUIDAO = mock(IApplicationAlarmUIDAO.class);
+        applicationMappingUIDAO = mock(IApplicationMappingUIDAO.class);
+        instanceAlarmUIDAO = mock(IInstanceAlarmUIDAO.class);
+        serviceAlarmUIDAO = mock(IServiceAlarmUIDAO.class);
+        applicationAlarmListUIDAO = mock(IApplicationAlarmListUIDAO.class);
+        applicationCacheService = mock(ApplicationCacheService.class);
+        serviceNameCacheService = mock(ServiceNameCacheService.class);
+        Whitebox.setInternalState(alarmService, "instanceDAO", instanceDAO);
+        Whitebox.setInternalState(alarmService, "applicationAlarmUIDAO", applicationAlarmUIDAO);
+        Whitebox.setInternalState(alarmService, "applicationMappingUIDAO", applicationMappingUIDAO);
+        Whitebox.setInternalState(alarmService, "instanceAlarmUIDAO", instanceAlarmUIDAO);
+        Whitebox.setInternalState(alarmService, "serviceAlarmUIDAO", serviceAlarmUIDAO);
+        Whitebox.setInternalState(alarmService, "applicationAlarmListUIDAO", applicationAlarmListUIDAO);
+        Whitebox.setInternalState(alarmService, "applicationCacheService", applicationCacheService);
+        Whitebox.setInternalState(alarmService, "serviceNameCacheService", serviceNameCacheService);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+    }
+
+    @Test
+    public void loadApplicationAlarmList() throws ParseException {
+        Mockito.when(applicationAlarmUIDAO.loadAlarmList(anyString(), anyLong(), anyLong(), anyInt(), anyInt())).then(invocation -> {
+            return testAlarm();
+        });
+        long startTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart()) / 100;
+        long endTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd()) / 100;
+        Mockito.when(applicationMappingUIDAO.load(anyObject(), anyLong(), anyLong())).then(invocation -> {
+            IApplicationMappingUIDAO.ApplicationMapping applicationMapping = new IApplicationMappingUIDAO.ApplicationMapping();
+            applicationMapping.setMappingApplicationId(1);
+            applicationMapping.setApplicationId(1);
+            return Collections.singletonList(applicationMapping);
+        });
+        mockCache();
+        Alarm alarm = alarmService.loadApplicationAlarmList("keyword", Step.MONTH, startTimeBucket, endTimeBucket, 10, 0);
+        Assert.assertTrue(alarm.getItems().size() == 1);
+        Assert.assertNotNull(alarm.getItems().get(0).getTitle());
+    }
+
+    @Test
+    public void loadInstanceAlarmList() throws ParseException {
+        long startTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart()) / 100;
+        long endTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd()) / 100;
+        Mockito.when(instanceAlarmUIDAO.loadAlarmList(anyString(), anyLong(), anyLong(), anyInt(), anyInt())).then(invocation -> testAlarm());
+        mockCache();
+        when(instanceDAO.getInstance(anyInt())).then(invocation -> {
+            Instance instance = new Instance();
+            JsonObject jsonObject = new JsonObject();
+            Gson gson = new Gson();
+            jsonObject.addProperty("hostName", "testHost");
+            instance.setOsInfo(gson.toJson(jsonObject));
+            return instance;
+        });
+        Alarm alarm = alarmService.loadInstanceAlarmList("keyword", Step.MONTH, startTimeBucket, endTimeBucket, 10, 0);
+        Assert.assertNotNull(alarm.getItems().get(0).getTitle());
+    }
+
+    private Alarm testAlarm() {
+        Alarm alarm = new Alarm();
+        AlarmItem alarmItem = new AlarmItem();
+        alarmItem.setId(1);
+        alarmItem.setTitle("test");
+        alarmItem.setCauseType(CauseType.SLOW_RESPONSE);
+        alarmItem.setAlarmType(AlarmType.APPLICATION);
+        alarmItem.setStartTime("2018-01-02 00:00:00");
+        alarm.setItems(Collections.singletonList(alarmItem));
+        alarm.setTotal(100);
+        return alarm;
+    }
+
+    @Test
+    public void loadServiceAlarmList() throws ParseException {
+        long startTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart()) / 100;
+        long endTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd()) / 100;
+        Mockito.when(serviceAlarmUIDAO.loadAlarmList(anyString(), anyLong(), anyLong(), anyInt(), anyInt())).then(invocation -> testAlarm());
+        mockCache();
+        when(serviceNameCacheService.get(anyInt())).then(invocation -> {
+            ServiceName serviceName = new ServiceName();
+            serviceName.setServiceName("serviceName");
+            return serviceName;
+        });
+        alarmService.loadServiceAlarmList("keyword", Step.MONTH, startTimeBucket, endTimeBucket, 10, 0);
+    }
+
+    private void mockCache() {
+        Mockito.when(applicationCacheService.getApplicationById(anyInt())).then(invocation -> {
+            Application application = new Application();
+            application.setApplicationId(1);
+            application.setApplicationCode("test");
+            return application;
+        });
+    }
+
+    @Test
+    public void getApplicationAlarmTrend() throws ParseException {
+        long startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        long endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(instanceDAO.getApplications(anyLong(), anyLong())).then(invocation -> {
+            org.apache.skywalking.apm.collector.storage.ui.application.Application application = new org.apache.skywalking.apm.collector.storage.ui.application.Application();
+            application.setId(1);
+            application.setName("test");
+            application.setNumOfServer(1);
+            return Collections.singletonList(application);
+        });
+        when(applicationAlarmListUIDAO.getAlarmedApplicationNum(anyObject(), anyLong(), anyLong())).then(invocation -> {
+            IApplicationAlarmListUIDAO.AlarmTrend alarmTrend = new IApplicationAlarmListUIDAO.AlarmTrend();
+            alarmTrend.setNumberOfApplication(1);
+            alarmTrend.setTimeBucket(20170108L);
+            return Collections.singletonList(alarmTrend);
+        });
+        AlarmTrend applicationAlarmTrend = alarmService.getApplicationAlarmTrend(duration.getStep(), startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertTrue(applicationAlarmTrend.getNumOfAlarmRate().size() > 0);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ApplicationServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ApplicationServiceTest.java
new file mode 100644
index 0000000..d74edc4
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ApplicationServiceTest.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.cache.service.ApplicationCacheService;
+import org.apache.skywalking.apm.collector.cache.service.ServiceNameCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IInstanceUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.INetworkAddressUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IServiceMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.table.register.ServiceName;
+import org.apache.skywalking.apm.collector.storage.ui.application.Application;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.overview.ApplicationTPS;
+import org.apache.skywalking.apm.collector.storage.ui.overview.ConjecturalApp;
+import org.apache.skywalking.apm.collector.storage.ui.overview.ConjecturalAppBrief;
+import org.apache.skywalking.apm.collector.storage.ui.service.ServiceMetric;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class ApplicationServiceTest {
+
+    private IInstanceUIDAO instanceDAO;
+    private IServiceMetricUIDAO serviceMetricUIDAO;
+    private IApplicationMetricUIDAO applicationMetricUIDAO;
+    private INetworkAddressUIDAO networkAddressUIDAO;
+    private ApplicationCacheService applicationCacheService;
+    private ServiceNameCacheService serviceNameCacheService;
+    private SecondBetweenService secondBetweenService;
+    private ApplicationService applicationService;
+    private Duration duration;
+
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        applicationService = new ApplicationService(moduleManager);
+        instanceDAO = mock(IInstanceUIDAO.class);
+        serviceMetricUIDAO = mock(IServiceMetricUIDAO.class);
+        applicationMetricUIDAO = mock(IApplicationMetricUIDAO.class);
+        networkAddressUIDAO = mock(INetworkAddressUIDAO.class);
+        applicationCacheService = mock(ApplicationCacheService.class);
+        serviceNameCacheService = mock(ServiceNameCacheService.class);
+        secondBetweenService = mock(SecondBetweenService.class);
+        Whitebox.setInternalState(applicationService, "instanceDAO", instanceDAO);
+        Whitebox.setInternalState(applicationService, "serviceMetricUIDAO", serviceMetricUIDAO);
+        Whitebox.setInternalState(applicationService, "applicationMetricUIDAO", applicationMetricUIDAO);
+        Whitebox.setInternalState(applicationService, "networkAddressUIDAO", networkAddressUIDAO);
+        Whitebox.setInternalState(applicationService, "applicationCacheService", applicationCacheService);
+        Whitebox.setInternalState(applicationService, "serviceNameCacheService", serviceNameCacheService);
+        Whitebox.setInternalState(applicationService, "secondBetweenService", secondBetweenService);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+    }
+
+    @Test
+    public void getApplications() throws ParseException {
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(instanceDAO.getApplications(anyLong(), anyLong())).then(invocation -> {
+            List<Application> applications = new ArrayList<>(2);
+            for (int i = 0; i < 2; i++) {
+                Application application = new Application();
+                application.setNumOfServer(i);
+                application.setName("test");
+                application.setId(i);
+                applications.add(application);
+            }
+            return applications;
+        });
+        mockCache();
+        List<Application> applications = applicationService.getApplications(startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertTrue(applications.size() == 1);
+    }
+
+    private void mockCache() {
+        Mockito.when(applicationCacheService.getApplicationById(anyInt())).then(invocation -> {
+            org.apache.skywalking.apm.collector.storage.table.register.Application application = new org.apache.skywalking.apm.collector.storage.table.register.Application();
+            application.setApplicationId(1);
+            application.setApplicationCode("test");
+            return application;
+        });
+    }
+
+    @Test
+    public void getSlowService() throws ParseException {
+        long startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        long endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(serviceMetricUIDAO.getSlowService(anyInt(), anyObject(), anyLong(), anyLong(), anyInt(), anyObject())).then(invocation -> {
+            ServiceMetric serviceMetric = new ServiceMetric();
+            serviceMetric.setCalls(200900);
+            serviceMetric.setName("test");
+            serviceMetric.setAvgResponseTime(100);
+            serviceMetric.setId(1);
+            return Collections.singletonList(serviceMetric);
+        });
+        when(serviceNameCacheService.get(anyInt())).then(invocation -> {
+            ServiceName serviceName = new ServiceName();
+            serviceName.setServiceName("serviceName");
+            return serviceName;
+        });
+        when(secondBetweenService.calculate(anyInt(), anyLong(), anyLong())).then(invocation -> 20L);
+        List<ServiceMetric> slowService = applicationService.getSlowService(-1, duration.getStep(), startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket, 10);
+        Assert.assertTrue(slowService.get(0).getCallsPerSec() > 0);
+    }
+
+    @Test
+    public void getTopNApplicationThroughput() throws ParseException {
+        long startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        long endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+        when(applicationMetricUIDAO.getTopNApplicationThroughput(anyObject(), anyLong(), anyLong(), anyInt(), anyInt(), anyObject())).then(invocation -> {
+            ApplicationTPS applicationTPS = new ApplicationTPS();
+            applicationTPS.setApplicationId(-1);
+            return Collections.singletonList(applicationTPS);
+        });
+        mockCache();
+        List<ApplicationTPS> topNApplicationThroughput = applicationService.getTopNApplicationThroughput(duration.getStep(), startTimeBucket, endTimeBucket, 10);
+        Assert.assertTrue(topNApplicationThroughput.size() > 0);
+    }
+
+    @Test
+    public void getConjecturalApps() throws ParseException {
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(networkAddressUIDAO.getConjecturalApps()).then(invocation -> {
+            ConjecturalApp conjecturalApp = new ConjecturalApp();
+            conjecturalApp.setId(1);
+            return Collections.singletonList(conjecturalApp);
+        });
+        ConjecturalAppBrief conjecturalApps = applicationService.getConjecturalApps(duration.getStep(), startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertTrue(conjecturalApps.getApps().size() > 0);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ApplicationTopologyServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ApplicationTopologyServiceTest.java
new file mode 100644
index 0000000..862f30c
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ApplicationTopologyServiceTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationComponentUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationMappingUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationReferenceMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.common.Topology;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class ApplicationTopologyServiceTest {
+
+    private ApplicationTopologyService applicationTopologyService;
+    private IApplicationComponentUIDAO applicationComponentUIDAO;
+    private IApplicationMappingUIDAO applicationMappingUIDAO;
+    private IApplicationMetricUIDAO applicationMetricUIDAO;
+    private IApplicationReferenceMetricUIDAO applicationReferenceMetricUIDAO;
+    private Duration duration;
+
+    @Before
+    public void setUp() {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        applicationTopologyService = new ApplicationTopologyService(moduleManager);
+        applicationComponentUIDAO = mock(IApplicationComponentUIDAO.class);
+        applicationMappingUIDAO = mock(IApplicationMappingUIDAO.class);
+        applicationMetricUIDAO = mock(IApplicationMetricUIDAO.class);
+        applicationReferenceMetricUIDAO = mock(IApplicationReferenceMetricUIDAO.class);
+        Whitebox.setInternalState(applicationTopologyService, "applicationComponentUIDAO", applicationComponentUIDAO);
+        Whitebox.setInternalState(applicationTopologyService, "applicationMappingUIDAO", applicationMappingUIDAO);
+        Whitebox.setInternalState(applicationTopologyService, "applicationMetricUIDAO", applicationMetricUIDAO);
+        Whitebox.setInternalState(applicationTopologyService, "applicationReferenceMetricUIDAO", applicationReferenceMetricUIDAO);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+    }
+
+    @Test
+    public void getApplicationTopology() throws ParseException {
+        long startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        long endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(applicationComponentUIDAO.load(anyObject(), anyLong(), anyLong())).then(invocation -> {
+            List<IApplicationComponentUIDAO.ApplicationComponent> componentList = new ArrayList<>();
+            for (int i = 0; i < 5; i++) {
+                IApplicationComponentUIDAO.ApplicationComponent applicationComponent = new IApplicationComponentUIDAO.ApplicationComponent();
+                applicationComponent.setApplicationId(i);
+                applicationComponent.setComponentId(i);
+                componentList.add(applicationComponent);
+            }
+            return componentList;
+        });
+        mockMapping();
+        Topology topology = applicationTopologyService.getApplicationTopology(duration.getStep(), 1, startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertNotNull(topology);
+    }
+
+    private void mockMapping() {
+        Mockito.when(applicationMappingUIDAO.load(anyObject(), anyLong(), anyLong())).then(invocation -> {
+            IApplicationMappingUIDAO.ApplicationMapping applicationMapping = new IApplicationMappingUIDAO.ApplicationMapping();
+            applicationMapping.setMappingApplicationId(1);
+            applicationMapping.setApplicationId(1);
+            return Collections.singletonList(applicationMapping);
+        });
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ClusterTopologyServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ClusterTopologyServiceTest.java
new file mode 100644
index 0000000..5c02973
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ClusterTopologyServiceTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationComponentUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationMappingUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationReferenceMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.common.Topology;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class ClusterTopologyServiceTest {
+
+    private ClusterTopologyService clusterTopologyService;
+    private IApplicationComponentUIDAO applicationComponentUIDAO;
+    private IApplicationMappingUIDAO applicationMappingUIDAO;
+    private IApplicationMetricUIDAO applicationMetricUIDAO;
+    private IApplicationReferenceMetricUIDAO applicationReferenceMetricUIDAO;
+    private Duration duration;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        clusterTopologyService = new ClusterTopologyService(moduleManager);
+        applicationComponentUIDAO = mock(IApplicationComponentUIDAO.class);
+        applicationMappingUIDAO = mock(IApplicationMappingUIDAO.class);
+        applicationMetricUIDAO = mock(IApplicationMetricUIDAO.class);
+        applicationReferenceMetricUIDAO = mock(IApplicationReferenceMetricUIDAO.class);
+        Whitebox.setInternalState(clusterTopologyService, "applicationComponentUIDAO", applicationComponentUIDAO);
+        Whitebox.setInternalState(clusterTopologyService, "applicationMappingUIDAO", applicationMappingUIDAO);
+        Whitebox.setInternalState(clusterTopologyService, "applicationMetricUIDAO", applicationMetricUIDAO);
+        Whitebox.setInternalState(clusterTopologyService, "applicationReferenceMetricUIDAO", applicationReferenceMetricUIDAO);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+    }
+
+    @Test
+    public void getClusterTopology() throws ParseException {
+        long startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        long endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(applicationComponentUIDAO.load(anyObject(), anyLong(), anyLong())).then(invocation -> {
+            List<IApplicationComponentUIDAO.ApplicationComponent> componentList = new ArrayList<>();
+            for (int i = 0; i < 5; i++) {
+                IApplicationComponentUIDAO.ApplicationComponent applicationComponent = new IApplicationComponentUIDAO.ApplicationComponent();
+                applicationComponent.setApplicationId(i + 1);
+                applicationComponent.setComponentId(i + 1);
+                componentList.add(applicationComponent);
+            }
+            return componentList;
+        });
+        mockMapping();
+        Topology clusterTopology = clusterTopologyService.getClusterTopology(duration.getStep(), startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertNotNull(clusterTopology);
+    }
+
+    private void mockMapping() {
+        Mockito.when(applicationMappingUIDAO.load(anyObject(), anyLong(), anyLong())).then(invocation -> {
+            IApplicationMappingUIDAO.ApplicationMapping applicationMapping = new IApplicationMappingUIDAO.ApplicationMapping();
+            applicationMapping.setMappingApplicationId(2);
+            applicationMapping.setApplicationId(2);
+            return Collections.singletonList(applicationMapping);
+        });
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/NetworkAddressServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/NetworkAddressServiceTest.java
new file mode 100644
index 0000000..c365e9e
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/NetworkAddressServiceTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.INetworkAddressUIDAO;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class NetworkAddressServiceTest {
+
+    private INetworkAddressUIDAO networkAddressUIDAO;
+    private NetworkAddressService networkAddressService;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        networkAddressService = new NetworkAddressService(moduleManager);
+        networkAddressUIDAO = mock(INetworkAddressUIDAO.class);
+        Whitebox.setInternalState(networkAddressService, "networkAddressUIDAO", networkAddressUIDAO);
+    }
+
+    @Test
+    public void getNumOfDatabase() {
+        int numOfDatabase = networkAddressService.getNumOfDatabase();
+        Assert.assertEquals(numOfDatabase, 0);
+    }
+
+    @Test
+    public void getNumOfCache() {
+        int numOfCache = networkAddressService.getNumOfCache();
+        Assert.assertEquals(numOfCache, 0);
+    }
+
+    @Test
+    public void getNumOfMQ() {
+        int numOfMQ = networkAddressService.getNumOfMQ();
+        Assert.assertEquals(numOfMQ, 0);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SecondBetweenServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SecondBetweenServiceTest.java
new file mode 100644
index 0000000..e7a204f
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SecondBetweenServiceTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IInstanceUIDAO;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class SecondBetweenServiceTest {
+
+    private SecondBetweenService secondBetweenService;
+
+    private IInstanceUIDAO instanceUIDAO;
+
+    private Duration duration;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        secondBetweenService = new SecondBetweenService(moduleManager);
+        instanceUIDAO = mock(IInstanceUIDAO.class);
+        Whitebox.setInternalState(secondBetweenService, "instanceUIDAO", instanceUIDAO);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+    }
+
+    @Test
+    public void calculate() throws ParseException {
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(instanceUIDAO.getLatestHeartBeatTime(anyInt())).then(invocation -> endSecondTimeBucket);
+        int seconds = secondBetweenService.calculate(1, startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertTrue(seconds > 0);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SegmentTopServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SegmentTopServiceTest.java
new file mode 100644
index 0000000..c9de354
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SegmentTopServiceTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IGlobalTraceUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.ISegmentDurationUIDAO;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.trace.BasicTrace;
+import org.apache.skywalking.apm.collector.storage.ui.trace.TraceBrief;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.Collections;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class SegmentTopServiceTest {
+
+    private ISegmentDurationUIDAO segmentDurationUIDAO;
+    private IGlobalTraceUIDAO globalTraceUIDAO;
+    private SegmentTopService segmentTopService;
+    private Duration duration;
+
+    @Before
+    public void setUp() {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        segmentTopService = new SegmentTopService(moduleManager);
+        segmentDurationUIDAO = mock(ISegmentDurationUIDAO.class);
+        globalTraceUIDAO = mock(IGlobalTraceUIDAO.class);
+        Whitebox.setInternalState(segmentTopService, "segmentDurationUIDAO", segmentDurationUIDAO);
+        Whitebox.setInternalState(segmentTopService, "globalTraceUIDAO", globalTraceUIDAO);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+    }
+
+    @Test
+    public void loadTop() throws ParseException {
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(globalTraceUIDAO.getSegmentIds(anyString())).then(invocation -> Collections.singletonList("segmentIds"));
+        when(segmentDurationUIDAO.loadTop(anyLong(), anyLong(), anyLong(), anyLong(), anyString(), anyInt(), anyInt(), anyInt())).then(invocation -> getTrace());
+        when(segmentDurationUIDAO.loadTop(anyLong(), anyLong(), anyLong(), anyLong(), anyString(), anyInt(), anyInt(), anyInt(), anyObject())).then(invocation -> getTrace());
+        TraceBrief traceBrief = segmentTopService.loadTop(startSecondTimeBucket, endSecondTimeBucket, 0, 1, "test", null, 1, 10, 0);
+        Assert.assertTrue(traceBrief.getTraces().size() == 1);
+        traceBrief = segmentTopService.loadTop(startSecondTimeBucket, endSecondTimeBucket, 0, 1, "test", "traceId", 1, 10, 0);
+        Assert.assertTrue(traceBrief.getTraces().size() == 1);
+    }
+
+    private TraceBrief getTrace() {
+        TraceBrief traceBrief = new TraceBrief();
+        BasicTrace basicTrace = new BasicTrace();
+        basicTrace.setDuration(12);
+        basicTrace.setError(false);
+        basicTrace.setOperationName("test");
+        basicTrace.setSegmentId("segmentId");
+        basicTrace.setStart(System.currentTimeMillis());
+        basicTrace.setTraceIds(Collections.singletonList("traceId"));
+        traceBrief.setTotal(1);
+        traceBrief.setTraces(Collections.singletonList(basicTrace));
+        return traceBrief;
+    }
+
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServerServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServerServiceTest.java
new file mode 100644
index 0000000..1930a19
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServerServiceTest.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import org.apache.skywalking.apm.collector.cache.service.ApplicationCacheService;
+import org.apache.skywalking.apm.collector.cache.service.InstanceCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.*;
+import org.apache.skywalking.apm.collector.storage.table.register.Application;
+import org.apache.skywalking.apm.collector.storage.table.register.Instance;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.ResponseTimeTrend;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.common.ThroughputTrend;
+import org.apache.skywalking.apm.collector.storage.ui.server.AppServerInfo;
+import org.apache.skywalking.apm.collector.storage.ui.server.CPUTrend;
+import org.apache.skywalking.apm.collector.storage.ui.server.GCTrend;
+import org.apache.skywalking.apm.collector.storage.ui.server.MemoryTrend;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class ServerServiceTest {
+
+    private IInstanceUIDAO instanceUIDAO;
+    private IInstanceMetricUIDAO instanceMetricUIDAO;
+    private ICpuMetricUIDAO cpuMetricUIDAO;
+    private IGCMetricUIDAO gcMetricUIDAO;
+    private IMemoryMetricUIDAO memoryMetricUIDAO;
+    private ApplicationCacheService applicationCacheService;
+    private InstanceCacheService instanceCacheService;
+    private SecondBetweenService secondBetweenService;
+    private ServerService serverService;
+    private Duration duration;
+    private long startSecondTimeBucket;
+    private long endSecondTimeBucket;
+    private long startTimeBucket;
+    private long endTimeBucket;
+
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        serverService = new ServerService(moduleManager);
+        instanceUIDAO = mock(IInstanceUIDAO.class);
+        instanceMetricUIDAO = mock(IInstanceMetricUIDAO.class);
+        cpuMetricUIDAO = mock(ICpuMetricUIDAO.class);
+        gcMetricUIDAO = mock(IGCMetricUIDAO.class);
+        memoryMetricUIDAO = mock(IMemoryMetricUIDAO.class);
+        applicationCacheService = mock(ApplicationCacheService.class);
+        instanceCacheService = mock(InstanceCacheService.class);
+        secondBetweenService = mock(SecondBetweenService.class);
+        Whitebox.setInternalState(serverService, "instanceUIDAO", instanceUIDAO);
+        Whitebox.setInternalState(serverService, "instanceMetricUIDAO", instanceMetricUIDAO);
+        Whitebox.setInternalState(serverService, "cpuMetricUIDAO", cpuMetricUIDAO);
+        Whitebox.setInternalState(serverService, "gcMetricUIDAO", gcMetricUIDAO);
+        Whitebox.setInternalState(serverService, "memoryMetricUIDAO", memoryMetricUIDAO);
+        Whitebox.setInternalState(serverService, "applicationCacheService", applicationCacheService);
+        Whitebox.setInternalState(serverService, "instanceCacheService", instanceCacheService);
+        Whitebox.setInternalState(serverService, "secondBetweenService", secondBetweenService);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+        startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+    }
+
+    @Test
+    public void searchServer() throws ParseException {
+        long startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        long endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        when(instanceUIDAO.searchServer(anyString(), anyLong(), anyLong())).then(invocation -> buildServerInfo());
+        mockCache();
+        List<AppServerInfo> serverInfos = serverService.searchServer("keyword", startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertNotNull(serverInfos.get(0).getPid());
+    }
+
+    private List<AppServerInfo> buildServerInfo() {
+        AppServerInfo appServerInfo = new AppServerInfo();
+        appServerInfo.setId(-1);
+        JsonObject jsonObject = new JsonObject();
+        jsonObject.addProperty("osName", "Mac");
+        jsonObject.addProperty("hostName", "computer");
+        jsonObject.addProperty("processId", "1");
+        JsonArray jsonElements = new JsonArray();
+        jsonElements.add("127.0.0.1");
+        jsonObject.add("ipv4s", jsonElements);
+        appServerInfo.setOsInfo(new Gson().toJson(jsonObject));
+        ArrayList<AppServerInfo> appServerInfos = new ArrayList<>();
+        appServerInfos.add(appServerInfo);
+        return appServerInfos;
+    }
+
+    private void mockCache() {
+        Mockito.when(applicationCacheService.getApplicationById(anyInt())).then(invocation -> {
+            Application application = new Application();
+            application.setApplicationId(1);
+            application.setApplicationCode("test");
+            return application;
+        });
+    }
+
+    @Test
+    public void getAllServer() throws ParseException {
+        when(instanceUIDAO.getAllServer(anyInt(), anyLong(), anyLong())).then(invocation -> buildServerInfo());
+        mockCache();
+        List<AppServerInfo> allServer = serverService.getAllServer(-1, startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertNotNull(allServer.get(0).getPid());
+    }
+
+    @Test
+    public void getServerResponseTimeTrend() throws ParseException {
+        when(instanceMetricUIDAO.getResponseTimeTrend(anyInt(), anyObject(), anyObject())).then(invocation -> Collections.singletonList(1));
+        ResponseTimeTrend serverResponseTimeTrend = serverService.getServerResponseTimeTrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertTrue(serverResponseTimeTrend.getTrendList().size() == 1);
+    }
+
+    @Test
+    public void getServerThroughput() throws ParseException {
+        when(instanceMetricUIDAO.getServerThroughput(anyInt(), anyObject(), anyLong(), anyLong(), anyInt(), anyInt(), anyObject())).then(invocation -> buildServerInfo());
+        when(instanceUIDAO.getInstance(anyInt())).then(invocation -> {
+            Instance instance = new Instance();
+            JsonObject jsonObject = new JsonObject();
+            JsonArray jsonElements = new JsonArray();
+            jsonElements.add("127.0.0.1");
+            jsonObject.add("ipv4s", jsonElements);
+            instance.setOsInfo(new Gson().toJson(jsonObject));
+            return instance;
+        });
+        mockCache();
+        List<AppServerInfo> serverThroughput = serverService.getServerThroughput(1, Step.MONTH, startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket, 10);
+        Assert.assertTrue(serverThroughput.size() == 1);
+    }
+
+    @Test
+    public void getServerTPSTrend() throws ParseException {
+        ThroughputTrend serverTPSTrend = serverService.getServerTPSTrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertNotNull(serverTPSTrend);
+    }
+
+    @Test
+    public void getCPUTrend() throws ParseException {
+        CPUTrend cpuTrend = serverService.getCPUTrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertNotNull(cpuTrend);
+    }
+
+    @Test
+    public void getGCTrend() throws ParseException {
+        GCTrend gcTrend = serverService.getGCTrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertNotNull(gcTrend);
+    }
+
+    @Test
+    public void getMemoryTrend() throws ParseException {
+        when(memoryMetricUIDAO.getHeapMemoryTrend(anyInt(), anyObject(), anyObject())).then(invocation -> {
+            IMemoryMetricUIDAO.Trend trend = new IMemoryMetricUIDAO.Trend();
+            trend.setMaxMetrics(Collections.singletonList(1));
+            trend.setMetrics(Collections.singletonList(2));
+            return trend;
+        });
+        when(memoryMetricUIDAO.getNoHeapMemoryTrend(anyInt(), anyObject(), anyObject())).then(invocation -> {
+            IMemoryMetricUIDAO.Trend trend = new IMemoryMetricUIDAO.Trend();
+            trend.setMaxMetrics(Collections.singletonList(1));
+            trend.setMetrics(Collections.singletonList(2));
+            return trend;
+        });
+        MemoryTrend memoryTrend = serverService.getMemoryTrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertNotNull(memoryTrend);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServiceNameServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServiceNameServiceTest.java
new file mode 100644
index 0000000..b57195e
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServiceNameServiceTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.cache.service.ServiceNameCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IServiceMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IServiceNameServiceUIDAO;
+import org.apache.skywalking.apm.collector.storage.table.register.ServiceName;
+import org.apache.skywalking.apm.collector.storage.ui.common.*;
+import org.apache.skywalking.apm.collector.storage.ui.service.ServiceInfo;
+import org.apache.skywalking.apm.collector.storage.ui.service.ServiceMetric;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class ServiceNameServiceTest {
+
+    private IServiceNameServiceUIDAO serviceNameServiceUIDAO;
+    private IServiceMetricUIDAO serviceMetricUIDAO;
+    private ServiceNameCacheService serviceNameCacheService;
+    private SecondBetweenService secondBetweenService;
+    private ServiceNameService serverNameService;
+    private Duration duration;
+    private long startSecondTimeBucket;
+    private long endSecondTimeBucket;
+    private long startTimeBucket;
+    private long endTimeBucket;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        serverNameService = new ServiceNameService(moduleManager);
+        serviceNameCacheService = mock(ServiceNameCacheService.class);
+        serviceMetricUIDAO = mock(IServiceMetricUIDAO.class);
+        secondBetweenService = mock(SecondBetweenService.class);
+        Whitebox.setInternalState(serverNameService, "serviceNameCacheService", serviceNameCacheService);
+        Whitebox.setInternalState(serverNameService, "serviceMetricUIDAO", serviceMetricUIDAO);
+        Whitebox.setInternalState(serverNameService, "secondBetweenService", secondBetweenService);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+        startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+    }
+
+    @Test
+    public void getCount() {
+        int count = serverNameService.getCount();
+        Assert.assertTrue(count == 0);
+    }
+
+    @Test
+    public void searchService() {
+        List<ServiceInfo> serviceInfos = serverNameService.searchService("keyword", 10);
+        Assert.assertTrue(serviceInfos.size() == 0);
+    }
+
+    @Test
+    public void getServiceTPSTrend() throws ParseException {
+        ThroughputTrend serviceTPSTrend = serverNameService.getServiceTPSTrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertNotNull(serviceTPSTrend);
+    }
+
+    @Test
+    public void getServiceResponseTimeTrend() throws ParseException {
+        ResponseTimeTrend serviceResponseTimeTrend = serverNameService.getServiceResponseTimeTrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertNotNull(serviceResponseTimeTrend);
+    }
+
+    @Test
+    public void getServiceSLATrend() throws ParseException {
+        SLATrend serviceSLATrend = serverNameService.getServiceSLATrend(1, duration.getStep(), startTimeBucket, endTimeBucket);
+        Assert.assertNotNull(serviceSLATrend);
+    }
+
+    @Test
+    public void getSlowService() throws ParseException {
+        when(serviceMetricUIDAO.getSlowService(anyInt(), anyObject(), anyLong(), anyLong(), anyInt(), anyObject())).then(invocation -> {
+            ServiceMetric serviceMetric = new ServiceMetric();
+            serviceMetric.setCalls(200901);
+            serviceMetric.setName("test");
+            serviceMetric.setAvgResponseTime(100);
+            serviceMetric.setId(1);
+            return Collections.singletonList(serviceMetric);
+        });
+        when(secondBetweenService.calculate(anyInt(), anyLong(), anyLong())).then(invocation -> 20L);
+        mockCache();
+        List<ServiceMetric> slowService = serverNameService.getSlowService(duration.getStep(), startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket, 10);
+        Assert.assertTrue(slowService.size() > 0);
+    }
+
+    private void mockCache() {
+        Mockito.when(serviceNameCacheService.get(anyInt())).then(invocation -> {
+            ServiceName serviceName = new ServiceName();
+            serviceName.setServiceName("test_name");
+            return serviceName;
+        });
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServiceTopologyServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServiceTopologyServiceTest.java
new file mode 100644
index 0000000..a81fc41
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/ServiceTopologyServiceTest.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.cache.service.ServiceNameCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationComponentUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IServiceMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IServiceReferenceMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.table.register.ServiceName;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Node;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.common.Topology;
+import org.apache.skywalking.apm.collector.storage.ui.service.ServiceNode;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class ServiceTopologyServiceTest {
+
+    private IApplicationComponentUIDAO applicationComponentUIDAO;
+    private IServiceMetricUIDAO serviceMetricUIDAO;
+    private IServiceReferenceMetricUIDAO serviceReferenceMetricUIDAO;
+    private ServiceNameCacheService serviceNameCacheService;
+    private SecondBetweenService secondBetweenService;
+    private ServiceTopologyService serviceTopologyService;
+    private Duration duration;
+    private long startSecondTimeBucket;
+    private long endSecondTimeBucket;
+    private long startTimeBucket;
+    private long endTimeBucket;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        serviceTopologyService = new ServiceTopologyService(moduleManager);
+        applicationComponentUIDAO = mock(IApplicationComponentUIDAO.class);
+        serviceMetricUIDAO = mock(IServiceMetricUIDAO.class);
+        serviceReferenceMetricUIDAO = mock(IServiceReferenceMetricUIDAO.class);
+        serviceNameCacheService = mock(ServiceNameCacheService.class);
+        secondBetweenService = mock(SecondBetweenService.class);
+        Whitebox.setInternalState(serviceTopologyService, "applicationComponentUIDAO", applicationComponentUIDAO);
+        Whitebox.setInternalState(serviceTopologyService, "serviceMetricUIDAO", serviceMetricUIDAO);
+        Whitebox.setInternalState(serviceTopologyService, "serviceReferenceMetricUIDAO", serviceReferenceMetricUIDAO);
+        Whitebox.setInternalState(serviceTopologyService, "serviceNameCacheService", serviceNameCacheService);
+        Whitebox.setInternalState(serviceTopologyService, "secondBetweenService", secondBetweenService);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+        startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+    }
+
+    @Test
+    public void getServiceTopology() throws ParseException {
+        when(applicationComponentUIDAO.load(anyObject(), anyLong(), anyLong())).then(invocation -> {
+            List<IApplicationComponentUIDAO.ApplicationComponent> componentList = new ArrayList<>();
+            for (int i = 0; i < 5; i++) {
+                IApplicationComponentUIDAO.ApplicationComponent applicationComponent = new IApplicationComponentUIDAO.ApplicationComponent();
+                applicationComponent.setApplicationId(i + 2);
+                applicationComponent.setComponentId(i + 2);
+                componentList.add(applicationComponent);
+            }
+            return componentList;
+        });
+        when(serviceReferenceMetricUIDAO.getFrontServices(anyObject(), anyLong(), anyLong(), anyObject(), anyInt())).then(invocation -> {
+            List<IServiceReferenceMetricUIDAO.ServiceReferenceMetric> list = new ArrayList<>();
+            for (int i = 0; i < 5; i++) {
+                IServiceReferenceMetricUIDAO.ServiceReferenceMetric serviceReferenceMetric = new IServiceReferenceMetricUIDAO.ServiceReferenceMetric();
+                serviceReferenceMetric.setSource(i);
+                serviceReferenceMetric.setTarget(i + 1);
+                serviceReferenceMetric.setCalls(200);
+                serviceReferenceMetric.setErrorCalls(2);
+                list.add(serviceReferenceMetric);
+            }
+            return list;
+        });
+        mockCache();
+
+        when(secondBetweenService.calculate(anyInt(), anyLong(), anyLong())).then(invocation -> 20L);
+        when(serviceMetricUIDAO.getServicesMetric(anyObject(), anyLong(), anyLong(), anyObject(), anyObject())).then(invocation -> {
+            List<Node> nodes = new LinkedList<>();
+            ServiceNode serviceNode = new ServiceNode();
+            serviceNode.setId(1);
+            serviceNode.setCalls(200);
+            serviceNode.setSla(99);
+            nodes.add(serviceNode);
+            return nodes;
+        });
+        Topology serviceTopology = serviceTopologyService.getServiceTopology(duration.getStep(), 1, startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertTrue(serviceTopology.getCalls().size() > 0);
+        Assert.assertTrue(serviceTopology.getNodes().size() > 0);
+    }
+
+    private void mockCache() {
+        Mockito.when(serviceNameCacheService.get(anyInt())).then(invocation -> {
+            ServiceName serviceName = new ServiceName();
+            serviceName.setServiceName("test_name");
+            return serviceName;
+        });
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SpanServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SpanServiceTest.java
new file mode 100644
index 0000000..67aacb4
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/SpanServiceTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import com.google.gson.JsonObject;
+import org.apache.skywalking.apm.collector.cache.service.ApplicationCacheService;
+import org.apache.skywalking.apm.collector.cache.service.ServiceNameCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.ISegmentUIDAO;
+import org.apache.skywalking.apm.network.proto.KeyWithStringValue;
+import org.apache.skywalking.apm.network.proto.LogMessage;
+import org.apache.skywalking.apm.network.proto.SpanObject;
+import org.apache.skywalking.apm.network.proto.TraceSegmentObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class SpanServiceTest {
+
+    private SpanService spanService;
+    private ISegmentUIDAO segmentDAO;
+    private ServiceNameCacheService serviceNameCacheService;
+    private ApplicationCacheService applicationCacheService;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        spanService = new SpanService(moduleManager);
+        serviceNameCacheService = mock(ServiceNameCacheService.class);
+        applicationCacheService = mock(ApplicationCacheService.class);
+        segmentDAO = mock(ISegmentUIDAO.class);
+        Whitebox.setInternalState(spanService, "serviceNameCacheService", serviceNameCacheService);
+        Whitebox.setInternalState(spanService, "applicationCacheService", applicationCacheService);
+        Whitebox.setInternalState(spanService, "segmentDAO", segmentDAO);
+    }
+
+    @Test
+    public void load() {
+        when(segmentDAO.load(anyString())).then(invocation -> {
+            LogMessage message = LogMessage.newBuilder()
+                    .setTime(System.currentTimeMillis())
+                    .addData(KeyWithStringValue.newBuilder().setKey("a").setValue("b").build())
+                    .build();
+            SpanObject testSpanObject = SpanObject.newBuilder()
+                    .setSpanId(1)
+                    .setOperationName("testSpanName")
+                    .addLogs(message)
+                    .addTags(KeyWithStringValue.newBuilder().setKey("tagKey").setValue("tagValue").build())
+                    .setOperationNameId(1)
+                    .build();
+            return TraceSegmentObject.newBuilder()
+                    .addSpans(testSpanObject)
+                    .build();
+        });
+
+        JsonObject load = spanService.load("123", 1);
+        Assert.assertNotNull(load);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TimeSynchronousServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TimeSynchronousServiceTest.java
new file mode 100644
index 0000000..fcb20ed
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TimeSynchronousServiceTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class TimeSynchronousServiceTest {
+
+    private TimeSynchronousService timeSynchronousService;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        timeSynchronousService = new TimeSynchronousService(moduleManager);
+    }
+
+    @Test
+    public void allInstanceLastTime() {
+        Long aLong = timeSynchronousService.allInstanceLastTime();
+        Assert.assertEquals((long) aLong, 0L);
+    }
+
+    @Test
+    public void instanceLastTime() {
+        Long aLong = timeSynchronousService.instanceLastTime(-1);
+        Assert.assertEquals((long) aLong, 0L);
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TopologyBuilderTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TopologyBuilderTest.java
new file mode 100644
index 0000000..fc5a592
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TopologyBuilderTest.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import org.apache.skywalking.apm.collector.cache.service.ApplicationCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationComponentUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationMappingUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IApplicationReferenceMetricUIDAO;
+import org.apache.skywalking.apm.collector.storage.table.register.Application;
+import org.apache.skywalking.apm.collector.storage.ui.alarm.Alarm;
+import org.apache.skywalking.apm.collector.storage.ui.alarm.AlarmItem;
+import org.apache.skywalking.apm.collector.storage.ui.common.Duration;
+import org.apache.skywalking.apm.collector.storage.ui.common.Step;
+import org.apache.skywalking.apm.collector.storage.ui.common.Topology;
+import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class TopologyBuilderTest {
+
+    private ApplicationCacheService applicationCacheService;
+    private ServerService serverService;
+    private SecondBetweenService secondBetweenService;
+    private AlarmService alarmService;
+    private TopologyBuilder topologyBuilder;
+    private Duration duration;
+    private long startSecondTimeBucket;
+    private long endSecondTimeBucket;
+    private long startTimeBucket;
+    private long endTimeBucket;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        topologyBuilder = new TopologyBuilder(moduleManager);
+        applicationCacheService = mock(ApplicationCacheService.class);
+        alarmService = mock(AlarmService.class);
+        secondBetweenService = mock(SecondBetweenService.class);
+        Whitebox.setInternalState(topologyBuilder, "applicationCacheService", applicationCacheService);
+        Whitebox.setInternalState(topologyBuilder, "alarmService", alarmService);
+        Whitebox.setInternalState(topologyBuilder, "secondBetweenService", secondBetweenService);
+        duration = new Duration();
+        duration.setEnd("2018-02");
+        duration.setStart("2018-01");
+        duration.setStep(Step.MONTH);
+        startSecondTimeBucket = DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(duration.getStep(), duration.getStart());
+        endSecondTimeBucket = DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(duration.getStep(), duration.getEnd());
+        startTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
+        endTimeBucket = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
+    }
+
+    @Test
+    public void build() throws ParseException {
+        List<IApplicationComponentUIDAO.ApplicationComponent> applicationComponents = new ArrayList<>();
+        IApplicationComponentUIDAO.ApplicationComponent component = new IApplicationComponentUIDAO.ApplicationComponent();
+        component.setComponentId(1);
+        component.setApplicationId(2);
+        applicationComponents.add(component);
+
+        List<IApplicationMappingUIDAO.ApplicationMapping> applicationMappings = new ArrayList<>();
+        IApplicationMappingUIDAO.ApplicationMapping mapping = new IApplicationMappingUIDAO.ApplicationMapping();
+        mapping.setApplicationId(2);
+        mapping.setMappingApplicationId(3);
+        applicationMappings.add(mapping);
+
+        List<IApplicationMetricUIDAO.ApplicationMetric> applicationMetrics = new ArrayList<>();
+        IApplicationMetricUIDAO.ApplicationMetric applicationMetric = new IApplicationMetricUIDAO.ApplicationMetric();
+        applicationMetric.setCalls(200);
+        applicationMetric.setErrorCalls(2);
+        applicationMetric.setDurations(100);
+        applicationMetric.setSatisfiedCount(100);
+        applicationMetric.setToleratingCount(50);
+        applicationMetric.setFrustratedCount(50);
+        applicationMetric.setErrorDurations(1000);
+        applicationMetrics.add(applicationMetric);
+
+        List<IApplicationReferenceMetricUIDAO.ApplicationReferenceMetric> callerReferenceMetric = new ArrayList<>();
+        IApplicationReferenceMetricUIDAO.ApplicationReferenceMetric applicationReferenceMetric = new IApplicationReferenceMetricUIDAO.ApplicationReferenceMetric();
+        applicationReferenceMetric.setCalls(200);
+        applicationReferenceMetric.setErrorCalls(2);
+        applicationReferenceMetric.setSource(1);
+        applicationReferenceMetric.setTarget(2);
+        callerReferenceMetric.add(applicationReferenceMetric);
+
+        List<IApplicationReferenceMetricUIDAO.ApplicationReferenceMetric> calleeReferenceMetric = new ArrayList<>();
+        IApplicationReferenceMetricUIDAO.ApplicationReferenceMetric metric = new IApplicationReferenceMetricUIDAO.ApplicationReferenceMetric();
+        metric.setCalls(200);
+        metric.setErrorCalls(2);
+        metric.setSource(1);
+        metric.setTarget(2);
+        calleeReferenceMetric.add(metric);
+        mockCache();
+
+        when(alarmService.loadApplicationAlarmList(anyString(), anyObject(), anyLong(), anyLong(), anyInt(), anyInt())).then(invocation -> {
+            Alarm alarm = new Alarm();
+            alarm.setItems(Collections.singletonList(new AlarmItem()));
+            return alarm;
+        });
+        when(alarmService.loadInstanceAlarmList(anyString(), anyObject(), anyLong(), anyLong(), anyInt(), anyInt())).then(invocation -> {
+            Alarm alarm = new Alarm();
+            alarm.setItems(Collections.singletonList(new AlarmItem()));
+            return alarm;
+        });
+        when(alarmService.loadServiceAlarmList(anyString(), anyObject(), anyLong(), anyLong(), anyInt(), anyInt())).then(invocation -> {
+            Alarm alarm = new Alarm();
+            alarm.setItems(Collections.singletonList(new AlarmItem()));
+            return alarm;
+        });
+        when(secondBetweenService.calculate(anyInt(), anyLong(), anyLong())).then(invocation -> 20L);
+        Topology topology = topologyBuilder.build(applicationComponents, applicationMappings, applicationMetrics, callerReferenceMetric, calleeReferenceMetric, duration.getStep(), startTimeBucket, endTimeBucket, startSecondTimeBucket, endSecondTimeBucket);
+        Assert.assertNotNull(topology);
+    }
+
+    private void mockCache() {
+        Mockito.when(applicationCacheService.getApplicationById(anyInt())).then(invocation -> {
+            Application application = new Application();
+            application.setApplicationId(1);
+            application.setApplicationCode("test");
+            return application;
+        });
+    }
+}
\ No newline at end of file
diff --git a/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TraceStackServiceTest.java b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TraceStackServiceTest.java
new file mode 100644
index 0000000..b40c882
--- /dev/null
+++ b/apm-collector/apm-collector-ui/collector-ui-jetty-provider/src/test/java/org/apache/skywalking/apm/collector/ui/service/TraceStackServiceTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.skywalking.apm.collector.ui.service;
+
+import com.google.common.collect.Lists;
+import org.apache.skywalking.apm.collector.cache.service.ApplicationCacheService;
+import org.apache.skywalking.apm.collector.cache.service.NetworkAddressCacheService;
+import org.apache.skywalking.apm.collector.cache.service.ServiceNameCacheService;
+import org.apache.skywalking.apm.collector.core.module.MockModule;
+import org.apache.skywalking.apm.collector.core.module.ModuleManager;
+import org.apache.skywalking.apm.collector.storage.dao.ui.IGlobalTraceUIDAO;
+import org.apache.skywalking.apm.collector.storage.dao.ui.ISegmentUIDAO;
+import org.apache.skywalking.apm.collector.storage.table.register.Application;
+import org.apache.skywalking.apm.collector.storage.ui.trace.Trace;
+import org.apache.skywalking.apm.network.proto.*;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+/**
+ * @author lican
+ */
+public class TraceStackServiceTest {
+
+    private TraceStackService traceStackService;
+    private IGlobalTraceUIDAO globalTraceDAO;
+    private ISegmentUIDAO segmentDAO;
+    private ApplicationCacheService applicationCacheService;
+    private ServiceNameCacheService serviceNameCacheService;
+    private NetworkAddressCacheService networkAddressCacheService;
+
+    @Before
+    public void setUp() throws Exception {
+        ModuleManager moduleManager = mock(ModuleManager.class);
+        when(moduleManager.find(anyString())).then(invocation -> new MockModule());
+        traceStackService = new TraceStackService(moduleManager);
+        globalTraceDAO = mock(IGlobalTraceUIDAO.class);
+        segmentDAO = mock(ISegmentUIDAO.class);
+        applicationCacheService = mock(ApplicationCacheService.class);
+        Whitebox.setInternalState(traceStackService, "globalTraceDAO", globalTraceDAO);
+        Whitebox.setInternalState(traceStackService, "segmentDAO", segmentDAO);
+        Whitebox.setInternalState(traceStackService, "applicationCacheService", applicationCacheService);
+    }
+
+    @Test
+    public void load() {
+        when(globalTraceDAO.getSegmentIds(anyString())).then(invocation -> Lists.newArrayList("1", "2", "3"));
+        when(segmentDAO.load(anyString())).then(invocation -> {
+            TraceSegmentReference traceSegmentReference = TraceSegmentReference.newBuilder()
+                    .setRefType(RefType.CrossProcess)
+                    .setRefTypeValue(1)
+                    .build();
+            LogMessage message = LogMessage.newBuilder()
+                    .setTime(System.currentTimeMillis())
+                    .addData(KeyWithStringValue.newBuilder().setKey("a").setValue("b").build())
+                    .build();
+            SpanObject testSpanObject = SpanObject.newBuilder()
+                    .setSpanId(1)
+                    .setOperationName("testSpanName")
+                    .addLogs(message)
+                    .addTags(KeyWithStringValue.newBuilder().setKey("tagKey").setValue("tagValue").build())
+                    .setOperationNameId(1)
+                    .addRefs(traceSegmentReference)
+                    .build();
+            return TraceSegmentObject.newBuilder()
+                    .addSpans(testSpanObject)
+                    .build();
+        });
+        mockCache();
+        Trace load = traceStackService.load("123");
+        Assert.assertNotNull(load);
+    }
+
+    private void mockCache() {
+        Mockito.when(applicationCacheService.getApplicationById(anyInt())).then(invocation -> {
+            Application application = new Application();
+            application.setApplicationId(1);
+            application.setApplicationCode("test");
+            return application;
+        });
+    }
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
pengys@apache.org.