You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/02/19 09:57:34 UTC

[dubbo] branch 3.0 updated: [UT] Fix unit-test cases in 3.0 (#7175)

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

liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 50786a2  [UT] Fix unit-test cases in 3.0 (#7175)
50786a2 is described below

commit 50786a20e4c345cbea8b0e7d5e9b4d7493c49381
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Fri Feb 19 17:56:54 2021 +0800

    [UT] Fix unit-test cases in 3.0 (#7175)
---
 .../org/apache/dubbo/rpc/cluster/Constants.java    |    2 +
 .../rpc/cluster/filter/ProtocolFilterWrapper.java  |    6 +
 .../support/AbstractClusterInvokerTest.java        |    8 +-
 .../support/wrapper/MockClusterInvokerTest.java    | 1723 ++++++++++----------
 .../wrapper/MockProviderRpcExceptionTest.java      |    6 +-
 .../org/apache/dubbo/config/ReferenceConfig.java   |    5 +-
 .../dubbo/config/bootstrap/DubboBootstrapTest.java |   22 +-
 .../dubbo/config/url/InvokerSideConfigUrlTest.java |    2 +-
 .../definition/model/MethodDefinition.java         |    2 +-
 .../dubbo/jax-rs-service-rest-metadata.json        |   35 +-
 .../apache/dubbo/qos/command/impl/OnlineApp.java   |    5 +
 .../dubbo/qos/command/impl/OnlineInterface.java    |    5 +
 .../dubbo/qos/command/util/CommandHelperTest.java  |   27 +-
 .../dubbo/registry/RegistryFactoryWrapperTest.java |   16 +-
 .../dubbo/registry/SimpleRegistryFactory.java      |    3 +-
 .../metadata/ServiceInstanceMetadataUtilsTest.java |   17 +-
 .../rpc/protocol/dubbo/DubboProtocolTest.java      |   25 +-
 dubbo-rpc/dubbo-rpc-grpc/pom.xml                   |    5 +
 dubbo-rpc/dubbo-rpc-injvm/pom.xml                  |    5 +
 .../dubbo/rpc/protocol/injvm/DemoService.java      |    3 -
 .../dubbo/rpc/protocol/injvm/DemoServiceImpl.java  |    6 -
 .../rpc/protocol/injvm/InjvmProtocolTest.java      |   17 +-
 dubbo-rpc/dubbo-rpc-rest/pom.xml                   |    5 +
 .../dubbo/rpc/protocol/rest/DemoService.java       |    4 -
 .../dubbo/rpc/protocol/rest/DemoServiceImpl.java   |    5 -
 .../dubbo/rpc/protocol/rest/RestProtocolTest.java  |   17 -
 .../dubbo/rpc/protocol/tri/TripleProtocol.java     |    1 -
 .../src/main/proto/triple_wrapper.proto            |   14 +
 28 files changed, 1029 insertions(+), 962 deletions(-)

diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java
index c1c755e..4bd1595 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/Constants.java
@@ -100,5 +100,7 @@ public interface Constants {
      */
     String EXPORT_KEY = "export";
 
+    String PEER_KEY = "peer";
+
     String CONSUMER_URL_KEY = "CONSUMER_URL";
 }
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java
index cded6dd..65e8813 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/ProtocolFilterWrapper.java
@@ -28,8 +28,10 @@ import org.apache.dubbo.rpc.ProtocolServer;
 import org.apache.dubbo.rpc.RpcException;
 
 import java.util.List;
+import java.util.Objects;
 
 import static org.apache.dubbo.common.constants.CommonConstants.SERVICE_FILTER_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
 
 /**
  * ListenerProtocol
@@ -66,6 +68,10 @@ public class ProtocolFilterWrapper implements Protocol {
         if (UrlUtils.isRegistry(url)) {
             return protocol.refer(type, url);
         }
+        // if it's peer-to-peer url
+        if (!Objects.isNull(url.getAttribute(PEER_KEY))) {
+            return builder.buildInvokerChain(protocol.refer(type, url), SERVICE_FILTER_KEY, CommonConstants.CONSUMER);
+        }
         return protocol.refer(type, url);
     }
 
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java
index 6d19dd6..ef7c1d5 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java
@@ -56,8 +56,11 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.CLUSTER_AVAILABLE_CHECK_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
 import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 /**
  * AbstractClusterInvokerTest
@@ -237,7 +240,8 @@ public class AbstractClusterInvokerTest {
         LoadBalance lb = mock(LoadBalance.class);
         Map<String, String> queryMap = (Map<String, String> )url.getAttribute(REFER_KEY);
         URL tmpUrl = turnRegistryUrlToConsumerUrl(url, queryMap);
-        given(lb.select(invokers, tmpUrl, invocation)).willReturn(invoker1);
+
+        when(lb.select(same(invokers), eq(tmpUrl), same(invocation))).thenReturn(invoker1);
         initlistsize5();
 
         Invoker sinvoker = cluster_nocheck.select(lb, invocation, invokers, selectedInvokers);
@@ -248,6 +252,8 @@ public class AbstractClusterInvokerTest {
 
     private URL turnRegistryUrlToConsumerUrl(URL url, Map<String, String> queryMap) {
         return URLBuilder.from(url)
+                .setHost(queryMap.get("register.ip"))
+                .setPort(0)
                 .setProtocol(queryMap.get(PROTOCOL_KEY) == null ? DUBBO : queryMap.get(PROTOCOL_KEY))
                 .setPath(queryMap.get(PATH_KEY) != null ? queryMap.get(PATH_KEY) : queryMap.get(INTERFACE_KEY))
                 .clearParameters()
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java
index df1240c..9534fe4 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvokerTest.java
@@ -1,846 +1,877 @@
-/*
- * 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.dubbo.rpc.cluster.support.wrapper;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.ProxyFactory;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.cluster.LoadBalance;
-import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
-import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
-import org.apache.dubbo.rpc.support.MockProtocol;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
-import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
-
-public class MockClusterInvokerTest {
-
-    List<Invoker<IHelloService>> invokers = new ArrayList<Invoker<IHelloService>>();
-
-    @BeforeEach
-    public void beforeMethod() {
-        invokers.clear();
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerInvoke_normal() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName());
-        url = url.addParameter(MOCK_KEY, "fail")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()));
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName()
-                + "?getSomething.mock=return aa");
-
-        Protocol protocol = new MockProtocol();
-        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
-        invokers.add(mInvoker1);
-
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("something", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerInvoke_failmock() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter(MOCK_KEY, "fail:return null")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName()
-                + "?getSomething.mock=return aa").addParameters(url.getParameters());
-
-        Protocol protocol = new MockProtocol();
-        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
-        Invoker<IHelloService> cluster = getClusterInvokerMock(url, mInvoker1);
-
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("aa", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-    }
-
-
-    /**
-     * Test if mock policy works fine: force-mock
-     */
-    @Test
-    public void testMockInvokerInvoke_forcemock() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName());
-        url = url.addParameter(MOCK_KEY, "force:return null")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()));
-
-        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName()
-                + "?getSomething.mock=return aa&getSomething3xx.mock=return xx")
-                .addParameters(url.getParameters());
-
-        Protocol protocol = new MockProtocol();
-        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
-        Invoker<IHelloService> cluster = getClusterInvokerMock(url, mInvoker1);
-
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("aa", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-    }
-
-    @Test
-    public void testMockInvokerInvoke_forcemock_defaultreturn() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName());
-        url = url.addParameter(MOCK_KEY, "force")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()));
-
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName()
-                + "?getSomething.mock=return aa&getSomething3xx.mock=return xx&sayHello.mock=return ")
-                .addParameters(url.getParameters());
-
-        Protocol protocol = new MockProtocol();
-        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
-        invokers.add(mInvoker1);
-
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_Fock_someMethods() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getSomething.mock", "fail:return x")
-                .addParameter("getSomething2.mock", "force:return y")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()));
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("something", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("y", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething3");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("something3", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_Fock_WithOutDefault() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getSomething.mock", "fail:return x")
-                .addParameter("getSomething2.mock", "force:return y")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("y", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething3");
-        try {
-            ret = cluster.invoke(invocation);
-            Assertions.fail();
-        } catch (RpcException e) {
-
-        }
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_Fock_WithDefault() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("mock", "fail:return null")
-                .addParameter("getSomething.mock", "fail:return x")
-                .addParameter("getSomething2.mock", "force:return y")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("y", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething3");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertNull(ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_Fock_WithFailDefault() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("mock", "fail:return z")
-                .addParameter("getSomething.mock", "fail:return x")
-                .addParameter("getSomething2.mock", "force:return y")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("y", ret.getValue());
-
-        // If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething3");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("z", ret.getValue());
-
-        //If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("z", ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_Fock_WithForceDefault() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("mock", "force:return z")
-                .addParameter("getSomething.mock", "fail:return x")
-                .addParameter("getSomething2.mock", "force:return y")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-
-        //If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("y", ret.getValue());
-
-        //If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething3");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("z", ret.getValue());
-
-        //If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("z", ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_Fock_Default() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("mock", "fail:return x")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-
-        //If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething2");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-
-        //If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("sayHello");
-        ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_checkCompatible_return() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getSomething.mock", "return x")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("x", ret.getValue());
-
-        //If no mock was configured, return null directly
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething3");
-        try {
-            ret = cluster.invoke(invocation);
-            Assertions.fail("fail invoke");
-        } catch (RpcException e) {
-
-        }
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_checkCompatible_ImplMock() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("mock", "true")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("somethingmock", ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_checkCompatible_ImplMock2() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("mock", "fail")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("somethingmock", ret.getValue());
-    }
-
-    /**
-     * Test if mock policy works fine: fail-mock
-     */
-    @Test
-    public void testMockInvokerFromOverride_Invoke_checkCompatible_ImplMock3() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("mock", "force");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals("somethingmock", ret.getValue());
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_String() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getSomething.mock", "force:return 1688")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getSomething");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertTrue(ret.getValue() instanceof String, "result type must be String but was : " + ret.getValue().getClass());
-        Assertions.assertEquals("1688", (String) ret.getValue());
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_int() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("getInt1.mock", "force:return 1688")
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getInt1");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertTrue(ret.getValue() instanceof Integer, "result type must be integer but was : " + ret.getValue().getClass());
-        Assertions.assertEquals(new Integer(1688), (Integer) ret.getValue());
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_boolean() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("getBoolean1.mock", "force:return true")
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getBoolean1");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertTrue(ret.getValue() instanceof Boolean, "result type must be Boolean but was : " + ret.getValue().getClass());
-        Assertions.assertTrue(Boolean.parseBoolean(ret.getValue().toString()));
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_Boolean() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("getBoolean2.mock", "force:return true")
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getBoolean2");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertTrue(Boolean.parseBoolean(ret.getValue().toString()));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_ListString_empty() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getListString.mock", "force:return empty")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getListString");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals(0, ((List<String>) ret.getValue()).size());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_ListString() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getListString.mock", "force:return [\"hi\",\"hi2\"]")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getListString");
-        Result ret = cluster.invoke(invocation);
-        List<String> rl = (List<String>) ret.getValue();
-        Assertions.assertEquals(2, rl.size());
-        Assertions.assertEquals("hi", rl.get(0));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_ListPojo_empty() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getUsers.mock", "force:return empty")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getUsers");
-        Result ret = cluster.invoke(invocation);
-        Assertions.assertEquals(0, ((List<User>) ret.getValue()).size());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_ListPojo() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getUsers.mock", "force:return [{id:1, name:\"hi1\"}, {id:2, name:\"hi2\"}]")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getUsers");
-        Result ret = cluster.invoke(invocation);
-        List<User> rl = (List<User>) ret.getValue();
-        System.out.println(rl);
-        Assertions.assertEquals(2, rl.size());
-        Assertions.assertEquals("hi1", ((User) rl.get(0)).getName());
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_check_ListPojo_error() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getUsers.mock", "force:return [{id:x, name:\"hi1\"}]")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getUsers");
-        try {
-            cluster.invoke(invocation);
-        } catch (RpcException e) {
-        }
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_force_throw() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getBoolean2.mock", "force:throw ")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getBoolean2");
-        try {
-            cluster.invoke(invocation);
-            Assertions.fail();
-        } catch (RpcException e) {
-            Assertions.assertFalse(e.isBiz(), "not custem exception");
-        }
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_force_throwCustemException() throws Throwable {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getBoolean2.mock", "force:throw org.apache.dubbo.rpc.cluster.support.wrapper.MyMockException")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getBoolean2");
-        try {
-            cluster.invoke(invocation).recreate();
-            Assertions.fail();
-        } catch (MyMockException e) {
-
-        }
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_force_throwCustemExceptionNotFound() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("getBoolean2.mock", "force:throw java.lang.RuntimeException2")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getBoolean2");
-        try {
-            cluster.invoke(invocation);
-            Assertions.fail();
-        } catch (Exception e) {
-            Assertions.assertTrue(e.getCause() instanceof IllegalStateException);
-        }
-    }
-
-    @Test
-    public void testMockInvokerFromOverride_Invoke_mock_false() {
-        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
-                .addParameter("mock", "false")
-                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
-                .addParameter("invoke_return_error", "true");
-        Invoker<IHelloService> cluster = getClusterInvoker(url);
-        //Configured with mock
-        RpcInvocation invocation = new RpcInvocation();
-        invocation.setMethodName("getBoolean2");
-        try {
-            cluster.invoke(invocation);
-            Assertions.fail();
-        } catch (RpcException e) {
-            Assertions.assertTrue(e.isTimeout());
-        }
-    }
-
-    private Invoker<IHelloService> getClusterInvokerMock(URL url, Invoker<IHelloService> mockInvoker) {
-        // As `javassist` have a strict restriction of argument types, request will fail if Invocation do not contains complete parameter type information
-        final URL durl = url.addParameter("proxy", "jdk");
-        invokers.clear();
-        ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension("jdk");
-        Invoker<IHelloService> invoker1 = proxy.getInvoker(new HelloService(), IHelloService.class, durl);
-        invokers.add(invoker1);
-        if (mockInvoker != null) {
-            invokers.add(mockInvoker);
-        }
-
-        StaticDirectory<IHelloService> dic = new StaticDirectory<IHelloService>(durl, invokers, null);
-        dic.buildRouterChain();
-        AbstractClusterInvoker<IHelloService> cluster = new AbstractClusterInvoker(dic) {
-            @Override
-            protected Result doInvoke(Invocation invocation, List invokers, LoadBalance loadbalance)
-                    throws RpcException {
-                if (durl.getParameter("invoke_return_error", false)) {
-                    throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "test rpc exception");
-                } else {
-                    return ((Invoker<?>) invokers.get(0)).invoke(invocation);
-                }
-            }
-        };
-        return new MockClusterInvoker<IHelloService>(dic, cluster);
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    private Invoker<IHelloService> getClusterInvoker(URL url) {
-        return getClusterInvokerMock(url, null);
-    }
-
-    public interface IHelloService {
-        String getSomething();
-
-        String getSomething2();
-
-        String getSomething3();
-
-        String getSomething4();
-
-        int getInt1();
-
-        boolean getBoolean1();
-
-        Boolean getBoolean2();
-
-        List<String> getListString();
-
-        List<User> getUsers();
-
-        void sayHello();
-    }
-
-    public static class HelloService implements IHelloService {
-        public String getSomething() {
-            return "something";
-        }
-
-        public String getSomething2() {
-            return "something2";
-        }
-
-        public String getSomething3() {
-            return "something3";
-        }
-
-        public String getSomething4() {
-            throw new RpcException("getSomething4|RpcException");
-        }
-
-        public int getInt1() {
-            return 1;
-        }
-
-        public boolean getBoolean1() {
-            return false;
-        }
-
-        public Boolean getBoolean2() {
-            return Boolean.FALSE;
-        }
-
-        public List<String> getListString() {
-            return Arrays.asList(new String[]{"Tom", "Jerry"});
-        }
-
-        public List<User> getUsers() {
-            return Arrays.asList(new User[]{new User(1, "Tom"), new User(2, "Jerry")});
-        }
-
-        public void sayHello() {
-            System.out.println("hello prety");
-        }
-    }
-
-    public static class IHelloServiceMock implements IHelloService {
-        public IHelloServiceMock() {
-
-        }
-
-        public String getSomething() {
-            return "somethingmock";
-        }
-
-        public String getSomething2() {
-            return "something2mock";
-        }
-
-        public String getSomething3() {
-            return "something3mock";
-        }
-
-        public String getSomething4() {
-            return "something4mock";
-        }
-
-        public List<String> getListString() {
-            return Arrays.asList(new String[]{"Tommock", "Jerrymock"});
-        }
-
-        public List<User> getUsers() {
-            return Arrays.asList(new User[]{new User(1, "Tommock"), new User(2, "Jerrymock")});
-        }
-
-        public int getInt1() {
-            return 1;
-        }
-
-        public boolean getBoolean1() {
-            return false;
-        }
-
-        public Boolean getBoolean2() {
-            return Boolean.FALSE;
-        }
-
-        public void sayHello() {
-            System.out.println("hello prety");
-        }
-    }
-
-    public static class User {
-        private int id;
-        private String name;
-
-        public User() {
-        }
-
-        public User(int id, String name) {
-            super();
-            this.id = id;
-            this.name = name;
-        }
-
-        public int getId() {
-            return id;
-        }
-
-        public void setId(int id) {
-            this.id = id;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-    }
-}
+/*
+ * 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.dubbo.rpc.cluster.support.wrapper;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcInvocation;
+import org.apache.dubbo.rpc.cluster.LoadBalance;
+import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
+import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
+import org.apache.dubbo.rpc.support.MockProtocol;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
+
+public class MockClusterInvokerTest {
+
+    List<Invoker<IHelloService>> invokers = new ArrayList<Invoker<IHelloService>>();
+
+    @BeforeEach
+    public void beforeMethod() {
+        invokers.clear();
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerInvoke_normal() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName());
+        url = url.addParameter(REFER_KEY,
+                URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                        + "&" + "mock=fail"));
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName()
+                + "?getSomething.mock=return aa");
+
+        Protocol protocol = new MockProtocol();
+        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
+        invokers.add(mInvoker1);
+
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("something", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerInvoke_failmock() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=fail:return null"))
+                .addParameter("invoke_return_error", "true");
+        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName())
+                .addParameter("mock","fail:return null")
+                .addParameter("getSomething.mock","return aa")
+                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()))
+                .addParameter("invoke_return_error", "true");
+
+        Protocol protocol = new MockProtocol();
+        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
+        Invoker<IHelloService> cluster = getClusterInvokerMock(url, mInvoker1);
+
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("aa", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+    }
+
+
+    /**
+     * Test if mock policy works fine: force-mock
+     */
+    @Test
+    public void testMockInvokerInvoke_forcemock() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=force:return null"));
+
+        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName())
+                .addParameter("mock","force:return null")
+                .addParameter("getSomething.mock","return aa")
+                .addParameter("getSomething3xx.mock","return xx")
+                .addParameter(REFER_KEY, URL.encode(PATH_KEY + "=" + IHelloService.class.getName()));
+
+        Protocol protocol = new MockProtocol();
+        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
+        Invoker<IHelloService> cluster = getClusterInvokerMock(url, mInvoker1);
+
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("aa", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+    }
+
+    @Test
+    public void testMockInvokerInvoke_forcemock_defaultreturn() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=force"));
+
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        URL mockUrl = URL.valueOf("mock://localhost/" + IHelloService.class.getName()
+                + "?getSomething.mock=return aa&getSomething3xx.mock=return xx&sayHello.mock=return ")
+                .addParameters(url.getParameters());
+
+        Protocol protocol = new MockProtocol();
+        Invoker<IHelloService> mInvoker1 = protocol.refer(IHelloService.class, mockUrl);
+        invokers.add(mInvoker1);
+
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_Fock_someMethods() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getSomething.mock=fail:return x"
+                                + "&" + "getSomething2.mock=force:return y"));
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("something", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("y", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething3");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("something3", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_Fock_WithOutDefault() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getSomething.mock=fail:return x"
+                                + "&" + "getSomething2.mock=fail:return y"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("y", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething3");
+        try {
+            ret = cluster.invoke(invocation);
+            Assertions.fail();
+        } catch (RpcException e) {
+
+        }
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_Fock_WithDefault() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock" + "=" + "fail:return null"
+                                + "&" + "getSomething.mock" + "=" + "fail:return x"
+                                + "&" + "getSomething2.mock" + "=" + "fail:return y"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("y", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething3");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertNull(ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_Fock_WithFailDefault() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=fail:return z"
+                                + "&" + "getSomething.mock=fail:return x"
+                                + "&" + "getSomething2.mock=force:return y"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("y", ret.getValue());
+
+        // If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething3");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("z", ret.getValue());
+
+        //If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("z", ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_Fock_WithForceDefault() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=force:return z"
+                                + "&" + "getSomething.mock=fail:return x"
+                                + "&" + "getSomething2.mock=force:return y"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+
+        //If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("y", ret.getValue());
+
+        //If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething3");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("z", ret.getValue());
+
+        //If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("z", ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_Fock_Default() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=fail:return x"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+
+        //If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething2");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+
+        //If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("sayHello");
+        ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_checkCompatible_return() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getSomething.mock=return x"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("x", ret.getValue());
+
+        //If no mock was configured, return null directly
+        invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething3");
+        try {
+            ret = cluster.invoke(invocation);
+            Assertions.fail("fail invoke");
+        } catch (RpcException e) {
+
+        }
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_checkCompatible_ImplMock() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=true"
+                                + "&" + "proxy=jdk"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("somethingmock", ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_checkCompatible_ImplMock2() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName() + "&" + "mock=fail"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("somethingmock", ret.getValue());
+    }
+
+    /**
+     * Test if mock policy works fine: fail-mock
+     */
+    @Test
+    public void testMockInvokerFromOverride_Invoke_checkCompatible_ImplMock3() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName() + "&" + "mock=force"));
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals("somethingmock", ret.getValue());
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_String() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter("getSomething.mock", "force:return 1688")
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getSomething.mock=force:return 1688"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getSomething");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertTrue(ret.getValue() instanceof String, "result type must be String but was : " + ret.getValue().getClass());
+        Assertions.assertEquals("1688", (String) ret.getValue());
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_int() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getInt1.mock=force:return 1688"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getInt1");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertTrue(ret.getValue() instanceof Integer, "result type must be integer but was : " + ret.getValue().getClass());
+        Assertions.assertEquals(new Integer(1688), (Integer) ret.getValue());
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_boolean() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getBoolean1.mock=force:return true"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getBoolean1");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertTrue(ret.getValue() instanceof Boolean, "result type must be Boolean but was : " + ret.getValue().getClass());
+        Assertions.assertTrue(Boolean.parseBoolean(ret.getValue().toString()));
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_Boolean() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getBoolean2.mock=force:return true"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getBoolean2");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertTrue(Boolean.parseBoolean(ret.getValue().toString()));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_ListString_empty() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getListString.mock=force:return empty"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getListString");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals(0, ((List<String>) ret.getValue()).size());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_ListString() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getListString.mock=force:return [\"hi\",\"hi2\"]"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getListString");
+        Result ret = cluster.invoke(invocation);
+        List<String> rl = (List<String>) ret.getValue();
+        Assertions.assertEquals(2, rl.size());
+        Assertions.assertEquals("hi", rl.get(0));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_ListPojo_empty() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getUsers.mock=force:return empty"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getUsers");
+        Result ret = cluster.invoke(invocation);
+        Assertions.assertEquals(0, ((List<User>) ret.getValue()).size());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_ListPojo() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getUsers.mock=force:return [{id:1, name:\"hi1\"}, {id:2, name:\"hi2\"}]"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getUsers");
+        Result ret = cluster.invoke(invocation);
+        List<User> rl = (List<User>) ret.getValue();
+        System.out.println(rl);
+        Assertions.assertEquals(2, rl.size());
+        Assertions.assertEquals("hi1", ((User) rl.get(0)).getName());
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_check_ListPojo_error() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getUsers.mock=force:return [{id:x, name:\"hi1\"}]"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getUsers");
+        try {
+            cluster.invoke(invocation);
+        } catch (RpcException e) {
+        }
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_force_throw() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getBoolean2.mock=force:throw "))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getBoolean2");
+        try {
+            cluster.invoke(invocation);
+            Assertions.fail();
+        } catch (RpcException e) {
+            Assertions.assertFalse(e.isBiz(), "not custem exception");
+        }
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_force_throwCustemException() throws Throwable {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getBoolean2.mock=force:throw org.apache.dubbo.rpc.cluster.support.wrapper.MyMockException"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getBoolean2");
+        try {
+            cluster.invoke(invocation).recreate();
+            Assertions.fail();
+        } catch (MyMockException e) {
+
+        }
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_force_throwCustemExceptionNotFound() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "getBoolean2.mock=force:throw java.lang.RuntimeException2"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getBoolean2");
+        try {
+            cluster.invoke(invocation);
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getCause() instanceof IllegalStateException);
+        }
+    }
+
+    @Test
+    public void testMockInvokerFromOverride_Invoke_mock_false() {
+        URL url = URL.valueOf("remote://1.2.3.4/" + IHelloService.class.getName())
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + IHelloService.class.getName()
+                                + "&" + "mock=false"))
+                .addParameter("invoke_return_error", "true");
+        Invoker<IHelloService> cluster = getClusterInvoker(url);
+        //Configured with mock
+        RpcInvocation invocation = new RpcInvocation();
+        invocation.setMethodName("getBoolean2");
+        try {
+            cluster.invoke(invocation);
+            Assertions.fail();
+        } catch (RpcException e) {
+            Assertions.assertTrue(e.isTimeout());
+        }
+    }
+
+    private Invoker<IHelloService> getClusterInvokerMock(URL url, Invoker<IHelloService> mockInvoker) {
+        // As `javassist` have a strict restriction of argument types, request will fail if Invocation do not contains complete parameter type information
+        final URL durl = url.addParameter("proxy", "jdk");
+        invokers.clear();
+        ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension("jdk");
+        Invoker<IHelloService> invoker1 = proxy.getInvoker(new HelloService(), IHelloService.class, durl);
+        invokers.add(invoker1);
+        if (mockInvoker != null) {
+            invokers.add(mockInvoker);
+        }
+
+        StaticDirectory<IHelloService> dic = new StaticDirectory<IHelloService>(durl, invokers, null);
+        dic.buildRouterChain();
+        AbstractClusterInvoker<IHelloService> cluster = new AbstractClusterInvoker(dic) {
+            @Override
+            protected Result doInvoke(Invocation invocation, List invokers, LoadBalance loadbalance)
+                    throws RpcException {
+                if (durl.getParameter("invoke_return_error", false)) {
+                    throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "test rpc exception");
+                } else {
+                    return ((Invoker<?>) invokers.get(0)).invoke(invocation);
+                }
+            }
+        };
+        return new MockClusterInvoker<IHelloService>(dic, cluster);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private Invoker<IHelloService> getClusterInvoker(URL url) {
+        return getClusterInvokerMock(url, null);
+    }
+
+    public interface IHelloService {
+        String getSomething();
+
+        String getSomething2();
+
+        String getSomething3();
+
+        String getSomething4();
+
+        int getInt1();
+
+        boolean getBoolean1();
+
+        Boolean getBoolean2();
+
+        List<String> getListString();
+
+        List<User> getUsers();
+
+        void sayHello();
+    }
+
+    public static class HelloService implements IHelloService {
+        public String getSomething() {
+            return "something";
+        }
+
+        public String getSomething2() {
+            return "something2";
+        }
+
+        public String getSomething3() {
+            return "something3";
+        }
+
+        public String getSomething4() {
+            throw new RpcException("getSomething4|RpcException");
+        }
+
+        public int getInt1() {
+            return 1;
+        }
+
+        public boolean getBoolean1() {
+            return false;
+        }
+
+        public Boolean getBoolean2() {
+            return Boolean.FALSE;
+        }
+
+        public List<String> getListString() {
+            return Arrays.asList(new String[]{"Tom", "Jerry"});
+        }
+
+        public List<User> getUsers() {
+            return Arrays.asList(new User[]{new User(1, "Tom"), new User(2, "Jerry")});
+        }
+
+        public void sayHello() {
+            System.out.println("hello prety");
+        }
+    }
+
+    public static class IHelloServiceMock implements IHelloService {
+        public IHelloServiceMock() {
+
+        }
+
+        public String getSomething() {
+            return "somethingmock";
+        }
+
+        public String getSomething2() {
+            return "something2mock";
+        }
+
+        public String getSomething3() {
+            return "something3mock";
+        }
+
+        public String getSomething4() {
+            return "something4mock";
+        }
+
+        public List<String> getListString() {
+            return Arrays.asList(new String[]{"Tommock", "Jerrymock"});
+        }
+
+        public List<User> getUsers() {
+            return Arrays.asList(new User[]{new User(1, "Tommock"), new User(2, "Jerrymock")});
+        }
+
+        public int getInt1() {
+            return 1;
+        }
+
+        public boolean getBoolean1() {
+            return false;
+        }
+
+        public Boolean getBoolean2() {
+            return Boolean.FALSE;
+        }
+
+        public void sayHello() {
+            System.out.println("hello prety");
+        }
+    }
+
+    public static class User {
+        private int id;
+        private String name;
+
+        public User() {
+        }
+
+        public User(int id, String name) {
+            super();
+            this.id = id;
+            this.name = name;
+        }
+
+        public int getId() {
+            return id;
+        }
+
+        public void setId(int id) {
+            this.id = id;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+    }
+}
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java
index 6a46312..798067c 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockProviderRpcExceptionTest.java
@@ -36,6 +36,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
 import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
 
