Package org.stagemonitor.web.monitor

Source Code of org.stagemonitor.web.monitor.TestController

package org.stagemonitor.web.monitor;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;

import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.stagemonitor.core.CorePlugin;
import org.stagemonitor.core.configuration.Configuration;
import org.stagemonitor.requestmonitor.RequestMonitor;
import org.stagemonitor.requestmonitor.RequestMonitorPlugin;
import org.stagemonitor.springmvc.SpringMvcPlugin;
import org.stagemonitor.web.WebPlugin;
import org.stagemonitor.web.monitor.filter.StatusExposingByteCountingServletResponse;

import static com.codahale.metrics.MetricRegistry.name;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.runners.Parameterized.Parameters;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.stagemonitor.core.util.GraphiteSanitizer.sanitizeGraphiteMetricSegment;

@RunWith(value = Parameterized.class)
public class SpringRequestMonitorTest {

  private MockHttpServletRequest mvcRequest = new MockHttpServletRequest("GET", "/test/requestName");
  private MockHttpServletRequest nonMvcRequest = new MockHttpServletRequest("GET", "/META-INF/resources/stagemonitor/static/jquery.js");
  private Configuration configuration = mock(Configuration.class);
  private SpringMvcPlugin mvcPlugin = mock(SpringMvcPlugin.class);
  private RequestMonitorPlugin requestMonitorPlugin = mock(RequestMonitorPlugin.class);
  private WebPlugin webPlugin = mock(WebPlugin.class);
  private CorePlugin corePlugin = mock(CorePlugin.class);
  private RequestMonitor requestMonitor;
  private MetricRegistry registry = new MetricRegistry();
  private SpringMVCRequestNameDeterminerAspect springMVCRequestNameDeterminerAspect;
  private final boolean useNameDeterminerAspect;
  private HandlerMapping getRequestNameHandlerMapping;

  public SpringRequestMonitorTest(boolean useNameDeterminerAspect) {
    this.useNameDeterminerAspect = useNameDeterminerAspect;
  }

  @Parameters
  public static Collection<Object[]> data() {
    Object[][] data = new Object[][] { { true }, { false } };
    return Arrays.asList(data);
  }

  @Before
  public void before() throws Exception {
    // the purpose of this class is to obtain a instance to a Method, because Method objects can't be mocked as they are final
    class TestController { public void testGetRequestName() {} }
    getRequestNameHandlerMapping = createHandlerMapping(mvcRequest, TestController.class.getMethod("testGetRequestName"));
    List<HandlerMapping> handlerMappings = Arrays.asList(
        createExceptionThrowingHandlerMapping(),
        createHandlerMappingNotReturningHandlerMethod(),
        getRequestNameHandlerMapping
    );
    SpringMonitoredHttpRequest.HandlerMappingServletContextListener.setAllHandlerMappings(handlerMappings);
    registry.removeMatching(new MetricFilter() {
      @Override
      public boolean matches(String name, Metric metric) {
        return true;
      }
    });
    when(configuration.getConfig(SpringMvcPlugin.class)).thenReturn(mvcPlugin);
    when(configuration.getConfig(RequestMonitorPlugin.class)).thenReturn(requestMonitorPlugin);
    when(configuration.getConfig(WebPlugin.class)).thenReturn(webPlugin);
    when(configuration.getConfig(CorePlugin.class)).thenReturn(corePlugin);
    when(corePlugin.isStagemonitorActive()).thenReturn(true);
    when(requestMonitorPlugin.isCollectRequestStats()).thenReturn(true);
    when(webPlugin.getGroupUrls()).thenReturn(Collections.singletonMap(Pattern.compile("(.*).js$"), "*.js"));
    requestMonitor = new RequestMonitor(corePlugin, registry, requestMonitorPlugin);
    springMVCRequestNameDeterminerAspect = Mockito.spy(new SpringMVCRequestNameDeterminerAspect(mvcPlugin, webPlugin));
  }

  @After
  public void after() {
    verify(springMVCRequestNameDeterminerAspect, times(useNameDeterminerAspect ? 1 : 0))
        .aroundGetHandler(any(HttpServletRequest.class), any(HandlerExecutionChain.class));
  }

  private HandlerMapping createExceptionThrowingHandlerMapping() throws Exception {
    HandlerMapping requestMappingHandlerMapping = mock(HandlerMapping.class);
    when(requestMappingHandlerMapping.getHandler((HttpServletRequest) any())).thenThrow(new Exception("This is a test exeption"));
    return requestMappingHandlerMapping;
  }

  private HandlerMapping createHandlerMappingNotReturningHandlerMethod() throws Exception {
    HandlerMapping requestMappingHandlerMapping = mock(HandlerMapping.class);
    HandlerExecutionChain handlerExecutionChain = mock(HandlerExecutionChain.class);

    when(handlerExecutionChain.getHandler()).thenReturn(new Object());
    when(requestMappingHandlerMapping.getHandler((HttpServletRequest) any())).thenReturn(handlerExecutionChain);
    return requestMappingHandlerMapping;
  }

