You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/02/22 05:26:29 UTC
[dubbo] branch 3.0 updated: Add unit test for
CacheableFailbackRegistry (#7157)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new 7fe4b6c Add unit test for CacheableFailbackRegistry (#7157)
7fe4b6c is described below
commit 7fe4b6ca5d32159d349fa8b82c04b90d69c55950
Author: Wu Zhiguo <wz...@gmail.com>
AuthorDate: Mon Feb 22 13:26:13 2021 +0800
Add unit test for CacheableFailbackRegistry (#7157)
---
.../support/CacheableFailbackRegistry.java | 17 ++-
.../registry/CacheableFailbackRegistryTest.java | 169 ++++++++++++++++++++-
.../dubbo/registry/MockCacheableRegistryImpl.java | 48 +++++-
3 files changed, 227 insertions(+), 7 deletions(-)
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
index ace03c2..ec3f3ca 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/CacheableFailbackRegistry.java
@@ -121,7 +121,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
newURLs.put(rawProvider, cachedURL);
}
} else {
- newURLs = new HashMap<>((int)(oldURLs.size()/.75 + 1));
+ newURLs = new HashMap<>((int) (oldURLs.size() / .75 + 1));
// maybe only default , or "env" + default
for (String rawProvider : providers) {
rawProvider = stripOffVariableKeys(rawProvider);
@@ -272,23 +272,31 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
}
protected String[] getVariableKeys() {
- return VARIABLE_KEYS;
+ return VARIABLE_KEYS;
}
protected String getDefaultURLProtocol() {
return DUBBO;
}
+ /**
+ * This method is for unit test to see if the RemovalTask has completed or not.<br />
+ * <strong>Please do not call this method in other places.</strong>
+ */
+ @Deprecated
+ protected Semaphore getSemaphore() {
+ return semaphore;
+ }
+
protected abstract boolean isMatch(URL subscribeUrl, URL providerUrl);
private static class RemovalTask implements Runnable {
@Override
public void run() {
- semaphore.release();
logger.info("Clearing cached URLs, size " + waitForRemove.size());
Iterator<Map.Entry<ServiceAddressURL, Long>> it = waitForRemove.entrySet().iterator();
- while(it.hasNext()) {
+ while (it.hasNext()) {
Map.Entry<ServiceAddressURL, Long> entry = it.next();
ServiceAddressURL removeURL = entry.getKey();
long removeTime = entry.getValue();
@@ -305,6 +313,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
it.remove();
}
}
+ semaphore.release();
if (CollectionUtils.isNotEmptyMap(waitForRemove)) {
// move to next schedule
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/CacheableFailbackRegistryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/CacheableFailbackRegistryTest.java
index 6045e2c..25dceb6 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/CacheableFailbackRegistryTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/CacheableFailbackRegistryTest.java
@@ -16,22 +16,189 @@
*/
package org.apache.dubbo.registry;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.URLStrParser;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
public class CacheableFailbackRegistryTest {
+ static String service;
+ static URL serviceUrl;
+ static URL registryUrl;
+ static String urlStr;
+ MockCacheableRegistryImpl registry;
+
+ @BeforeAll
+ static void setProperty() {
+ System.setProperty("dubbo.application.url.cache.task.interval", "0");
+ System.setProperty("dubbo.application.url.cache.clear.waiting", "0");
+ }
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ service = "org.apache.dubbo.test.DemoService";
+ serviceUrl = URL.valueOf("dubbo://127.0.0.1/org.apache.dubbo.test.DemoService?category=providers");
+ registryUrl = URL.valueOf("http://1.2.3.4:9090/registry?check=false&file=N/A");
+ urlStr = "dubbo%3A%2F%2F172.19.4.113%3A20880%2Forg.apache.dubbo.demo.DemoService%3Fside%3Dprovider%26timeout%3D3000";
+ }
+
+ @AfterEach
+ public void tearDown() {
+ registry.getStringUrls().clear();
+ registry.getStringAddress().clear();
+ registry.getStringParam().clear();
+ }
+
+ @Test
public void testFullURLCache() {
+ final AtomicReference<Integer> resCount = new AtomicReference<>(0);
+ registry = new MockCacheableRegistryImpl(registryUrl);
+ URL url = URLStrParser.parseEncodedStr(urlStr);
+
+ NotifyListener listener = new NotifyListener() {
+ @Override
+ public void notify(List<URL> urls) {
+ resCount.set(urls.size());
+ }
+ };
+
+ registry.addChildren(url);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringUrls().get(serviceUrl).size());
+ assertEquals(1, resCount.get());
+ registry.addChildren(url);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringUrls().get(serviceUrl).size());
+ assertEquals(1, resCount.get());
+
+ URL url1 = url.addParameter("k1", "v1");
+ registry.addChildren(url1);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(2, registry.getStringUrls().get(serviceUrl).size());
+ assertEquals(2, resCount.get());
+
+ URL url2 = url1.setHost("192.168.1.1");
+ registry.addChildren(url2);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(3, registry.getStringUrls().get(serviceUrl).size());
+ assertEquals(3, resCount.get());
}
+ @Test
public void testURLAddressCache() {
+ final AtomicReference<Integer> resCount = new AtomicReference<>(0);
+ registry = new MockCacheableRegistryImpl(registryUrl);
+ URL url = URLStrParser.parseEncodedStr(urlStr);
+
+ NotifyListener listener = new NotifyListener() {
+ @Override
+ public void notify(List<URL> urls) {
+ resCount.set(urls.size());
+ }
+ };
+
+ registry.addChildren(url);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringAddress().size());
+ assertEquals(1, resCount.get());
+ URL url1 = url.addParameter("k1", "v1");
+ registry.addChildren(url1);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringAddress().size());
+ assertEquals(2, resCount.get());
+
+ URL url2 = url1.setHost("192.168.1.1");
+ registry.addChildren(url2);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(2, registry.getStringAddress().size());
+ assertEquals(3, resCount.get());
}
+ @Test
public void testURLParamCache() {
+ final AtomicReference<Integer> resCount = new AtomicReference<>(0);
+ registry = new MockCacheableRegistryImpl(registryUrl);
+ URL url = URLStrParser.parseEncodedStr(urlStr);
+
+ NotifyListener listener = new NotifyListener() {
+ @Override
+ public void notify(List<URL> urls) {
+ resCount.set(urls.size());
+ }
+ };
+
+ registry.addChildren(url);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringParam().size());
+ assertEquals(1, resCount.get());
+ URL url1 = url.addParameter("k1", "v1");
+ registry.addChildren(url1);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(2, registry.getStringParam().size());
+ assertEquals(2, resCount.get());
+
+ URL url2 = url1.setHost("192.168.1.1");
+ registry.addChildren(url2);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(2, registry.getStringParam().size());
+ assertEquals(3, resCount.get());
}
- public void testRemove() {
+ @Test
+ public void testRemove() throws Exception {
+ final AtomicReference<Integer> resCount = new AtomicReference<>(0);
+ registry = new MockCacheableRegistryImpl(registryUrl);
+ URL url = URLStrParser.parseEncodedStr(urlStr);
+
+ NotifyListener listener = new NotifyListener() {
+ @Override
+ public void notify(List<URL> urls) {
+ resCount.set(urls.size());
+ }
+ };
+
+ registry.addChildren(url);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringUrls().get(serviceUrl).size());
+ assertEquals(1, registry.getStringAddress().size());
+ assertEquals(1, registry.getStringParam().size());
+ assertEquals(1, resCount.get());
+
+ registry.clearChildren();
+ URL url1 = url.addParameter("k1", "v1");
+ registry.addChildren(url1);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringUrls().get(serviceUrl).size());
+ assertEquals(1, resCount.get());
+
+ // After RemovalTask
+ assertEquals(1, registry.getStringParam().size());
+ // StringAddress will be deleted because the related stringUrls cache has been deleted.
+ assertEquals(0, registry.getStringAddress().size());
+
+ registry.clearChildren();
+ URL url2 = url1.setHost("192.168.1.1");
+ registry.addChildren(url2);
+ registry.subscribe(serviceUrl, listener);
+ assertEquals(1, registry.getStringUrls().get(serviceUrl).size());
+ assertEquals(1, resCount.get());
+ // After RemovalTask
+ assertEquals(1, registry.getStringAddress().size());
+ // StringParam will be deleted because the related stringUrls cache has been deleted.
+ assertEquals(0, registry.getStringParam().size());
}
}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/MockCacheableRegistryImpl.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/MockCacheableRegistryImpl.java
index 2ebab9a..ff9f661 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/MockCacheableRegistryImpl.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/MockCacheableRegistryImpl.java
@@ -17,13 +17,24 @@
package org.apache.dubbo.registry;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.url.component.ServiceAddressURL;
+import org.apache.dubbo.common.url.component.URLAddress;
+import org.apache.dubbo.common.url.component.URLParam;
+import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.registry.support.CacheableFailbackRegistry;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
/**
*
*/
public class MockCacheableRegistryImpl extends CacheableFailbackRegistry {
+ private final List<String> children = new ArrayList<>();
+
public MockCacheableRegistryImpl(URL url) {
super(url);
}
@@ -35,7 +46,7 @@ public class MockCacheableRegistryImpl extends CacheableFailbackRegistry {
@Override
protected boolean isMatch(URL subscribeUrl, URL providerUrl) {
- return false;
+ return UrlUtils.isMatch(subscribeUrl, providerUrl);
}
@Override
@@ -50,7 +61,16 @@ public class MockCacheableRegistryImpl extends CacheableFailbackRegistry {
@Override
public void doSubscribe(URL url, NotifyListener listener) {
-
+ List<URL> res = toUrlsWithoutEmpty(url, children);
+ Semaphore semaphore = getSemaphore();
+ while (semaphore.availablePermits() != 1) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ listener.notify(res);
}
@Override
@@ -62,4 +82,28 @@ public class MockCacheableRegistryImpl extends CacheableFailbackRegistry {
public boolean isAvailable() {
return false;
}
+
+ public void addChildren(URL url) {
+ children.add(URL.encode(url.toFullString()));
+ }
+
+ public List<String> getChildren() {
+ return children;
+ }
+
+ public void clearChildren() {
+ children.clear();
+ }
+
+ public Map<URL, Map<String, ServiceAddressURL>> getStringUrls() {
+ return stringUrls;
+ }
+
+ public Map<String, URLAddress> getStringAddress() {
+ return stringAddress;
+ }
+
+ public Map<String, URLParam> getStringParam() {
+ return stringParam;
+ }
}