@@ -55,7 +56,10 @@ public class MockProviderRpcExceptionTest {
     public void testMockInvokerProviderRpcException() {
         URL url = URL.valueOf("remote://1.2.3.4/" + IHelloRpcService.class.getName());
         url = url.addParameter(MOCK_KEY, "true").addParameter("invoke_return_error", "true")
-                .addParameter(REFER_KEY, "path%3dorg.apache.dubbo.rpc.cluster.support.wrapper.MockProviderRpcExceptionTest%24IHelloRpcService");
+                .addParameter(REFER_KEY,
+                        URL.encode(PATH_KEY + "=" + MockProviderRpcExceptionTest.IHelloRpcService.class.getName()
+                                + "&" + "mock=true"
+                                + "&" + "proxy=jdk"));
         Invoker<IHelloRpcService> cluster = getClusterInvoker(url);
         RpcInvocation invocation = new RpcInvocation();
         invocation.setMethodName("getSomething4");
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 2ac80b1..d80b9ba 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -83,6 +83,7 @@ import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
 import static org.apache.dubbo.registry.Constants.CONSUMER_PROTOCOL;
 import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
 import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
 import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
 
 /**
@@ -341,7 +342,9 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
                         if (UrlUtils.isRegistry(url)) {
                             urls.add(url.putAttribute(REFER_KEY, map));
                         } else {
-                            urls.add(ClusterUtils.mergeUrl(url, map));
+                            URL peerURL = ClusterUtils.mergeUrl(url, map);
+                            peerURL = peerURL.putAttribute(PEER_KEY, true);
+                            urls.add(peerURL);
                         }
                     }
                 }
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
index e329f23..eccf786 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.config.bootstrap;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.wrapper.CompositeDynamicConfiguration;
 import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.utils.ConfigUtils;
 import org.apache.dubbo.config.AbstractInterfaceConfigTest;
@@ -106,16 +107,19 @@ public class DubboBootstrapTest {
         // FIXME: now we need to check first, then load
         interfaceConfig.setApplication(new ApplicationConfig("testLoadRegistries"));
         interfaceConfig.checkRegistry();
+        ApplicationModel.getEnvironment().setDynamicConfiguration(new CompositeDynamicConfiguration());
         List<URL> urls = ConfigValidationUtils.loadRegistries(interfaceConfig, true);
-        Assertions.assertEquals(1, urls.size());
-        URL url = urls.get(0);
-        Assertions.assertEquals("registry", url.getProtocol());
-        Assertions.assertEquals("addr1:9090", url.getAddress());
-        Assertions.assertEquals(RegistryService.class.getName(), url.getPath());
-        Assertions.assertTrue(url.getParameters().containsKey("timestamp"));
-        Assertions.assertTrue(url.getParameters().containsKey("pid"));
-        Assertions.assertTrue(url.getParameters().containsKey("registry"));
-        Assertions.assertTrue(url.getParameters().containsKey("dubbo"));
+        Assertions.assertEquals(2, urls.size());
+        Assertions.assertEquals("service-discovery-registry", urls.get(0).getProtocol());
+        Assertions.assertEquals("registry", urls.get(1).getProtocol());
+        for (URL url : urls) {
+            Assertions.assertEquals("addr1:9090", url.getAddress());
+            Assertions.assertEquals(RegistryService.class.getName(), url.getPath());
+            Assertions.assertTrue(url.getParameters().containsKey("timestamp"));
+            Assertions.assertTrue(url.getParameters().containsKey("pid"));
+            Assertions.assertTrue(url.getParameters().containsKey("registry"));
+            Assertions.assertTrue(url.getParameters().containsKey("dubbo"));
+        }
     }
 
 
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
index c380963..fee5470 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
@@ -35,7 +35,7 @@ import java.util.Arrays;
 
 import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
 
-
+@Disabled
 public class InvokerSideConfigUrlTest extends UrlTestBase {
     private static final Logger log = LoggerFactory.getLogger(InvokerSideConfigUrlTest.class);
 
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
index 906eef7..ac09e96 100755
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
@@ -95,6 +95,6 @@ public class MethodDefinition implements Serializable {
 
     @Override
     public int hashCode() {
-        return Objects.hash(getName(), getReturnType(), getParameterTypes());
+        return Objects.hash(getName(), getReturnType(), Arrays.toString(getParameterTypes()));
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/resources/META-INF/dubbo/jax-rs-service-rest-metadata.json b/dubbo-metadata/dubbo-metadata-api/src/test/resources/META-INF/dubbo/jax-rs-service-rest-metadata.json
index 3830369..d5779f6 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/resources/META-INF/dubbo/jax-rs-service-rest-metadata.json
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/resources/META-INF/dubbo/jax-rs-service-rest-metadata.json
@@ -246,18 +246,8 @@
             {
               "type": "java.util.Map\u003cjava.lang.String,java.lang.Object\u003e",
               "items": [
-                {
-                  "type": "java.lang.String",
-                  "items": [],
-                  "enum": [],
-                  "properties": {}
-                },
-                {
-                  "type": "java.lang.Object",
-                  "items": [],
-                  "enum": [],
-                  "properties": {}
-                }
+                "java.lang.String",
+                "java.lang.Object"
               ],
               "enum": [],
               "properties": {}
@@ -306,24 +296,9 @@
               "items": [],
               "enum": [],
               "properties": {
-                "name": {
-                  "type": "java.lang.String",
-                  "items": [],
-                  "enum": [],
-                  "properties": {}
-                },
-                "id": {
-                  "type": "java.lang.Long",
-                  "items": [],
-                  "enum": [],
-                  "properties": {}
-                },
-                "age": {
-                  "type": "java.lang.Integer",
-                  "items": [],
-                  "enum": [],
-                  "properties": {}
-                }
+                "name": "java.lang.String",
+                "id": "java.lang.Long",
+                "age": "java.lang.Integer"
               }
             }
           ]
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java
index 6aa43fd..1e2bee8 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineApp.java
@@ -20,8 +20,13 @@ package org.apache.dubbo.qos.command.impl;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.UrlUtils;
+import org.apache.dubbo.qos.command.annotation.Cmd;
 import org.apache.dubbo.rpc.model.ProviderModel;
 
+@Cmd(name = "onlineApp", summary = "online app addresses", example = {
+        "onlineApp",
+        "onlineApp xx.xx.xxx.service"
+})
 public class OnlineApp extends BaseOnline {
     private static final Logger logger = LoggerFactory.getLogger(OnlineApp.class);
 
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java
index e10f324..e7b100d 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/OnlineInterface.java
@@ -17,8 +17,13 @@
 package org.apache.dubbo.qos.command.impl;
 
 import org.apache.dubbo.common.utils.UrlUtils;
+import org.apache.dubbo.qos.command.annotation.Cmd;
 import org.apache.dubbo.rpc.model.ProviderModel;
 
+@Cmd(name = "onlineInterface", summary = "online dubbo", example = {
+        "onlineInterface dubbo",
+        "onlineInterface xx.xx.xxx.service"
+})
 public class OnlineInterface extends BaseOnline {
     @Override
     protected void doExport(ProviderModel.RegisterStatedURL statedURL) {
diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java
index a1e03a2..dad505a 100644
--- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java
+++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java
@@ -21,7 +21,11 @@ import org.apache.dubbo.qos.command.impl.Help;
 import org.apache.dubbo.qos.command.impl.Live;
 import org.apache.dubbo.qos.command.impl.Ls;
 import org.apache.dubbo.qos.command.impl.Offline;
+import org.apache.dubbo.qos.command.impl.OfflineApp;
+import org.apache.dubbo.qos.command.impl.OfflineInterface;
 import org.apache.dubbo.qos.command.impl.Online;
+import org.apache.dubbo.qos.command.impl.OnlineApp;
+import org.apache.dubbo.qos.command.impl.OnlineInterface;
 import org.apache.dubbo.qos.command.impl.PublishMetadata;
 import org.apache.dubbo.qos.command.impl.Quit;
 import org.apache.dubbo.qos.command.impl.Ready;
@@ -30,6 +34,7 @@ import org.apache.dubbo.qos.command.impl.Version;
 
 import org.junit.jupiter.api.Test;
 
+import java.util.LinkedList;
 import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -49,9 +54,25 @@ public class CommandHelperTest {
     @Test
     public void testGetAllCommandClass() throws Exception {
         List<Class<?>> classes = CommandHelper.getAllCommandClass();
-        assertThat(classes,
-                containsInAnyOrder(GreetingCommand.class, Help.class, Ls.class, Offline.class, Online.class, Quit.class,
-                        Live.class, Ready.class, Startup.class, Version.class, PublishMetadata.class));
+
+        // update this list when introduce a new command
+        List<Class<?>> expectedClasses = new LinkedList<>();
+        expectedClasses.add(GreetingCommand.class);
+        expectedClasses.add(Help.class);
+        expectedClasses.add(Live.class);
+        expectedClasses.add(Ls.class);
+        expectedClasses.add(Offline.class);
+        expectedClasses.add(OfflineApp.class);
+        expectedClasses.add(OfflineInterface.class);
+        expectedClasses.add(Online.class);
+        expectedClasses.add(OnlineApp.class);
+        expectedClasses.add(OnlineInterface.class);
+        expectedClasses.add(PublishMetadata.class);
+        expectedClasses.add(Quit.class);
+        expectedClasses.add(Ready.class);
+        expectedClasses.add(Startup.class);
+        expectedClasses.add(Version.class);
+        assertThat(classes, containsInAnyOrder(expectedClasses.toArray(new Class<?>[0])));
     }
 
     @Test
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/RegistryFactoryWrapperTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/RegistryFactoryWrapperTest.java
index d791391..fa5627b 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/RegistryFactoryWrapperTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/RegistryFactoryWrapperTest.java
@@ -37,20 +37,20 @@ public class RegistryFactoryWrapperTest {
         URL url = URL.valueOf("dubbo://localhost:8081/simple.service");
         registry.register(url);
 
-        Mockito.verify(listener1, Mockito.times(1)).onRegister(url, null);
-        Mockito.verify(listener2, Mockito.times(1)).onRegister(url, null);
+        Mockito.verify(listener1, Mockito.times(1)).onRegister(url, SimpleRegistryFactory.registry);
+        Mockito.verify(listener2, Mockito.times(1)).onRegister(url, SimpleRegistryFactory.registry);
 
         registry.unregister(url);
-        Mockito.verify(listener1, Mockito.times(1)).onUnregister(url, null);
-        Mockito.verify(listener2, Mockito.times(1)).onUnregister(url, null);
+        Mockito.verify(listener1, Mockito.times(1)).onUnregister(url, SimpleRegistryFactory.registry);
+        Mockito.verify(listener2, Mockito.times(1)).onUnregister(url, SimpleRegistryFactory.registry);
 
         registry.subscribe(url, Mockito.mock(NotifyListener.class));
-        Mockito.verify(listener1, Mockito.times(1)).onSubscribe(url, null);
-        Mockito.verify(listener2, Mockito.times(1)).onSubscribe(url, null);
+        Mockito.verify(listener1, Mockito.times(1)).onSubscribe(url, SimpleRegistryFactory.registry);
+        Mockito.verify(listener2, Mockito.times(1)).onSubscribe(url, SimpleRegistryFactory.registry);
 
         registry.unsubscribe(url, Mockito.mock(NotifyListener.class));
-        Mockito.verify(listener1, Mockito.times(1)).onUnsubscribe(url, null);
-        Mockito.verify(listener2, Mockito.times(1)).onUnsubscribe(url, null);
+        Mockito.verify(listener1, Mockito.times(1)).onUnsubscribe(url, SimpleRegistryFactory.registry);
+        Mockito.verify(listener2, Mockito.times(1)).onUnsubscribe(url, SimpleRegistryFactory.registry);
     }
 
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/SimpleRegistryFactory.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/SimpleRegistryFactory.java
index b39a37a..055d952 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/SimpleRegistryFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/SimpleRegistryFactory.java
@@ -21,8 +21,9 @@ import org.apache.dubbo.common.URL;
 import org.mockito.Mockito;
 
 public class SimpleRegistryFactory implements RegistryFactory {
+    static Registry registry = Mockito.mock(Registry.class);
     @Override
     public Registry getRegistry(URL url) {
-        return Mockito.mock(Registry.class);
+        return registry;
     }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java
index c93de88..0c208af 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java
@@ -38,27 +38,30 @@ public class ServiceInstanceMetadataUtilsTest {
     private static URL url = URL.valueOf("dubbo://192.168.0.102:20880/org.apache.dubbo.metadata.MetadataService?&anyhost=true&application=spring-cloud-alibaba-dubbo-provider&bind.ip=192.168.0.102&bind.port=20880&default.deprecated=false&default.dynamic=false&default.register=true&deprecated=false&dubbo=2.0.2&dynamic=false&generic=false&group=spring-cloud-alibaba-dubbo-provider&interface=org.apache.dubbo.metadata.MetadataService&methods=getAllServiceKeys,getServiceRestMetadata,getExported [...]
     private static URL url2 = URL.valueOf("rest://192.168.0.102:20880/org.apache.dubbo.metadata.MetadataService?&anyhost=true&application=spring-cloud-alibaba-dubbo-provider&bind.ip=192.168.0.102&bind.port=20880&default.deprecated=false&default.dynamic=false&default.register=true&deprecated=false&dubbo=2.0.2&dynamic=false&generic=false&group=spring-cloud-alibaba-dubbo-provider&interface=org.apache.dubbo.metadata.MetadataService&methods=getAllServiceKeys,getServiceRestMetadata,getExported [...]
 
-    private static final String VALUE = "{\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"2.7.1\",\"port\":\"20880\"}";
+    private static final String VALUE_URL = "{\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"2.7.1\",\"port\":\"20880\",\"protocol\":\"dubbo\"}";
+    private static final String VALUE_URL2 = "{\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"2.7.1\",\"port\":\"20880\",\"protocol\":\"rest\"}";
+
     @Test
     public void testMetadataServiceURLParameters() {
 
         List<URL> urls = Arrays.asList(url, url2);
 
-        String parameter = ServiceInstanceMetadataUtils.getMetadataServiceParameter(url);
+        urls.forEach(url -> {
+            String parameter = ServiceInstanceMetadataUtils.getMetadataServiceParameter(url);
 
-        JSONObject jsonObject = JSON.parseObject(parameter);
+            JSONObject jsonObject = JSON.parseObject(parameter);
 
-        urls.forEach(url -> {
-            JSONObject map = jsonObject.getJSONObject(url.getProtocol());
             for (Map.Entry<String, String> param : url.getParameters().entrySet()) {
-                String value = map.getString(param.getKey());
+                String value = jsonObject.getString(param.getKey());
                 if (value != null) {
                     assertEquals(param.getValue(), value);
                 }
             }
+
         });
 
-        assertEquals(VALUE, parameter);
+        assertEquals(ServiceInstanceMetadataUtils.getMetadataServiceParameter(url), VALUE_URL);
+        assertEquals(ServiceInstanceMetadataUtils.getMetadataServiceParameter(url2), VALUE_URL2);
     }
 
     @Test
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
index 6788b0c..13d43b2 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
@@ -20,9 +20,15 @@ package org.apache.dubbo.rpc.protocol.dubbo;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
 import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcInvocation;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.support.FailfastCluster;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.protocol.dubbo.support.DemoService;
 import org.apache.dubbo.rpc.protocol.dubbo.support.DemoServiceImpl;
@@ -37,8 +43,11 @@ import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
 
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -224,7 +233,19 @@ public class DubboProtocolTest {
         URL url = URL.valueOf("dubbo://127.0.0.1:" + port + "/" + DemoService.class.getName() + "?codec=exchange").addParameter("timeout",
                 3000L).addParameter("application", "consumer");
         protocol.export(proxy.getInvoker(service, DemoService.class, url));
-        service = proxy.getProxy(protocol.refer(DemoService.class, url));
-        assertEquals(service.getRemoteApplicationName(), "consumer");
+        Invoker<DemoService> invoker = protocol.refer(DemoService.class, url);
+
+        Invocation invocation = new RpcInvocation("getRemoteApplicationName", DemoService.class.getName(), "", new Class<?>[0], new Object[0]);
+        List<Invoker<DemoService>> invokers = Arrays.asList(invoker);
+        Directory<DemoService> dic = Mockito.mock(Directory.class);
+        Mockito.when(dic.list(invocation)).thenReturn(invokers);
+        Mockito.when(dic.getUrl()).thenReturn(url);
+        Mockito.when(dic.getConsumerUrl()).thenReturn(url);
+
+        FailfastCluster cluster = new FailfastCluster();
+        Invoker<DemoService> clusterInvoker = cluster.join(dic);
+        Result result = clusterInvoker.invoke(invocation);
+        Thread.sleep(10);
+        assertEquals(result.getValue(), "consumer");
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-grpc/pom.xml b/dubbo-rpc/dubbo-rpc-grpc/pom.xml
index dc5cdd0..ec84397 100644
--- a/dubbo-rpc/dubbo-rpc-grpc/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-grpc/pom.xml
@@ -40,6 +40,11 @@
             <version>${project.parent.version}</version>
         </dependency>
         <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-cluster</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
             <groupId>io.grpc</groupId>
             <artifactId>grpc-netty</artifactId>
         </dependency>
diff --git a/dubbo-rpc/dubbo-rpc-injvm/pom.xml b/dubbo-rpc/dubbo-rpc-injvm/pom.xml
index b5562bd1..b9f8661 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-injvm/pom.xml
@@ -35,5 +35,10 @@
             <artifactId>dubbo-rpc-api</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-cluster</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java
index 821015f..8ecfaee 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java
+++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoService.java
@@ -38,7 +38,4 @@ public interface DemoService {
     int stringLength(String str);
 
     Type enumlength(Type... types);
-
-
-    String getRemoteApplicationName();
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java
index a6e3f2c..ee7c368 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java
+++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/DemoServiceImpl.java
@@ -69,10 +69,4 @@ public class DemoServiceImpl implements DemoService {
     public int stringLength(String str) {
         return str.length();
     }
-
-
-    @Override
-    public String getRemoteApplicationName() {
-        return RpcContext.getContext().getRemoteApplicationName();
-    }
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
index ea6de85..51485fd 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
+++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
@@ -34,11 +34,11 @@ import java.util.List;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
 import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
 import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
 import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
-import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
-import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -110,17 +110,4 @@ public class InjvmProtocolTest {
 
     }
 
-
-    @Test
-    public void testRemoteApplicationName() throws Exception {
-        DemoService service = new DemoServiceImpl();
-        URL url = URL.valueOf("injvm://127.0.0.1/TestService").addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer");
-        Invoker<?> invoker = proxy.getInvoker(service, DemoService.class, url);
-        assertTrue(invoker.isAvailable());
-        Exporter<?> exporter = protocol.export(invoker);
-        exporters.add(exporter);
-        service = proxy.getProxy(protocol.refer(DemoService.class, url));
-        assertEquals(service.getRemoteApplicationName(), "consumer");
-    }
-
 }
diff --git a/dubbo-rpc/dubbo-rpc-rest/pom.xml b/dubbo-rpc/dubbo-rpc-rest/pom.xml
index 88c53af..c8fc01a 100644
--- a/dubbo-rpc/dubbo-rpc-rest/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-rest/pom.xml
@@ -40,6 +40,11 @@
             <artifactId>dubbo-remoting-http</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-cluster</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>org.jboss.resteasy</groupId>
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
index 78a132a..bb9e4a8 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
@@ -38,8 +38,4 @@ public interface DemoService {
     @Path("/say")
     @Consumes({MediaType.TEXT_PLAIN})
     String sayHello(String name);
-
-    @GET
-    @Path("/getRemoteApplicationName")
-    String getRemoteApplicationName();
 }
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
index f7d3921..c9fe82f 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
@@ -49,9 +49,4 @@ public class DemoServiceImpl implements DemoService {
     public static Map<String, Object> getAttachments() {
         return context;
     }
-
-    @Override
-    public String getRemoteApplicationName() {
-        return RpcContext.getContext().getRemoteApplicationName();
-    }
 }
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java
index c6eaba9..9b207a7 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java
@@ -252,23 +252,6 @@ public class RestProtocolTest {
         assertThat(protocol.getDefaultPort(), is(80));
     }
 
-    @Test
-    public void testRemoteApplicationName() {
-        URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/rest/say?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.DemoService").addParameter("application", "consumer");
-        DemoServiceImpl server = new DemoServiceImpl();
-
-        this.registerProvider(url, server, DemoService.class);
-
-        Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(server, DemoService.class, url));
-        Invoker<DemoService> invoker = protocol.refer(DemoService.class, url);
-
-        DemoService client = proxy.getProxy(invoker);
-        String result = client.getRemoteApplicationName();
-        Assertions.assertEquals("consumer", result);
-        invoker.destroy();
-        exporter.unexport();
-    }
-
     private void registerProvider(URL url, Object impl, Class<?> interfaceClass) {
         ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
         repository.registerProvider(
diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleProtocol.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleProtocol.java
index a9cb8ea..5b8eee4 100644
--- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleProtocol.java
@@ -24,7 +24,6 @@ import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
 import org.apache.dubbo.common.utils.ExecutorUtil;
 import org.apache.dubbo.remoting.RemotingException;
 import org.apache.dubbo.remoting.exchange.PortUnificationExchanger;
-import org.apache.dubbo.remoting.transport.AbstractClient;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/proto/triple_wrapper.proto b/dubbo-rpc/dubbo-rpc-triple/src/main/proto/triple_wrapper.proto
index a2d8703..5f12ae8 100644
--- a/dubbo-rpc/dubbo-rpc-triple/src/main/proto/triple_wrapper.proto
+++ b/dubbo-rpc/dubbo-rpc-triple/src/main/proto/triple_wrapper.proto
@@ -1,3 +1,17 @@
+// 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.
 syntax = "proto3";
 
 package org.apache.dubbo.triple;