Add more test cases for Sentinel core internal (e.g. Entry, CtSph)
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
fe6b4f4865
commit
e50fc55d68
|
|
@ -1,9 +1,11 @@
|
|||
package com.alibaba.csp.sentinel;
|
||||
|
||||
import com.alibaba.csp.sentinel.context.Context;
|
||||
import com.alibaba.csp.sentinel.context.ContextTestUtil;
|
||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
|
@ -22,6 +24,8 @@ public class AsyncEntryTest {
|
|||
try {
|
||||
ContextUtil.enter(contextName);
|
||||
Context curContext = ContextUtil.getContext();
|
||||
Entry previousEntry = new CtEntry(new StringResourceWrapper("entry-sync", EntryType.IN),
|
||||
null, curContext);
|
||||
AsyncEntry entry = new AsyncEntry(new StringResourceWrapper("testCleanCurrentEntryInLocal", EntryType.OUT),
|
||||
null, curContext);
|
||||
|
||||
|
|
@ -29,9 +33,26 @@ public class AsyncEntryTest {
|
|||
|
||||
entry.cleanCurrentEntryInLocal();
|
||||
assertNotSame(entry, curContext.getCurEntry());
|
||||
assertSame(previousEntry, curContext.getCurEntry());
|
||||
} finally {
|
||||
ContextUtil.getContext().setCurEntry(null);
|
||||
ContextUtil.exit();
|
||||
ContextTestUtil.cleanUpContext();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testCleanCurrentEntryInLocalError() {
|
||||
final String contextName = "abc";
|
||||
try {
|
||||
ContextUtil.enter(contextName);
|
||||
Context curContext = ContextUtil.getContext();
|
||||
AsyncEntry entry = new AsyncEntry(new StringResourceWrapper("testCleanCurrentEntryInLocal", EntryType.OUT),
|
||||
null, curContext);
|
||||
|
||||
entry.cleanCurrentEntryInLocal();
|
||||
|
||||
entry.cleanCurrentEntryInLocal();
|
||||
} finally {
|
||||
ContextTestUtil.cleanUpContext();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,8 +68,6 @@ public class AsyncEntryTest {
|
|||
assertNull(entry.getAsyncContext());
|
||||
|
||||
entry.initAsyncContext();
|
||||
System.out.println(curContext.getName());
|
||||
System.out.println(curContext.getOrigin());
|
||||
|
||||
Context asyncContext = entry.getAsyncContext();
|
||||
assertNotNull(asyncContext);
|
||||
|
|
@ -58,19 +77,25 @@ public class AsyncEntryTest {
|
|||
assertSame(entry, asyncContext.getCurEntry());
|
||||
assertTrue(asyncContext.isAsync());
|
||||
} finally {
|
||||
ContextUtil.getContext().setCurEntry(null);
|
||||
ContextUtil.exit();
|
||||
ContextTestUtil.cleanUpContext();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@Test
|
||||
public void testDuplicateInitAsyncContext() {
|
||||
Context context = new Context(null, "abc");
|
||||
AsyncEntry entry = new AsyncEntry(new StringResourceWrapper("testDuplicateInitAsyncContext", EntryType.OUT),
|
||||
null, context);
|
||||
entry.initAsyncContext();
|
||||
Context asyncContext = entry.getAsyncContext();
|
||||
|
||||
// Duplicate init.
|
||||
entry.initAsyncContext();
|
||||
assertSame(asyncContext, entry.getAsyncContext());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ContextTestUtil.cleanUpContext();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
package com.alibaba.csp.sentinel;
|
||||
|
||||
import com.alibaba.csp.sentinel.context.Context;
|
||||
import com.alibaba.csp.sentinel.context.ContextTestUtil;
|
||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||
import com.alibaba.csp.sentinel.context.NullContext;
|
||||
import com.alibaba.csp.sentinel.node.Node;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class CtEntryTest {
|
||||
|
||||
@Test
|
||||
public void testExitNotMatchCurEntry() {
|
||||
String contextName = "context-rpc";
|
||||
ContextUtil.enter(contextName);
|
||||
Context context = ContextUtil.getContext();
|
||||
CtEntry entry1 = null;
|
||||
CtEntry entry2 = null;
|
||||
try {
|
||||
entry1 = new CtEntry(new StringResourceWrapper("res1", EntryType.IN),
|
||||
null, ContextUtil.getContext());
|
||||
assertSame(entry1, context.getCurEntry());
|
||||
entry2 = new CtEntry(new StringResourceWrapper("res2", EntryType.IN),
|
||||
null, ContextUtil.getContext());
|
||||
assertSame(entry2, context.getCurEntry());
|
||||
|
||||
// Forget to exit for entry 2...
|
||||
// Directly exit for entry 1, then boom...
|
||||
entry1.exit();
|
||||
} catch (ErrorEntryFreeException ex) {
|
||||
assertNotNull(entry1);
|
||||
assertNotNull(entry2);
|
||||
assertNull(entry1.context);
|
||||
assertNull(entry2.context);
|
||||
assertNull(context.getCurEntry());
|
||||
return;
|
||||
} finally {
|
||||
ContextUtil.exit();
|
||||
}
|
||||
fail("Mismatch entry-exit should throw an ErrorEntryFreeException");
|
||||
}
|
||||
|
||||
private Context getFakeDefaultContext() {
|
||||
return new Context(null, Constants.CONTEXT_DEFAULT_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExitLastEntryWithDefaultContext() {
|
||||
final Context defaultContext = getFakeDefaultContext();
|
||||
ContextUtil.runOnContext(defaultContext, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CtEntry entry = new CtEntry(new StringResourceWrapper("res", EntryType.IN),
|
||||
null, ContextUtil.getContext());
|
||||
assertSame(entry, defaultContext.getCurEntry());
|
||||
assertSame(defaultContext, ContextUtil.getContext());
|
||||
entry.exit();
|
||||
assertNull(defaultContext.getCurEntry());
|
||||
// Default context will be automatically exited.
|
||||
assertNull(ContextUtil.getContext());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExitTwoLastEntriesWithCustomContext() {
|
||||
String contextName = "context-rpc";
|
||||
ContextUtil.enter(contextName);
|
||||
Context context = ContextUtil.getContext();
|
||||
try {
|
||||
CtEntry entry1 = new CtEntry(new StringResourceWrapper("resA", EntryType.IN),
|
||||
null, context);
|
||||
entry1.exit();
|
||||
assertEquals(context, ContextUtil.getContext());
|
||||
CtEntry entry2 = new CtEntry(new StringResourceWrapper("resB", EntryType.IN),
|
||||
null, context);
|
||||
entry2.exit();
|
||||
assertEquals(context, ContextUtil.getContext());
|
||||
} finally {
|
||||
ContextUtil.exit();
|
||||
assertNull(ContextUtil.getContext());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryAndExitWithNullContext() {
|
||||
Context context = new NullContext();
|
||||
CtEntry entry = new CtEntry(new StringResourceWrapper("testEntryAndExitWithNullContext", EntryType.IN),
|
||||
null, context);
|
||||
assertNull(context.getCurEntry());
|
||||
entry.exit();
|
||||
assertNull(context.getCurEntry());
|
||||
// Won't true exit, so the context won't be cleared.
|
||||
assertEquals(context, entry.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastNode() {
|
||||
Context context = new NullContext();
|
||||
CtEntry entry = new CtEntry(new StringResourceWrapper("testGetLastNode", EntryType.IN),
|
||||
null, context);
|
||||
assertNull(entry.parent);
|
||||
assertNull(entry.getLastNode());
|
||||
Entry parentEntry = mock(Entry.class);
|
||||
Node node = mock(Node.class);
|
||||
when(parentEntry.getCurNode()).thenReturn(node);
|
||||
entry.parent = parentEntry;
|
||||
assertSame(node, entry.getLastNode());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ContextTestUtil.cleanUpContext();
|
||||
ContextTestUtil.resetContextMap();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ContextTestUtil.cleanUpContext();
|
||||
ContextTestUtil.resetContextMap();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,365 @@
|
|||
package com.alibaba.csp.sentinel;
|
||||
|
||||
import com.alibaba.csp.sentinel.context.Context;
|
||||
import com.alibaba.csp.sentinel.context.ContextTestUtil;
|
||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||
import com.alibaba.csp.sentinel.node.DefaultNode;
|
||||
import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
|
||||
import com.alibaba.csp.sentinel.slotchain.DefaultProcessorSlotChain;
|
||||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
|
||||
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slotchain.SlotChainProvider;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* Test cases for Sentinel internal {@link CtSph}.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class CtSphTest {
|
||||
|
||||
private final CtSph ctSph = new CtSph();
|
||||
|
||||
private void testCustomContextEntryWithFullContextSize(String resourceName, boolean async) {
|
||||
fillFullContext();
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
String contextName = "custom-context-" + System.currentTimeMillis();
|
||||
ContextUtil.enter(contextName, "9527");
|
||||
|
||||
// Prepare a slot that "should not pass". If entered the slot, exception will be thrown.
|
||||
addShouldNotPassSlotFor(resourceWrapper);
|
||||
|
||||
Entry entry = null;
|
||||
try {
|
||||
if (async) {
|
||||
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getType(), 1);
|
||||
} else {
|
||||
entry = ctSph.entry(resourceWrapper, 1);
|
||||
}
|
||||
} catch (BlockException ex) {
|
||||
fail("Unexpected blocked: " + ex.getClass().getCanonicalName());
|
||||
} finally {
|
||||
if (entry != null) {
|
||||
entry.exit();
|
||||
}
|
||||
ContextUtil.exit();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomContextSyncEntryWithFullContextSize() {
|
||||
String resourceName = "testCustomContextSyncEntryWithFullContextSize";
|
||||
testCustomContextEntryWithFullContextSize(resourceName, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomContextAsyncEntryWithFullContextSize() {
|
||||
String resourceName = "testCustomContextAsyncEntryWithFullContextSize";
|
||||
testCustomContextEntryWithFullContextSize(resourceName, true);
|
||||
}
|
||||
|
||||
private void testDefaultContextEntryWithFullContextSize(String resourceName, boolean async) {
|
||||
fillFullContext();
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
|
||||
// Prepare a slot that "should pass".
|
||||
ShouldPassSlot slot = addShouldPassSlotFor(resourceWrapper);
|
||||
assertFalse(slot.entered || slot.exited);
|
||||
|
||||
Entry entry = null;
|
||||
try {
|
||||
if (!async) {
|
||||
entry = ctSph.entry(resourceWrapper, 1);
|
||||
} else {
|
||||
entry = ctSph.asyncEntry(resourceName, resourceWrapper.getType(), 1);
|
||||
Context asyncContext = ((AsyncEntry)entry).getAsyncContext();
|
||||
assertTrue(ContextUtil.isDefaultContext(asyncContext));
|
||||
assertTrue(asyncContext.isAsync());
|
||||
}
|
||||
assertTrue(ContextUtil.isDefaultContext(ContextUtil.getContext()));
|
||||
assertTrue(slot.entered);
|
||||
} catch (BlockException ex) {
|
||||
fail("Unexpected blocked: " + ex.getClass().getCanonicalName());
|
||||
} finally {
|
||||
if (entry != null) {
|
||||
entry.exit();
|
||||
assertTrue(slot.exited);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultContextSyncEntryWithFullContextSize() {
|
||||
String resourceName = "testDefaultContextSyncEntryWithFullContextSize";
|
||||
testDefaultContextEntryWithFullContextSize(resourceName, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultContextAsyncEntryWithFullContextSize() {
|
||||
String resourceName = "testDefaultContextAsyncEntryWithFullContextSize";
|
||||
testDefaultContextEntryWithFullContextSize(resourceName, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryAndAsyncEntryWhenSwitchOff() {
|
||||
// Turn off the switch.
|
||||
Constants.ON = false;
|
||||
|
||||
String resourceNameA = "resSync";
|
||||
String resourceNameB = "resAsync";
|
||||
ResourceWrapper resourceWrapperA = new StringResourceWrapper(resourceNameA, EntryType.IN);
|
||||
ResourceWrapper resourceWrapperB = new StringResourceWrapper(resourceNameB, EntryType.IN);
|
||||
|
||||
// Prepare a slot that "should not pass". If entered the slot, exception will be thrown.
|
||||
addShouldNotPassSlotFor(resourceWrapperA);
|
||||
addShouldNotPassSlotFor(resourceWrapperB);
|
||||
|
||||
Entry entry = null;
|
||||
AsyncEntry asyncEntry = null;
|
||||
try {
|
||||
entry = ctSph.entry(resourceWrapperA, 1);
|
||||
asyncEntry = ctSph.asyncEntry(resourceNameB, resourceWrapperB.getType(), 1);
|
||||
} catch (BlockException ex) {
|
||||
fail("Unexpected blocked: " + ex.getClass().getCanonicalName());
|
||||
} finally {
|
||||
if (asyncEntry != null) {
|
||||
asyncEntry.exit();
|
||||
}
|
||||
if (entry != null) {
|
||||
entry.exit();
|
||||
}
|
||||
Constants.ON = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncEntryNormalPass() {
|
||||
String resourceName = "testAsyncEntryNormalPass";
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
AsyncEntry entry = null;
|
||||
|
||||
// Prepare a slot that "should pass".
|
||||
ShouldPassSlot slot = addShouldPassSlotFor(resourceWrapper);
|
||||
assertFalse(slot.entered || slot.exited);
|
||||
|
||||
ContextUtil.enter("abc");
|
||||
Entry previousEntry = ContextUtil.getContext().getCurEntry();
|
||||
try {
|
||||
entry = ctSph.asyncEntry(resourceName, EntryType.IN, 1);
|
||||
assertTrue(slot.entered);
|
||||
assertFalse(slot.exited);
|
||||
Context asyncContext = entry.getAsyncContext();
|
||||
assertNotNull(asyncContext);
|
||||
assertSame(entry, asyncContext.getCurEntry());
|
||||
assertNotSame("The async entry should not be added to current context",
|
||||
entry, ContextUtil.getContext().getCurEntry());
|
||||
assertSame(previousEntry, ContextUtil.getContext().getCurEntry());
|
||||
} catch (BlockException ex) {
|
||||
fail("Unexpected blocked: " + ex.getClass().getCanonicalName());
|
||||
} finally {
|
||||
if (entry != null) {
|
||||
Context asyncContext = entry.getAsyncContext();
|
||||
entry.exit();
|
||||
assertTrue(slot.exited);
|
||||
assertNull(entry.getAsyncContext());
|
||||
assertSame(previousEntry, asyncContext.getCurEntry());
|
||||
}
|
||||
ContextUtil.exit();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncEntryNestedInSyncEntryNormalBlocked() {
|
||||
String previousResourceName = "fff";
|
||||
String resourceName = "testAsyncEntryNestedInSyncEntryNormalBlocked";
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN);
|
||||
|
||||
// Prepare a slot that "must block".
|
||||
MustBlockSlot slot = addMustBlockSlot(resourceWrapper);
|
||||
assertFalse(slot.exited);
|
||||
// Previous entry should pass.
|
||||
addShouldPassSlotFor(new StringResourceWrapper(previousResourceName, EntryType.IN));
|
||||
ContextUtil.enter("bcd-" + System.currentTimeMillis());
|
||||
|
||||
AsyncEntry entry = null;
|
||||
Entry syncEntry = null;
|
||||
Entry previousEntry = null;
|
||||
try {
|
||||
// First enter a sync resource.
|
||||
syncEntry = ctSph.entry(previousResourceName, EntryType.IN, 1);
|
||||
// Record current entry (previous for next).
|
||||
previousEntry = ContextUtil.getContext().getCurEntry();
|
||||
// Then enter an async resource.
|
||||
entry = ctSph.asyncEntry(resourceName, EntryType.IN, 1);
|
||||
|
||||
// Should not pass here.
|
||||
} catch (BlockException ex) {
|
||||
assertNotNull(previousEntry);
|
||||
assertNull(entry);
|
||||
assertTrue(slot.exited);
|
||||
assertSame(previousEntry, ContextUtil.getContext().getCurEntry());
|
||||
return;
|
||||
} finally {
|
||||
assertNull(entry);
|
||||
assertNotNull(syncEntry);
|
||||
|
||||
syncEntry.exit();
|
||||
ContextUtil.exit();
|
||||
}
|
||||
fail("This async entry is expected to be blocked");
|
||||
}
|
||||
|
||||
private void testEntryAmountExceeded(boolean async) {
|
||||
fillFullResources();
|
||||
Entry entry = null;
|
||||
try {
|
||||
if (!async) {
|
||||
entry = ctSph.entry("testSync", EntryType.IN, 1);
|
||||
} else {
|
||||
entry = ctSph.asyncEntry("testSync", EntryType.IN, 1);
|
||||
}
|
||||
assertNull(((CtEntry)entry).chain);
|
||||
if (!async) {
|
||||
assertSame(entry, ContextUtil.getContext().getCurEntry());
|
||||
} else {
|
||||
Context asyncContext = ((AsyncEntry)entry).getAsyncContext();
|
||||
assertNotNull(asyncContext);
|
||||
assertSame(entry, asyncContext.getCurEntry());
|
||||
}
|
||||
} catch (BlockException ex) {
|
||||
fail("Unexpected blocked: " + ex.getClass().getCanonicalName());
|
||||
} finally {
|
||||
if (entry != null) {
|
||||
entry.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryAmountExceededForSyncEntry() {
|
||||
testEntryAmountExceeded(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryAmountExceededForAsyncEntry() {
|
||||
testEntryAmountExceeded(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLookUpSlotChain() {
|
||||
ResourceWrapper r1 = new StringResourceWrapper("firstRes", EntryType.IN);
|
||||
assertFalse(CtSph.getChainMap().containsKey(r1));
|
||||
ProcessorSlot<Object> chainR1 = ctSph.lookProcessChain(r1);
|
||||
assertNotNull("The slot chain for r1 should be created", chainR1);
|
||||
assertSame("Should return the cached slot chain once it has been created", chainR1, ctSph.lookProcessChain(r1));
|
||||
|
||||
fillFullResources();
|
||||
ResourceWrapper r2 = new StringResourceWrapper("secondRes", EntryType.IN);
|
||||
assertFalse(CtSph.getChainMap().containsKey(r2));
|
||||
assertNull("The slot chain for r2 should not be created because amount exceeded", ctSph.lookProcessChain(r2));
|
||||
assertNull(ctSph.lookProcessChain(r2));
|
||||
}
|
||||
|
||||
private void fillFullContext() {
|
||||
for (int i = 0; i < Constants.MAX_CONTEXT_NAME_SIZE; i++) {
|
||||
ContextUtil.enter("test-context-" + i);
|
||||
ContextUtil.exit();
|
||||
}
|
||||
}
|
||||
|
||||
private void fillFullResources() {
|
||||
for (int i = 0; i < Constants.MAX_SLOT_CHAIN_SIZE; i++) {
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper("test-resource-" + i, EntryType.IN);
|
||||
CtSph.getChainMap().put(resourceWrapper, SlotChainProvider.newSlotChain());
|
||||
}
|
||||
}
|
||||
|
||||
private void addShouldNotPassSlotFor(ResourceWrapper resourceWrapper) {
|
||||
ProcessorSlotChain slotChain = new DefaultProcessorSlotChain();
|
||||
slotChain.addLast(new ShouldNotPassSlot());
|
||||
CtSph.getChainMap().put(resourceWrapper, slotChain);
|
||||
}
|
||||
|
||||
private ShouldPassSlot addShouldPassSlotFor(ResourceWrapper resourceWrapper) {
|
||||
ProcessorSlotChain slotChain = new DefaultProcessorSlotChain();
|
||||
ShouldPassSlot shouldPassSlot = new ShouldPassSlot();
|
||||
slotChain.addLast(shouldPassSlot);
|
||||
CtSph.getChainMap().put(resourceWrapper, slotChain);
|
||||
return shouldPassSlot;
|
||||
}
|
||||
|
||||
private MustBlockSlot addMustBlockSlot(ResourceWrapper resourceWrapper) {
|
||||
ProcessorSlotChain slotChain = new DefaultProcessorSlotChain();
|
||||
MustBlockSlot mustBlockSlot = new MustBlockSlot();
|
||||
slotChain.addLast(mustBlockSlot);
|
||||
CtSph.getChainMap().put(resourceWrapper, slotChain);
|
||||
return mustBlockSlot;
|
||||
}
|
||||
|
||||
private class ShouldNotPassSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
@Override
|
||||
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode param, int count,
|
||||
Object... args) {
|
||||
throw new IllegalStateException("Should not enter this slot!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
|
||||
throw new IllegalStateException("Should not exit this slot!");
|
||||
}
|
||||
}
|
||||
|
||||
private class MustBlockSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
boolean exited = false;
|
||||
|
||||
@Override
|
||||
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode param, int count,
|
||||
Object... args) throws Throwable {
|
||||
throw new BlockException("custom") {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
|
||||
exited = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class ShouldPassSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
|
||||
boolean entered = false;
|
||||
boolean exited = false;
|
||||
|
||||
@Override
|
||||
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode param, int count,
|
||||
Object... args) {
|
||||
entered = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
|
||||
exited = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ContextTestUtil.cleanUpContext();
|
||||
ContextTestUtil.resetContextMap();
|
||||
CtSph.resetChainMap();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ContextTestUtil.cleanUpContext();
|
||||
ContextTestUtil.resetContextMap();
|
||||
CtSph.resetChainMap();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package com.alibaba.csp.sentinel;
|
||||
|
||||
import com.alibaba.csp.sentinel.node.Node;
|
||||
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
|
||||
import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* Test cases for {@link Entry}.
|
||||
*
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class EntryTest {
|
||||
|
||||
@Test
|
||||
public void testEntryExitCounts() {
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper("resA", EntryType.IN);
|
||||
TestEntry entry = new TestEntry(resourceWrapper);
|
||||
entry.exit();
|
||||
assertEquals(-1, entry.count);
|
||||
entry.exit(9);
|
||||
assertEquals(-10, entry.count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntryFieldsGetSet() {
|
||||
ResourceWrapper resourceWrapper = new StringResourceWrapper("resA", EntryType.IN);
|
||||
Entry entry = new TestEntry(resourceWrapper);
|
||||
assertSame(resourceWrapper, entry.getResourceWrapper());
|
||||
Throwable error = new IllegalStateException();
|
||||
entry.setError(error);
|
||||
assertSame(error, entry.getError());
|
||||
Node curNode = mock(Node.class);
|
||||
entry.setCurNode(curNode);
|
||||
assertSame(curNode, entry.getCurNode());
|
||||
Node originNode = mock(Node.class);
|
||||
entry.setOriginNode(originNode);
|
||||
assertSame(originNode, entry.getOriginNode());
|
||||
}
|
||||
|
||||
private class TestEntry extends Entry {
|
||||
|
||||
int count = 0;
|
||||
|
||||
TestEntry(ResourceWrapper resourceWrapper) {
|
||||
super(resourceWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit(int count, Object... args) throws ErrorEntryFreeException {
|
||||
this.count -= count;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry trueExit(int count, Object... args) throws ErrorEntryFreeException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getLastNode() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
package com.alibaba.csp.sentinel.context;
|
||||
|
||||
import com.alibaba.csp.sentinel.Constants;
|
||||
import com.alibaba.csp.sentinel.TestUtil;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
|
@ -39,7 +38,7 @@ public class ContextTest {
|
|||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
TestUtil.cleanUpContext();
|
||||
ContextTestUtil.cleanUpContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -80,8 +79,7 @@ public class ContextTest {
|
|||
}
|
||||
|
||||
private void resetContextMap() {
|
||||
ContextUtil.resetContextMap();
|
||||
Constants.ROOT.removeChildList();
|
||||
ContextTestUtil.resetContextMap();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue