This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new a72123a Add unit test for FrameworkModel/ApplicationModel/ModuleModel
and add test case for ConfigManager (#9301)
a72123a is described below
commit a72123a3e2738c35847bfb96154f8e61845b906c
Author: 灼华 <[email protected]>
AuthorDate: Sun Nov 28 16:32:18 2021 +0800
Add unit test for FrameworkModel/ApplicationModel/ModuleModel and add test
case for ConfigManager (#9301)
* Add unit test for FrameworkModel/ApplicationModel/ModuleModel and add
test case for ConfigManager
* FIX
---
.../dubbo/common/lang/ShutdownHookCallbacks.java | 2 +-
.../common/resource/GlobalResourcesRepository.java | 16 ++-
.../common/utils/ClassLoaderResourceLoader.java | 16 ++-
.../config/context/AbstractConfigManager.java | 10 +-
.../apache/dubbo/config/context/ConfigManager.java | 2 +-
.../dubbo/config/context/ModuleConfigManager.java | 11 +-
.../org/apache/dubbo/rpc/model/ScopeModel.java | 4 +
.../common/config/ConfigurationCacheTest.java | 35 +++++
.../resource/GlobalResourcesRepositoryTest.java | 77 +++++++++++
.../utils/ClassLoaderResourceLoaderTest.java | 58 ++++++++
.../dubbo/config/context/ConfigManagerTest.java | 96 +++++++++++++-
.../dubbo/rpc/model/ApplicationModelTest.java | 146 +++++++++++++++++++++
.../apache/dubbo/rpc/model/FrameworkModelTest.java | 106 +++++++++++++++
.../apache/dubbo/rpc/model/ModuleModelTest.java | 89 +++++++++++++
.../org/apache/dubbo/rpc/model/ScopeModelTest.java | 9 +-
.../rpc/support/MockScopeModelDestroyListener.java | 39 ++++++
16 files changed, 686 insertions(+), 30 deletions(-)
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java
index da3f6a7..8665e9b 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/lang/ShutdownHookCallbacks.java
@@ -27,7 +27,7 @@ import static java.util.Collections.sort;
import static org.apache.dubbo.common.function.ThrowableAction.execute;
/**
- * The compose {@link ShutdownHookCallback} class to manipulate one and more
{@link ShutdownHookCallback} instances
+ * The composed {@link ShutdownHookCallback} class to manipulate one and more
{@link ShutdownHookCallback} instances
*
* @since 2.7.5
*/
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/resource/GlobalResourcesRepository.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/resource/GlobalResourcesRepository.java
index 4f74ddc..7a309e6 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/common/resource/GlobalResourcesRepository.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/resource/GlobalResourcesRepository.java
@@ -87,7 +87,7 @@ public class GlobalResourcesRepository {
return executorService;
}
- synchronized public void destroy() {
+ public synchronized void destroy() {
if (logger.isInfoEnabled()) {
logger.info("Destroying global resources ...");
}
@@ -125,14 +125,24 @@ public class GlobalResourcesRepository {
* Register a one-off disposable, the disposable is removed automatically
on first shutdown.
* @param disposable
*/
- synchronized public void registerDisposable(Disposable disposable) {
+ public synchronized void registerDisposable(Disposable disposable) {
if (!oneoffDisposables.contains(disposable)) {
oneoffDisposables.add(disposable);
}
}
- synchronized public void removeDisposable(Disposable disposable) {
+ public synchronized void removeDisposable(Disposable disposable) {
this.oneoffDisposables.remove(disposable);
}
+
+ // for test
+ public static List<Disposable> getGlobalReusedDisposables() {
+ return globalReusedDisposables;
+ }
+
+ // for test
+ public List<Disposable> getOneoffDisposables() {
+ return oneoffDisposables;
+ }
}
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java
index 2fba54f..8266938 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoader.java
@@ -42,8 +42,8 @@ public class ClassLoaderResourceLoader {
GlobalResourcesRepository.registerGlobalDisposable(()-> destroy());
}
- public static Map<ClassLoader, Set<java.net.URL>> loadResources(String
fileName, List<ClassLoader> classLoaders) {
- Map<ClassLoader, Set<java.net.URL>> resources = new
ConcurrentHashMap<>();
+ public static Map<ClassLoader, Set<URL>> loadResources(String fileName,
List<ClassLoader> classLoaders) {
+ Map<ClassLoader, Set<URL>> resources = new ConcurrentHashMap<>();
CountDownLatch countDownLatch = new
CountDownLatch(classLoaders.size());
for (ClassLoader classLoader : classLoaders) {
GlobalResourcesRepository.getGlobalExecutorService().submit(() -> {
@@ -59,8 +59,8 @@ public class ClassLoaderResourceLoader {
return Collections.unmodifiableMap(new LinkedHashMap<>(resources));
}
- public static Set<java.net.URL> loadResources(String fileName, ClassLoader
currentClassLoader) {
- Map<ClassLoader, Map<String, Set<java.net.URL>>> classLoaderCache;
+ public static Set<URL> loadResources(String fileName, ClassLoader
currentClassLoader) {
+ Map<ClassLoader, Map<String, Set<URL>>> classLoaderCache;
if (classLoaderResourcesCache == null || (classLoaderCache =
classLoaderResourcesCache.get()) == null) {
synchronized (ClassLoaderResourceLoader.class) {
if (classLoaderResourcesCache == null || (classLoaderCache =
classLoaderResourcesCache.get()) == null) {
@@ -72,9 +72,9 @@ public class ClassLoaderResourceLoader {
if (!classLoaderCache.containsKey(currentClassLoader)) {
classLoaderCache.putIfAbsent(currentClassLoader, new
ConcurrentHashMap<>());
}
- Map<String, Set<java.net.URL>> urlCache =
classLoaderCache.get(currentClassLoader);
+ Map<String, Set<URL>> urlCache =
classLoaderCache.get(currentClassLoader);
if (!urlCache.containsKey(fileName)) {
- Set<java.net.URL> set = new LinkedHashSet<>();
+ Set<URL> set = new LinkedHashSet<>();
Enumeration<URL> urls;
try {
urls = currentClassLoader.getResources(fileName);
@@ -113,4 +113,8 @@ public class ClassLoaderResourceLoader {
}
+ // for test
+ protected static SoftReference<Map<ClassLoader, Map<String, Set<URL>>>>
getClassLoaderResourcesCache() {
+ return classLoaderResourcesCache;
+ }
}
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java
b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java
index 282c18a..69c6771 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java
@@ -327,7 +327,7 @@ public abstract class AbstractConfigManager extends
LifecycleAdapter {
if (configsMap.isEmpty()) {
return null;
}
- // try find config by name
+ // try to find config by name
if (ReflectUtils.hasMethod(cls, CONFIG_NAME_READ_METHOD)) {
List<C> list = configsMap.values().stream()
.filter(cfg -> name.equals(getConfigName(cfg)))
@@ -344,7 +344,7 @@ public abstract class AbstractConfigManager extends
LifecycleAdapter {
private <C extends AbstractConfig> String getConfigName(C config) {
try {
- return (String) ReflectUtils.getProperty(config,
CONFIG_NAME_READ_METHOD);
+ return ReflectUtils.getProperty(config, CONFIG_NAME_READ_METHOD);
} catch (Exception e) {
return null;
}
@@ -463,7 +463,7 @@ public abstract class AbstractConfigManager extends
LifecycleAdapter {
Set<String> configIds = this.getConfigIdsFromProps(cls);
configIds.forEach(id -> {
if (!this.getConfig(cls, id).isPresent()) {
- T config = null;
+ T config;
try {
config = createConfig(cls, scopeModel);
config.setId(id);
@@ -500,7 +500,7 @@ public abstract class AbstractConfigManager extends
LifecycleAdapter {
// load single config
List<Map<String, String>> configurationMaps =
environment.getConfigurationMaps();
if (ConfigurationUtils.hasSubProperties(configurationMaps,
AbstractConfig.getTypePrefix(cls))) {
- T config = null;
+ T config;
try {
config = createConfig(cls, scopeModel);
config.refresh();
@@ -560,7 +560,7 @@ public abstract class AbstractConfigManager extends
LifecycleAdapter {
throw new IllegalStateException("Add default config failed: " +
configType.getSimpleName(), e);
}
- //validate configs
+ // validate configs
Collection<T> configs = this.getConfigs(configType);
if (getConfigValidator() != null) {
for (T config : configs) {
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
index 2d6de5f..a6f4484 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
@@ -219,7 +219,7 @@ public class ConfigManager extends AbstractConfigManager
implements ApplicationE
@Override
public void refreshAll() {
- // refresh all configs here,
+ // refresh all configs here
getApplication().ifPresent(ApplicationConfig::refresh);
getMonitor().ifPresent(MonitorConfig::refresh);
getMetrics().ifPresent(MetricsConfig::refresh);
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java
b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java
index c8c802a..a935a88 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ModuleConfigManager.java
@@ -168,18 +168,13 @@ public class ModuleConfigManager extends
AbstractConfigManager {
@Override
public void refreshAll() {
- // refresh all configs here,
+ // refresh all configs here
getModule().ifPresent(ModuleConfig::refresh);
getProviders().forEach(ProviderConfig::refresh);
getConsumers().forEach(ConsumerConfig::refresh);
- for (ReferenceConfigBase<?> reference : getReferences()) {
- reference.refresh();
- }
-
- for (ServiceConfigBase sc : getServices()) {
- sc.refresh();
- }
+ getReferences().forEach(ReferenceConfigBase::refresh);
+ getServices().forEach(ServiceConfigBase::refresh);
}
@Override
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java
b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java
index 042fc5b..dd4becb 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ScopeModel.java
@@ -167,6 +167,10 @@ public abstract class ScopeModel implements
ExtensionAccessor {
return parent;
}
+ public ExtensionScope getScope() {
+ return scope;
+ }
+
public void addClassLoader(ClassLoader classLoader) {
this.classLoaders.add(classLoader);
if (parent != null) {
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/config/ConfigurationCacheTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/config/ConfigurationCacheTest.java
new file mode 100644
index 0000000..e4a5aca
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/config/ConfigurationCacheTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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.common.config;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * {@link ConfigurationCache}
+ */
+public class ConfigurationCacheTest {
+
+ @Test
+ public void test() {
+ ConfigurationCache configurationCache = new ConfigurationCache();
+ String value = configurationCache.computeIfAbsent("k1", k -> "v1");
+ Assertions.assertEquals(value, "v1");
+ value = configurationCache.computeIfAbsent("k1", k -> "v2");
+ Assertions.assertEquals(value, "v1");
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/resource/GlobalResourcesRepositoryTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/resource/GlobalResourcesRepositoryTest.java
new file mode 100644
index 0000000..28ce084
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/resource/GlobalResourcesRepositoryTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.common.resource;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * {@link GlobalResourcesRepository}
+ */
+public class GlobalResourcesRepositoryTest {
+
+ @Test
+ public void test() throws NoSuchFieldException {
+ GlobalResourcesRepository repository =
GlobalResourcesRepository.getInstance();
+
+ ExecutorService globalExecutorService =
GlobalResourcesRepository.getGlobalExecutorService();
+ Assertions.assertNotNull(globalExecutorService);
+
+ GlobalDisposable globalDisposable = new GlobalDisposable();
+ GlobalResourcesRepository.registerGlobalDisposable(globalDisposable);
+
+ OneOffDisposable oneOffDisposable = new OneOffDisposable();
+ repository.registerDisposable(oneOffDisposable);
+
+ repository.destroy();
+ Assertions.assertTrue(globalExecutorService.isShutdown());
+ Assertions.assertTrue(globalDisposable.isDestroyed());
+ Assertions.assertTrue(oneOffDisposable.isDestroyed());
+
Assertions.assertTrue(!GlobalResourcesRepository.getGlobalReusedDisposables().isEmpty());
+
Assertions.assertTrue(GlobalResourcesRepository.getGlobalReusedDisposables().contains(globalDisposable));
+ Assertions.assertTrue(repository.getOneoffDisposables().isEmpty());
+ }
+
+ class GlobalDisposable implements Disposable {
+
+ boolean destroyed = false;
+
+ @Override
+ public void destroy() {
+ destroyed = true;
+ }
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+ }
+
+ class OneOffDisposable implements Disposable {
+ boolean destroyed = false;
+
+ @Override
+ public void destroy() {
+ destroyed = true;
+ }
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoaderTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoaderTest.java
new file mode 100644
index 0000000..10331e8
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ClassLoaderResourceLoaderTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.common.utils;
+
+import org.apache.dubbo.common.extension.DubboInternalLoadingStrategy;
+import org.apache.dubbo.common.extension.director.FooAppProvider;
+import org.apache.dubbo.common.resource.GlobalResourcesRepository;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * {@link ClassLoaderResourceLoader}
+ */
+public class ClassLoaderResourceLoaderTest {
+
+ @Test
+ public void test() {
+ DubboInternalLoadingStrategy dubboInternalLoadingStrategy = new
DubboInternalLoadingStrategy();
+ String directory = dubboInternalLoadingStrategy.directory();
+ String type = FooAppProvider.class.getName();
+ String fileName = directory + type;
+
+ ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
+ Map<ClassLoader, Set<URL>> loadResources =
ClassLoaderResourceLoader.loadResources(fileName,
Arrays.asList(contextClassLoader));
+ Assertions.assertTrue(loadResources.containsKey(contextClassLoader));
+
Assertions.assertTrue(!loadResources.get(contextClassLoader).isEmpty());
+
+ // cache
+
Assertions.assertNotNull(ClassLoaderResourceLoader.getClassLoaderResourcesCache());
+ loadResources = ClassLoaderResourceLoader.loadResources(fileName,
Arrays.asList(contextClassLoader));
+ Assertions.assertTrue(loadResources.containsKey(contextClassLoader));
+
Assertions.assertTrue(!loadResources.get(contextClassLoader).isEmpty());
+
+
Assertions.assertNotNull(GlobalResourcesRepository.getGlobalReusedDisposables());
+
+ ClassLoaderResourceLoader.destroy();
+
Assertions.assertNull(ClassLoaderResourceLoader.getClassLoaderResourcesCache());
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
index 8e50939..321343c 100644
---
a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
+++
b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
@@ -31,6 +31,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Collection;
+import java.util.Optional;
import static java.util.Arrays.asList;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
@@ -43,7 +44,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
/**
+ * {@link AbstractConfigManager} Test
* {@link ConfigManager} Test
+ * {@link ModuleConfigManager} Test
*
* @since 2.7.5
*/
@@ -119,7 +122,7 @@ public class ConfigManagerTest {
assertEquals(monitorConfig, moduleConfigManager.getMonitor().get());
}
- // Test MonitorConfig correlative methods
+ // Test ModuleConfig correlative methods
@Test
public void testModuleConfig() {
ModuleConfig config = new ModuleConfig();
@@ -306,4 +309,95 @@ public class ConfigManagerTest {
System.clearProperty(DUBBO_CONFIG_MODE);
}
}
+
+ @Test
+ public void testGetConfigByIdOrName() {
+ RegistryConfig registryConfig = new RegistryConfig();
+ registryConfig.setId("registryID_1");
+ configManager.addRegistry(registryConfig);
+ Optional<RegistryConfig> registryConfigOptional =
configManager.getConfig(RegistryConfig.class, registryConfig.getId());
+ Assertions.assertEquals(registryConfigOptional.get(), registryConfig);
+
+
+ ProtocolConfig protocolConfig = new ProtocolConfig("dubbo");
+ configManager.addProtocol(protocolConfig);
+ Optional<ProtocolConfig> protocolConfigOptional =
configManager.getConfig(ProtocolConfig.class, protocolConfig.getName());
+ Assertions.assertEquals(protocolConfigOptional.get(), protocolConfig);
+
+ ModuleConfig moduleConfig = new ModuleConfig();
+ moduleConfig.setId("moduleID_1");
+ moduleConfigManager.setModule(moduleConfig);
+ Optional<ModuleConfig> moduleConfigOptional =
moduleConfigManager.getConfig(ModuleConfig.class, moduleConfig.getId());
+ Assertions.assertEquals(moduleConfigOptional.get(), moduleConfig);
+
+ Optional<RegistryConfig> config =
moduleConfigManager.getConfig(RegistryConfig.class, registryConfig.getId());
+ Assertions.assertEquals(config.get(), registryConfig);
+ }
+
+ @Test
+ public void testLoadConfigsOfTypeFromProps() {
+ try {
+ // dubbo.application.enable-file-cache = false
+ configManager.loadConfigsOfTypeFromProps(ApplicationConfig.class);
+ Optional<ApplicationConfig> application =
configManager.getApplication();
+ Assertions.assertTrue(application.isPresent());
+ configManager.removeConfig(application.get());
+
+ System.setProperty("dubbo.protocols.dubbo1.port", "20880");
+ System.setProperty("dubbo.protocols.dubbo2.port", "20881");
+ System.setProperty("dubbo.protocols.rest1.port", "8080");
+ System.setProperty("dubbo.protocols.rest2.port", "8081");
+ configManager.loadConfigsOfTypeFromProps(ProtocolConfig.class);
+ Collection<ProtocolConfig> protocols =
configManager.getProtocols();
+ Assertions.assertEquals(protocols.size(), 4);
+
+ System.setProperty("dubbo.applications.app1.name", "app-demo1");
+ System.setProperty("dubbo.applications.app2.name", "app-demo2");
+ try {
+
configManager.loadConfigsOfTypeFromProps(ApplicationConfig.class);
+ Assertions.fail();
+ } catch (Exception e) {
+ Assertions.assertTrue(e.getMessage().contains("load config
failed"));
+ }
+ } finally {
+ System.clearProperty("dubbo.protocols.dubbo1.port");
+ System.clearProperty("dubbo.protocols.dubbo2.port");
+ System.clearProperty("dubbo.protocols.rest1.port");
+ System.clearProperty("dubbo.protocols.rest2.port");
+ System.clearProperty("dubbo.applications.app1.name");
+ System.clearProperty("dubbo.applications.app2.name");
+ }
+
+ }
+
+ @Test
+ public void testLoadConfig() {
+ configManager.loadConfigs();
+ Assertions.assertTrue(configManager.getApplication().isPresent());
+ Assertions.assertTrue(configManager.getSsl().isPresent());
+ Assertions.assertFalse(configManager.getProtocols().isEmpty());
+
+ int port = 20880;
+ ProtocolConfig config1 = new ProtocolConfig();
+ config1.setName("dubbo");
+ config1.setPort(port);
+
+ ProtocolConfig config2 = new ProtocolConfig();
+ config2.setName("rest");
+ config2.setPort(port);
+ configManager.addProtocols(asList(config1, config2));
+ try {
+ configManager.loadConfigs();
+ Assertions.fail();
+ } catch (Exception e) {
+ Assertions.assertTrue(e instanceof IllegalStateException);
+ Assertions.assertTrue(e.getMessage().contains("Duplicated port
used by protocol configs, port: " + port));
+ }
+
+ moduleConfigManager.loadConfigs();
+ Assertions.assertTrue(moduleConfigManager.getModule().isPresent());
+ Assertions.assertFalse(moduleConfigManager.getProviders().isEmpty());
+ Assertions.assertFalse(moduleConfigManager.getConsumers().isEmpty());
+
+ }
}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ApplicationModelTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ApplicationModelTest.java
new file mode 100644
index 0000000..b42a39b
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ApplicationModelTest.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.model;
+
+import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
+import org.apache.dubbo.common.config.ConfigurationCache;
+import org.apache.dubbo.common.extension.ExtensionScope;
+import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
+import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.support.MockScopeModelDestroyListener;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * {@link ApplicationModel}
+ */
+public class ApplicationModelTest {
+
+ @Test
+ public void testInitialize() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ ApplicationModel applicationModel = new
ApplicationModel(frameworkModel);
+
+ Assertions.assertEquals(applicationModel.getParent(), frameworkModel);
+ Assertions.assertEquals(applicationModel.getScope(),
ExtensionScope.APPLICATION);
+ Assertions.assertEquals(applicationModel.getFrameworkModel(),
frameworkModel);
+ Assertions.assertFalse(applicationModel.isInternal());
+
Assertions.assertTrue(frameworkModel.getApplicationModels().contains(applicationModel));
+ Assertions.assertNotNull(applicationModel.getInternalId());
+
+ Assertions.assertNotNull(applicationModel.getExtensionDirector());
+ Assertions.assertNotNull(applicationModel.getBeanFactory());
+
Assertions.assertTrue(applicationModel.getClassLoaders().contains(ScopeModel.class.getClassLoader()));
+
+ Assertions.assertNotNull(applicationModel.getInternalModule());
+
Assertions.assertNotNull(applicationModel.getApplicationServiceRepository());
+
+ ScopeBeanFactory applicationModelBeanFactory =
applicationModel.getBeanFactory();
+
Assertions.assertNotNull(applicationModelBeanFactory.getBean(ShutdownHookCallbacks.class));
+
Assertions.assertNotNull(applicationModelBeanFactory.getBean(FrameworkStatusReportService.class));
+
Assertions.assertNotNull(applicationModelBeanFactory.getBean(ConfigurationCache.class));
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testDefaultApplication() {
+ ApplicationModel applicationModel = ApplicationModel.defaultModel();
+ FrameworkModel frameworkModel = applicationModel.getFrameworkModel();
+
+ Assertions.assertFalse(applicationModel.isInternal());
+ Assertions.assertEquals(frameworkModel.defaultApplication(),
applicationModel);
+
Assertions.assertTrue(frameworkModel.getApplicationModels().contains(applicationModel));
+
+ String desc = applicationModel.getDesc();
+ Assertions.assertEquals(desc, "Dubbo Application[" +
applicationModel.getInternalId() + "](unknown)");
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testModule() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ ApplicationModel applicationModel = new
ApplicationModel(frameworkModel);
+
+ ModuleModel defaultModule = applicationModel.getDefaultModule();
+ ModuleModel internalModule = applicationModel.getInternalModule();
+
+
Assertions.assertTrue(applicationModel.getModuleModels().contains(defaultModule));
+
Assertions.assertTrue(applicationModel.getModuleModels().contains(internalModule));
+
Assertions.assertTrue(applicationModel.getPubModuleModels().contains(defaultModule));
+
Assertions.assertFalse(applicationModel.getPubModuleModels().contains(internalModule));
+
+ applicationModel.removeModule(defaultModule);
+
Assertions.assertFalse(applicationModel.getModuleModels().contains(defaultModule));
+
Assertions.assertFalse(applicationModel.getPubModuleModels().contains(defaultModule));
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testOfNullable() {
+ ApplicationModel applicationModel = ApplicationModel.ofNullable(null);
+ Assertions.assertEquals(ApplicationModel.defaultModel(),
applicationModel);
+ applicationModel.getFrameworkModel().destroy();
+
+ FrameworkModel frameworkModel = new FrameworkModel();
+ ApplicationModel applicationModel1 = new
ApplicationModel(frameworkModel);
+ ApplicationModel applicationModel2 =
ApplicationModel.ofNullable(applicationModel1);
+ Assertions.assertEquals(applicationModel1, applicationModel2);
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testDestroy() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ ApplicationModel applicationModel = new
ApplicationModel(frameworkModel);
+
+ applicationModel.getDefaultModule();
+ applicationModel.newModule();
+
+ MockScopeModelDestroyListener destroyListener = new
MockScopeModelDestroyListener();
+ applicationModel.addDestroyListener(destroyListener);
+ applicationModel.destroy();
+
+
Assertions.assertFalse(frameworkModel.getApplicationModels().contains(applicationModel));
+ Assertions.assertTrue(applicationModel.getModuleModels().isEmpty());
+ Assertions.assertTrue(destroyListener.isDestroyed());
+ Assertions.assertEquals(destroyListener.getScopeModel(),
applicationModel);
+
Assertions.assertNull(applicationModel.getApplicationServiceRepository());
+ Assertions.assertTrue(applicationModel.isDestroyed());
+ // trigger frameworkModel.tryDestroy()
+ Assertions.assertTrue(frameworkModel.isDestroyed());
+
+ try {
+ applicationModel.getDefaultModule();
+ Assertions.fail("Cannot create new module after application model
destroyed");
+ } catch (Exception e) {
+ Assertions.assertEquals("ApplicationModel is destroyed",
e.getMessage(), StringUtils.toString(e));
+ }
+
+ try {
+ applicationModel.newModule();
+ Assertions.fail("Cannot create new module after application model
destroyed");
+ } catch (Exception e) {
+ Assertions.assertEquals("ApplicationModel is destroyed",
e.getMessage(), StringUtils.toString(e));
+ }
+
+ }
+
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/FrameworkModelTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/FrameworkModelTest.java
new file mode 100644
index 0000000..9967d57
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/FrameworkModelTest.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.rpc.model;
+
+import org.apache.dubbo.common.extension.ExtensionScope;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * {@link FrameworkModel}
+ */
+public class FrameworkModelTest {
+ @Test
+ public void testInitialize() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+
+ Assertions.assertNull(frameworkModel.getParent());
+ Assertions.assertEquals(frameworkModel.getScope(),
ExtensionScope.FRAMEWORK);
+
+ Assertions.assertNotNull(frameworkModel.getInternalId());
+
Assertions.assertTrue(FrameworkModel.getAllInstances().contains(frameworkModel));
+ Assertions.assertEquals(FrameworkModel.defaultModel(), frameworkModel);
+
+ Assertions.assertNotNull(frameworkModel.getExtensionDirector());
+ Assertions.assertNotNull(frameworkModel.getBeanFactory());
+
Assertions.assertTrue(frameworkModel.getClassLoaders().contains(ScopeModel.class.getClassLoader()));
+
+ Assertions.assertNotNull(frameworkModel.getServiceRepository());
+ ApplicationModel applicationModel =
frameworkModel.getInternalApplicationModel();
+ Assertions.assertNotNull(applicationModel);
+
Assertions.assertTrue(frameworkModel.getAllApplicationModels().contains(applicationModel));
+
Assertions.assertFalse(frameworkModel.getApplicationModels().contains(applicationModel));
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testDefaultModel() {
+ FrameworkModel frameworkModel = FrameworkModel.defaultModel();
+
Assertions.assertTrue(FrameworkModel.getAllInstances().contains(frameworkModel));
+ String desc = frameworkModel.getDesc();
+ Assertions.assertEquals(desc, "Dubbo Framework[" +
frameworkModel.getInternalId() + "]");
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testApplicationModel() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+
+ ApplicationModel applicationModel =
frameworkModel.defaultApplication();
+ ApplicationModel internalApplicationModel =
frameworkModel.getInternalApplicationModel();
+
+ Assertions.assertEquals(frameworkModel.getDefaultAppModel(),
applicationModel);
+
Assertions.assertTrue(frameworkModel.getAllApplicationModels().contains(applicationModel));
+
Assertions.assertTrue(frameworkModel.getAllApplicationModels().contains(internalApplicationModel));
+
Assertions.assertTrue(frameworkModel.getApplicationModels().contains(applicationModel));
+
Assertions.assertFalse(frameworkModel.getApplicationModels().contains(internalApplicationModel));
+
+ frameworkModel.removeApplication(applicationModel);
+
Assertions.assertFalse(frameworkModel.getAllApplicationModels().contains(applicationModel));
+
Assertions.assertFalse(frameworkModel.getApplicationModels().contains(applicationModel));
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void destroyAll() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ frameworkModel.defaultApplication();
+ frameworkModel.newApplication();
+
+ FrameworkModel.destroyAll();
+ Assertions.assertTrue(FrameworkModel.getAllInstances().isEmpty());
+ Assertions.assertTrue(frameworkModel.isDestroyed());
+
+ try {
+ frameworkModel.defaultApplication();
+ Assertions.fail("Cannot create new application after framework
model destroyed");
+ } catch (Exception e) {
+ Assertions.assertEquals("FrameworkModel is destroyed",
e.getMessage(), StringUtils.toString(e));
+ }
+
+ try {
+ frameworkModel.newApplication();
+ Assertions.fail("Cannot create new application after framework
model destroyed");
+ } catch (Exception e) {
+ Assertions.assertEquals("FrameworkModel is destroyed",
e.getMessage(), StringUtils.toString(e));
+ }
+ }
+
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ModuleModelTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ModuleModelTest.java
new file mode 100644
index 0000000..75366f5
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ModuleModelTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.model;
+
+import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
+import org.apache.dubbo.common.config.ConfigurationCache;
+import org.apache.dubbo.common.config.ModuleEnvironment;
+import org.apache.dubbo.common.extension.ExtensionScope;
+import org.apache.dubbo.rpc.support.MockScopeModelDestroyListener;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * {@link ModuleModel}
+ */
+public class ModuleModelTest {
+
+ @Test
+ public void testInitialize() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ ApplicationModel applicationModel = new
ApplicationModel(frameworkModel);
+ ModuleModel moduleModel = new ModuleModel(applicationModel);
+ Assertions.assertEquals(moduleModel.getParent(), applicationModel);
+ Assertions.assertEquals(moduleModel.getScope(), ExtensionScope.MODULE);
+ Assertions.assertEquals(moduleModel.getApplicationModel(),
applicationModel);
+
Assertions.assertTrue(applicationModel.getPubModuleModels().contains(moduleModel));
+ Assertions.assertNotNull(moduleModel.getInternalId());
+
+ Assertions.assertNotNull(moduleModel.getExtensionDirector());
+ Assertions.assertNotNull(moduleModel.getBeanFactory());
+
Assertions.assertTrue(moduleModel.getClassLoaders().contains(ScopeModel.class.getClassLoader()));
+
+ Assertions.assertNotNull(moduleModel.getServiceRepository());
+ Assertions.assertNotNull(moduleModel.getConfigManager());
+
+ ScopeBeanFactory moduleModelBeanFactory = moduleModel.getBeanFactory();
+
Assertions.assertNotNull(moduleModelBeanFactory.getBean(ConfigurationCache.class));
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testModelEnvironment() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ ApplicationModel applicationModel = new
ApplicationModel(frameworkModel);
+ ModuleModel moduleModel = new ModuleModel(applicationModel);
+
+ ModuleEnvironment modelEnvironment = moduleModel.getModelEnvironment();
+ Assertions.assertNotNull(modelEnvironment);
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ public void testDestroy() {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ ApplicationModel applicationModel = new
ApplicationModel(frameworkModel);
+ ModuleModel moduleModel = new ModuleModel(applicationModel);
+
+ MockScopeModelDestroyListener destroyListener = new
MockScopeModelDestroyListener();
+ moduleModel.addDestroyListener(destroyListener);
+
+ moduleModel.destroy();
+ Assertions.assertTrue(destroyListener.isDestroyed());
+ Assertions.assertEquals(destroyListener.getScopeModel(), moduleModel);
+
Assertions.assertFalse(applicationModel.getPubModuleModels().contains(moduleModel));
+ Assertions.assertNull(moduleModel.getServiceRepository());
+ Assertions.assertTrue(moduleModel.isDestroyed());
+
+ // trigger tryDestroy
+ Assertions.assertTrue(applicationModel.isDestroyed());
+ Assertions.assertTrue(frameworkModel.isDestroyed());
+
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelTest.java
index dd9608d..f450586 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/rpc/model/ScopeModelTest.java
@@ -32,21 +32,20 @@ public class ScopeModelTest {
FrameworkModel.destroyAll();
FrameworkModel frameworkModel = new FrameworkModel();
- ApplicationModel applicationModel1 = frameworkModel.newApplication();
- ApplicationModel applicationModel2 = frameworkModel.newApplication();
+ ApplicationModel applicationModel = frameworkModel.newApplication();
List<Throwable> errors = new ArrayList<>();
- applicationModel1.addDestroyListener(scopeModel -> {
+ applicationModel.addDestroyListener(scopeModel -> {
try {
try {
- applicationModel1.getDefaultModule();
+ applicationModel.getDefaultModule();
Assertions.fail("Cannot create new module after
application model destroyed");
} catch (Exception e) {
Assertions.assertEquals("ApplicationModel is destroyed",
e.getMessage(), StringUtils.toString(e));
}
try {
- applicationModel1.newModule();
+ applicationModel.newModule();
Assertions.fail("Cannot create new module after
application model destroyed");
} catch (Exception e) {
Assertions.assertEquals("ApplicationModel is destroyed",
e.getMessage(), StringUtils.toString(e));
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/rpc/support/MockScopeModelDestroyListener.java
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/support/MockScopeModelDestroyListener.java
new file mode 100644
index 0000000..f89771d
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/rpc/support/MockScopeModelDestroyListener.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.rpc.support;
+
+import org.apache.dubbo.rpc.model.ScopeModel;
+import org.apache.dubbo.rpc.model.ScopeModelDestroyListener;
+
+public class MockScopeModelDestroyListener implements
ScopeModelDestroyListener {
+ private boolean destroyed = false;
+ private ScopeModel scopeModel;
+
+ @Override
+ public void onDestroy(ScopeModel scopeModel) {
+ this.destroyed = true;
+ this.scopeModel = scopeModel;
+ }
+
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ public ScopeModel getScopeModel() {
+ return scopeModel;
+ }
+}