Browse Source

Add some unit test for sentinel-dubbo-adapter module (#569)

master
cdfive Eric Zhao 5 years ago
parent
commit
6d1e7bcb7a
10 changed files with 436 additions and 9 deletions
  1. +24
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java
  2. +41
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/AbstractDubboFilterTest.java
  3. +59
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilterTest.java
  4. +39
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtilsTest.java
  5. +131
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java
  6. +133
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilterTest.java
  7. +1
    -1
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoService.java
  8. +2
    -2
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/impl/DemoServiceImpl.java
  9. +3
    -3
      sentinel-adapter/sentinel-dubbo-adapter/src/test/resources/spring-dubbo-consumer-filter.xml
  10. +3
    -3
      sentinel-adapter/sentinel-dubbo-adapter/src/test/resources/spring-dubbo-provider-filter.xml

+ 24
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java View File

@@ -0,0 +1,24 @@
package com.alibaba.csp.sentinel;

import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
import com.alibaba.dubbo.rpc.RpcContext;

/**
* Base test class, provide common methods for subClass
* The package is same as CtSph, to call CtSph.resetChainMap() method for test
*
* Note: Only for test. DO NOT USE IN PRODUCTION!
*
* @author cdfive
*/
public class BaseTest {

/**
* Clean up resources for context, clusterNodeMap, processorSlotChainMap
*/
protected static void cleanUpAll() {
RpcContext.removeContext();
ClusterBuilderSlot.getClusterNodeMap().clear();
CtSph.resetChainMap();
}
}

+ 41
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/AbstractDubboFilterTest.java View File

@@ -0,0 +1,41 @@
package com.alibaba.csp.sentinel.adapter.dubbo;

import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
import org.junit.Test;

import java.lang.reflect.Method;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
* @author cdfive
*/
public class AbstractDubboFilterTest {

private AbstractDubboFilter filter = new AbstractDubboFilter() {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
return null;
}
};

@Test
public void testGetResourceName() {
Invoker invoker = mock(Invoker.class);
when(invoker.getInterface()).thenReturn(DemoService.class);

Invocation invocation = mock(Invocation.class);
Method method = DemoService.class.getMethods()[0];
when(invocation.getMethodName()).thenReturn(method.getName());
when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());

String resourceName = filter.getResourceName(invoker, invocation);

assertEquals("com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
}
}

+ 59
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilterTest.java View File

@@ -0,0 +1,59 @@
package com.alibaba.csp.sentinel.adapter.dubbo;

import com.alibaba.csp.sentinel.BaseTest;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.RpcContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
* @author cdfive
*/
public class DubboAppContextFilterTest extends BaseTest {

private DubboAppContextFilter filter = new DubboAppContextFilter();

@Before
public void setUp() {
cleanUpAll();
}

@After
public void cleanUp() {
cleanUpAll();
}

@Test
public void testInvokeApplicationKey() {
Invoker invoker = mock(Invoker.class);
Invocation invocation = mock(Invocation.class);
URL url = URL.valueOf("test://test:111/test?application=serviceA");
when(invoker.getUrl()).thenReturn(url);

filter.invoke(invoker, invocation);
verify(invoker).invoke(invocation);

String application = RpcContext.getContext().getAttachment(DubboUtils.DUBBO_APPLICATION_KEY);
assertEquals("serviceA", application);
}

@Test
public void testInvokeNullApplicationKey() {
Invoker invoker = mock(Invoker.class);
Invocation invocation = mock(Invocation.class);
URL url = URL.valueOf("test://test:111/test?application=");
when(invoker.getUrl()).thenReturn(url);

filter.invoke(invoker, invocation);
verify(invoker).invoke(invocation);

String application = RpcContext.getContext().getAttachment(DubboUtils.DUBBO_APPLICATION_KEY);
assertNull(application);
}
}

+ 39
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtilsTest.java View File

@@ -0,0 +1,39 @@
package com.alibaba.csp.sentinel.adapter.dubbo;

import com.alibaba.dubbo.rpc.Invocation;
import org.junit.Test;

import java.util.HashMap;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.*;

/**
* @author cdfive
*/
public class DubboUtilsTest {

@Test
public void testGetApplication() {
Invocation invocation = mock(Invocation.class);
when(invocation.getAttachments()).thenReturn(new HashMap<String, String>());
when(invocation.getAttachment(DubboUtils.DUBBO_APPLICATION_KEY, "")).thenReturn("consumerA");

String application = DubboUtils.getApplication(invocation, "");
verify(invocation).getAttachment(DubboUtils.DUBBO_APPLICATION_KEY, "");

assertEquals("consumerA", application);
}

@Test(expected = IllegalArgumentException.class)
public void testGetApplicationNoAttachments() {
Invocation invocation = mock(Invocation.class);
when(invocation.getAttachments()).thenReturn(null);
when(invocation.getAttachment(DubboUtils.DUBBO_APPLICATION_KEY, "")).thenReturn("consumerA");

DubboUtils.getApplication(invocation, "");

fail("No attachments in invocation, IllegalArgumentException should be thrown!");
}
}

