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 2018/11/01 07:20:12 UTC
[incubator-dubbo] 03/06: Move UT in config-api to bootstrap
temporarily, to solve the unreasonable dependency problem between modules.
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch dev-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git
commit a45bfd4f3a92af11f8a13aee6439d5a32ae5c5fc
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Nov 1 10:50:32 2018 +0800
Move UT in config-api to bootstrap temporarily, to solve the unreasonable dependency problem between modules.
---
.../apache/dubbo/config/AbstractConfigTest.java | 515 +++++++++++++++++++++
.../dubbo/config/AbstractInterfaceConfigTest.java | 407 ++++++++++++++++
.../dubbo/config/AbstractMethodConfigTest.java | 119 +++++
.../dubbo/config/AbstractReferenceConfigTest.java | 157 +++++++
.../dubbo/config/AbstractServiceConfigTest.java | 181 ++++++++
.../apache/dubbo/config/ApplicationConfigTest.java | 177 +++++++
.../apache/dubbo/config/ArgumentConfigTest.java | 63 +++
.../apache/dubbo/config/ConsumerConfigTest.java | 81 ++++
.../apache/dubbo/config/GenericServiceTest.java | 314 +++++++++++++
.../org/apache/dubbo/config/MethodConfigTest.java | 182 ++++++++
.../org/apache/dubbo/config/ModuleConfigTest.java | 110 +++++
.../org/apache/dubbo/config/MonitorConfigTest.java | 107 +++++
.../apache/dubbo/config/ProtocolConfigTest.java | 217 +++++++++
.../apache/dubbo/config/ProviderConfigTest.java | 219 +++++++++
.../apache/dubbo/config/ReferenceConfigTest.java | 108 +++++
.../apache/dubbo/config/RegistryConfigTest.java | 178 +++++++
.../org/apache/dubbo/config/ServiceConfigTest.java | 205 ++++++++
.../test/java/org/apache/dubbo/config/api/Box.java | 23 +
.../org/apache/dubbo/config/api/DemoException.java | 42 ++
.../org/apache/dubbo/config/api/DemoService.java | 37 ++
.../java/org/apache/dubbo/config/api/Greeting.java | 24 +
.../java/org/apache/dubbo/config/api/User.java | 65 +++
.../apache/dubbo/config/cache/CacheService.java | 26 ++
.../dubbo/config/cache/CacheServiceImpl.java | 32 ++
.../org/apache/dubbo/config/cache/CacheTest.java | 118 +++++
.../config/consumer/DemoActionByAnnotation.java | 34 ++
.../dubbo/config/consumer/DemoActionBySetter.java | 36 ++
.../dubbo/config/consumer/DemoInterceptor.java | 31 ++
.../DelegateProviderMetaDataInvokerTest.java | 59 +++
.../apache/dubbo/config/mock/GreetingLocal1.java | 21 +
.../apache/dubbo/config/mock/GreetingLocal2.java | 26 ++
.../apache/dubbo/config/mock/GreetingLocal3.java | 32 ++
.../apache/dubbo/config/mock/GreetingMock1.java | 20 +
.../apache/dubbo/config/mock/GreetingMock2.java | 29 ++
.../org/apache/dubbo/config/mock/MockCluster.java | 29 ++
.../org/apache/dubbo/config/mock/MockCodec.java | 37 ++
.../apache/dubbo/config/mock/MockDispatcher.java | 29 ++
.../apache/dubbo/config/mock/MockExchanger.java | 37 ++
.../dubbo/config/mock/MockExporterListener.java | 34 ++
.../org/apache/dubbo/config/mock/MockFilter.java | 30 ++
.../dubbo/config/mock/MockInvokerListener.java | 33 ++
.../apache/dubbo/config/mock/MockLoadBalance.java | 32 ++
.../org/apache/dubbo/config/mock/MockProtocol.java | 86 ++++
.../apache/dubbo/config/mock/MockProtocol2.java | 48 ++
.../apache/dubbo/config/mock/MockProxyFactory.java | 39 ++
.../org/apache/dubbo/config/mock/MockRegistry.java | 108 +++++
.../dubbo/config/mock/MockRegistryFactory.java | 37 ++
.../dubbo/config/mock/MockRegistryFactory2.java | 31 ++
.../dubbo/config/mock/MockStatusChecker.java | 28 ++
.../dubbo/config/mock/MockTelnetHandler.java | 29 ++
.../apache/dubbo/config/mock/MockThreadPool.java | 30 ++
.../apache/dubbo/config/mock/MockTransporter.java | 41 ++
.../apache/dubbo/config/mock/TestProxyFactory.java | 33 ++
.../config/provider/impl/DemoServiceImpl.java | 51 ++
.../config/url/ExporterSideConfigUrlTest.java | 98 ++++
.../dubbo/config/url/InvokerSideConfigUrlTest.java | 227 +++++++++
.../dubbo/config/url/RpcConfigGetSetProxy.java | 166 +++++++
.../org/apache/dubbo/config/url/UrlTestBase.java | 211 +++++++++
.../dubbo/config/utils/MockReferenceConfig.java | 53 +++
.../config/utils/ReferenceConfigCacheTest.java | 114 +++++
.../config/validation/ValidationParameter.java | 106 +++++
.../dubbo/config/validation/ValidationService.java | 70 +++
.../config/validation/ValidationServiceImpl.java | 37 ++
.../dubbo/config/validation/ValidationTest.java | 301 ++++++++++++
.../org.apache.dubbo.common.status.StatusChecker | 18 +
.../org.apache.dubbo.common.threadpool.ThreadPool | 18 +
.../org.apache.dubbo.registry.RegistryFactory | 2 +
.../services/org.apache.dubbo.remoting.Codec | 18 +
.../services/org.apache.dubbo.remoting.Dispatcher | 18 +
.../services/org.apache.dubbo.remoting.Transporter | 18 +
.../org.apache.dubbo.remoting.exchange.Exchanger | 18 +
.../org.apache.dubbo.remoting.telnet.TelnetHandler | 18 +
.../services/org.apache.dubbo.rpc.ExporterListener | 18 +
.../META-INF/services/org.apache.dubbo.rpc.Filter | 1 +
.../services/org.apache.dubbo.rpc.InvokerListener | 1 +
.../services/org.apache.dubbo.rpc.Protocol | 2 +
.../services/org.apache.dubbo.rpc.ProxyFactory | 2 +
.../services/org.apache.dubbo.rpc.cluster.Cluster | 1 +
.../org.apache.dubbo.rpc.cluster.LoadBalance | 1 +
dubbo-bootstrap/src/main/test/resources/log4j.xml | 28 ++
80 files changed, 6382 insertions(+)
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractConfigTest.java
new file mode 100644
index 0000000..a9300ec
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractConfigTest.java
@@ -0,0 +1,515 @@
+/*
+ * 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.config;
+
+import junit.framework.TestCase;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.support.Parameter;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertThat;
+
+public class AbstractConfigTest {
+
+ //FIXME
+ /*@Test
+ public void testAppendProperties1() throws Exception {
+ try {
+ System.setProperty("dubbo.properties.i", "1");
+ System.setProperty("dubbo.properties.c", "c");
+ System.setProperty("dubbo.properties.b", "2");
+ System.setProperty("dubbo.properties.d", "3");
+ System.setProperty("dubbo.properties.f", "4");
+ System.setProperty("dubbo.properties.l", "5");
+ System.setProperty("dubbo.properties.s", "6");
+ System.setProperty("dubbo.properties.str", "dubbo");
+ System.setProperty("dubbo.properties.bool", "true");
+ PropertiesConfig config = new PropertiesConfig();
+ AbstractConfig.appendProperties(config);
+ TestCase.assertEquals(1, config.getI());
+ TestCase.assertEquals('c', config.getC());
+ TestCase.assertEquals((byte) 0x02, config.getB());
+ TestCase.assertEquals(3d, config.getD());
+ TestCase.assertEquals(4f, config.getF());
+ TestCase.assertEquals(5L, config.getL());
+ TestCase.assertEquals(6, config.getS());
+ TestCase.assertEquals("dubbo", config.getStr());
+ TestCase.assertTrue(config.isBool());
+ } finally {
+ System.clearProperty("dubbo.properties.i");
+ System.clearProperty("dubbo.properties.c");
+ System.clearProperty("dubbo.properties.b");
+ System.clearProperty("dubbo.properties.d");
+ System.clearProperty("dubbo.properties.f");
+ System.clearProperty("dubbo.properties.l");
+ System.clearProperty("dubbo.properties.s");
+ System.clearProperty("dubbo.properties.str");
+ System.clearProperty("dubbo.properties.bool");
+ }
+ }
+
+ @Test
+ public void testAppendProperties2() throws Exception {
+ try {
+ System.setProperty("dubbo.properties.two.i", "2");
+ PropertiesConfig config = new PropertiesConfig("two");
+ AbstractConfig.appendProperties(config);
+ TestCase.assertEquals(2, config.getI());
+ } finally {
+ System.clearProperty("dubbo.properties.two.i");
+ }
+ }
+
+ @Test
+ public void testAppendProperties3() throws Exception {
+ try {
+ Properties p = new Properties();
+ p.put("dubbo.properties.str", "dubbo");
+ ConfigUtils.setProperties(p);
+ PropertiesConfig config = new PropertiesConfig();
+ AbstractConfig.appendProperties(config);
+ TestCase.assertEquals("dubbo", config.getStr());
+ } finally {
+ System.clearProperty(Constants.DUBBO_PROPERTIES_KEY);
+ ConfigUtils.setProperties(null);
+ }
+ }*/
+
+ @Test
+ public void testAppendParameters1() throws Exception {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("default.num", "one");
+ parameters.put("num", "ONE");
+ AbstractConfig.appendParameters(parameters, new ParameterConfig(1, "hello/world", 30, "password"), "prefix");
+ TestCase.assertEquals("one", parameters.get("prefix.key.1"));
+ TestCase.assertEquals("two", parameters.get("prefix.key.2"));
+ TestCase.assertEquals("ONE,one,1", parameters.get("prefix.num"));
+ TestCase.assertEquals("hello%2Fworld", parameters.get("prefix.naming"));
+ TestCase.assertEquals("30", parameters.get("prefix.age"));
+ TestCase.assertFalse(parameters.containsKey("prefix.key-2"));
+ TestCase.assertFalse(parameters.containsKey("prefix.secret"));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAppendParameters2() throws Exception {
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractConfig.appendParameters(parameters, new ParameterConfig());
+ }
+
+ @Test
+ public void testAppendParameters3() throws Exception {
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractConfig.appendParameters(parameters, null);
+ TestCase.assertTrue(parameters.isEmpty());
+ }
+
+ @Test
+ public void testAppendParameters4() throws Exception {
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractConfig.appendParameters(parameters, new ParameterConfig(1, "hello/world", 30, "password"));
+ TestCase.assertEquals("one", parameters.get("key.1"));
+ TestCase.assertEquals("two", parameters.get("key.2"));
+ TestCase.assertEquals("1", parameters.get("num"));
+ TestCase.assertEquals("hello%2Fworld", parameters.get("naming"));
+ TestCase.assertEquals("30", parameters.get("age"));
+ }
+
+ @Test
+ public void testAppendAttributes1() throws Exception {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ AbstractConfig.appendAttributes(parameters, new AttributeConfig('l', true, (byte) 0x01), "prefix");
+ TestCase.assertEquals('l', parameters.get("prefix.let"));
+ TestCase.assertEquals(true, parameters.get("prefix.activate"));
+ TestCase.assertFalse(parameters.containsKey("prefix.flag"));
+ }
+
+ @Test
+ public void testAppendAttributes2() throws Exception {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ AbstractConfig.appendAttributes(parameters, new AttributeConfig('l', true, (byte) 0x01));
+ TestCase.assertEquals('l', parameters.get("let"));
+ TestCase.assertEquals(true, parameters.get("activate"));
+ TestCase.assertFalse(parameters.containsKey("flag"));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkExtension() throws Exception {
+ AbstractConfig.checkExtension(Greeting.class, "hello", "world");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkMultiExtension1() throws Exception {
+ AbstractConfig.checkMultiExtension(Greeting.class, "hello", "default,world");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkMultiExtension2() throws Exception {
+ AbstractConfig.checkMultiExtension(Greeting.class, "hello", "default,-world");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkLength() throws Exception {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i <= 200; i++) {
+ builder.append("a");
+ }
+ AbstractConfig.checkLength("hello", builder.toString());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkPathLength() throws Exception {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i <= 200; i++) {
+ builder.append("a");
+ }
+ AbstractConfig.checkPathLength("hello", builder.toString());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkName() throws Exception {
+ AbstractConfig.checkName("hello", "world%");
+ }
+
+ @Test
+ public void checkNameHasSymbol() throws Exception {
+ try {
+ AbstractConfig.checkNameHasSymbol("hello", ":*,/-0123abcdABCD");
+ } catch (Exception e) {
+ TestCase.fail("the value should be legal.");
+ }
+ }
+
+ @Test
+ public void checkKey() throws Exception {
+ try {
+ AbstractConfig.checkKey("hello", "*,-0123abcdABCD");
+ } catch (Exception e) {
+ TestCase.fail("the value should be legal.");
+ }
+ }
+
+ @Test
+ public void checkMultiName() throws Exception {
+ try {
+ AbstractConfig.checkMultiName("hello", ",-._0123abcdABCD");
+ } catch (Exception e) {
+ TestCase.fail("the value should be legal.");
+ }
+ }
+
+ @Test
+ public void checkPathName() throws Exception {
+ try {
+ AbstractConfig.checkPathName("hello", "/-$._0123abcdABCD");
+ } catch (Exception e) {
+ TestCase.fail("the value should be legal.");
+ }
+ }
+
+ @Test
+ public void checkMethodName() throws Exception {
+ try {
+ AbstractConfig.checkMethodName("hello", "abcdABCD0123abcd");
+ } catch (Exception e) {
+ TestCase.fail("the value should be legal.");
+ }
+
+ try {
+ AbstractConfig.checkMethodName("hello", "0a");
+ TestCase.fail("the value should be illegal.");
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ @Test
+ public void checkParameterName() throws Exception {
+ Map<String, String> parameters = Collections.singletonMap("hello", ":*,/-._0123abcdABCD");
+ try {
+ AbstractConfig.checkParameterName(parameters);
+ } catch (Exception e) {
+ TestCase.fail("the value should be legal.");
+ }
+ }
+
+ @Test
+ @Config(interfaceClass = Greeting.class, filter = {"f1, f2"}, listener = {"l1, l2"},
+ parameters = {"k1", "v1", "k2", "v2"})
+ public void appendAnnotation() throws Exception {
+ Config config = getClass().getMethod("appendAnnotation").getAnnotation(Config.class);
+ AnnotationConfig annotationConfig = new AnnotationConfig();
+ annotationConfig.appendAnnotation(Config.class, config);
+ TestCase.assertSame(Greeting.class, annotationConfig.getInterface());
+ TestCase.assertEquals("f1, f2", annotationConfig.getFilter());
+ TestCase.assertEquals("l1, l2", annotationConfig.getListener());
+ TestCase.assertEquals(2, annotationConfig.getParameters().size());
+ TestCase.assertEquals("v1", annotationConfig.getParameters().get("k1"));
+ TestCase.assertEquals("v2", annotationConfig.getParameters().get("k2"));
+ assertThat(annotationConfig.toString(), Matchers.containsString("filter=\"f1, f2\" "));
+ assertThat(annotationConfig.toString(), Matchers.containsString("listener=\"l1, l2\" "));
+ }
+
+ private static class PropertiesConfig extends AbstractConfig {
+ private char c;
+ private boolean bool;
+ private byte b;
+ private int i;
+ private long l;
+ private float f;
+ private double d;
+ private short s;
+ private String str;
+
+ PropertiesConfig() {
+ }
+
+ PropertiesConfig(String id) {
+ this.id = id;
+ }
+
+ public char getC() {
+ return c;
+ }
+
+ public void setC(char c) {
+ this.c = c;
+ }
+
+ public boolean isBool() {
+ return bool;
+ }
+
+ public void setBool(boolean bool) {
+ this.bool = bool;
+ }
+
+ public byte getB() {
+ return b;
+ }
+
+ public void setB(byte b) {
+ this.b = b;
+ }
+
+ public int getI() {
+ return i;
+ }
+
+ public void setI(int i) {
+ this.i = i;
+ }
+
+ public long getL() {
+ return l;
+ }
+
+ public void setL(long l) {
+ this.l = l;
+ }
+
+ public float getF() {
+ return f;
+ }
+
+ public void setF(float f) {
+ this.f = f;
+ }
+
+ public double getD() {
+ return d;
+ }
+
+ public void setD(double d) {
+ this.d = d;
+ }
+
+ public String getStr() {
+ return str;
+ }
+
+ public void setStr(String str) {
+ this.str = str;
+ }
+
+ public short getS() {
+ return s;
+ }
+
+ public void setS(short s) {
+ this.s = s;
+ }
+ }
+
+ private static class ParameterConfig {
+ private int number;
+ private String name;
+ private int age;
+ private String secret;
+
+ ParameterConfig() {
+ }
+
+ ParameterConfig(int number, String name, int age, String secret) {
+ this.number = number;
+ this.name = name;
+ this.age = age;
+ this.secret = secret;
+ }
+
+ @Parameter(key = "num", append = true)
+ public int getNumber() {
+ return number;
+ }
+
+ public void setNumber(int number) {
+ this.number = number;
+ }
+
+ @Parameter(key = "naming", append = true, escaped = true, required = true)
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ @Parameter(excluded = true)
+ public String getSecret() {
+ return secret;
+ }
+
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+
+ public Map getParameters() {
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("key.1", "one");
+ map.put("key-2", "two");
+ return map;
+ }
+ }
+
+ private static class AttributeConfig {
+ private char letter;
+ private boolean activate;
+ private byte flag;
+
+ public AttributeConfig(char letter, boolean activate, byte flag) {
+ this.letter = letter;
+ this.activate = activate;
+ this.flag = flag;
+ }
+
+ @Parameter(attribute = true, key = "let")
+ public char getLetter() {
+ return letter;
+ }
+
+ public void setLetter(char letter) {
+ this.letter = letter;
+ }
+
+ @Parameter(attribute = true)
+ public boolean isActivate() {
+ return activate;
+ }
+
+ public void setActivate(boolean activate) {
+ this.activate = activate;
+ }
+
+ public byte getFlag() {
+ return flag;
+ }
+
+ public void setFlag(byte flag) {
+ this.flag = flag;
+ }
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
+ public @interface Config {
+ Class<?> interfaceClass() default void.class;
+
+ String interfaceName() default "";
+
+ String[] filter() default {};
+
+ String[] listener() default {};
+
+ String[] parameters() default {};
+ }
+
+ private static class AnnotationConfig extends AbstractConfig {
+ private Class interfaceClass;
+ private String filter;
+ private String listener;
+ private Map<String, String> parameters;
+
+ public Class getInterface() {
+ return interfaceClass;
+ }
+
+ public void setInterface(Class interfaceName) {
+ this.interfaceClass = interfaceName;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public void setFilter(String filter) {
+ this.filter = filter;
+ }
+
+ public String getListener() {
+ return listener;
+ }
+
+ public void setListener(String listener) {
+ this.listener = listener;
+ }
+
+ public Map<String, String> getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map<String, String> parameters) {
+ this.parameters = parameters;
+ }
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
new file mode 100644
index 0000000..a99a910
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
@@ -0,0 +1,407 @@
+/*
+ * 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.config;
+
+import junit.framework.TestCase;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.mock.GreetingLocal1;
+import org.apache.dubbo.config.mock.GreetingLocal2;
+import org.apache.dubbo.config.mock.GreetingLocal3;
+import org.apache.dubbo.config.mock.GreetingMock1;
+import org.apache.dubbo.config.mock.GreetingMock2;
+import org.apache.dubbo.monitor.MonitorService;
+import org.apache.dubbo.registry.RegistryService;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+public class AbstractInterfaceConfigTest {
+ @ClassRule
+ public static TemporaryFolder tempDir = new TemporaryFolder();
+ private static File dubboProperties;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ dubboProperties = tempDir.newFile(Constants.DUBBO_PROPERTIES_KEY);
+ System.setProperty(Constants.DUBBO_PROPERTIES_KEY, dubboProperties.getAbsolutePath());
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ System.clearProperty(Constants.DUBBO_PROPERTIES_KEY);
+ }
+
+ @Test
+ public void testCheckRegistry1() throws Exception {
+ System.setProperty("dubbo.registry.address", "addr1|addr2");
+ try {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkRegistry();
+ TestCase.assertEquals(2, interfaceConfig.getRegistries().size());
+ } finally {
+ System.clearProperty("dubbo.registry.address");
+ }
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testCheckRegistry2() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkRegistry();
+ }
+
+ @Test
+ public void checkApplication1() throws Exception {
+ try {
+ ConfigUtils.setProperties(null);
+ System.clearProperty(Constants.SHUTDOWN_WAIT_KEY);
+ System.clearProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY);
+
+ writeDubboProperties(Constants.SHUTDOWN_WAIT_KEY, "100");
+ System.setProperty("dubbo.application.name", "demo");
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkApplication();
+ ApplicationConfig appConfig = interfaceConfig.getApplication();
+ TestCase.assertEquals("demo", appConfig.getName());
+ TestCase.assertEquals("100", System.getProperty(Constants.SHUTDOWN_WAIT_KEY));
+
+ System.clearProperty(Constants.SHUTDOWN_WAIT_KEY);
+ ConfigUtils.setProperties(null);
+ writeDubboProperties(Constants.SHUTDOWN_WAIT_SECONDS_KEY, "1000");
+ System.setProperty("dubbo.application.name", "demo");
+ interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkApplication();
+ TestCase.assertEquals("1000", System.getProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY));
+ } finally {
+ ConfigUtils.setProperties(null);
+ System.clearProperty("dubbo.application.name");
+ System.clearProperty(Constants.SHUTDOWN_WAIT_KEY);
+ System.clearProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY);
+ }
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkApplication2() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkApplication();
+ }
+
+ @Test
+ public void testLoadRegistries() throws Exception {
+ System.setProperty("dubbo.registry.address", "addr1");
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ List<URL> urls = interfaceConfig.loadRegistries(true);
+ TestCase.assertEquals(1, urls.size());
+ URL url = urls.get(0);
+ TestCase.assertEquals("registry", url.getProtocol());
+ TestCase.assertEquals("addr1:9090", url.getAddress());
+ TestCase.assertEquals(RegistryService.class.getName(), url.getPath());
+ TestCase.assertTrue(url.getParameters().containsKey("timestamp"));
+ TestCase.assertTrue(url.getParameters().containsKey("pid"));
+ TestCase.assertTrue(url.getParameters().containsKey("registry"));
+ TestCase.assertTrue(url.getParameters().containsKey("dubbo"));
+ }
+
+ @Test
+ public void testLoadMonitor() throws Exception {
+ System.setProperty("dubbo.monitor.address", "monitor-addr:12080");
+ System.setProperty("dubbo.monitor.protocol", "monitor");
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ URL url = interfaceConfig.loadMonitor(new URL("dubbo", "addr1", 9090));
+ TestCase.assertEquals("monitor-addr:12080", url.getAddress());
+ TestCase.assertEquals(MonitorService.class.getName(), url.getParameter("interface"));
+ TestCase.assertNotNull(url.getParameter("dubbo"));
+ TestCase.assertNotNull(url.getParameter("pid"));
+ TestCase.assertNotNull(url.getParameter("timestamp"));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkInterfaceAndMethods1() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkInterfaceAndMethods(null, null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkInterfaceAndMethods2() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkInterfaceAndMethods(AbstractInterfaceConfigTest.class, null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkInterfaceAndMethod3() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkInterfaceAndMethod4() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setName("nihao");
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
+ }
+
+ @Test
+ public void checkInterfaceAndMethod5() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setName("hello");
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkStubAndMock1() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setLocal(GreetingLocal1.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkStubAndMock2() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setLocal(GreetingLocal2.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test
+ public void checkStubAndMock3() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setLocal(GreetingLocal3.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkStubAndMock4() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setStub(GreetingLocal1.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkStubAndMock5() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setStub(GreetingLocal2.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test
+ public void checkStubAndMock6() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setStub(GreetingLocal3.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkStubAndMock7() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setMock("return {a, b}");
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkStubAndMock8() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setMock(GreetingMock1.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void checkStubAndMock9() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setMock(GreetingMock2.class.getName());
+ interfaceConfig.checkStubAndMock(Greeting.class);
+ }
+
+ @Test
+ public void testLocal() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setLocal((Boolean) null);
+ TestCase.assertNull(interfaceConfig.getLocal());
+ interfaceConfig.setLocal(true);
+ TestCase.assertEquals("true", interfaceConfig.getLocal());
+ interfaceConfig.setLocal("GreetingMock");
+ TestCase.assertEquals("GreetingMock", interfaceConfig.getLocal());
+ }
+
+ @Test
+ public void testStub() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setStub((Boolean) null);
+ TestCase.assertNull(interfaceConfig.getStub());
+ interfaceConfig.setStub(true);
+ TestCase.assertEquals("true", interfaceConfig.getStub());
+ interfaceConfig.setStub("GreetingMock");
+ TestCase.assertEquals("GreetingMock", interfaceConfig.getStub());
+ }
+
+ @Test
+ public void testCluster() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setCluster("mockcluster");
+ TestCase.assertEquals("mockcluster", interfaceConfig.getCluster());
+ }
+
+ @Test
+ public void testProxy() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setProxy("mockproxyfactory");
+ TestCase.assertEquals("mockproxyfactory", interfaceConfig.getProxy());
+ }
+
+ @Test
+ public void testConnections() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setConnections(1);
+ TestCase.assertEquals(1, interfaceConfig.getConnections().intValue());
+ }
+
+ @Test
+ public void testFilter() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setFilter("mockfilter");
+ TestCase.assertEquals("mockfilter", interfaceConfig.getFilter());
+ }
+
+ @Test
+ public void testListener() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setListener("mockinvokerlistener");
+ TestCase.assertEquals("mockinvokerlistener", interfaceConfig.getListener());
+ }
+
+ @Test
+ public void testLayer() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setLayer("layer");
+ TestCase.assertEquals("layer", interfaceConfig.getLayer());
+ }
+
+ @Test
+ public void testApplication() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ ApplicationConfig applicationConfig = new ApplicationConfig();
+ interfaceConfig.setApplication(applicationConfig);
+ TestCase.assertSame(applicationConfig, interfaceConfig.getApplication());
+ }
+
+ @Test
+ public void testModule() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ ModuleConfig moduleConfig = new ModuleConfig();
+ interfaceConfig.setModule(moduleConfig);
+ TestCase.assertSame(moduleConfig, interfaceConfig.getModule());
+ }
+
+ @Test
+ public void testRegistry() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ RegistryConfig registryConfig = new RegistryConfig();
+ interfaceConfig.setRegistry(registryConfig);
+ TestCase.assertSame(registryConfig, interfaceConfig.getRegistry());
+ }
+
+ @Test
+ public void testRegistries() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ RegistryConfig registryConfig = new RegistryConfig();
+ interfaceConfig.setRegistries(Collections.singletonList(registryConfig));
+ TestCase.assertEquals(1, interfaceConfig.getRegistries().size());
+ TestCase.assertSame(registryConfig, interfaceConfig.getRegistries().get(0));
+ }
+
+ @Test
+ public void testMonitor() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setMonitor("monitor-addr");
+ TestCase.assertEquals("monitor-addr", interfaceConfig.getMonitor().getAddress());
+ MonitorConfig monitorConfig = new MonitorConfig();
+ interfaceConfig.setMonitor(monitorConfig);
+ TestCase.assertSame(monitorConfig, interfaceConfig.getMonitor());
+ }
+
+ @Test
+ public void testOwner() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setOwner("owner");
+ TestCase.assertEquals("owner", interfaceConfig.getOwner());
+ }
+
+ @Test
+ public void testCallbacks() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setCallbacks(2);
+ TestCase.assertEquals(2, interfaceConfig.getCallbacks().intValue());
+ }
+
+ @Test
+ public void testOnconnect() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setOnconnect("onConnect");
+ TestCase.assertEquals("onConnect", interfaceConfig.getOnconnect());
+ }
+
+ @Test
+ public void testOndisconnect() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setOndisconnect("onDisconnect");
+ TestCase.assertEquals("onDisconnect", interfaceConfig.getOndisconnect());
+ }
+
+ @Test
+ public void testScope() throws Exception {
+ InterfaceConfig interfaceConfig = new InterfaceConfig();
+ interfaceConfig.setScope("scope");
+ TestCase.assertEquals("scope", interfaceConfig.getScope());
+ }
+
+ private void writeDubboProperties(String key, String value) {
+ OutputStream os = null;
+ try {
+ os = new BufferedOutputStream(new FileOutputStream(dubboProperties));
+ Properties properties = new Properties();
+ properties.put(key, value);
+ properties.store(os, "");
+ os.close();
+ } catch (IOException e) {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ private static class InterfaceConfig extends AbstractInterfaceConfig {
+
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java
new file mode 100644
index 0000000..41549e3
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractMethodConfigTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.config;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.sameInstance;
+import static org.junit.Assert.assertThat;
+
+public class AbstractMethodConfigTest {
+ @Test
+ public void testTimeout() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setTimeout(10);
+ assertThat(methodConfig.getTimeout(), equalTo(10));
+ }
+
+ @Test
+ public void testRetries() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setRetries(3);
+ assertThat(methodConfig.getRetries(), equalTo(3));
+ }
+
+ @Test
+ public void testLoadbalance() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setLoadbalance("mockloadbalance");
+ assertThat(methodConfig.getLoadbalance(), equalTo("mockloadbalance"));
+ }
+
+ @Test
+ public void testAsync() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setAsync(true);
+ assertThat(methodConfig.isAsync(), is(true));
+ }
+
+ @Test
+ public void testActives() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setActives(10);
+ assertThat(methodConfig.getActives(), equalTo(10));
+ }
+
+ @Test
+ public void testSent() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setSent(true);
+ assertThat(methodConfig.getSent(), is(true));
+ }
+
+ @Test
+ public void testMock() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setMock((Boolean) null);
+ assertThat(methodConfig.getMock(), isEmptyOrNullString());
+ methodConfig.setMock(true);
+ assertThat(methodConfig.getMock(), equalTo("true"));
+ methodConfig.setMock("return null");
+ assertThat(methodConfig.getMock(), equalTo("return null"));
+ methodConfig.setMock("mock");
+ assertThat(methodConfig.getMock(), equalTo("mock"));
+ }
+
+ @Test
+ public void testMerger() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setMerger("merger");
+ assertThat(methodConfig.getMerger(), equalTo("merger"));
+ }
+
+ @Test
+ public void testCache() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setCache("cache");
+ assertThat(methodConfig.getCache(), equalTo("cache"));
+ }
+
+ @Test
+ public void testValidation() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ methodConfig.setValidation("validation");
+ assertThat(methodConfig.getValidation(), equalTo("validation"));
+ }
+
+ @Test
+ public void testParameters() throws Exception {
+ MethodConfig methodConfig = new MethodConfig();
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("key", "value");
+ methodConfig.setParameters(parameters);
+ assertThat(methodConfig.getParameters(), sameInstance(parameters));
+ }
+
+ private static class MethodConfig extends AbstractMethodConfig {
+
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java
new file mode 100644
index 0000000..a53217c
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.hasValue;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class AbstractReferenceConfigTest {
+
+ @Test
+ public void testCheck() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setCheck(true);
+ assertThat(referenceConfig.isCheck(), is(true));
+ }
+
+ @Test
+ public void testInit() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setInit(true);
+ assertThat(referenceConfig.isInit(), is(true));
+ }
+
+ @Test
+ public void testGeneric() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setGeneric(true);
+ assertThat(referenceConfig.isGeneric(), is(true));
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+ // FIXME: not sure why AbstractReferenceConfig has both isGeneric and getGeneric
+ assertThat(parameters, hasKey("generic"));
+ }
+
+ @Test
+ public void testInjvm() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setInit(true);
+ assertThat(referenceConfig.isInit(), is(true));
+ }
+
+ @Test
+ public void testFilter() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setFilter("mockfilter");
+ assertThat(referenceConfig.getFilter(), equalTo("mockfilter"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(Constants.REFERENCE_FILTER_KEY, "prefilter");
+ AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+ assertThat(parameters, hasValue("prefilter,mockfilter"));
+ }
+
+ @Test
+ public void testListener() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setListener("mockinvokerlistener");
+ assertThat(referenceConfig.getListener(), equalTo("mockinvokerlistener"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(Constants.INVOKER_LISTENER_KEY, "prelistener");
+ AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+ assertThat(parameters, hasValue("prelistener,mockinvokerlistener"));
+ }
+
+ @Test
+ public void testLazy() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setLazy(true);
+ assertThat(referenceConfig.getLazy(), is(true));
+ }
+
+ @Test
+ public void testOnconnect() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setOnconnect("onConnect");
+ assertThat(referenceConfig.getOnconnect(), equalTo("onConnect"));
+ assertThat(referenceConfig.getStubevent(), is(true));
+ }
+
+ @Test
+ public void testOndisconnect() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setOndisconnect("onDisconnect");
+ assertThat(referenceConfig.getOndisconnect(), equalTo("onDisconnect"));
+ assertThat(referenceConfig.getStubevent(), is(true));
+ }
+
+ @Test
+ public void testStubevent() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setOnconnect("onConnect");
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+ assertThat(parameters, hasKey(Constants.STUB_EVENT_KEY));
+ }
+
+ @Test
+ public void testReconnect() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setReconnect("reconnect");
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+ assertThat(referenceConfig.getReconnect(), equalTo("reconnect"));
+ assertThat(parameters, hasKey(Constants.RECONNECT_KEY));
+ }
+
+ @Test
+ public void testSticky() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setSticky(true);
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractInterfaceConfig.appendParameters(parameters, referenceConfig);
+ assertThat(referenceConfig.getSticky(), is(true));
+ assertThat(parameters, hasKey(Constants.CLUSTER_STICKY_KEY));
+ }
+
+ @Test
+ public void testVersion() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setVersion("version");
+ assertThat(referenceConfig.getVersion(), equalTo("version"));
+ }
+
+ @Test
+ public void testGroup() throws Exception {
+ ReferenceConfig referenceConfig = new ReferenceConfig();
+ referenceConfig.setGroup("group");
+ assertThat(referenceConfig.getGroup(), equalTo("group"));
+ }
+
+ private static class ReferenceConfig extends AbstractReferenceConfig {
+
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java
new file mode 100644
index 0000000..3f79541
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java
@@ -0,0 +1,181 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class AbstractServiceConfigTest {
+ @Test
+ public void testVersion() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setVersion("version");
+ assertThat(serviceConfig.getVersion(), equalTo("version"));
+ }
+
+ @Test
+ public void testGroup() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setGroup("group");
+ assertThat(serviceConfig.getGroup(), equalTo("group"));
+ }
+
+ @Test
+ public void testDelay() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setDelay(1000);
+ assertThat(serviceConfig.getDelay(), equalTo(1000));
+ }
+
+ @Test
+ public void testExport() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setExport(true);
+ assertThat(serviceConfig.getExport(), is(true));
+ }
+
+ @Test
+ public void testWeight() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setWeight(500);
+ assertThat(serviceConfig.getWeight(), equalTo(500));
+ }
+
+ @Test
+ public void testDocument() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setDocument("http://dubbo.io");
+ assertThat(serviceConfig.getDocument(), equalTo("http://dubbo.io"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractServiceConfig.appendParameters(parameters, serviceConfig);
+ assertThat(parameters, hasEntry("document", "http%3A%2F%2Fdubbo.io"));
+ }
+
+ @Test
+ public void testToken() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setToken("token");
+ assertThat(serviceConfig.getToken(), equalTo("token"));
+ serviceConfig.setToken((Boolean) null);
+ assertThat(serviceConfig.getToken(), nullValue());
+ serviceConfig.setToken(true);
+ assertThat(serviceConfig.getToken(), is("true"));
+ }
+
+ @Test
+ public void testDeprecated() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setDeprecated(true);
+ assertThat(serviceConfig.isDeprecated(), is(true));
+ }
+
+ @Test
+ public void testDynamic() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setDynamic(true);
+ assertThat(serviceConfig.isDynamic(), is(true));
+ }
+
+ @Test
+ public void testProtocol() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ assertThat(serviceConfig.getProtocol(), nullValue());
+ serviceConfig.setProtocol(new ProtocolConfig());
+ assertThat(serviceConfig.getProtocol(), notNullValue());
+ serviceConfig.setProtocols(Collections.singletonList(new ProtocolConfig()));
+ assertThat(serviceConfig.getProtocols(), hasSize(1));
+ }
+
+ @Test
+ public void testAccesslog() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setAccesslog("access.log");
+ assertThat(serviceConfig.getAccesslog(), equalTo("access.log"));
+ serviceConfig.setAccesslog((Boolean) null);
+ assertThat(serviceConfig.getAccesslog(), nullValue());
+ serviceConfig.setAccesslog(true);
+ assertThat(serviceConfig.getAccesslog(), equalTo("true"));
+ }
+
+ @Test
+ public void testExecutes() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setExecutes(10);
+ assertThat(serviceConfig.getExecutes(), equalTo(10));
+ }
+
+ @Test
+ public void testFilter() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setFilter("mockfilter");
+ assertThat(serviceConfig.getFilter(), equalTo("mockfilter"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(Constants.SERVICE_FILTER_KEY, "prefilter");
+ AbstractServiceConfig.appendParameters(parameters, serviceConfig);
+ assertThat(parameters, hasEntry(Constants.SERVICE_FILTER_KEY, "prefilter,mockfilter"));
+ }
+
+ @Test
+ public void testListener() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setListener("mockexporterlistener");
+ assertThat(serviceConfig.getListener(), equalTo("mockexporterlistener"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(Constants.EXPORTER_LISTENER_KEY, "prelistener");
+ AbstractServiceConfig.appendParameters(parameters, serviceConfig);
+ assertThat(parameters, hasEntry(Constants.EXPORTER_LISTENER_KEY, "prelistener,mockexporterlistener"));
+ }
+
+ @Test
+ public void testRegister() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setRegister(true);
+ assertThat(serviceConfig.isRegister(), is(true));
+ }
+
+ @Test
+ public void testWarmup() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setWarmup(100);
+ assertThat(serviceConfig.getWarmup(), equalTo(100));
+ }
+
+ @Test
+ public void testSerialization() throws Exception {
+ ServiceConfig serviceConfig = new ServiceConfig();
+ serviceConfig.setSerialization("serialization");
+ assertThat(serviceConfig.getSerialization(), equalTo("serialization"));
+ }
+
+
+ private static class ServiceConfig extends AbstractServiceConfig {
+
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ApplicationConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ApplicationConfigTest.java
new file mode 100644
index 0000000..1cc5a22
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ApplicationConfigTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.junit.Assert.assertThat;
+
+public class ApplicationConfigTest {
+ @Test
+ public void testName() throws Exception {
+ ApplicationConfig application = new ApplicationConfig();
+ application.setName("app");
+ assertThat(application.getName(), equalTo("app"));
+ application = new ApplicationConfig("app2");
+ assertThat(application.getName(), equalTo("app2"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ ApplicationConfig.appendParameters(parameters, application);
+ assertThat(parameters, hasEntry(Constants.APPLICATION_KEY, "app2"));
+ }
+
+ @Test
+ public void testVersion() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setVersion("1.0.0");
+ assertThat(application.getVersion(), equalTo("1.0.0"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ ApplicationConfig.appendParameters(parameters, application);
+ assertThat(parameters, hasEntry("application.version", "1.0.0"));
+ }
+
+ @Test
+ public void testOwner() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setOwner("owner");
+ assertThat(application.getOwner(), equalTo("owner"));
+ }
+
+ @Test
+ public void testOrganization() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setOrganization("org");
+ assertThat(application.getOrganization(), equalTo("org"));
+ }
+
+ @Test
+ public void testArchitecture() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setArchitecture("arch");
+ assertThat(application.getArchitecture(), equalTo("arch"));
+ }
+
+ @Test
+ public void testEnvironment1() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setEnvironment("develop");
+ assertThat(application.getEnvironment(), equalTo("develop"));
+ application.setEnvironment("test");
+ assertThat(application.getEnvironment(), equalTo("test"));
+ application.setEnvironment("product");
+ assertThat(application.getEnvironment(), equalTo("product"));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testEnvironment2() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setEnvironment("illegal-env");
+ }
+
+ @Test
+ public void testRegistry() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ RegistryConfig registry = new RegistryConfig();
+ application.setRegistry(registry);
+ assertThat(application.getRegistry(), sameInstance(registry));
+ application.setRegistries(Collections.singletonList(registry));
+ assertThat(application.getRegistries(), contains(registry));
+ assertThat(application.getRegistries(), hasSize(1));
+ }
+
+ @Test
+ public void testMonitor() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setMonitor(new MonitorConfig("monitor-addr"));
+ assertThat(application.getMonitor().getAddress(), equalTo("monitor-addr"));
+ application.setMonitor("monitor-addr");
+ assertThat(application.getMonitor().getAddress(), equalTo("monitor-addr"));
+ }
+
+ @Test
+ public void testLogger() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setLogger("log4j");
+ assertThat(application.getLogger(), equalTo("log4j"));
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setDefault(true);
+ assertThat(application.isDefault(), is(true));
+ }
+
+ @Test
+ public void testDumpDirectory() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setDumpDirectory("/dump");
+ assertThat(application.getDumpDirectory(), equalTo("/dump"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ ApplicationConfig.appendParameters(parameters, application);
+ assertThat(parameters, hasEntry(Constants.DUMP_DIRECTORY, "/dump"));
+ }
+
+ @Test
+ public void testQosEnable() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setQosEnable(true);
+ assertThat(application.getQosEnable(), is(true));
+ Map<String, String> parameters = new HashMap<String, String>();
+ ApplicationConfig.appendParameters(parameters, application);
+ assertThat(parameters, hasEntry(Constants.QOS_ENABLE, "true"));
+ }
+
+ @Test
+ public void testQosPort() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setQosPort(8080);
+ assertThat(application.getQosPort(), equalTo(8080));
+ }
+
+ @Test
+ public void testQosAcceptForeignIp() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setQosAcceptForeignIp(true);
+ assertThat(application.getQosAcceptForeignIp(), is(true));
+ Map<String, String> parameters = new HashMap<String, String>();
+ ApplicationConfig.appendParameters(parameters, application);
+ assertThat(parameters, hasEntry(Constants.ACCEPT_FOREIGN_IP, "true"));
+ }
+
+ @Test
+ public void testParameters() throws Exception {
+ ApplicationConfig application = new ApplicationConfig("app");
+ application.setQosAcceptForeignIp(true);
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("k1", "v1");
+ ApplicationConfig.appendParameters(parameters, application);
+ assertThat(parameters, hasEntry("k1", "v1"));
+ assertThat(parameters, hasEntry(Constants.ACCEPT_FOREIGN_IP, "true"));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ArgumentConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ArgumentConfigTest.java
new file mode 100644
index 0000000..26051f9
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ArgumentConfigTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.config;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class ArgumentConfigTest {
+ @Test
+ public void testIndex() throws Exception {
+ ArgumentConfig argument = new ArgumentConfig();
+ argument.setIndex(1);
+ assertThat(argument.getIndex(), is(1));
+ }
+
+ @Test
+ public void testType() throws Exception {
+ ArgumentConfig argument = new ArgumentConfig();
+ argument.setType("int");
+ assertThat(argument.getType(), equalTo("int"));
+ }
+
+ @Test
+ public void testCallback() throws Exception {
+ ArgumentConfig argument = new ArgumentConfig();
+ argument.setCallback(true);
+ assertThat(argument.isCallback(), is(true));
+ }
+
+ @Test
+ public void testArguments() throws Exception {
+ ArgumentConfig argument = new ArgumentConfig();
+ argument.setIndex(1);
+ argument.setType("int");
+ argument.setCallback(true);
+ Map<String, String> parameters = new HashMap<String, String>();
+ AbstractServiceConfig.appendParameters(parameters, argument);
+ assertThat(parameters, hasEntry("callback", "true"));
+ assertThat(parameters.size(), is(1));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ConsumerConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ConsumerConfigTest.java
new file mode 100644
index 0000000..b9a1a9a
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ConsumerConfigTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.config;
+
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class ConsumerConfigTest {
+ @Test
+ public void testTimeout() throws Exception {
+ try {
+ System.clearProperty("sun.rmi.transport.tcp.responseTimeout");
+ ConsumerConfig consumer = new ConsumerConfig();
+ consumer.setTimeout(10);
+ assertThat(consumer.getTimeout(), is(10));
+ assertThat(System.getProperty("sun.rmi.transport.tcp.responseTimeout"), equalTo("10"));
+ } finally {
+ System.clearProperty("sun.rmi.transport.tcp.responseTimeout");
+ }
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ ConsumerConfig consumer = new ConsumerConfig();
+ consumer.setDefault(true);
+ assertThat(consumer.isDefault(), is(true));
+ }
+
+ @Test
+ public void testClient() throws Exception {
+ ConsumerConfig consumer = new ConsumerConfig();
+ consumer.setClient("client");
+ assertThat(consumer.getClient(), equalTo("client"));
+ }
+
+ @Test
+ public void testThreadpool() throws Exception {
+ ConsumerConfig consumer = new ConsumerConfig();
+ consumer.setThreadpool("fixed");
+ assertThat(consumer.getThreadpool(), equalTo("fixed"));
+ }
+
+ @Test
+ public void testCorethreads() throws Exception {
+ ConsumerConfig consumer = new ConsumerConfig();
+ consumer.setCorethreads(10);
+ assertThat(consumer.getCorethreads(), equalTo(10));
+ }
+
+ @Test
+ public void testThreads() throws Exception {
+ ConsumerConfig consumer = new ConsumerConfig();
+ consumer.setThreads(20);
+ assertThat(consumer.getThreads(), equalTo(20));
+ }
+
+ @Test
+ public void testQueues() throws Exception {
+ ConsumerConfig consumer = new ConsumerConfig();
+ consumer.setQueues(5);
+ assertThat(consumer.getQueues(), equalTo(5));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/GenericServiceTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/GenericServiceTest.java
new file mode 100644
index 0000000..eed9b1e
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/GenericServiceTest.java
@@ -0,0 +1,314 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.beanutil.JavaBeanAccessor;
+import org.apache.dubbo.common.beanutil.JavaBeanDescriptor;
+import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.common.utils.ReflectUtils;
+import org.apache.dubbo.config.api.DemoException;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.api.User;
+import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+import org.apache.dubbo.rpc.service.GenericException;
+import org.apache.dubbo.rpc.service.GenericService;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * GenericServiceTest
+ */
+public class GenericServiceTest {
+
+ @Test
+ public void testGenericServiceException() {
+ ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
+ service.setApplication(new ApplicationConfig("generic-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("dubbo", 29581));
+ service.setInterface(DemoService.class.getName());
+ service.setRef(new GenericService() {
+
+ public Object $invoke(String method, String[] parameterTypes, Object[] args)
+ throws GenericException {
+ if ("sayName".equals(method)) {
+ return "Generic " + args[0];
+ }
+ if ("throwDemoException".equals(method)) {
+ throw new GenericException(DemoException.class.getName(), "Generic");
+ }
+ if ("getUsers".equals(method)) {
+ return args[0];
+ }
+ return null;
+ }
+ });
+ service.export();
+ try {
+ ReferenceConfig<DemoService> reference = new ReferenceConfig<DemoService>();
+ reference.setApplication(new ApplicationConfig("generic-consumer"));
+ reference.setInterface(DemoService.class);
+ reference.setUrl("dubbo://127.0.0.1:29581?generic=true&timeout=3000");
+ DemoService demoService = reference.get();
+ try {
+ // say name
+ Assert.assertEquals("Generic Haha", demoService.sayName("Haha"));
+ // get users
+ List<User> users = new ArrayList<User>();
+ users.add(new User("Aaa"));
+ users = demoService.getUsers(users);
+ Assert.assertEquals("Aaa", users.get(0).getName());
+ // throw demo exception
+ try {
+ demoService.throwDemoException();
+ Assert.fail();
+ } catch (DemoException e) {
+ Assert.assertEquals("Generic", e.getMessage());
+ }
+ } finally {
+ reference.destroy();
+ }
+ } finally {
+ service.unexport();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testGenericReferenceException() {
+ ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
+ service.setApplication(new ApplicationConfig("generic-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("dubbo", 29581));
+ service.setInterface(DemoService.class.getName());
+ service.setRef(new DemoServiceImpl());
+ service.export();
+ try {
+ ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
+ reference.setApplication(new ApplicationConfig("generic-consumer"));
+ reference.setInterface(DemoService.class);
+ reference.setUrl("dubbo://127.0.0.1:29581?scope=remote&timeout=3000");
+ reference.setGeneric(true);
+ GenericService genericService = reference.get();
+ try {
+ List<Map<String, Object>> users = new ArrayList<Map<String, Object>>();
+ Map<String, Object> user = new HashMap<String, Object>();
+ user.put("class", "org.apache.dubbo.config.api.User");
+ user.put("name", "actual.provider");
+ users.add(user);
+ users = (List<Map<String, Object>>) genericService.$invoke("getUsers", new String[]{List.class.getName()}, new Object[]{users});
+ Assert.assertEquals(1, users.size());
+ Assert.assertEquals("actual.provider", users.get(0).get("name"));
+ } finally {
+ reference.destroy();
+ }
+ } finally {
+ service.unexport();
+ }
+ }
+
+ @Test
+ public void testGenericSerializationJava() throws Exception {
+ ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
+ service.setApplication(new ApplicationConfig("generic-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("dubbo", 29581));
+ service.setInterface(DemoService.class.getName());
+ DemoServiceImpl ref = new DemoServiceImpl();
+ service.setRef(ref);
+ service.export();
+ try {
+ ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
+ reference.setApplication(new ApplicationConfig("generic-consumer"));
+ reference.setInterface(DemoService.class);
+ reference.setUrl("dubbo://127.0.0.1:29581?scope=remote&timeout=3000");
+ reference.setGeneric(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA);
+ GenericService genericService = reference.get();
+ try {
+ String name = "kimi";
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(512);
+ ExtensionLoader.getExtensionLoader(Serialization.class)
+ .getExtension("nativejava").serialize(null, bos).writeObject(name);
+ byte[] arg = bos.toByteArray();
+ Object obj = genericService.$invoke("sayName", new String[]{String.class.getName()}, new Object[]{arg});
+ Assert.assertTrue(obj instanceof byte[]);
+ byte[] result = (byte[]) obj;
+ Assert.assertEquals(ref.sayName(name), ExtensionLoader.getExtensionLoader(Serialization.class)
+ .getExtension("nativejava").deserialize(null, new ByteArrayInputStream(result)).readObject().toString());
+
+ // getUsers
+ List<User> users = new ArrayList<User>();
+ User user = new User();
+ user.setName(name);
+ users.add(user);
+ bos = new ByteArrayOutputStream(512);
+ ExtensionLoader.getExtensionLoader(Serialization.class)
+ .getExtension("nativejava").serialize(null, bos).writeObject(users);
+ obj = genericService.$invoke("getUsers",
+ new String[]{List.class.getName()},
+ new Object[]{bos.toByteArray()});
+ Assert.assertTrue(obj instanceof byte[]);
+ result = (byte[]) obj;
+ Assert.assertEquals(users,
+ ExtensionLoader.getExtensionLoader(Serialization.class)
+ .getExtension("nativejava")
+ .deserialize(null, new ByteArrayInputStream(result))
+ .readObject());
+
+ // echo(int)
+ bos = new ByteArrayOutputStream(512);
+ ExtensionLoader.getExtensionLoader(Serialization.class).getExtension("nativejava")
+ .serialize(null, bos).writeObject(Integer.MAX_VALUE);
+ obj = genericService.$invoke("echo", new String[]{int.class.getName()}, new Object[]{bos.toByteArray()});
+ Assert.assertTrue(obj instanceof byte[]);
+ Assert.assertEquals(Integer.MAX_VALUE,
+ ExtensionLoader.getExtensionLoader(Serialization.class)
+ .getExtension("nativejava")
+ .deserialize(null, new ByteArrayInputStream((byte[]) obj))
+ .readObject());
+
+ } finally {
+ reference.destroy();
+ }
+ } finally {
+ service.unexport();
+ }
+ }
+
+ @Test
+ public void testGenericInvokeWithBeanSerialization() throws Exception {
+ ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
+ service.setApplication(new ApplicationConfig("bean-provider"));
+ service.setInterface(DemoService.class);
+ service.setRegistry(new RegistryConfig("N/A"));
+ DemoServiceImpl impl = new DemoServiceImpl();
+ service.setRef(impl);
+ service.setProtocol(new ProtocolConfig("dubbo", 29581));
+ service.export();
+ ReferenceConfig<GenericService> reference = null;
+ try {
+ reference = new ReferenceConfig<GenericService>();
+ reference.setApplication(new ApplicationConfig("bean-consumer"));
+ reference.setInterface(DemoService.class);
+ reference.setUrl("dubbo://127.0.0.1:29581?scope=remote&timeout=3000");
+ reference.setGeneric(Constants.GENERIC_SERIALIZATION_BEAN);
+ GenericService genericService = reference.get();
+ User user = new User();
+ user.setName("zhangsan");
+ List<User> users = new ArrayList<User>();
+ users.add(user);
+ Object result = genericService.$invoke("getUsers", new String[]{ReflectUtils.getName(List.class)}, new Object[]{JavaBeanSerializeUtil.serialize(users, JavaBeanAccessor.METHOD)});
+ Assert.assertTrue(result instanceof JavaBeanDescriptor);
+ JavaBeanDescriptor descriptor = (JavaBeanDescriptor) result;
+ Assert.assertTrue(descriptor.isCollectionType());
+ Assert.assertEquals(1, descriptor.propertySize());
+ descriptor = (JavaBeanDescriptor) descriptor.getProperty(0);
+ Assert.assertTrue(descriptor.isBeanType());
+ Assert.assertEquals(user.getName(), ((JavaBeanDescriptor) descriptor.getProperty("name")).getPrimitiveProperty());
+ } finally {
+ if (reference != null) {
+ reference.destroy();
+ }
+ service.unexport();
+ }
+ }
+
+ @Test
+ public void testGenericImplementationWithBeanSerialization() throws Exception {
+ final AtomicReference reference = new AtomicReference();
+ ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
+ service.setApplication(new ApplicationConfig("bean-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("dubbo", 29581));
+ service.setInterface(DemoService.class.getName());
+ service.setRef(new GenericService() {
+
+ public Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException {
+ if ("getUsers".equals(method)) {
+ GenericParameter arg = new GenericParameter();
+ arg.method = method;
+ arg.parameterTypes = parameterTypes;
+ arg.arguments = args;
+ reference.set(arg);
+ return args[0];
+ }
+ if ("sayName".equals(method)) {
+ return null;
+ }
+ return args;
+ }
+ });
+ service.export();
+ ReferenceConfig<DemoService> ref = null;
+ try {
+ ref = new ReferenceConfig<DemoService>();
+ ref.setApplication(new ApplicationConfig("bean-consumer"));
+ ref.setInterface(DemoService.class);
+ ref.setUrl("dubbo://127.0.0.1:29581?scope=remote&generic=bean&timeout=3000");
+ DemoService demoService = ref.get();
+ User user = new User();
+ user.setName("zhangsan");
+ List<User> users = new ArrayList<User>();
+ users.add(user);
+ List<User> result = demoService.getUsers(users);
+ Assert.assertEquals(users.size(), result.size());
+ Assert.assertEquals(user.getName(), result.get(0).getName());
+
+ GenericParameter gp = (GenericParameter) reference.get();
+ Assert.assertEquals("getUsers", gp.method);
+ Assert.assertEquals(1, gp.parameterTypes.length);
+ Assert.assertEquals(ReflectUtils.getName(List.class), gp.parameterTypes[0]);
+ Assert.assertEquals(1, gp.arguments.length);
+ Assert.assertTrue(gp.arguments[0] instanceof JavaBeanDescriptor);
+ JavaBeanDescriptor descriptor = (JavaBeanDescriptor) gp.arguments[0];
+ Assert.assertTrue(descriptor.isCollectionType());
+ Assert.assertEquals(ArrayList.class.getName(), descriptor.getClassName());
+ Assert.assertEquals(1, descriptor.propertySize());
+ descriptor = (JavaBeanDescriptor) descriptor.getProperty(0);
+ Assert.assertTrue(descriptor.isBeanType());
+ Assert.assertEquals(User.class.getName(), descriptor.getClassName());
+ Assert.assertEquals(user.getName(), ((JavaBeanDescriptor) descriptor.getProperty("name")).getPrimitiveProperty());
+ Assert.assertNull(demoService.sayName("zhangsan"));
+ } finally {
+ if (ref != null) {
+ ref.destroy();
+ }
+ service.unexport();
+ }
+ }
+
+ protected static class GenericParameter {
+
+ String method;
+
+ String[] parameterTypes;
+
+ Object[] arguments;
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/MethodConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/MethodConfigTest.java
new file mode 100644
index 0000000..8f7e860
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/MethodConfigTest.java
@@ -0,0 +1,182 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+public class MethodConfigTest {
+ @Test
+ public void testName() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setName("hello");
+ assertThat(method.getName(), equalTo("hello"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MethodConfig.appendParameters(parameters, method);
+ assertThat(parameters, not(hasKey("name")));
+ }
+
+ @Test
+ public void testStat() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setStat(10);
+ assertThat(method.getStat(), equalTo(10));
+ }
+
+ @Test
+ public void testRetry() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setRetry(true);
+ assertThat(method.isRetry(), is(true));
+ }
+
+ @Test
+ public void testReliable() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setReliable(true);
+ assertThat(method.isReliable(), is(true));
+ }
+
+ @Test
+ public void testExecutes() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setExecutes(10);
+ assertThat(method.getExecutes(), equalTo(10));
+ }
+
+ @Test
+ public void testDeprecated() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setDeprecated(true);
+ assertThat(method.getDeprecated(), is(true));
+ }
+
+ @Test
+ public void testArguments() throws Exception {
+ MethodConfig method = new MethodConfig();
+ ArgumentConfig argument = new ArgumentConfig();
+ method.setArguments(Collections.singletonList(argument));
+ assertThat(method.getArguments(), contains(argument));
+ assertThat(method.getArguments(), Matchers.<ArgumentConfig>hasSize(1));
+ }
+
+ @Test
+ public void testSticky() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setSticky(true);
+ assertThat(method.getSticky(), is(true));
+ }
+
+ @Test
+ public void testOnreturn() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setOnreturn("on-return-object");
+ assertThat(method.getOnreturn(), equalTo((Object) "on-return-object"));
+ Map<String, Object> attribute = new HashMap<String, Object>();
+ MethodConfig.appendAttributes(attribute, method);
+ assertThat(attribute, hasEntry((Object) Constants.ON_RETURN_INSTANCE_KEY, (Object) "on-return-object"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MethodConfig.appendParameters(parameters, method);
+ assertThat(parameters.size(), is(0));
+ }
+
+ @Test
+ public void testOnreturnMethod() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setOnreturnMethod("on-return-method");
+ assertThat(method.getOnreturnMethod(), equalTo("on-return-method"));
+ Map<String, Object> attribute = new HashMap<String, Object>();
+ MethodConfig.appendAttributes(attribute, method);
+ assertThat(attribute, hasEntry((Object) Constants.ON_RETURN_METHOD_KEY, (Object) "on-return-method"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MethodConfig.appendParameters(parameters, method);
+ assertThat(parameters.size(), is(0));
+ }
+
+ @Test
+ public void testOnthrow() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setOnthrow("on-throw-object");
+ assertThat(method.getOnthrow(), equalTo((Object) "on-throw-object"));
+ Map<String, Object> attribute = new HashMap<String, Object>();
+ MethodConfig.appendAttributes(attribute, method);
+ assertThat(attribute, hasEntry((Object) Constants.ON_THROW_INSTANCE_KEY, (Object) "on-throw-object"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MethodConfig.appendParameters(parameters, method);
+ assertThat(parameters.size(), is(0));
+ }
+
+ @Test
+ public void testOnthrowMethod() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setOnthrowMethod("on-throw-method");
+ assertThat(method.getOnthrowMethod(), equalTo("on-throw-method"));
+ Map<String, Object> attribute = new HashMap<String, Object>();
+ MethodConfig.appendAttributes(attribute, method);
+ assertThat(attribute, hasEntry((Object) Constants.ON_THROW_METHOD_KEY, (Object) "on-throw-method"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MethodConfig.appendParameters(parameters, method);
+ assertThat(parameters.size(), is(0));
+ }
+
+ @Test
+ public void testOninvoke() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setOninvoke("on-invoke-object");
+ assertThat(method.getOninvoke(), equalTo((Object) "on-invoke-object"));
+ Map<String, Object> attribute = new HashMap<String, Object>();
+ MethodConfig.appendAttributes(attribute, method);
+ assertThat(attribute, hasEntry((Object) Constants.ON_INVOKE_INSTANCE_KEY, (Object) "on-invoke-object"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MethodConfig.appendParameters(parameters, method);
+ assertThat(parameters.size(), is(0));
+ }
+
+ @Test
+ public void testOninvokeMethod() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setOninvokeMethod("on-invoke-method");
+ assertThat(method.getOninvokeMethod(), equalTo("on-invoke-method"));
+ Map<String, Object> attribute = new HashMap<String, Object>();
+ MethodConfig.appendAttributes(attribute, method);
+ assertThat(attribute, hasEntry((Object) Constants.ON_INVOKE_METHOD_KEY, (Object) "on-invoke-method"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MethodConfig.appendParameters(parameters, method);
+ assertThat(parameters.size(), is(0));
+ }
+
+ @Test
+ public void testReturn() throws Exception {
+ MethodConfig method = new MethodConfig();
+ method.setReturn(true);
+ assertThat(method.isReturn(), is(true));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ModuleConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ModuleConfigTest.java
new file mode 100644
index 0000000..c535e99
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ModuleConfigTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.config;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
+import static org.junit.Assert.assertThat;
+
+public class ModuleConfigTest {
+ @Test(expected = IllegalStateException.class)
+ public void testName1() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ Map<String, String> parameters = new HashMap<String, String>();
+ ModuleConfig.appendParameters(parameters, module);
+ }
+
+ @Test
+ public void testName2() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ module.setName("module-name");
+ assertThat(module.getName(), equalTo("module-name"));
+ assertThat(module.getId(), equalTo("module-name"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ ModuleConfig.appendParameters(parameters, module);
+ assertThat(parameters, hasEntry("module", "module-name"));
+ }
+
+ @Test
+ public void testVersion() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ module.setName("module-name");
+ module.setVersion("1.0.0");
+ assertThat(module.getVersion(), equalTo("1.0.0"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ ModuleConfig.appendParameters(parameters, module);
+ assertThat(parameters, hasEntry("module.version", "1.0.0"));
+ }
+
+ @Test
+ public void testOwner() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ module.setOwner("owner");
+ assertThat(module.getOwner(), equalTo("owner"));
+ }
+
+ @Test
+ public void testOrganization() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ module.setOrganization("org");
+ assertThat(module.getOrganization(), equalTo("org"));
+ }
+
+ @Test
+ public void testRegistry() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ RegistryConfig registry = new RegistryConfig();
+ module.setRegistry(registry);
+ assertThat(module.getRegistry(), sameInstance(registry));
+ }
+
+ @Test
+ public void testRegistries() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ RegistryConfig registry = new RegistryConfig();
+ module.setRegistries(Collections.singletonList(registry));
+ assertThat(module.getRegistries(), Matchers.<RegistryConfig>hasSize(1));
+ assertThat(module.getRegistries(), contains(registry));
+ }
+
+ @Test
+ public void testMonitor() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ module.setMonitor("monitor-addr1");
+ assertThat(module.getMonitor().getAddress(), equalTo("monitor-addr1"));
+ module.setMonitor(new MonitorConfig("monitor-addr2"));
+ assertThat(module.getMonitor().getAddress(), equalTo("monitor-addr2"));
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ ModuleConfig module = new ModuleConfig();
+ module.setDefault(true);
+ assertThat(module.isDefault(), is(true));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/MonitorConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/MonitorConfigTest.java
new file mode 100644
index 0000000..c666072
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/MonitorConfigTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.config;
+
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class MonitorConfigTest {
+ @Test
+ public void testAddress() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setAddress("monitor-addr");
+ assertThat(monitor.getAddress(), equalTo("monitor-addr"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MonitorConfig.appendParameters(parameters, monitor);
+ assertThat(parameters.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testProtocol() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setProtocol("protocol");
+ assertThat(monitor.getProtocol(), equalTo("protocol"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MonitorConfig.appendParameters(parameters, monitor);
+ assertThat(parameters.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testUsername() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setUsername("user");
+ assertThat(monitor.getUsername(), equalTo("user"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MonitorConfig.appendParameters(parameters, monitor);
+ assertThat(parameters.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testPassword() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setPassword("secret");
+ assertThat(monitor.getPassword(), equalTo("secret"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ MonitorConfig.appendParameters(parameters, monitor);
+ assertThat(parameters.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testGroup() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setGroup("group");
+ assertThat(monitor.getGroup(), equalTo("group"));
+ }
+
+ @Test
+ public void testVersion() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setVersion("1.0.0");
+ assertThat(monitor.getVersion(), equalTo("1.0.0"));
+ }
+
+ @Test
+ public void testParameters() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ Map<String, String> parameters = Collections.singletonMap("k1", "v1");
+ monitor.setParameters(parameters);
+ assertThat(monitor.getParameters(), hasEntry("k1", "v1"));
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setDefault(true);
+ assertThat(monitor.isDefault(), is(true));
+ }
+
+ @Test
+ public void testInterval() throws Exception {
+ MonitorConfig monitor = new MonitorConfig();
+ monitor.setInterval("100");
+ assertThat(monitor.getInterval(), equalTo("100"));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ProtocolConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ProtocolConfigTest.java
new file mode 100644
index 0000000..04c5a43
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ProtocolConfigTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.config.mock.MockProtocol2;
+import org.apache.dubbo.rpc.Protocol;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class ProtocolConfigTest {
+
+ @Test
+ public void testDestroy() throws Exception {
+ Protocol protocol = Mockito.mock(Protocol.class);
+ MockProtocol2.delegate = protocol;
+ ProtocolConfig protocolConfig = new ProtocolConfig();
+ protocolConfig.setName("mockprotocol2");
+ protocolConfig.destroy();
+ Mockito.verify(protocol).destroy();
+ }
+
+ @Test
+ public void testName() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setName("name");
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProtocolConfig.appendParameters(parameters, protocol);
+ assertThat(protocol.getName(), equalTo("name"));
+ assertThat(protocol.getId(), equalTo("name"));
+ assertThat(parameters.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testHost() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setHost("host");
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProtocolConfig.appendParameters(parameters, protocol);
+ assertThat(protocol.getHost(), equalTo("host"));
+ assertThat(parameters.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testPort() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setPort(8080);
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProtocolConfig.appendParameters(parameters, protocol);
+ assertThat(protocol.getPort(), equalTo(8080));
+ assertThat(parameters.isEmpty(), is(true));
+ }
+
+ @Test
+ public void testPath() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setContextpath("context-path");
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProtocolConfig.appendParameters(parameters, protocol);
+ assertThat(protocol.getPath(), equalTo("context-path"));
+ assertThat(protocol.getContextpath(), equalTo("context-path"));
+ assertThat(parameters.isEmpty(), is(true));
+ protocol.setPath("path");
+ assertThat(protocol.getPath(), equalTo("path"));
+ assertThat(protocol.getContextpath(), equalTo("path"));
+ }
+
+ @Test
+ public void testCorethreads() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setCorethreads(10);
+ assertThat(protocol.getCorethreads(), is(10));
+ }
+
+ @Test
+ public void testThreads() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setThreads(10);
+ assertThat(protocol.getThreads(), is(10));
+ }
+
+ @Test
+ public void testIothreads() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setIothreads(10);
+ assertThat(protocol.getIothreads(), is(10));
+ }
+
+ @Test
+ public void testQueues() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setQueues(10);
+ assertThat(protocol.getQueues(), is(10));
+ }
+
+ @Test
+ public void testAccepts() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setAccepts(10);
+ assertThat(protocol.getAccepts(), is(10));
+ }
+
+ @Test
+ public void testCodec() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setName("dubbo");
+ protocol.setCodec("mockcodec");
+ assertThat(protocol.getCodec(), equalTo("mockcodec"));
+ }
+
+ @Test
+ public void testAccesslog() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setAccesslog("access.log");
+ assertThat(protocol.getAccesslog(), equalTo("access.log"));
+ }
+
+ @Test
+ public void testTelnet() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setTelnet("mocktelnethandler");
+ assertThat(protocol.getTelnet(), equalTo("mocktelnethandler"));
+ }
+
+ @Test
+ public void testRegister() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setRegister(true);
+ assertThat(protocol.isRegister(), is(true));
+ }
+
+ @Test
+ public void testTransporter() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setTransporter("mocktransporter");
+ assertThat(protocol.getTransporter(), equalTo("mocktransporter"));
+ }
+
+ @Test
+ public void testExchanger() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setExchanger("mockexchanger");
+ assertThat(protocol.getExchanger(), equalTo("mockexchanger"));
+ }
+
+ @Test
+ public void testDispatcher() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setDispatcher("mockdispatcher");
+ assertThat(protocol.getDispatcher(), equalTo("mockdispatcher"));
+ }
+
+ @Test
+ public void testNetworker() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setNetworker("networker");
+ assertThat(protocol.getNetworker(), equalTo("networker"));
+ }
+
+ @Test
+ public void testParameters() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setParameters(Collections.singletonMap("k1", "v1"));
+ assertThat(protocol.getParameters(), hasEntry("k1", "v1"));
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setDefault(true);
+ assertThat(protocol.isDefault(), is(true));
+ }
+
+ @Test
+ public void testKeepAlive() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setKeepAlive(true);
+ assertThat(protocol.getKeepAlive(), is(true));
+ }
+
+ @Test
+ public void testOptimizer() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setOptimizer("optimizer");
+ assertThat(protocol.getOptimizer(), equalTo("optimizer"));
+ }
+
+ @Test
+ public void testExtension() throws Exception {
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setExtension("extension");
+ assertThat(protocol.getExtension(), equalTo("extension"));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ProviderConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ProviderConfigTest.java
new file mode 100644
index 0000000..18c630a
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ProviderConfigTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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.config;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+public class ProviderConfigTest {
+ @Test
+ public void testProtocol() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setProtocol("protocol");
+ assertThat(provider.getProtocol().getName(), equalTo("protocol"));
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setDefault(true);
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProviderConfig.appendParameters(parameters, provider);
+ assertThat(provider.isDefault(), is(true));
+ assertThat(parameters, not(hasKey("default")));
+ }
+
+ @Test
+ public void testHost() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setHost("demo-host");
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProviderConfig.appendParameters(parameters, provider);
+ assertThat(provider.getHost(), equalTo("demo-host"));
+ assertThat(parameters, not(hasKey("host")));
+ }
+
+ @Test
+ public void testPort() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setPort(8080);
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProviderConfig.appendParameters(parameters, provider);
+ assertThat(provider.getPort(), is(8080));
+ assertThat(parameters, not(hasKey("port")));
+ }
+
+ @Test
+ public void testPath() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setPath("/path");
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProviderConfig.appendParameters(parameters, provider);
+ assertThat(provider.getPath(), equalTo("/path"));
+ assertThat(provider.getContextpath(), equalTo("/path"));
+ assertThat(parameters, not(hasKey("path")));
+ }
+
+ @Test
+ public void testContextPath() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setContextpath("/context-path");
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProviderConfig.appendParameters(parameters, provider);
+ assertThat(provider.getContextpath(), equalTo("/context-path"));
+ assertThat(parameters, not(hasKey("/context-path")));
+ }
+
+ @Test
+ public void testThreadpool() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setThreadpool("mockthreadpool");
+ assertThat(provider.getThreadpool(), equalTo("mockthreadpool"));
+ }
+
+ @Test
+ public void testThreads() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setThreads(10);
+ assertThat(provider.getThreads(), is(10));
+ }
+
+ @Test
+ public void testIothreads() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setIothreads(10);
+ assertThat(provider.getIothreads(), is(10));
+ }
+
+ @Test
+ public void testQueues() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setQueues(10);
+ assertThat(provider.getQueues(), is(10));
+ }
+
+ @Test
+ public void testAccepts() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setAccepts(10);
+ assertThat(provider.getAccepts(), is(10));
+ }
+
+ @Test
+ public void testCharset() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setCharset("utf-8");
+ assertThat(provider.getCharset(), equalTo("utf-8"));
+ }
+
+ @Test
+ public void testPayload() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setPayload(10);
+ assertThat(provider.getPayload(), is(10));
+ }
+
+ @Test
+ public void testBuffer() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setBuffer(10);
+ assertThat(provider.getBuffer(), is(10));
+ }
+
+ @Test
+ public void testServer() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setServer("demo-server");
+ assertThat(provider.getServer(), equalTo("demo-server"));
+ }
+
+ @Test
+ public void testClient() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setClient("client");
+ assertThat(provider.getClient(), equalTo("client"));
+ }
+
+ @Test
+ public void testTelnet() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setTelnet("mocktelnethandler");
+ assertThat(provider.getTelnet(), equalTo("mocktelnethandler"));
+ }
+
+ @Test
+ public void testPrompt() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setPrompt("#");
+ Map<String, String> parameters = new HashMap<String, String>();
+ ProviderConfig.appendParameters(parameters, provider);
+ assertThat(provider.getPrompt(), equalTo("#"));
+ assertThat(parameters, hasEntry("prompt", "%23"));
+ }
+
+ @Test
+ public void testStatus() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setStatus("mockstatuschecker");
+ assertThat(provider.getStatus(), equalTo("mockstatuschecker"));
+ }
+
+ @Test
+ public void testTransporter() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setTransporter("mocktransporter");
+ assertThat(provider.getTransporter(), equalTo("mocktransporter"));
+ }
+
+ @Test
+ public void testExchanger() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setExchanger("mockexchanger");
+ assertThat(provider.getExchanger(), equalTo("mockexchanger"));
+ }
+
+ @Test
+ public void testDispatcher() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setDispatcher("mockdispatcher");
+ assertThat(provider.getDispatcher(), equalTo("mockdispatcher"));
+ }
+
+ @Test
+ public void testNetworker() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setNetworker("networker");
+ assertThat(provider.getNetworker(), equalTo("networker"));
+ }
+
+ @Test
+ public void testWait() throws Exception {
+ ProviderConfig provider = new ProviderConfig();
+ provider.setWait(10);
+ assertThat(provider.getWait(), equalTo(10));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
new file mode 100644
index 0000000..0b1840f
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ReferenceConfigTest {
+
+ @Test
+ public void testInjvm() throws Exception {
+ ApplicationConfig application = new ApplicationConfig();
+ application.setName("test-protocol-random-port");
+
+ RegistryConfig registry = new RegistryConfig();
+ registry.setAddress("multicast://224.5.6.7:1234");
+
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setName("dubbo");
+
+ ServiceConfig<DemoService> demoService;
+ demoService = new ServiceConfig<DemoService>();
+ demoService.setInterface(DemoService.class);
+ demoService.setRef(new DemoServiceImpl());
+ demoService.setApplication(application);
+ demoService.setRegistry(registry);
+ demoService.setProtocol(protocol);
+
+ ReferenceConfig<DemoService> rc = new ReferenceConfig<DemoService>();
+ rc.setApplication(application);
+ rc.setRegistry(registry);
+ rc.setInterface(DemoService.class.getName());
+ rc.setInjvm(false);
+
+ try {
+ demoService.export();
+ rc.get();
+ Assert.assertTrue(!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(
+ rc.getInvoker().getUrl().getProtocol()));
+ } finally {
+ demoService.unexport();
+ }
+ }
+
+ /**
+ * unit test for dubbo-1765
+ */
+ @Test
+ public void testReferenceRetry() {
+ ApplicationConfig application = new ApplicationConfig();
+ application.setName("test-reference-retry");
+ RegistryConfig registry = new RegistryConfig();
+ registry.setAddress("multicast://224.5.6.7:1234");
+ ProtocolConfig protocol = new ProtocolConfig();
+ protocol.setName("dubbo");
+
+ ReferenceConfig<DemoService> rc = new ReferenceConfig<DemoService>();
+ rc.setApplication(application);
+ rc.setRegistry(registry);
+ rc.setInterface(DemoService.class.getName());
+
+ boolean success = false;
+ DemoService demoService = null;
+ try {
+ demoService = rc.get();
+ success = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Assert.assertFalse(success);
+ Assert.assertNull(demoService);
+
+ ServiceConfig<DemoService> sc = new ServiceConfig<DemoService>();
+ sc.setInterface(DemoService.class);
+ sc.setRef(new DemoServiceImpl());
+ sc.setApplication(application);
+ sc.setRegistry(registry);
+ sc.setProtocol(protocol);
+
+ try {
+ sc.export();
+ demoService = rc.get();
+ success = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Assert.assertTrue(success);
+ Assert.assertNotNull(demoService);
+
+ }
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/RegistryConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/RegistryConfigTest.java
new file mode 100644
index 0000000..75c99b1
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/RegistryConfigTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+public class RegistryConfigTest {
+ @Test
+ public void testProtocol() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setProtocol("protocol");
+ assertThat(registry.getProtocol(), equalTo(registry.getProtocol()));
+ }
+
+ @Test
+ public void testAddress() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setAddress("localhost");
+ assertThat(registry.getAddress(), equalTo("localhost"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ RegistryConfig.appendParameters(parameters, registry);
+ assertThat(parameters, not(hasKey("address")));
+ }
+
+ @Test
+ public void testUsername() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setUsername("username");
+ assertThat(registry.getUsername(), equalTo("username"));
+ }
+
+ @Test
+ public void testPassword() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setPassword("password");
+ assertThat(registry.getPassword(), equalTo("password"));
+ }
+
+ @Test
+ public void testWait() throws Exception {
+ try {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setWait(10);
+ assertThat(registry.getWait(), is(10));
+ assertThat(System.getProperty(Constants.SHUTDOWN_WAIT_KEY), equalTo("10"));
+ } finally {
+ System.clearProperty(Constants.SHUTDOWN_TIMEOUT_KEY);
+ }
+ }
+
+ @Test
+ public void testCheck() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setCheck(true);
+ assertThat(registry.isCheck(), is(true));
+ }
+
+ @Test
+ public void testFile() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setFile("file");
+ assertThat(registry.getFile(), equalTo("file"));
+ }
+
+ @Test
+ public void testTransporter() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setTransporter("transporter");
+ assertThat(registry.getTransporter(), equalTo("transporter"));
+ }
+
+ @Test
+ public void testClient() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setClient("client");
+ assertThat(registry.getClient(), equalTo("client"));
+ }
+
+ @Test
+ public void testTimeout() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setTimeout(10);
+ assertThat(registry.getTimeout(), is(10));
+ }
+
+ @Test
+ public void testSession() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setSession(10);
+ assertThat(registry.getSession(), is(10));
+ }
+
+ @Test
+ public void testDynamic() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setDynamic(true);
+ assertThat(registry.isDynamic(), is(true));
+ }
+
+ @Test
+ public void testRegister() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setRegister(true);
+ assertThat(registry.isRegister(), is(true));
+ }
+
+ @Test
+ public void testSubscribe() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setSubscribe(true);
+ assertThat(registry.isSubscribe(), is(true));
+ }
+
+ @Test
+ public void testCluster() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setCluster("cluster");
+ assertThat(registry.getCluster(), equalTo("cluster"));
+ }
+
+ @Test
+ public void testGroup() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setGroup("group");
+ assertThat(registry.getGroup(), equalTo("group"));
+ }
+
+ @Test
+ public void testVersion() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setVersion("1.0.0");
+ assertThat(registry.getVersion(), equalTo("1.0.0"));
+ }
+
+ @Test
+ public void testParameters() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setParameters(Collections.singletonMap("k1", "v1"));
+ assertThat(registry.getParameters(), hasEntry("k1", "v1"));
+ Map<String, String> parameters = new HashMap<String, String>();
+ RegistryConfig.appendParameters(parameters, registry);
+ assertThat(parameters, hasEntry("k1", "v1"));
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ RegistryConfig registry = new RegistryConfig();
+ registry.setDefault(true);
+ assertThat(registry.isDefault(), is(true));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ServiceConfigTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ServiceConfigTest.java
new file mode 100644
index 0000000..b0a4aef
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/ServiceConfigTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.config.mock.MockProtocol2;
+import org.apache.dubbo.config.mock.MockRegistryFactory2;
+import org.apache.dubbo.config.mock.TestProxyFactory;
+import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.service.GenericService;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Collections;
+
+import static org.apache.dubbo.common.Constants.GENERIC_SERIALIZATION_BEAN;
+import static org.apache.dubbo.common.Constants.GENERIC_SERIALIZATION_DEFAULT;
+import static org.apache.dubbo.common.Constants.GENERIC_SERIALIZATION_NATIVE_JAVA;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.withSettings;
+
+public class ServiceConfigTest {
+ private Protocol protocolDelegate = Mockito.mock(Protocol.class);
+ private Registry registryDelegate = Mockito.mock(Registry.class);
+ private Exporter exporter = Mockito.mock(Exporter.class);
+ private ServiceConfig<DemoServiceImpl> service = new ServiceConfig<DemoServiceImpl>();
+ private ServiceConfig<DemoServiceImpl> service2 = new ServiceConfig<DemoServiceImpl>();
+
+
+ @Before
+ public void setUp() throws Exception {
+ MockProtocol2.delegate = protocolDelegate;
+ MockRegistryFactory2.registry = registryDelegate;
+ Mockito.when(protocolDelegate.export(Mockito.any(Invoker.class))).thenReturn(exporter);
+
+ ApplicationConfig app = new ApplicationConfig("app");
+
+ ProtocolConfig protocolConfig = new ProtocolConfig();
+ protocolConfig.setName("mockprotocol2");
+
+ ProviderConfig provider = new ProviderConfig();
+ provider.setExport(true);
+ provider.setProtocol(protocolConfig);
+
+ RegistryConfig registry = new RegistryConfig();
+ registry.setProtocol("mockprotocol2");
+
+ ArgumentConfig argument = new ArgumentConfig();
+ argument.setIndex(0);
+ argument.setCallback(false);
+
+ MethodConfig method = new MethodConfig();
+ method.setName("echo");
+ method.setArguments(Collections.singletonList(argument));
+
+ service.setProvider(provider);
+ service.setApplication(app);
+ service.setRegistry(registry);
+ service.setInterface(DemoService.class);
+ service.setRef(new DemoServiceImpl());
+ service.setMethods(Collections.singletonList(method));
+
+ service2.setProvider(provider);
+ service2.setApplication(app);
+ service2.setRegistry(registry);
+ service2.setInterface(DemoService.class);
+ service2.setRef(new DemoServiceImpl());
+ service2.setMethods(Collections.singletonList(method));
+ service2.setProxy("testproxyfactory");
+ }
+
+ @Test
+ public void testExport() throws Exception {
+ service.export();
+
+ assertThat(service.getExportedUrls(), hasSize(1));
+ URL url = service.toUrl();
+ assertThat(url.getProtocol(), equalTo("mockprotocol2"));
+ assertThat(url.getPath(), equalTo(DemoService.class.getName()));
+ assertThat(url.getParameters(), hasEntry(Constants.ANYHOST_KEY, "true"));
+ assertThat(url.getParameters(), hasEntry(Constants.APPLICATION_KEY, "app"));
+ assertThat(url.getParameters(), hasKey(Constants.BIND_IP_KEY));
+ assertThat(url.getParameters(), hasKey(Constants.BIND_PORT_KEY));
+ assertThat(url.getParameters(), hasEntry(Constants.DEFAULT_KEY + "." + Constants.EXPORT_KEY, "true"));
+ assertThat(url.getParameters(), hasEntry(Constants.EXPORT_KEY, "true"));
+ assertThat(url.getParameters(), hasEntry("echo.0.callback", "false"));
+ assertThat(url.getParameters(), hasEntry(Constants.GENERIC_KEY, "false"));
+ assertThat(url.getParameters(), hasEntry(Constants.INTERFACE_KEY, DemoService.class.getName()));
+ assertThat(url.getParameters(), hasKey(Constants.METHODS_KEY));
+ assertThat(url.getParameters().get(Constants.METHODS_KEY), containsString("echo"));
+ assertThat(url.getParameters(), hasEntry(Constants.SIDE_KEY, Constants.PROVIDER));
+ Mockito.verify(protocolDelegate).export(Mockito.any(Invoker.class));
+ }
+
+ @Test
+ public void testProxy() throws Exception {
+ service2.export();
+
+ assertThat(service2.getExportedUrls(), hasSize(1));
+ assertEquals(2, TestProxyFactory.count); // local injvm and registry protocol, so expected is 2
+ }
+
+ @Test
+ @Ignore("cannot pass in travis")
+ public void testUnexport() throws Exception {
+ System.setProperty(Constants.SHUTDOWN_WAIT_KEY, "0");
+ try {
+ service.export();
+ service.unexport();
+ Thread.sleep(1000);
+ Mockito.verify(exporter, Mockito.atLeastOnce()).unexport();
+ } finally {
+ System.clearProperty(Constants.SHUTDOWN_TIMEOUT_KEY);
+ }
+ }
+
+ @Test
+ public void testInterfaceClass() throws Exception {
+ ServiceConfig<Greeting> service = new ServiceConfig<Greeting>();
+ service.setInterface(Greeting.class.getName());
+ service.setRef(Mockito.mock(Greeting.class));
+ assertThat(service.getInterfaceClass() == Greeting.class, is(true));
+ service = new ServiceConfig<Greeting>();
+ service.setRef(Mockito.mock(Greeting.class, withSettings().extraInterfaces(GenericService.class)));
+ assertThat(service.getInterfaceClass() == GenericService.class, is(true));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testInterface1() throws Exception {
+ ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
+ service.setInterface(DemoServiceImpl.class);
+ }
+
+ @Test
+ public void testInterface2() throws Exception {
+ ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
+ service.setInterface(DemoService.class);
+ assertThat(service.getInterface(), equalTo(DemoService.class.getName()));
+ }
+
+ @Test
+ public void testProvider() throws Exception {
+ ServiceConfig service = new ServiceConfig();
+ ProviderConfig provider = new ProviderConfig();
+ service.setProvider(provider);
+ assertThat(service.getProvider(), is(provider));
+ }
+
+ @Test
+ public void testGeneric1() throws Exception {
+ ServiceConfig service = new ServiceConfig();
+ service.setGeneric(GENERIC_SERIALIZATION_DEFAULT);
+ assertThat(service.getGeneric(), equalTo(GENERIC_SERIALIZATION_DEFAULT));
+ service.setGeneric(GENERIC_SERIALIZATION_NATIVE_JAVA);
+ assertThat(service.getGeneric(), equalTo(GENERIC_SERIALIZATION_NATIVE_JAVA));
+ service.setGeneric(GENERIC_SERIALIZATION_BEAN);
+ assertThat(service.getGeneric(), equalTo(GENERIC_SERIALIZATION_BEAN));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGeneric2() throws Exception {
+ ServiceConfig service = new ServiceConfig();
+ service.setGeneric("illegal");
+ }
+
+ @Test
+ public void testUniqueServiceName() throws Exception {
+ ServiceConfig<Greeting> service = new ServiceConfig<Greeting>();
+ service.setGroup("dubbo");
+ service.setInterface(Greeting.class);
+ service.setVersion("1.0.0");
+ assertThat(service.getUniqueServiceName(), equalTo("dubbo/" + Greeting.class.getName() + ":1.0.0"));
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/Box.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/Box.java
new file mode 100644
index 0000000..e63f924
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/Box.java
@@ -0,0 +1,23 @@
+/*
+ * 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.config.api;
+
+public interface Box {
+
+ String getName();
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/DemoException.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/DemoException.java
new file mode 100644
index 0000000..2f32c3f
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/DemoException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.config.api;
+
+/**
+ * DemoException
+ */
+public class DemoException extends Exception {
+
+ private static final long serialVersionUID = -8213943026163641747L;
+
+ public DemoException() {
+ super();
+ }
+
+ public DemoException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DemoException(String message) {
+ super(message);
+ }
+
+ public DemoException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/DemoService.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/DemoService.java
new file mode 100644
index 0000000..c5bc722
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/DemoService.java
@@ -0,0 +1,37 @@
+/*
+ * 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.config.api;
+
+import java.util.List;
+
+
+/**
+ * DemoService
+ */
+public interface DemoService {
+
+ String sayName(String name);
+
+ Box getBox();
+
+ void throwDemoException() throws DemoException;
+
+ List<User> getUsers(List<User> users);
+
+ int echo(int i);
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/Greeting.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/Greeting.java
new file mode 100644
index 0000000..c2afa98
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/Greeting.java
@@ -0,0 +1,24 @@
+/*
+ * 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.config.api;
+
+import org.apache.dubbo.common.extension.SPI;
+
+@SPI
+public interface Greeting {
+ String hello();
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/User.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/User.java
new file mode 100644
index 0000000..5e55cbb
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/api/User.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.api;
+
+import java.io.Serializable;
+
+/**
+ * User
+ */
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String name;
+
+ public User() {
+ }
+
+ public User(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public int hashCode() {
+ return name == null ? -1 : name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof User)) {
+ return false;
+ }
+ User other = (User) obj;
+ if (this == other) {
+ return true;
+ }
+ if (name != null && other.name != null) {
+ return name.equals(other.name);
+ }
+ return false;
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheService.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheService.java
new file mode 100644
index 0000000..7696b24
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheService.java
@@ -0,0 +1,26 @@
+/*
+ * 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.config.cache;
+
+/**
+ * ValidationService
+ */
+public interface CacheService {
+
+ String findCache(String id);
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheServiceImpl.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheServiceImpl.java
new file mode 100644
index 0000000..14e9ee7
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheServiceImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.config.cache;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * ValidationServiceImpl
+ */
+public class CacheServiceImpl implements CacheService {
+
+ private final AtomicInteger i = new AtomicInteger();
+
+ public String findCache(String id) {
+ return "request: " + id + ", response: " + i.getAndIncrement();
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheTest.java
new file mode 100644
index 0000000..6c79b8e
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/cache/CacheTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.config.cache;
+
+import junit.framework.TestCase;
+import org.apache.dubbo.cache.Cache;
+import org.apache.dubbo.cache.CacheFactory;
+import org.apache.dubbo.cache.support.threadlocal.ThreadLocalCache;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MethodConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.RpcInvocation;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * CacheTest
+ */
+public class CacheTest extends TestCase {
+
+ private void testCache(String type) throws Exception {
+ ServiceConfig<CacheService> service = new ServiceConfig<CacheService>();
+ service.setApplication(new ApplicationConfig("cache-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("injvm"));
+ service.setInterface(CacheService.class.getName());
+ service.setRef(new CacheServiceImpl());
+ service.export();
+ try {
+ ReferenceConfig<CacheService> reference = new ReferenceConfig<CacheService>();
+ reference.setApplication(new ApplicationConfig("cache-consumer"));
+ reference.setInterface(CacheService.class);
+ reference.setUrl("injvm://127.0.0.1?scope=remote&cache=true");
+
+ MethodConfig method = new MethodConfig();
+ method.setName("findCache");
+ method.setCache(type);
+ reference.setMethods(Arrays.asList(method));
+
+ CacheService cacheService = reference.get();
+ try {
+ // verify cache, same result is returned for multiple invocations (in fact, the return value increases
+ // on every invocation on the server side)
+ String fix = null;
+ for (int i = 0; i < 3; i++) {
+ String result = cacheService.findCache("0");
+ assertTrue(fix == null || fix.equals(result));
+ fix = result;
+ Thread.sleep(100);
+ }
+
+ if ("lru".equals(type)) {
+ // default cache.size is 1000 for LRU, should have cache expired if invoke more than 1001 times
+ for (int n = 0; n < 1001; n++) {
+ String pre = null;
+ for (int i = 0; i < 10; i++) {
+ String result = cacheService.findCache(String.valueOf(n));
+ assertTrue(pre == null || pre.equals(result));
+ pre = result;
+ }
+ }
+
+ // verify if the first cache item is expired in LRU cache
+ String result = cacheService.findCache("0");
+ assertFalse(fix == null || fix.equals(result));
+ }
+ } finally {
+ reference.destroy();
+ }
+ } finally {
+ service.unexport();
+ }
+ }
+
+ @Test
+ public void testCache() throws Exception {
+ testCache("lru");
+ testCache("threadlocal");
+ }
+
+ @Test
+ public void testCacheProvider() throws Exception {
+ CacheFactory cacheFactory = ExtensionLoader.getExtensionLoader(CacheFactory.class).getAdaptiveExtension();
+
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("findCache.cache", "threadlocal");
+ URL url = new URL("dubbo", "127.0.0.1", 29582, "org.apache.dubbo.config.cache.CacheService", parameters);
+
+ Invocation invocation = new RpcInvocation("findCache", new Class[]{String.class}, new String[]{"0"}, null, null);
+
+ Cache cache = cacheFactory.getCache(url, invocation);
+ assertTrue(cache instanceof ThreadLocalCache);
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoActionByAnnotation.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoActionByAnnotation.java
new file mode 100644
index 0000000..8fd477a
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoActionByAnnotation.java
@@ -0,0 +1,34 @@
+/*
+ * 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.config.consumer;
+
+import org.apache.dubbo.config.api.DemoService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * DemoAction
+ */
+public class DemoActionByAnnotation {
+
+ @Autowired
+ private DemoService demoService;
+
+ public DemoService getDemoService() {
+ return demoService;
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoActionBySetter.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoActionBySetter.java
new file mode 100644
index 0000000..0606e26
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoActionBySetter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.config.consumer;
+
+import org.apache.dubbo.config.api.DemoService;
+
+/**
+ * DemoAction
+ */
+public class DemoActionBySetter {
+
+ private DemoService demoService;
+
+ public DemoService getDemoService() {
+ return demoService;
+ }
+
+ public void setDemoService(DemoService demoService) {
+ this.demoService = demoService;
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoInterceptor.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoInterceptor.java
new file mode 100644
index 0000000..46d7e9a
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/consumer/DemoInterceptor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.config.consumer;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * DemoInterceptor
+ */
+public class DemoInterceptor implements MethodInterceptor {
+
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ return "aop:" + invocation.proceed();
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java
new file mode 100644
index 0000000..7630842
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/invoker/DelegateProviderMetaDataInvokerTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.config.invoker;
+
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.api.Greeting;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.hamcrest.Matchers.sameInstance;
+import static org.junit.Assert.assertThat;
+
+public class DelegateProviderMetaDataInvokerTest {
+ private ServiceConfig service;
+ private Invoker<Greeting> invoker;
+
+ @Before
+ public void setUp() throws Exception {
+ service = Mockito.mock(ServiceConfig.class);
+ invoker = Mockito.mock(Invoker.class);
+ }
+
+ @Test
+ public void testDelegate() throws Exception {
+ DelegateProviderMetaDataInvoker<Greeting> delegate =
+ new DelegateProviderMetaDataInvoker<Greeting>(invoker, service);
+ delegate.getInterface();
+ Mockito.verify(invoker).getInterface();
+ delegate.getUrl();
+ Mockito.verify(invoker).getUrl();
+ delegate.isAvailable();
+ Mockito.verify(invoker).isAvailable();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ delegate.invoke(invocation);
+ Mockito.verify(invoker).invoke(invocation);
+ delegate.destroy();
+ Mockito.verify(invoker).destroy();
+ assertThat(delegate.getMetadata(), sameInstance(service));
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal1.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal1.java
new file mode 100644
index 0000000..f3d5ee5
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal1.java
@@ -0,0 +1,21 @@
+/*
+ * 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.config.mock;
+
+public class GreetingLocal1 {
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal2.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal2.java
new file mode 100644
index 0000000..8cae406
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal2.java
@@ -0,0 +1,26 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.config.api.Greeting;
+
+public class GreetingLocal2 implements Greeting {
+ @Override
+ public String hello() {
+ return "local";
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal3.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal3.java
new file mode 100644
index 0000000..9b14ac6
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingLocal3.java
@@ -0,0 +1,32 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.config.api.Greeting;
+
+public class GreetingLocal3 implements Greeting {
+ private Greeting greeting;
+
+ public GreetingLocal3(Greeting greeting) {
+ this.greeting = greeting;
+ }
+
+ @Override
+ public String hello() {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingMock1.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingMock1.java
new file mode 100644
index 0000000..8bfe6e6
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingMock1.java
@@ -0,0 +1,20 @@
+/*
+ * 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.config.mock;
+
+public class GreetingMock1 {
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingMock2.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingMock2.java
new file mode 100644
index 0000000..429bff4
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/GreetingMock2.java
@@ -0,0 +1,29 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.config.api.Greeting;
+
+public class GreetingMock2 implements Greeting {
+ private GreetingMock2() {
+ }
+
+ @Override
+ public String hello() {
+ return "mock";
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockCluster.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockCluster.java
new file mode 100644
index 0000000..39bf974
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockCluster.java
@@ -0,0 +1,29 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Cluster;
+import org.apache.dubbo.rpc.cluster.Directory;
+
+public class MockCluster implements Cluster {
+ @Override
+ public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockCodec.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockCodec.java
new file mode 100644
index 0000000..c1aac42
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockCodec.java
@@ -0,0 +1,37 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.remoting.Channel;
+import org.apache.dubbo.remoting.Codec;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class MockCodec implements Codec {
+ @Override
+ public void encode(Channel channel, OutputStream output, Object message) throws IOException {
+
+ }
+
+ @Override
+ public Object decode(Channel channel, InputStream input) throws IOException {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockDispatcher.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockDispatcher.java
new file mode 100644
index 0000000..32fffca
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockDispatcher.java
@@ -0,0 +1,29 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.ChannelHandler;
+import org.apache.dubbo.remoting.Dispatcher;
+
+public class MockDispatcher implements Dispatcher {
+ @Override
+ public ChannelHandler dispatch(ChannelHandler handler, URL url) {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockExchanger.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockExchanger.java
new file mode 100644
index 0000000..fccfd23
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockExchanger.java
@@ -0,0 +1,37 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.exchange.ExchangeClient;
+import org.apache.dubbo.remoting.exchange.ExchangeHandler;
+import org.apache.dubbo.remoting.exchange.ExchangeServer;
+import org.apache.dubbo.remoting.exchange.Exchanger;
+
+public class MockExchanger implements Exchanger {
+ @Override
+ public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
+ return null;
+ }
+
+ @Override
+ public ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockExporterListener.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockExporterListener.java
new file mode 100644
index 0000000..b93f44c
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockExporterListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ExporterListener;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockExporterListener implements ExporterListener {
+ @Override
+ public void exported(Exporter<?> exporter) throws RpcException {
+
+ }
+
+ @Override
+ public void unexported(Exporter<?> exporter) {
+
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockFilter.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockFilter.java
new file mode 100644
index 0000000..d51f123
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockFilter.java
@@ -0,0 +1,30 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockFilter implements Filter {
+ @Override
+ public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockInvokerListener.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockInvokerListener.java
new file mode 100644
index 0000000..c929e54
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockInvokerListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.InvokerListener;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockInvokerListener implements InvokerListener {
+ @Override
+ public void referred(Invoker<?> invoker) throws RpcException {
+
+ }
+
+ @Override
+ public void destroyed(Invoker<?> invoker) {
+
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockLoadBalance.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockLoadBalance.java
new file mode 100644
index 0000000..377f328
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockLoadBalance.java
@@ -0,0 +1,32 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.LoadBalance;
+
+import java.util.List;
+
+public class MockLoadBalance implements LoadBalance {
+ @Override
+ public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProtocol.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProtocol.java
new file mode 100644
index 0000000..f4cb8ce
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProtocol.java
@@ -0,0 +1,86 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockProtocol implements Protocol {
+
+ /* (non-Javadoc)
+ * @see org.apache.dubbo.rpc.Protocol#getDefaultPort()
+ */
+ @Override
+ public int getDefaultPort() {
+
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.dubbo.rpc.Protocol#export(org.apache.dubbo.rpc.Invoker)
+ */
+ public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.dubbo.rpc.Protocol#refer(java.lang.Class, org.apache.dubbo.common.URL)
+ */
+ public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
+
+ final URL u = url;
+
+ return new Invoker<T>() {
+ @Override
+ public Class<T> getInterface() {
+ return null;
+ }
+
+ public URL getUrl() {
+ return u;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ public Result invoke(Invocation invocation) throws RpcException {
+ return null;
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+ };
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.dubbo.rpc.Protocol#destroy()
+ */
+ @Override
+ public void destroy() {
+
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProtocol2.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProtocol2.java
new file mode 100644
index 0000000..91653d4
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProtocol2.java
@@ -0,0 +1,48 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockProtocol2 implements Protocol {
+ public static Protocol delegate;
+
+ @Override
+ public int getDefaultPort() {
+ return delegate.getDefaultPort();
+ }
+
+ @Override
+ public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
+ return delegate.export(invoker);
+ }
+
+ @Override
+ public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
+ return delegate.refer(type, url);
+ }
+
+ @Override
+ public void destroy() {
+ delegate.destroy();
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProxyFactory.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProxyFactory.java
new file mode 100644
index 0000000..49f05d8
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockProxyFactory.java
@@ -0,0 +1,39 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.RpcException;
+
+public class MockProxyFactory implements ProxyFactory {
+ @Override
+ public <T> T getProxy(Invoker<T> invoker) throws RpcException {
+ return null;
+ }
+
+ @Override
+ public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
+ return null;
+ }
+
+ @Override
+ public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistry.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistry.java
new file mode 100644
index 0000000..5632887
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistry.java
@@ -0,0 +1,108 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.NotifyListener;
+import org.apache.dubbo.registry.Registry;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TODO Comment of MockRegistry
+ */
+public class MockRegistry implements Registry {
+
+ static URL subscribedUrl = new URL("null", "0.0.0.0", 0);
+
+ public static URL getSubscribedUrl() {
+ return subscribedUrl;
+ }
+
+ /*
+ * @see org.apache.dubbo.common.Node#getUrl()
+ */
+ public URL getUrl() {
+ return null;
+ }
+
+ /*
+ * @see org.apache.dubbo.common.Node#isAvailable()
+ */
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ /*
+ * @see org.apache.dubbo.common.Node#destroy()
+ */
+ @Override
+ public void destroy() {
+
+ }
+
+ /*
+ * @see org.apache.dubbo.registry.RegistryService#register(org.apache.dubbo.common.URL)
+ */
+ @Override
+ public void register(URL url) {
+
+ }
+
+ /*
+ * @see org.apache.dubbo.registry.RegistryService#unregister(org.apache.dubbo.common.URL)
+ */
+ @Override
+ public void unregister(URL url) {
+
+ }
+
+ /*
+ * @see org.apache.dubbo.registry.RegistryService#subscribe(org.apache.dubbo.common.URL, org.apache.dubbo.registry.NotifyListener)
+ */
+ @Override
+ public void subscribe(URL url, NotifyListener listener) {
+ this.subscribedUrl = url;
+ List<URL> urls = new ArrayList<URL>();
+
+ urls.add(url.setProtocol("mockprotocol")
+ .removeParameter(Constants.CATEGORY_KEY)
+ .addParameter(Constants.METHODS_KEY, "sayHello"));
+
+ listener.notify(urls);
+ }
+
+ /*
+ * @see org.apache.dubbo.registry.RegistryService#unsubscribe(org.apache.dubbo.common.URL, org.apache.dubbo.registry.NotifyListener)
+ */
+ @Override
+ public void unsubscribe(URL url, NotifyListener listener) {
+
+ }
+
+ /*
+ * @see org.apache.dubbo.registry.RegistryService#lookup(org.apache.dubbo.common.URL)
+ */
+ @Override
+ public List<URL> lookup(URL url) {
+ return null;
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistryFactory.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistryFactory.java
new file mode 100644
index 0000000..1e0e6e7
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistryFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.RegistryFactory;
+
+/**
+ * TODO Comment of MockRegistryFactory
+ */
+public class MockRegistryFactory implements RegistryFactory {
+
+ /*
+ * @see org.apache.dubbo.registry.RegistryFactory#getRegistry(org.apache.dubbo.common.URL)
+ */
+ @Override
+ public Registry getRegistry(URL url) {
+
+ return new MockRegistry();
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistryFactory2.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistryFactory2.java
new file mode 100644
index 0000000..2ab3da8
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockRegistryFactory2.java
@@ -0,0 +1,31 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.RegistryFactory;
+
+public class MockRegistryFactory2 implements RegistryFactory {
+ public static Registry registry;
+
+ @Override
+ public Registry getRegistry(URL url) {
+ return registry;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockStatusChecker.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockStatusChecker.java
new file mode 100644
index 0000000..e144c7b
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockStatusChecker.java
@@ -0,0 +1,28 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.status.Status;
+import org.apache.dubbo.common.status.StatusChecker;
+
+public class MockStatusChecker implements StatusChecker {
+ @Override
+ public Status check() {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockTelnetHandler.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockTelnetHandler.java
new file mode 100644
index 0000000..a08160f
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockTelnetHandler.java
@@ -0,0 +1,29 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.remoting.Channel;
+import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.telnet.TelnetHandler;
+
+public class MockTelnetHandler implements TelnetHandler {
+ @Override
+ public String telnet(Channel channel, String message) throws RemotingException {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockThreadPool.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockThreadPool.java
new file mode 100644
index 0000000..fe96689
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockThreadPool.java
@@ -0,0 +1,30 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.threadpool.ThreadPool;
+
+import java.util.concurrent.Executor;
+
+public class MockThreadPool implements ThreadPool {
+ @Override
+ public Executor getExecutor(URL url) {
+ return null;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockTransporter.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockTransporter.java
new file mode 100644
index 0000000..08d005d
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/MockTransporter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.ChannelHandler;
+import org.apache.dubbo.remoting.Client;
+import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.Server;
+import org.apache.dubbo.remoting.Transporter;
+import org.mockito.Mockito;
+
+public class MockTransporter implements Transporter {
+ private Server server = Mockito.mock(Server.class);
+ private Client client = Mockito.mock(Client.class);
+
+ @Override
+ public Server bind(URL url, ChannelHandler handler) throws RemotingException {
+ return server;
+ }
+
+ @Override
+ public Client connect(URL url, ChannelHandler handler) throws RemotingException {
+ return client;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/TestProxyFactory.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/TestProxyFactory.java
new file mode 100644
index 0000000..fe22bd1
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/mock/TestProxyFactory.java
@@ -0,0 +1,33 @@
+/*
+ * 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.config.mock;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory;
+
+public class TestProxyFactory extends JdkProxyFactory {
+ public static int count = 0;
+
+ @Override
+ public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
+ count++;
+ return super.getInvoker(proxy, type, url);
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/provider/impl/DemoServiceImpl.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/provider/impl/DemoServiceImpl.java
new file mode 100644
index 0000000..d81269e
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/provider/impl/DemoServiceImpl.java
@@ -0,0 +1,51 @@
+/*
+ * 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.config.provider.impl;
+
+import org.apache.dubbo.config.api.Box;
+import org.apache.dubbo.config.api.DemoException;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.api.User;
+
+import java.util.List;
+
+/**
+ * DemoServiceImpl
+ */
+public class DemoServiceImpl implements DemoService {
+
+ public String sayName(String name) {
+ return "say:" + name;
+ }
+
+ public Box getBox() {
+ return null;
+ }
+
+ public void throwDemoException() throws DemoException {
+ throw new DemoException("DemoServiceImpl");
+ }
+
+ public List<User> getUsers(List<User> users) {
+ return users;
+ }
+
+ public int echo(int i) {
+ return i;
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
new file mode 100644
index 0000000..e2ebd63
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.config.url;
+
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+public class ExporterSideConfigUrlTest extends UrlTestBase {
+
+ private static final Logger log = LoggerFactory.getLogger(ExporterSideConfigUrlTest.class);
+
+ // ======================================================
+ // tests start
+ // ======================================================
+ @BeforeClass
+ public static void start() {
+ }
+
+
+ @Before
+ public void setUp() {
+ initServConf();
+ }
+
+ @After()
+ public void teardown() {
+ }
+
+ @Test
+ public void exporterMethodConfigUrlTest() {
+ verifyExporterUrlGeneration(methodConfForService, methodConfForServiceTable);
+ }
+
+ @Test
+ public void exporterServiceConfigUrlTest() {
+ verifyExporterUrlGeneration(servConf, servConfTable);
+ }
+
+ @Test
+ public void exporterProviderConfigUrlTest() {
+
+ verifyExporterUrlGeneration(provConf, provConfTable);
+ }
+
+ @Test
+ public void exporterRegistryConfigUrlTest() {
+
+ //verifyExporterUrlGeneration(regConfForService, regConfForServiceTable);
+ }
+
+
+ protected <T> void verifyExporterUrlGeneration(T config, Object[][] dataTable) {
+
+ // 1. fill corresponding config with data
+ ////////////////////////////////////////////////////////////
+ fillConfigs(config, dataTable, TESTVALUE1);
+
+ // 2. export service and get url parameter string from db
+ ////////////////////////////////////////////////////////////
+ servConf.export();
+ String paramStringFromDb = getProviderParamString();
+ try {
+ paramStringFromDb = URLDecoder.decode(paramStringFromDb, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // impossible
+ }
+
+
+ assertUrlStringWithLocalTable(paramStringFromDb, dataTable, config.getClass().getName(), TESTVALUE1);
+
+
+ // 4. unexport service
+ ////////////////////////////////////////////////////////////
+ servConf.unexport();
+ }
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
new file mode 100644
index 0000000..a7b5842
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/InvokerSideConfigUrlTest.java
@@ -0,0 +1,227 @@
+/*
+ * 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.config.url;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ConsumerConfig;
+import org.apache.dubbo.config.MethodConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.mock.MockRegistry;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+
+public class InvokerSideConfigUrlTest extends UrlTestBase {
+ private static final Logger log = LoggerFactory.getLogger(InvokerSideConfigUrlTest.class);
+
+ // ======================================================
+ // invoker related data preparing
+ // ======================================================
+ private ApplicationConfig appConfForConsumer;
+ private ApplicationConfig appConfForReference;
+ private RegistryConfig regConfForConsumer;
+ private RegistryConfig regConfForReference;
+ private MethodConfig methodConfForReference;
+ private ConsumerConfig consumerConf;
+ private ReferenceConfig<DemoService> refConf;
+
+ private Object appConfForConsumerTable[][] = {
+ {"", "", "", "", "", "", "", "", "", ""},
+ };
+
+ private Object appConfForReferenceTable[][] = {
+ {"", "", "", "", "", "", "", "", "", ""},
+ };
+
+ private Object regConfForConsumerTable[][] = {
+// {"timeout", "registry.timeout", "int", 5000, 9000, "", "", "", "", ""},
+// {"file", "registry.file", "string", "", "regConfForServiceTable.log", "", "", "", "", ""},
+// {"wait", "registry.wait", "int", 0, 9000, "", "", "", "", ""},
+// {"transport", "registry.transporter", "string", "netty", "mina", "", "", "", "", ""},
+ {"subscribe", "subscribe", "boolean", true, false, "", "", "", "", ""},
+ {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
+ };
+
+ private Object regConfForReferenceTable[][] = {
+ {"timeout", "registry.timeout", "int", 5000, 9000, "", "", "", "", ""},
+ {"file", "registry.file", "string", "", "regConfForServiceTable.log", "", "", "", "", ""},
+ {"wait", "registry.wait", "int", 0, 9000, "", "", "", "", ""},
+ {"transport", "registry.transporter", "string", "netty", "mina", "", "", "", "", ""},
+ {"subscribe", "subscribe", "boolean", true, false, "", "", "", "", ""},
+ {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
+ };
+
+ private Object methodConfForReferenceTable[][] = {
+ {"actives", "eatTiger.actives", "int", 0, 90, "", "", "", "", ""},
+ {"executes", "eatTiger.executes", "int", 0, 90, "", "", "", "", ""},
+ {"deprecated", "eatTiger.deprecated", "boolean", false, true, "", "", "", "", ""},
+ {"async", "eatTiger.async", "boolean", false, true, "", "", "", "", ""},
+ {"timeout", "eatTiger.timeout", "int", 0, 90, "", "", "", "", ""},
+ };
+
+ private Object refConfTable[][] = {
+// {"version", "version", "string", "0.0.0", "1.2.3", "", "", "", "", ""},
+// {"group", "group", "string", "", "HaominTest", "", "", "", "", ""},
+
+// {"delay", "delay", "int", 0, 5, "", "", "", "", ""}, // not boolean
+ {"timeout", "timeout", "int", 5000, 3000, "", "", "", "", ""},
+ {"retries", "retries", "int", 2, 5, "", "", "", "", ""},
+ {"connections", "connections", "boolean", 100, 20, "", "", "", "", ""},
+ {"loadbalance", "loadbalance", "string", "random", "roundrobin", "leastactive", "", "", ""},
+ {"async", "async", "boolean", false, true, "", "", "", "", ""},
+ //excluded = true
+// {"generic", "generic", "boolean", false, true, "", "", "", "", ""},
+ {"check", "check", "boolean", false, true, "", "", "", "", ""},
+ //{"local", "local", "string", "false", "HelloServiceLocal", "true", "", "", "", ""},
+ //{"local", "local", "string", "false", "true", "", "", "", "", ""},
+ //{"mock", "mock", "string", "false", "dubbo.test.HelloServiceMock", "true", "", "", "", ""},
+ {"mock", "mock", "string", "false", "false", "", "", "", "", ""},
+ {"proxy", "proxy", "boolean", "javassist", "jdk", "", "", "", "", ""},
+ {"client", "client", "string", "netty", "mina", "", "", "", "", ""},
+ {"client", "client", "string", "netty", "mina", "", "", "", "", ""},
+ {"owner", "owner", "string", "", "haomin,ludvik", "", "", "", "", ""},
+ {"actives", "actives", "int", 0, 30, "", "", "", "", ""},
+ {"cluster", "cluster", "string", "failover", "failfast", "failsafe", "failback", "forking", "", ""},
+ //excluded = true
+// {"filter", "service.filter", "string", "default", "-generic", "", "", "", "", ""},
+ //excluded = true
+// {"listener", "exporter.listener", "string", "default", "-deprecated", "", "", "", "", ""},
+ //{"", "", "", "", "", "", "", "", "", ""},
+ };
+
+ private Object consumerConfTable[][] = {
+ {"timeout", "default.timeout", "int", 5000, 8000, "", "", "", "", ""},
+ {"retries", "default.retries", "int", 2, 5, "", "", "", "", ""},
+ {"loadbalance", "default.loadbalance", "string", "random", "leastactive", "", "", "", "", ""},
+ {"async", "default.async", "boolean", false, true, "", "", "", "", ""},
+ {"connections", "default.connections", "int", 100, 5, "", "", "", "", ""},
+// {"generic", "generic", "boolean", false, false, "", "", "", "", ""},
+ {"check", "check", "boolean", true, false, "", "", "", "", ""},
+ {"proxy", "proxy", "string", "javassist", "jdk", "javassist", "", "", "", ""},
+ {"owner", "owner", "string", "", "haomin", "", "", "", "", ""},
+ {"actives", "default.actives", "int", 0, 5, "", "", "", "", ""},
+ {"cluster", "default.cluster", "string", "failover", "forking", "", "", "", "", ""},
+ {"filter", "", "string", "", "", "", "", "", "", ""},
+ {"listener", "", "string", "", "", "", "", "", "", ""},
+// {"", "", "", "", "", "", "", "", "", ""},
+ };
+
+ // ======================================================
+ // test Start
+ // ======================================================
+
+ @BeforeClass
+ public static void start() {
+ //RegistryController.startRegistryIfAbsence(1);
+ }
+
+
+ @Before
+ public void setUp() {
+ initServConf();
+ initRefConf();
+ }
+
+ @After()
+ public void teardown() {
+ //RegistryServer.reloadCache();
+ }
+
+
+ @Test
+ public void consumerConfUrlTest() {
+ verifyInvokerUrlGeneration(consumerConf, consumerConfTable);
+ }
+
+ @Test
+ public void refConfUrlTest() {
+ verifyInvokerUrlGeneration(refConf, refConfTable);
+ }
+
+ @Ignore("parameter on register center will not be merged any longer with query parameter request from the consumer")
+ @Test
+ public void regConfForConsumerUrlTest() {
+ verifyInvokerUrlGeneration(regConfForConsumer, regConfForConsumerTable);
+ }
+
+ // ======================================================
+ // private helper
+ // ======================================================
+ private void initRefConf() {
+
+ appConfForConsumer = new ApplicationConfig();
+ appConfForReference = new ApplicationConfig();
+ regConfForConsumer = new RegistryConfig();
+ regConfForReference = new RegistryConfig();
+ methodConfForReference = new MethodConfig();
+
+ refConf = new ReferenceConfig<DemoService>();
+ consumerConf = new ConsumerConfig();
+
+ methodConfForReference.setName("sayName");
+ regConfForReference.setAddress("127.0.0.1:9090");
+ regConfForReference.setProtocol("mockregistry");
+ appConfForReference.setName("ConfigTests");
+ refConf.setInterface("org.apache.dubbo.config.api.DemoService");
+
+ refConf.setApplication(appConfForReference);
+ consumerConf.setApplication(appConfForConsumer);
+
+ refConf.setRegistry(regConfForReference);
+ consumerConf.setRegistry(regConfForConsumer);
+
+ refConf.setConsumer(consumerConf);
+
+ refConf.setMethods(Arrays.asList(new MethodConfig[]{methodConfForReference}));
+
+ refConf.setScope(Constants.SCOPE_REMOTE);
+ }
+
+ private <T> void verifyInvokerUrlGeneration(T config, Object[][] dataTable) {
+ servConf.export();
+
+ fillConfigs(config, dataTable, TESTVALUE1);
+ refConf.get();
+
+ String subScribedUrlStr = getSubscribedUrlString();
+
+ System.out.println("url string=========:" + subScribedUrlStr);
+ String configName = config.getClass().getName();
+ int column = TESTVALUE1;
+
+ assertUrlStringWithLocalTable(subScribedUrlStr, dataTable, configName, column);
+
+ try {
+ refConf.destroy();
+ } catch (Exception e) {
+ }
+ }
+
+ private String getSubscribedUrlString() {
+ return MockRegistry.getSubscribedUrl().toString();
+ }
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/RpcConfigGetSetProxy.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/RpcConfigGetSetProxy.java
new file mode 100644
index 0000000..d883ec2
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/RpcConfigGetSetProxy.java
@@ -0,0 +1,166 @@
+/*
+ * 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.config.url;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.config.AbstractConfig;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+public class RpcConfigGetSetProxy {
+
+ private static final String RPC_CONFIG_BASECLASS = AbstractConfig.class.getName();
+ private static final Logger log = LoggerFactory.getLogger(RpcConfigGetSetProxy.class);
+
+
+ private Object proxiee = null;
+ private Class<?> proxieeClass = null;
+ private Boolean isOk = false;
+
+ public RpcConfigGetSetProxy(Object p) {
+
+ if (p == null) {
+ return;
+ }
+
+ if (!isKindOf(p.getClass(), RPC_CONFIG_BASECLASS)) {
+ return;
+ }
+
+ proxiee = p;
+ //proxieeClass = c;
+ proxieeClass = p.getClass();
+ isOk = true;
+
+ }
+
+ public static boolean isKindOf(Class<?> c, String type) {
+
+ // get the class def for obj and type
+
+ Class<?> tClass;
+ try {
+ tClass = Class.forName(type);
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+
+ // check against type and superclasses
+ while (c != null) {
+ if (c == tClass) return true;
+ c = c.getSuperclass();
+ }
+
+ return false;
+ }
+
+ public boolean isOk() {
+ return isOk;
+ }
+
+ public Object setValue(String key, Object value) {
+
+ if (!isOk()) {
+ return null;
+ }
+
+ Method m = findSetMethod(key, value, proxieeClass);
+ return invoke(m, value);
+ }
+
+ public Object getValue(String key) {
+
+ if (!isOk()) {
+ return null;
+ }
+
+ Method m = findGetMethod(key, proxieeClass);
+ return invoke(m, null);
+ }
+
+ private Object invoke(Method m, Object value) {
+
+ if (m == null) {
+ return null;
+ }
+
+ try {
+ if (value == null) {
+ return m.invoke(proxiee, (Object[]) null);
+ } else {
+ return m.invoke(proxiee, value);
+ }
+ } catch (IllegalArgumentException e) {
+ log.error("IllegalArgumentException", e);
+ return null;
+ } catch (IllegalAccessException e) {
+ log.error("IllegalAccessException", e);
+ return null;
+ } catch (InvocationTargetException e) {
+ log.error("InvocationTargetException", e);
+ return null;
+ }
+ }
+
+ private Method findGetMethod(String key, Class<?> clazz) {
+
+ Method m = findMethod(key, null, "get", clazz);
+ if (m != null) {
+ return m;
+ }
+
+ return findMethod(key, null, "is", clazz);
+ }
+
+ private Method findSetMethod(String key, Object value, Class<?> clazz) {
+
+ return findMethod(key, value, "set", clazz);
+ }
+
+ private Method getMethod(String methodName, Object value, Class<?> clazz) {
+
+ try {
+ if (value == null) {
+ return clazz.getMethod(methodName, (Class<?>[]) null);
+ } else {
+ return clazz.getMethod(methodName, value.getClass());
+ }
+ } catch (SecurityException e) {
+ log.error("SecurityException: " + e.getMessage());
+ return null;
+ } catch (NoSuchMethodException e) {
+ log.error("NoSuchMethodException: " + e.getMessage());
+ return null;
+ }
+ }
+
+ private Method findMethod(String key, Object value, String prefix, Class<?> clazz) {
+
+ if (key.length() < 2) {
+ return null;
+ }
+
+ key = key.substring(0, 1).toUpperCase() + key.substring(1);
+ String methodName = prefix + key;
+
+ return getMethod(methodName, value, clazz);
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/UrlTestBase.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/UrlTestBase.java
new file mode 100644
index 0000000..b342685
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/url/UrlTestBase.java
@@ -0,0 +1,211 @@
+/*
+ * 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.config.url;
+
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MethodConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ProviderConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.api.DemoService;
+import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+
+import java.util.Arrays;
+
+import static junit.framework.TestCase.fail;
+
+@SuppressWarnings("unused")
+public class UrlTestBase {
+
+ // ======================================================
+ // data column definition
+ // ======================================================
+ protected static final int KEY = 0;
+ protected static final int URL_KEY = 1;
+ protected static final int TESTVALUE1 = 4;
+ private static final Logger log = LoggerFactory.getLogger(UrlTestBase.class);
+ private static final int TYPE = 2;
+ private static final int DEFAULT = 3;
+ private static final int TESTVALUE2 = 5;
+ private static final int TESTVALUE3 = 6;
+ private static final int TESTVALUE4 = 7;
+ private static final int TESTVALUE5 = 8;
+ private static final int TESTVALUE6 = 9;
+ private static final int TESTVALUE7 = 10;
+ protected ApplicationConfig appConfForProvider;
+ protected ApplicationConfig appConfForService;
+ protected RegistryConfig regConfForProvider;
+ protected RegistryConfig regConfForService;
+ protected ProviderConfig provConf;
+ protected ProtocolConfig protoConfForProvider;
+ protected ProtocolConfig protoConfForService;
+ protected MethodConfig methodConfForService;
+ protected ServiceConfig<DemoService> servConf;
+ protected Object servConfTable[][] = {
+ {"proxy", "proxy", "string", "javassist", "jdk", "javassist", "", "", "", ""},
+ {"actives", "actives", "int", 0, 90, "", "", "", "", ""},
+ {"executes", "executes", "int", 0, 90, "", "", "", "", ""},
+ {"deprecated", "deprecated", "boolean", false, true, "", "", "", "", ""},
+ {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
+ {"accesslog", "accesslog", "string", "", "haominTest", "", "", "", "", ""},
+ {"document", "document", "string", "", "http://b2b-doc.alibaba-inc.com/display/RC/dubbo_devguide.htm?testquery=你好你好", "", "", "", "", ""},
+ {"weight", "weight", "int", 0, 90, "", "", "", "", ""},
+
+ //{"filter", "service.filter", "string", "", "", "", "", "", "", ""},
+ //{"listener", "listener", "string", "", "", "", "", "", "", ""},
+
+ };
+ protected Object regConfForServiceTable[][] = {
+ // {"timeout", "registry.timeout", "int", 5000, 9000, "", "", "", "", ""},
+ // {"file", "registry.file", "string", "", "regConfForServiceTable.log", "", "", "", "", ""},
+ // {"wait", "registry.wait", "int", 0, 9000, "", "", "", "", ""},
+ // {"transport", "registry.transporter", "string", "netty", "mina", "", "", "", "", ""},
+ // {"subscribe", "subscribe", "boolean", true, false, "", "", "", "", ""},
+ {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
+ };
+ protected Object provConfTable[][] = {
+ {"cluster", "default.cluster", "string", "string", "failover", "failfast", "failsafe", "", "", ""},
+ {"async", "default.async", "boolean", false, true, "", "", "", "", ""},
+ {"loadbalance", "default.loadbalance", "string", "random", "leastactive", "", "", "", "", ""},
+ {"connections", "default.connections", "int", 0, 60, "", "", "", "", ""},
+ {"retries", "default.retries", "int", 2, 60, "", "", "", "", ""},
+ {"timeout", "default.timeout", "int", 5000, 60, "", "", "", "", ""},
+ //change by fengting listener 没有缺省值
+ //{"listener", "exporter.listener", "string", "", "", "", "", "", "", ""},
+ //{"filter", "service.filter", "string", "", "", "", "", "", "", ""},
+
+ };
+ protected Object methodConfForServiceTable[][] = {
+ {"actives", "sayName.actives", "int", 0, 90, "", "", "", "", ""},
+ {"executes", "sayName.executes", "int", 0, 90, "", "", "", "", ""},
+ {"deprecated", "sayName.deprecated", "boolean", false, true, "", "", "", "", ""},
+ {"async", "sayName.async", "boolean", false, true, "", "", "", "", ""},
+ {"timeout", "sayName.timeout", "int", 0, 90, "", "", "", "", ""},
+ };
+ protected DemoService demoService = new DemoServiceImpl();
+ private Object appConfForProviderTable[][] = {
+ {"", "", "", "", "", "", "", "", "", ""},
+ };
+ private Object appConfForServiceTable[][] = {
+ {"", "", "", "", "", "", "", "", "", ""},
+ };
+ private Object regConfForProviderTable[][] = {
+ {"", "", "", "", "", "", "", "", "", ""},
+ };
+ private Object protoConfForProviderTable[][] = {
+ {"", "", "", "", "", "", "", "", "", ""},
+ };
+ private Object protoConfForServiceTable[][] = {
+ {"", "", "", "", "", "", "", "", "", ""},
+ };
+
+ // ======================================================
+ // data table manipulation utils
+ // ======================================================
+ protected String genParamString(Object urlKey, Object value) {
+
+ return (String) urlKey + "=" + value.toString();
+ }
+
+ protected <T> void fillConfigs(T conf, Object[][] table, int column) {
+
+ for (Object[] row : table) {
+ fillConfig(conf, row, column);
+ }
+ }
+
+ protected <T> void fillConfig(T conf, Object[] row, int column) {
+
+ RpcConfigGetSetProxy proxy = new RpcConfigGetSetProxy(conf);
+ proxy.setValue((String) row[KEY], row[column]);
+
+ }
+
+ @SuppressWarnings("deprecation")
+ protected void initServConf() {
+
+ appConfForProvider = new ApplicationConfig();
+ appConfForService = new ApplicationConfig();
+ regConfForProvider = new RegistryConfig();
+ regConfForService = new RegistryConfig();
+ provConf = new ProviderConfig();
+ protoConfForProvider = new ProtocolConfig();
+ protoConfForService = new ProtocolConfig();
+ methodConfForService = new MethodConfig();
+ servConf = new ServiceConfig<DemoService>();
+
+ provConf.setApplication(appConfForProvider);
+ servConf.setApplication(appConfForService);
+
+ provConf.setRegistry(regConfForProvider);
+ servConf.setRegistry(regConfForService);
+
+ provConf.setProtocols(Arrays.asList(new ProtocolConfig[]{protoConfForProvider}));
+ servConf.setProtocols(Arrays.asList(new ProtocolConfig[]{protoConfForService}));
+
+ servConf.setMethods(Arrays.asList(new MethodConfig[]{methodConfForService}));
+ servConf.setProvider(provConf);
+
+ servConf.setRef(demoService);
+ servConf.setInterfaceClass(DemoService.class);
+
+ methodConfForService.setName("sayName");
+ regConfForService.setAddress("127.0.0.1:9090");
+ regConfForService.setProtocol("mockregistry");
+ appConfForService.setName("ConfigTests");
+ }
+
+ protected String getProviderParamString() {
+ return servConf.getExportedUrls().get(0).toString();
+ }
+
+ /**
+ * @param paramStringFromDb
+ * @param dataTable
+ * @param configName
+ * @param column
+ */
+ protected void assertUrlStringWithLocalTable(String paramStringFromDb,
+ Object[][] dataTable, String configName, int column) {
+ final String FAILLOG_HEADER = "The following config items are not found in URLONE: ";
+
+ log.warn("Verifying service url for " + configName + "... ");
+ log.warn("Consumer url string: " + paramStringFromDb);
+
+ String failLog = FAILLOG_HEADER;
+ for (Object[] row : dataTable) {
+
+ String targetString = genParamString(row[URL_KEY], row[column]);
+
+ log.warn("Checking " + (String) row[KEY] + "for" + targetString);
+ if (paramStringFromDb.contains(targetString)) {
+ log.warn((String) row[KEY] + " --> " + targetString + " OK!");
+ } else {
+ failLog += targetString + ", ";
+ }
+ }
+
+ if (!failLog.equals(FAILLOG_HEADER)) {
+ fail(failLog);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/utils/MockReferenceConfig.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/utils/MockReferenceConfig.java
new file mode 100644
index 0000000..68df6cd
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/utils/MockReferenceConfig.java
@@ -0,0 +1,53 @@
+/*
+ * 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.config.utils;
+
+import org.apache.dubbo.config.ReferenceConfig;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+public class MockReferenceConfig extends ReferenceConfig<String> {
+ static AtomicLong counter = new AtomicLong();
+
+ String value;
+ boolean destroyMethodRun = false;
+
+ public static void setCounter(long c) {
+ counter.set(c);
+ }
+
+ public boolean isGetMethodRun() {
+ return value != null;
+ }
+
+ public boolean isDestroyMethodRun() {
+ return destroyMethodRun;
+ }
+
+ @Override
+ public synchronized String get() {
+ if (value != null) return value;
+
+ value = "" + counter.getAndIncrement();
+ return value;
+ }
+
+ @Override
+ public synchronized void destroy() {
+ destroyMethodRun = true;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/utils/ReferenceConfigCacheTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/utils/ReferenceConfigCacheTest.java
new file mode 100644
index 0000000..8216609
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/utils/ReferenceConfigCacheTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.config.utils;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ReferenceConfigCacheTest {
+ @Before
+ public void setUp() throws Exception {
+ MockReferenceConfig.setCounter(0);
+ ReferenceConfigCache.cacheHolder.clear();
+ }
+
+ @Test
+ public void testGetCacheSameReference() throws Exception {
+ ReferenceConfigCache cache = ReferenceConfigCache.getCache();
+ MockReferenceConfig config = buildMockReferenceConfig("FooService", "group1", "1.0.0");
+ String value = cache.get(config);
+ assertTrue(config.isGetMethodRun());
+ assertEquals("0", value);
+
+ MockReferenceConfig configCopy = buildMockReferenceConfig("FooService", "group1", "1.0.0");
+ value = cache.get(configCopy);
+ assertFalse(configCopy.isGetMethodRun());
+ assertEquals("0", value);
+ }
+
+ @Test
+ public void testGetCacheDiffReference() throws Exception {
+ ReferenceConfigCache cache = ReferenceConfigCache.getCache();
+ MockReferenceConfig config = buildMockReferenceConfig("FooService", "group1", "1.0.0");
+ String value = cache.get(config);
+ assertTrue(config.isGetMethodRun());
+ assertEquals("0", value);
+
+ MockReferenceConfig configCopy = buildMockReferenceConfig("XxxService", "group1", "1.0.0");
+ value = cache.get(configCopy);
+ assertTrue(configCopy.isGetMethodRun());
+ assertEquals("1", value);
+ }
+
+ @Test
+ public void testGetCacheDiffName() throws Exception {
+ ReferenceConfigCache cache = ReferenceConfigCache.getCache();
+ MockReferenceConfig config = buildMockReferenceConfig("FooService", "group1", "1.0.0");
+ String value = cache.get(config);
+ assertTrue(config.isGetMethodRun());
+ assertEquals("0", value);
+
+ cache = ReferenceConfigCache.getCache("foo");
+ config = buildMockReferenceConfig("FooService", "group1", "1.0.0");
+ value = cache.get(config);
+ // still init for the same ReferenceConfig if the cache is different
+ assertTrue(config.isGetMethodRun());
+ assertEquals("1", value);
+ }
+
+ @Test
+ public void testDestroy() throws Exception {
+ ReferenceConfigCache cache = ReferenceConfigCache.getCache();
+ MockReferenceConfig config = buildMockReferenceConfig("FooService", "group1", "1.0.0");
+ cache.get(config);
+ MockReferenceConfig configCopy = buildMockReferenceConfig("XxxService", "group1", "1.0.0");
+ cache.get(configCopy);
+ assertEquals(2, cache.cache.size());
+ cache.destroy(config);
+ assertTrue(config.isDestroyMethodRun());
+ assertEquals(1, cache.cache.size());
+ cache.destroy(configCopy);
+ assertTrue(configCopy.isDestroyMethodRun());
+ assertEquals(0, cache.cache.size());
+ }
+
+ @Test
+ public void testDestroyAll() throws Exception {
+ ReferenceConfigCache cache = ReferenceConfigCache.getCache();
+ MockReferenceConfig config = buildMockReferenceConfig("FooService", "group1", "1.0.0");
+ cache.get(config);
+ MockReferenceConfig configCopy = buildMockReferenceConfig("XxxService", "group1", "1.0.0");
+ cache.get(configCopy);
+ assertEquals(2, cache.cache.size());
+ cache.destroyAll();
+ assertTrue(config.isDestroyMethodRun());
+ assertTrue(configCopy.isDestroyMethodRun());
+ assertEquals(0, cache.cache.size());
+ }
+
+ private MockReferenceConfig buildMockReferenceConfig(String service, String group, String version) {
+ MockReferenceConfig config = new MockReferenceConfig();
+ config.setInterface(service);
+ config.setGroup(group);
+ config.setVersion(version);
+ return config;
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationParameter.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationParameter.java
new file mode 100644
index 0000000..70c4d0e
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationParameter.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.validation;
+
+import javax.validation.constraints.Future;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Past;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * ValidationParameter
+ */
+public class ValidationParameter implements Serializable {
+
+ private static final long serialVersionUID = 7158911668568000392L;
+
+ @NotNull(groups = ValidationService.Update.class)
+ private Integer id;
+
+ @NotNull
+ @Size(min = 2, max = 20)
+ private String name;
+
+ // not allow to save null, but allow to update with null which means not update the field
+ @NotNull(groups = ValidationService.Save.class)
+ @Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
+ private String email;
+
+ @Min(18)
+ @Max(100)
+ private int age;
+
+ @Past
+ private Date loginDate;
+
+ @Future
+ private Date expiryDate;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public Date getLoginDate() {
+ return loginDate;
+ }
+
+ public void setLoginDate(Date loginDate) {
+ this.loginDate = loginDate;
+ }
+
+ public Date getExpiryDate() {
+ return expiryDate;
+ }
+
+ public void setExpiryDate(Date expiryDate) {
+ this.expiryDate = expiryDate;
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationService.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationService.java
new file mode 100644
index 0000000..2efc5e0
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationService.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config.validation;
+
+import org.apache.dubbo.validation.MethodValidated;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+
+/**
+ * ValidationService
+ * <p>
+ * Use service interface to distinguish validation scenario, for example: @NotNull(groups = ValidationService.class)
+ */
+public interface ValidationService {
+
+ /**
+ * The current logic will not verify 'groups = ValidationService.Save.class' if
+ * '@MethodValidated(ValidationService.Save.class)' is not present
+ *
+ * @param parameter
+ */
+ @MethodValidated(Save.class)
+ void save(ValidationParameter parameter);
+
+ void update(ValidationParameter parameter);
+
+ void delete(@Min(1) long id, @NotNull @Size(min = 2, max = 16) @Pattern(regexp = "^[a-zA-Z]+$") String operator);
+
+ /**
+ * Assume both id and email are needed to pass in, need to verify Save group and Update group.
+ *
+ * @param parameter
+ */
+ @MethodValidated({Save.class, Update.class})
+ void relatedQuery(ValidationParameter parameter);
+
+ /**
+ * annotation which has the same name with the method but has the first letter in capital
+ * used for distinguish validation scenario, for example: @NotNull(groups = ValidationService.Save.class)
+ * optional
+ */
+ @interface Save {
+ }
+
+ /**
+ * annotation which has the same name with the method but has the first letter in capital
+ * used for distinguish validation scenario, for example: @NotNull(groups = ValidationService.Update.class)
+ * optional
+ */
+ @interface Update {
+ }
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationServiceImpl.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationServiceImpl.java
new file mode 100644
index 0000000..837e7e4
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationServiceImpl.java
@@ -0,0 +1,37 @@
+/*
+ * 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.config.validation;
+
+/**
+ * ValidationServiceImpl
+ */
+public class ValidationServiceImpl implements ValidationService {
+
+ public void save(ValidationParameter parameter) {
+ }
+
+ public void update(ValidationParameter parameter) {
+ }
+
+ public void delete(long id, String operator) {
+ }
+
+ public void relatedQuery(ValidationParameter parameter) {
+
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationTest.java b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationTest.java
new file mode 100644
index 0000000..39655ae
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/java/org/apache/dubbo/config/validation/ValidationTest.java
@@ -0,0 +1,301 @@
+/*
+ * 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.config.validation;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.service.GenericException;
+import org.apache.dubbo.rpc.service.GenericService;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * GenericServiceTest
+ */
+public class ValidationTest {
+
+ @Test
+ public void testValidation() {
+ ServiceConfig<ValidationService> service = new ServiceConfig<ValidationService>();
+ service.setApplication(new ApplicationConfig("validation-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("dubbo", 29582));
+ service.setInterface(ValidationService.class.getName());
+ service.setRef(new ValidationServiceImpl());
+ service.setValidation(String.valueOf(true));
+ service.export();
+ try {
+ ReferenceConfig<ValidationService> reference = new ReferenceConfig<ValidationService>();
+ reference.setApplication(new ApplicationConfig("validation-consumer"));
+ reference.setInterface(ValidationService.class);
+ reference.setUrl("dubbo://127.0.0.1:29582?scope=remote&validation=true");
+ ValidationService validationService = reference.get();
+ try {
+ // Save OK
+ ValidationParameter parameter = new ValidationParameter();
+ parameter.setName("liangfei");
+ parameter.setEmail("liangfei@liang.fei");
+ parameter.setAge(50);
+ parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000));
+ parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));
+ validationService.save(parameter);
+
+ try {
+ parameter = new ValidationParameter();
+ parameter.setName("l");
+ parameter.setEmail("liangfei@liang.fei");
+ parameter.setAge(50);
+ parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000));
+ parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));
+ validationService.save(parameter);
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertNotNull(violations);
+ }
+
+ // verify save group, save error
+ try {
+ parameter = new ValidationParameter();
+ parameter.setName("liangfei");
+ parameter.setAge(50);
+ parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000));
+ parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));
+ validationService.save(parameter);
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertNotNull(violations);
+ }
+
+ // relatedQuery error, no id and email is passed, will trigger validation exception for both Save
+ // and Update
+ try {
+ parameter = new ValidationParameter();
+ parameter.setName("liangfei");
+ parameter.setAge(50);
+ parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000));
+ parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));
+ validationService.relatedQuery(parameter);
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertEquals(violations.size(), 2);
+ }
+
+ // Save Error
+ try {
+ parameter = new ValidationParameter();
+ validationService.save(parameter);
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertTrue(violations.size() == 3);
+ Assert.assertNotNull(violations);
+ }
+
+ // Delete OK
+ validationService.delete(2, "abc");
+
+ // Delete Error
+ try {
+ validationService.delete(2, "a");
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertNotNull(violations);
+ Assert.assertEquals(1, violations.size());
+ }
+
+ // Delete Error
+ try {
+ validationService.delete(0, "abc");
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertNotNull(violations);
+ Assert.assertEquals(1, violations.size());
+ }
+ try {
+ validationService.delete(2, null);
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertNotNull(violations);
+ Assert.assertEquals(1, violations.size());
+ }
+ try {
+ validationService.delete(0, null);
+ Assert.fail();
+ } catch (ConstraintViolationException ve) {
+ Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();
+ Assert.assertNotNull(violations);
+ Assert.assertEquals(2, violations.size());
+ }
+ } finally {
+ reference.destroy();
+ }
+ } finally {
+ service.unexport();
+ }
+ }
+
+ @Test
+ public void testProviderValidation() {
+ ServiceConfig<ValidationService> service = new ServiceConfig<ValidationService>();
+ service.setApplication(new ApplicationConfig("validation-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("dubbo", 29582));
+ service.setInterface(ValidationService.class.getName());
+ service.setRef(new ValidationServiceImpl());
+ service.setValidation(String.valueOf(true));
+ service.export();
+ try {
+ ReferenceConfig<ValidationService> reference = new ReferenceConfig<ValidationService>();
+ reference.setApplication(new ApplicationConfig("validation-consumer"));
+ reference.setInterface(ValidationService.class);
+ reference.setUrl("dubbo://127.0.0.1:29582");
+ ValidationService validationService = reference.get();
+ try {
+ // Save OK
+ ValidationParameter parameter = new ValidationParameter();
+ parameter.setName("liangfei");
+ parameter.setEmail("liangfei@liang.fei");
+ parameter.setAge(50);
+ parameter.setLoginDate(new Date(System.currentTimeMillis() - 1000000));
+ parameter.setExpiryDate(new Date(System.currentTimeMillis() + 1000000));
+ validationService.save(parameter);
+
+ // Save Error
+ try {
+ parameter = new ValidationParameter();
+ validationService.save(parameter);
+ Assert.fail();
+ } catch (RpcException e) {
+ Assert.assertTrue(e.getMessage().contains("ConstraintViolation"));
+ }
+
+ // Delete OK
+ validationService.delete(2, "abc");
+
+ // Delete Error
+ try {
+ validationService.delete(0, "abc");
+ Assert.fail();
+ } catch (RpcException e) {
+ Assert.assertTrue(e.getMessage().contains("ConstraintViolation"));
+ }
+ try {
+ validationService.delete(2, null);
+ Assert.fail();
+ } catch (RpcException e) {
+ Assert.assertTrue(e.getMessage().contains("ConstraintViolation"));
+ }
+ try {
+ validationService.delete(0, null);
+ Assert.fail();
+ } catch (RpcException e) {
+ Assert.assertTrue(e.getMessage().contains("ConstraintViolation"));
+ }
+ } finally {
+ reference.destroy();
+ }
+ } finally {
+ service.unexport();
+ }
+ }
+
+ @Test
+ public void testGenericValidation() {
+ ServiceConfig<ValidationService> service = new ServiceConfig<ValidationService>();
+ service.setApplication(new ApplicationConfig("validation-provider"));
+ service.setRegistry(new RegistryConfig("N/A"));
+ service.setProtocol(new ProtocolConfig("dubbo", 29582));
+ service.setInterface(ValidationService.class.getName());
+ service.setRef(new ValidationServiceImpl());
+ service.setValidation(String.valueOf(true));
+ service.export();
+ try {
+ ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
+ reference.setApplication(new ApplicationConfig("validation-consumer"));
+ reference.setInterface(ValidationService.class.getName());
+ reference.setUrl("dubbo://127.0.0.1:29582?scope=remote&validation=true&timeout=9000000");
+ reference.setGeneric(true);
+ GenericService validationService = reference.get();
+ try {
+ // Save OK
+ Map<String, Object> parameter = new HashMap<String, Object>();
+ parameter.put("name", "liangfei");
+ parameter.put("Email", "liangfei@liang.fei");
+ parameter.put("Age", 50);
+ parameter.put("LoginDate", new Date(System.currentTimeMillis() - 1000000));
+ parameter.put("ExpiryDate", new Date(System.currentTimeMillis() + 1000000));
+ validationService.$invoke("save", new String[]{ValidationParameter.class.getName()}, new Object[]{parameter});
+
+ // Save Error
+ try {
+ parameter = new HashMap<String, Object>();
+ validationService.$invoke("save", new String[]{ValidationParameter.class.getName()}, new Object[]{parameter});
+ Assert.fail();
+ } catch (GenericException e) {
+ Assert.assertTrue(e.getMessage().contains("Failed to validate service"));
+ }
+
+ // Delete OK
+ validationService.$invoke("delete", new String[]{long.class.getName(), String.class.getName()}, new Object[]{2, "abc"});
+
+ // Delete Error
+ try {
+ validationService.$invoke("delete", new String[]{long.class.getName(), String.class.getName()}, new Object[]{0, "abc"});
+ Assert.fail();
+ } catch (GenericException e) {
+ Assert.assertTrue(e.getMessage().contains("Failed to validate service"));
+ }
+ try {
+ validationService.$invoke("delete", new String[]{long.class.getName(), String.class.getName()}, new Object[]{2, null});
+ Assert.fail();
+ } catch (GenericException e) {
+ Assert.assertTrue(e.getMessage().contains("Failed to validate service"));
+ }
+ try {
+ validationService.$invoke("delete", new String[]{long.class.getName(), String.class.getName()}, new Object[]{0, null});
+ Assert.fail();
+ } catch (GenericException e) {
+ Assert.assertTrue(e.getMessage().contains("Failed to validate service"));
+ }
+ } catch (GenericException e) {
+ Assert.assertTrue(e.getMessage().contains("Failed to validate service"));
+ } finally {
+ reference.destroy();
+ }
+ } finally {
+ service.unexport();
+ }
+ }
+
+}
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.common.status.StatusChecker b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.common.status.StatusChecker
new file mode 100644
index 0000000..d7d3b44
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.common.status.StatusChecker
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mockstatuschecker=org.apache.dubbo.config.mock.MockStatusChecker
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.common.threadpool.ThreadPool b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.common.threadpool.ThreadPool
new file mode 100644
index 0000000..f4f5d34
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.common.threadpool.ThreadPool
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mockthreadpool=org.apache.dubbo.config.mock.MockThreadPool
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.registry.RegistryFactory b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.registry.RegistryFactory
new file mode 100644
index 0000000..7b8cf68
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.registry.RegistryFactory
@@ -0,0 +1,2 @@
+mockregistry=org.apache.dubbo.config.mock.MockRegistryFactory
+mockprotocol2=org.apache.dubbo.config.mock.MockRegistryFactory2
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Codec b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Codec
new file mode 100644
index 0000000..94f7668
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Codec
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mockcodec=org.apache.dubbo.config.mock.MockCodec
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Dispatcher b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Dispatcher
new file mode 100644
index 0000000..febb4f8
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Dispatcher
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mockdispatcher=org.apache.dubbo.config.mock.MockDispatcher
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Transporter b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Transporter
new file mode 100644
index 0000000..ef9ec51
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.Transporter
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mocktransporter=org.apache.dubbo.config.mock.MockTransporter
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.exchange.Exchanger b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.exchange.Exchanger
new file mode 100644
index 0000000..f8d3c3b
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.exchange.Exchanger
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mockexchanger=org.apache.dubbo.config.mock.MockExchanger
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.telnet.TelnetHandler b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.telnet.TelnetHandler
new file mode 100644
index 0000000..76dfd94
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.remoting.telnet.TelnetHandler
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+mocktelnethandler=org.apache.dubbo.config.mock.MockTelnetHandler
+
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.ExporterListener b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.ExporterListener
new file mode 100644
index 0000000..f9c818d
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.ExporterListener
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+mockexporterlistener=org.apache.dubbo.config.mock.MockExporterListener
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.Filter b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.Filter
new file mode 100644
index 0000000..1938f96
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.Filter
@@ -0,0 +1 @@
+mockfilter=org.apache.dubbo.config.mock.MockFilter
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.InvokerListener b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.InvokerListener
new file mode 100644
index 0000000..9e6d042
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.InvokerListener
@@ -0,0 +1 @@
+mockinvokerlistener=org.apache.dubbo.config.mock.MockInvokerListener
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.Protocol b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.Protocol
new file mode 100644
index 0000000..6c04497
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.Protocol
@@ -0,0 +1,2 @@
+mockprotocol=org.apache.dubbo.config.mock.MockProtocol
+mockprotocol2=org.apache.dubbo.config.mock.MockProtocol2
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.ProxyFactory b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.ProxyFactory
new file mode 100644
index 0000000..ded1b88
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.ProxyFactory
@@ -0,0 +1,2 @@
+mockproxyfactory=org.apache.dubbo.config.mock.MockProxyFactory
+testproxyfactory=org.apache.dubbo.config.mock.TestProxyFactory
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.cluster.Cluster b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.cluster.Cluster
new file mode 100644
index 0000000..066d136
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.cluster.Cluster
@@ -0,0 +1 @@
+mockcluster=org.apache.dubbo.config.mock.MockCluster
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.cluster.LoadBalance b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.cluster.LoadBalance
new file mode 100644
index 0000000..23b5087
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/META-INF/services/org.apache.dubbo.rpc.cluster.LoadBalance
@@ -0,0 +1 @@
+mockloadbalance=org.apache.dubbo.config.mock.MockLoadBalance
\ No newline at end of file
diff --git a/dubbo-bootstrap/src/main/test/resources/log4j.xml b/dubbo-bootstrap/src/main/test/resources/log4j.xml
new file mode 100644
index 0000000..8607f5d
--- /dev/null
+++ b/dubbo-bootstrap/src/main/test/resources/log4j.xml
@@ -0,0 +1,28 @@
+<!--
+ 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.
+ -->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n"/>
+ </layout>
+ </appender>
+ <root>
+ <level value="INFO"/>
+ <appender-ref ref="CONSOLE"/>
+ </root>
+</log4j:configuration>
\ No newline at end of file