  private HandlerMapping createHandlerMapping(MockHttpServletRequest request, Method requestMappingMethod) throws Exception {
    System.out.println("createHandlerMapping"+request);
    HandlerMapping requestMappingHandlerMapping = mock(HandlerMapping.class);
    HandlerExecutionChain handlerExecutionChain = mock(HandlerExecutionChain.class);
    HandlerMethod handlerMethod = mock(HandlerMethod.class);

    when(handlerMethod.getMethod()).thenReturn(requestMappingMethod);
    when(handlerExecutionChain.getHandler()).thenReturn(handlerMethod);
    when(requestMappingHandlerMapping.getHandler(Matchers.argThat(new Matcher<HttpServletRequest>() {
      @Override
      public boolean matches(Object item) {
        return ((HttpServletRequest) item).getRequestURI().equals("/test/requestName");
      }

      public void describeMismatch(Object item, Description mismatchDescription) {
      }

      @Override
      public void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
      }

      @Override
      public void describeTo(Description description) {
      }
    }))).thenReturn(handlerExecutionChain);
    return requestMappingHandlerMapping;
  }

  @Test
  public void testRequestMonitorMvcRequest() throws Exception {
    System.out.println("useNameDeterminerAspect="+useNameDeterminerAspect);
    when(mvcPlugin.isMonitorOnlySpringMvcRequests()).thenReturn(false);

    SpringMonitoredHttpRequest monitoredRequest = createSpringMonitoredHttpRequest(mvcRequest);
    registerAspect(monitoredRequest, mvcRequest, getRequestNameHandlerMapping.getHandler(mvcRequest));
    final RequestMonitor.RequestInformation<HttpRequestTrace> requestInformation = requestMonitor.monitor(monitoredRequest);

    assertEquals(1, requestInformation.getRequestTimer().getCount());
    assertEquals("Test-Get-Request-Name", requestInformation.getTimerName());
    assertEquals("Test Get Request Name", requestInformation.getRequestTrace().getName());
    assertEquals("/test/requestName", requestInformation.getRequestTrace().getUrl());
    assertEquals(Integer.valueOf(200), requestInformation.getRequestTrace().getStatusCode());
    assertEquals("GET", requestInformation.getRequestTrace().getMethod());
    Assert.assertNull(requestInformation.getExecutionResult());
    assertNotNull(registry.getTimers().get(name("request", "Test-Get-Request-Name", "server", "time", "total")));
    verify(monitoredRequest, times(1)).onPostExecute(anyRequestInformation());
    verify(monitoredRequest, times(useNameDeterminerAspect ? 0 : 1)).getRequestName();
  }

  @Test
  public void testRequestMonitorNonMvcRequestDoMonitor() throws Exception {
    when(mvcPlugin.isMonitorOnlySpringMvcRequests()).thenReturn(false);

    final SpringMonitoredHttpRequest monitoredRequest = createSpringMonitoredHttpRequest(nonMvcRequest);
    registerAspect(monitoredRequest, nonMvcRequest, null);
    RequestMonitor.RequestInformation<HttpRequestTrace> requestInformation = requestMonitor.monitor(monitoredRequest);

    assertEquals(1, requestInformation.getRequestTimer().getCount());
    assertEquals("GET-*:js", requestInformation.getTimerName());
    assertEquals("GET *.js", requestInformation.getRequestTrace().getName());
    assertNotNull(registry.getTimers().get(name("request", "GET-*:js", "server", "time", "total")));
    verify(monitoredRequest, times(1)).onPostExecute(anyRequestInformation());
    verify(monitoredRequest, times(useNameDeterminerAspect ? 0 : 1)).getRequestName();
  }

  @Test
  public void testRequestMonitorNonMvcRequestDontMonitor() throws Exception {
    when(mvcPlugin.isMonitorOnlySpringMvcRequests()).thenReturn(true);

    final SpringMonitoredHttpRequest monitoredRequest = createSpringMonitoredHttpRequest(nonMvcRequest);
    registerAspect(monitoredRequest, nonMvcRequest, null);
    RequestMonitor.RequestInformation<HttpRequestTrace> requestInformation = requestMonitor.monitor(monitoredRequest);

    Assert.assertEquals("", requestInformation.getRequestTrace().getName());
    assertNull(registry.getTimers().get(name("request", sanitizeGraphiteMetricSegment("GET *.js"), "server", "time", "total")));
    verify(monitoredRequest, never()).onPostExecute(anyRequestInformation());
    verify(monitoredRequest, times(useNameDeterminerAspect ? 0 : 1)).getRequestName();
  }

  private void registerAspect(SpringMonitoredHttpRequest monitoredRequest, final HttpServletRequest request, final HandlerExecutionChain mapping) throws Exception {
    if (useNameDeterminerAspect) {
      when(monitoredRequest.execute()).thenAnswer(new Answer<Object>() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
          springMVCRequestNameDeterminerAspect.aroundGetHandler(request, mapping);
          return null;
        }
      });
    }
  }

  private RequestMonitor.RequestInformation<HttpRequestTrace> anyRequestInformation() {
    return any();
  }

  private SpringMonitoredHttpRequest createSpringMonitoredHttpRequest(HttpServletRequest request) throws IOException {
    final StatusExposingByteCountingServletResponse response = new StatusExposingByteCountingServletResponse(new MockHttpServletResponse());
    return Mockito.spy(new SpringMonitoredHttpRequest(request, response, new MockFilterChain(), configuration));
  }
}
TOP

Related Classes of org.stagemonitor.web.monitor.TestController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.