+ 131
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilterTest.java View File

@@ -0,0 +1,131 @@
package com.alibaba.csp.sentinel.adapter.dubbo;

import com.alibaba.csp.sentinel.BaseTest;
import com.alibaba.csp.sentinel.Constants;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService;
import com.alibaba.csp.sentinel.context.Context;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.node.ClusterNode;
import com.alibaba.csp.sentinel.node.DefaultNode;
import com.alibaba.csp.sentinel.node.Node;
import com.alibaba.csp.sentinel.node.StatisticNode;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
* @author cdfive
*/
public class SentinelDubboConsumerFilterTest extends BaseTest {

private SentinelDubboConsumerFilter filter = new SentinelDubboConsumerFilter();

@Before
public void setUp() {
cleanUpAll();
}

@After
public void cleanUp() {
cleanUpAll();
}

@Test
public void testInvoke() {
final Invoker invoker = mock(Invoker.class);
when(invoker.getInterface()).thenReturn(DemoService.class);

final Invocation invocation = mock(Invocation.class);
Method method = DemoService.class.getMethods()[0];
when(invocation.getMethodName()).thenReturn(method.getName());
when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());

final Result result = mock(Result.class);
when(result.hasException()).thenReturn(false);
when(invoker.invoke(invocation)).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
verifyInvocationStructure(invoker, invocation);
return result;
}
});

filter.invoke(invoker, invocation);
verify(invoker).invoke(invocation);

Context context = ContextUtil.getContext();
assertNull(context);
}

/**
* Simply verify invocation structure in memory:
* EntranceNode(defaultContextName)
* --InterfaceNode(interfaceName)
* ----MethodNode(resourceName)
*/
private void verifyInvocationStructure(Invoker invoker, Invocation invocation) {
Context context = ContextUtil.getContext();
assertNotNull(context);

// As not call ContextUtil.enter(resourceName, application) in SentinelDubboConsumerFilter, use default context
// In actual project, a consumer is usually also a provider, the context will be created by SentinelDubboProviderFilter
// If consumer is on the top of Dubbo RPC invocation chain, use default context
String resourceName = filter.getResourceName(invoker, invocation);
assertEquals(Constants.CONTEXT_DEFAULT_NAME, context.getName());
assertEquals("", context.getOrigin());

DefaultNode entranceNode = context.getEntranceNode();
ResourceWrapper entranceResource = entranceNode.getId();
assertEquals(Constants.CONTEXT_DEFAULT_NAME, entranceResource.getName());
assertSame(EntryType.IN, entranceResource.getType());

// As SphU.entry(interfaceName, EntryType.OUT);
Set<Node> childList = entranceNode.getChildList();
assertEquals(1, childList.size());
DefaultNode interfaceNode = (DefaultNode) childList.iterator().next();
ResourceWrapper interfaceResource = interfaceNode.getId();
assertEquals(DemoService.class.getName(), interfaceResource.getName());
assertSame(EntryType.OUT, interfaceResource.getType());

// As SphU.entry(resourceName, EntryType.OUT);
childList = interfaceNode.getChildList();
assertEquals(1, childList.size());
DefaultNode methodNode = (DefaultNode) childList.iterator().next();
ResourceWrapper methodResource = methodNode.getId();
assertEquals(resourceName, methodResource.getName());
assertSame(EntryType.OUT, methodResource.getType());

// Verify curEntry
Entry curEntry = context.getCurEntry();
assertSame(methodNode, curEntry.getCurNode());
assertSame(interfaceNode, curEntry.getLastNode());
assertNull(curEntry.getOriginNode());// As context origin is not "", no originNode should be created in curEntry

// Verify clusterNode
ClusterNode methodClusterNode = methodNode.getClusterNode();
ClusterNode interfaceClusterNode = interfaceNode.getClusterNode();
assertNotSame(methodClusterNode, interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode

// As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode
Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
assertEquals(0, methodOriginCountMap.size());

Map<String, StatisticNode> interfaceOriginCountMap = interfaceClusterNode.getOriginCountMap();
assertEquals(0, interfaceOriginCountMap.size());
}
}

+ 133
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilterTest.java View File

@@ -0,0 +1,133 @@
package com.alibaba.csp.sentinel.adapter.dubbo;

