1   package org.mod4j.runtime.aspects;
2   
3   import java.util.logging.Level;
4   import java.util.logging.LogRecord;
5   
6   import org.apache.commons.logging.Log;
7   import org.apache.commons.logging.LogFactory;
8   import org.aspectj.lang.ProceedingJoinPoint;
9   import org.aspectj.lang.Signature;
10  import org.easymock.Capture;
11  import org.easymock.classextension.EasyMock;
12  import org.junit.Test;
13  import org.junit.matchers.JUnitMatchers;
14  import org.mod4j.runtime.test.AbstractLoggingTest;
15  
16  import static org.junit.Assert.assertThat;
17  import static org.junit.Assert.fail;
18  
19  import static org.easymock.EasyMock.capture;
20  import static org.easymock.EasyMock.createMock;
21  import static org.easymock.EasyMock.expect;
22  import static org.easymock.EasyMock.replay;
23  import static org.easymock.EasyMock.verify;
24  
25  /**
26   * Test for {@link TimingAspect}.
27   */
28  public class TimingAspectTest extends AbstractLoggingTest {
29  
30      /** Used to return as method name */
31      private static final String DUMMY_METHOD_NAME = "dummy";
32  
33      /**
34       * Test the {@link TimingAspect#time(ProceedingJoinPoint)} method.
35       * 
36       * @throws Throwable Not expect.
37       */
38      @Test
39      public void testTiming() throws Throwable {
40          // Class under test.
41          final TimingAspect timingAspect = new TimingAspect();
42          /*
43           * Set up the mocks.
44           */
45          final ProceedingJoinPoint call = createMock(ProceedingJoinPoint.class);
46          // Return this class as target. That means this classname will be written to the log.
47          expect(call.getTarget()).andReturn(this);
48          final Signature signature = createMock(Signature.class);
49          expect(call.getSignature()).andReturn(signature);
50          expect(signature.getName()).andReturn(DUMMY_METHOD_NAME);
51          // Throw an exception so we can verify the logline is still written in the finally.
52          expect(call.proceed()).andThrow(new IllegalArgumentException());
53  
54          // This should be the log message
55          final Capture<LogRecord> capturedLogRecord = new Capture<LogRecord>();
56          mockHandler.publish(capture(capturedLogRecord));
57  
58          EasyMock.replay(mockHandler);
59          replay(call, signature);
60          try {
61              timingAspect.time(call);
62              fail("Should have thrown an exception here");
63          } catch (final IllegalArgumentException illegalArgumentException) {
64              // expected
65          }
66          EasyMock.verify(mockHandler);
67          verify(call, signature);
68  
69          // Validate the written logline
70          // Since we don't know the actual ms, we'll just check on the first part of the logline.
71          final String expectedMessagePrefix = "Execution of method [" + DUMMY_METHOD_NAME + "] in";
72          assertThat(capturedLogRecord.getValue().getMessage(), JUnitMatchers.containsString(expectedMessagePrefix));
73      }
74  
75      /**
76       * Test the {@link TimingAspect#time(ProceedingJoinPoint)} method with loglevel set to 'info', which should in
77       * nothing but a call to proceed().
78       * 
79       * @throws Throwable Not expected.
80       */
81      @Test
82      public void testNoLogging() throws Throwable {
83          // Class under test.
84          final TimingAspect timingAspect = new TimingAspect();
85  
86          // Override the loglevel: set it do info (not fine enough to log trace level).
87          logger.setLevel(Level.INFO);
88  
89          // Should only trigger the proceed and do nothing else.
90          final ProceedingJoinPoint call = createMock(ProceedingJoinPoint.class);
91          expect(call.getTarget()).andReturn(this);
92          expect(call.proceed()).andReturn(null);
93  
94          EasyMock.replay(mockHandler);
95          replay(call);
96          timingAspect.time(call);
97          EasyMock.verify(mockHandler);
98          verify(call);
99      }
100 
101     /**
102      * @return The {@link Log} for the target (which is this class).
103      */
104     @Override
105     protected Log getLog() {
106         return LogFactory.getLog(this.getClass());
107     }
108 
109 }