content: package com.alibaba.csp.sentinel;
  
  import com.alibaba.csp.sentinel.context.ContextTestUtil;
  import com.alibaba.csp.sentinel.context.ContextUtil;
  import com.alibaba.csp.sentinel.util.function.Predicate;
  import org.junit.After;
  import org.junit.Assert;
  import org.junit.Before;
  import org.junit.Test;
  
  /**
   * @author Carpenter Lee
   */
  public class TracerTest extends Tracer {
  
      @Before
      public void setUp() {
          ContextTestUtil.cleanUpContext();
          ContextTestUtil.resetContextMap();
          Tracer.exceptionPredicate = null;
      }
  
      @After
      public void tearDown() {
          ContextTestUtil.cleanUpContext();
          ContextTestUtil.resetContextMap();
          Tracer.exceptionPredicate = null;
      }
  
      @Test
      public void testTraceWhenContextSizeExceedsThreshold() {
          int i = 0;
          for (; i < Constants.MAX_CONTEXT_NAME_SIZE; i++) {
              ContextUtil.enter("test-context-" + i);
              ContextUtil.exit();
          }
  
          try {
              ContextUtil.enter("test-context-" + i);
              throw new RuntimeException("test");
          } catch (Exception e) {
              Tracer.trace(e);
          } finally {
              ContextUtil.exit();
          }
      }
  
      @Test
      public void setExceptionsToTrace() {
          Tracer.ignoreClasses = null;
          Tracer.traceClasses = null;
          Tracer.setExceptionsToTrace(TraceException.class, TraceException2.class);
          Assert.assertTrue(Tracer.shouldTrace(new TraceException2()));
          Assert.assertTrue(Tracer.shouldTrace(new TraceExceptionSub()));
          Assert.assertFalse(Tracer.shouldTrace(new Exception()));
      }
  
      @Test
      public void setExceptionPredicate() {
  
          Predicate<Throwable> throwablePredicate = new Predicate<Throwable>() {
              @Override
              public boolean test(Throwable throwable) {
                  if (throwable instanceof TraceException) {
                      return true;
                  } else if (throwable instanceof IgnoreException) {
                      return false;
                  }
                  return false;
              }
          };
          Tracer.setExceptionPredicate(throwablePredicate);
          Assert.assertTrue(Tracer.shouldTrace(new TraceException()));
          Assert.assertFalse(Tracer.shouldTrace(new IgnoreException()));
      }
  
      @Test
      public void setExceptionsToIgnore() {
          Tracer.ignoreClasses = null;
          Tracer.traceClasses = null;
          Tracer.setExceptionsToIgnore(IgnoreException.class, IgnoreException2.class);
          Assert.assertFalse(Tracer.shouldTrace(new IgnoreException()));
          Assert.assertFalse(Tracer.shouldTrace(new IgnoreExceptionSub()));
          Assert.assertTrue(Tracer.shouldTrace(new Exception()));
      }
  
      @Test
      public void testBoth() {
          Tracer.ignoreClasses = null;
          Tracer.traceClasses = null;
          Tracer.setExceptionsToTrace(TraceException.class, TraceException2.class, BothException.class);
          Tracer.setExceptionsToIgnore(IgnoreException.class, IgnoreException2.class, BothException.class);
          Assert.assertFalse(Tracer.shouldTrace(new IgnoreException()));
          Assert.assertFalse(Tracer.shouldTrace(new BothException()));
          Assert.assertTrue(Tracer.shouldTrace(new TraceException()));
      }
  
      @Test(expected = IllegalArgumentException.class)
      public void testNull() {
          Tracer.setExceptionsToTrace(null);
      }
  
      @Test(expected = IllegalArgumentException.class)
      public void testNull1() {
          Tracer.setExceptionsToTrace(TraceException.class, null);
      }
  
      @Test(expected = IllegalArgumentException.class)
      public void testNull2() {
          Tracer.setExceptionsToIgnore(IgnoreException.class, null);
      }
  
      @Test(expected = IllegalArgumentException.class)
      public void testNull3() {
          Tracer.setExceptionPredicate(null);
      }
  
      private class TraceException extends Exception {}
  
      private class TraceException2 extends Exception {}
  
      private class TraceExceptionSub extends TraceException {}
  
      private class IgnoreException extends Exception {}
  
      private class IgnoreException2 extends Exception {}
  
      private class IgnoreExceptionSub extends IgnoreException {}
  
      private class BothException extends Exception {}
  }