import com.alibaba.csp.sentinel.BaseTest;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService;
import com.alibaba.csp.sentinel.context.Context;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.node.ClusterNode;
import com.alibaba.csp.sentinel.node.DefaultNode;
import com.alibaba.csp.sentinel.node.Node;
import com.alibaba.csp.sentinel.node.StatisticNode;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
* @author cdfive
*/
public class SentinelDubboProviderFilterTest extends BaseTest {

private SentinelDubboProviderFilter filter = new SentinelDubboProviderFilter();

@Before
public void setUp() {
cleanUpAll();
}

@After
public void cleanUp() {
cleanUpAll();
}

@Test
public void testInvoke() {
final String originApplication = "consumerA";

final Invoker invoker = mock(Invoker.class);
when(invoker.getInterface()).thenReturn(DemoService.class);

final Invocation invocation = mock(Invocation.class);
Method method = DemoService.class.getMethods()[0];
when(invocation.getMethodName()).thenReturn(method.getName());
when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
when(invocation.getAttachment(DubboUtils.DUBBO_APPLICATION_KEY, "")).thenReturn(originApplication);

final Result result = mock(Result.class);
when(result.hasException()).thenReturn(false);
when(invoker.invoke(invocation)).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
verifyInvocationStructure(originApplication, invoker, invocation);
return result;
}
});

filter.invoke(invoker, invocation);
verify(invoker).invoke(invocation);

Context context = ContextUtil.getContext();
assertNull(context);
}

/**
* Simply verify invocation structure in memory:
* EntranceNode(resourceName)
* --InterfaceNode(interfaceName)
* ----MethodNode(resourceName)
*/
private void verifyInvocationStructure(String originApplication, Invoker invoker, Invocation invocation) {
Context context = ContextUtil.getContext();
assertNotNull(context);

// As ContextUtil.enter(resourceName, application) in SentinelDubboProviderFilter
String resourceName = filter.getResourceName(invoker, invocation);
assertEquals(resourceName, context.getName());
assertEquals(originApplication, context.getOrigin());

DefaultNode entranceNode = context.getEntranceNode();
ResourceWrapper entranceResource = entranceNode.getId();
assertEquals(resourceName, entranceResource.getName());
assertSame(EntryType.IN, entranceResource.getType());

// As SphU.entry(interfaceName, EntryType.IN);
Set<Node> childList = entranceNode.getChildList();
assertEquals(1, childList.size());
DefaultNode interfaceNode = (DefaultNode) childList.iterator().next();
ResourceWrapper interfaceResource = interfaceNode.getId();
assertEquals(DemoService.class.getName(), interfaceResource.getName());
assertSame(EntryType.IN, interfaceResource.getType());

// As SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments());
childList = interfaceNode.getChildList();
assertEquals(1, childList.size());
DefaultNode methodNode = (DefaultNode) childList.iterator().next();
ResourceWrapper methodResource = methodNode.getId();
assertEquals(resourceName, methodResource.getName());
assertSame(EntryType.IN, methodResource.getType());

// Verify curEntry
Entry curEntry = context.getCurEntry();
assertSame(methodNode, curEntry.getCurNode());
assertSame(interfaceNode, curEntry.getLastNode());
assertNotNull(curEntry.getOriginNode());// As context origin is not "", originNode should be created

// Verify clusterNode
ClusterNode methodClusterNode = methodNode.getClusterNode();
ClusterNode interfaceClusterNode = interfaceNode.getClusterNode();
assertNotSame(methodClusterNode, interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode

// As context origin is not "", the StatisticNode should be created in originCountMap of ClusterNode
Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
assertEquals(1, methodOriginCountMap.size());
assertTrue(methodOriginCountMap.containsKey(originApplication));

Map<String, StatisticNode> interfaceOriginCountMap = interfaceClusterNode.getOriginCountMap();
assertEquals(1, interfaceOriginCountMap.size());
assertTrue(interfaceOriginCountMap.containsKey(originApplication));
}
}

sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DemoService.java → sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoService.java View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.dubbo;
package com.alibaba.csp.sentinel.adapter.dubbo.provider;

/**
* @author leyou

sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoServiceImpl.java → sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/impl/DemoServiceImpl.java View File

@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.dubbo.provider;
package com.alibaba.csp.sentinel.adapter.dubbo.provider.impl;

import com.alibaba.csp.sentinel.adapter.dubbo.DemoService;
import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService;

/**
* @author leyou

+ 3
- 3
sentinel-adapter/sentinel-dubbo-adapter/src/test/resources/spring-dubbo-consumer-filter.xml View File

@@ -10,9 +10,9 @@
<dubbo:application name="demo-consumer"/>
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<dubbo:protocol name="dubbo" port="20880"/>
<dubbo:service interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService" ref="demoServiceImp" />
<bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoServiceImpl"/>
<dubbo:service interface="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService" ref="demoServiceImp" />
<bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo.provider.impl.DemoServiceImpl"/>

<dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService"/>
<dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService"/>

</beans>

+ 3
- 3
sentinel-adapter/sentinel-dubbo-adapter/src/test/resources/spring-dubbo-provider-filter.xml View File

@@ -10,9 +10,9 @@
<dubbo:application name="demo-provider"/>
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<dubbo:protocol name="dubbo" port="20880"/>
<dubbo:service interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService" ref="demoServiceImp" />
<bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoServiceImpl"/>
<dubbo:service interface="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService" ref="demoServiceImp" />
<bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo.provider.impl.DemoServiceImpl"/>

<dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService"/>
<dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService"/>

</beans>

Loading…
Cancel
Save