/* * Copyright 2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.glowroot.ui; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.regex.Pattern; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Charsets; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.http.HttpResponseStatus; import org.junit.Test; import org.glowroot.common.util.Clock; import org.glowroot.ui.CommonHandler.CommonRequest; import org.glowroot.ui.CommonHandler.CommonResponse; import org.glowroot.ui.HttpSessionManager.Authentication; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; public class CommonHandlerTest { // this constant is from org.h2.api.ErrorCode.STATEMENT_WAS_CANCELED // (but h2 jar is not a dependency of glowroot-ui) private static final int H2_STATEMENT_WAS_CANCELED = 57014; private static final CommonHandler HTTP_SERVER_HANDLER = new CommonHandler(mock(LayoutService.class), new HashMap<Pattern, HttpService>(), mock(HttpSessionManager.class), new ArrayList<Object>(), mock(Clock.class)); @Test public void shouldCreateJsonServiceExceptionResponse() throws Exception { // given Exception e = new JsonServiceException(HttpResponseStatus.PRECONDITION_FAILED, new IllegalStateException("An ignored message")); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); assertThat(content).isEqualTo("{\"message\":\"\"}"); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.PRECONDITION_FAILED); } @Test public void shouldCreateJsonServiceExceptionResponseWithMessage() throws Exception { // given Exception e = new JsonServiceException(HttpResponseStatus.PRECONDITION_FAILED, "A message"); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); assertThat(content).isEqualTo("{\"message\":\"A message\"}"); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.PRECONDITION_FAILED); } @Test public void shouldCreateJsonServiceExceptionResponseFromInvocationTargetException() throws Exception { // given Exception e = new InvocationTargetException( new JsonServiceException(HttpResponseStatus.PRECONDITION_FAILED, new IllegalStateException("An ignored message"))); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); assertThat(content).isEqualTo("{\"message\":\"\"}"); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.PRECONDITION_FAILED); } @Test public void shouldCreateJsonServiceExceptionResponseWithMessageFromInvocationTargetException() throws Exception { // given Exception e = new InvocationTargetException( new JsonServiceException(HttpResponseStatus.PRECONDITION_FAILED, "A message")); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); assertThat(content).isEqualTo("{\"message\":\"A message\"}"); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.PRECONDITION_FAILED); } @Test public void shouldCreateSqlTimeoutResponse() throws Exception { // given Exception e = new SQLException("", "", H2_STATEMENT_WAS_CANCELED); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); assertThat(content).isEqualTo("{\"message\":" + "\"Query timed out (timeout is configurable under Configuration > Advanced)\"}"); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.REQUEST_TIMEOUT); } @Test public void shouldCreateNonTimeoutSqlExceptionResponse() throws Exception { // given Exception e = new SQLException("Another message", "", H2_STATEMENT_WAS_CANCELED + 1); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); ObjectNode node = (ObjectNode) new ObjectMapper().readTree(content); assertThat(node.get("message").asText()).isEqualTo("Another message"); assertThat(node.get("stackTrace")).isNotNull(); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.INTERNAL_SERVER_ERROR); } @Test public void shouldCreateExceptionResponse() throws Exception { // given Exception e = new Exception("Banother message"); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); ObjectNode node = (ObjectNode) new ObjectMapper().readTree(content); assertThat(node.get("message").asText()).isEqualTo("Banother message"); assertThat(node.get("stackTrace")).isNotNull(); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.INTERNAL_SERVER_ERROR); } @Test public void shouldCreateWrappedExceptionResponse() throws Exception { // given Exception e = new Exception(new Exception(new Exception("Wrapped message"))); // when CommonResponse httpResponse = HTTP_SERVER_HANDLER.newHttpResponseFromException( mock(CommonRequest.class), mock(Authentication.class), e); // then String content = ((ByteBuf) httpResponse.getContent()).toString(Charsets.ISO_8859_1); ObjectNode node = (ObjectNode) new ObjectMapper().readTree(content); assertThat(node.get("message").asText()).isEqualTo("Wrapped message"); assertThat(node.get("stackTrace")).isNotNull(); assertThat(httpResponse.getStatus()).isEqualTo(HttpResponseStatus.INTERNAL_SERVER_ERROR); } @Test public void shouldStripContextPath() { assertThat(HttpServerHandler.stripContextPath("/one", "/")).isEqualTo("/one"); assertThat(HttpServerHandler.stripContextPath("/", "/")).isEqualTo("/"); assertThat(HttpServerHandler.stripContextPath("/one", "/one")).isEqualTo("/"); assertThat(HttpServerHandler.stripContextPath("/one/", "/one")).isEqualTo("/"); assertThat(HttpServerHandler.stripContextPath("/one/two", "/one")).isEqualTo("/two"); assertThat(HttpServerHandler.stripContextPath("/one/two/", "/one")).isEqualTo("/two/"); } }