| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.sling.tracer.internal; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.util.zip.GZIPInputStream; |
| |
| import javax.json.Json; |
| import javax.json.JsonObject; |
| import javax.servlet.ServletOutputStream; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import org.apache.commons.io.IOUtils; |
| import org.apache.sling.testing.mock.osgi.junit.OsgiContext; |
| import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; |
| import org.jetbrains.annotations.NotNull; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.mockito.ArgumentCaptor; |
| import org.mockito.Mock; |
| import org.mockito.junit.MockitoJUnit; |
| import org.mockito.junit.MockitoRule; |
| |
| import static org.apache.sling.tracer.internal.TestUtil.createTracker; |
| import static org.hamcrest.CoreMatchers.containsString; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertThat; |
| import static org.mockito.Matchers.eq; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| public class TracerLogServletTest { |
| |
| @Rule |
| public final OsgiContext context = new OsgiContext(); |
| @Rule |
| public final MockitoRule mockito = MockitoJUnit.rule(); |
| |
| @Mock |
| private HttpServletRequest request; |
| @Mock |
| private HttpServletResponse response; |
| |
| @Test |
| public void noRecordingByDefault() throws Exception{ |
| TracerLogServlet logServlet = newLogServlet(); |
| assertSame(Recording.NOOP, logServlet.startRecording(request, response)); |
| assertSame(Recording.NOOP, logServlet.getRecordingForRequest(request)); |
| } |
| |
| @Test |
| public void recordingWhenRequested() throws Exception{ |
| TracerLogServlet logServlet = newLogServlet(); |
| request = new MockSlingHttpServletRequest(context.bundleContext()); |
| |
| Recording recording = logServlet.startRecording(request, response); |
| assertNotNull(recording); |
| |
| //Once recording is created then it should be returned |
| Recording recording2 = logServlet.getRecordingForRequest(request); |
| assertSame(recording, recording2); |
| |
| //Repeated call should return same recording instance |
| Recording recording3 = logServlet.startRecording(request, response); |
| assertSame(recording, recording3); |
| |
| logServlet.resetCache(); |
| |
| //If recording gets lost then NOOP must be returned |
| Recording recording4 = logServlet.getRecordingForRequest(request); |
| assertSame(Recording.NOOP, recording4); |
| } |
| |
| @Test |
| public void jsonRendering() throws Exception{ |
| TracerLogServlet logServlet = newLogServlet(); |
| when(request.getMethod()).thenReturn("GET"); |
| when(request.getHeader(TracerLogServlet.HEADER_TRACER_RECORDING)).thenReturn("true"); |
| |
| Recording recording = logServlet.startRecording(request, response); |
| recording.registerTracker(createTracker("x" ,"y")); |
| logServlet.endRecording(request, recording); |
| |
| ArgumentCaptor<String> requestIdCaptor = ArgumentCaptor.forClass(String.class); |
| verify(response).setHeader(eq(TracerLogServlet.HEADER_TRACER_REQUEST_ID), requestIdCaptor.capture()); |
| verify(response).setHeader(TracerLogServlet.HEADER_TRACER_PROTOCOL_VERSION, |
| String.valueOf(TracerLogServlet.TRACER_PROTOCOL_VERSION)); |
| |
| ByteArrayServletOutputStream sos = new ByteArrayServletOutputStream(); |
| when(response.getOutputStream()).thenReturn(sos); |
| when(request.getRequestURI()).thenReturn("/system/console/" + requestIdCaptor.getValue() + ".json" ); |
| |
| logServlet.renderContent(request, response); |
| JsonObject json = Json.createReader(new StringReader(sos.baos.toString("UTF-8"))).readObject(); |
| assertEquals("GET", json.getString("method")); |
| assertEquals(2, json.getJsonArray("requestProgressLogs").size()); |
| } |
| |
| @Test |
| public void gzipResponse() throws Exception{ |
| TracerLogServlet logServlet = newLogServlet(); |
| when(request.getMethod()).thenReturn("GET"); |
| when(request.getHeader(TracerLogServlet.HEADER_TRACER_RECORDING)).thenReturn("true"); |
| when(request.getHeader("Accept-Encoding")).thenReturn("gzip, deflate"); |
| |
| Recording recording = logServlet.startRecording(request, response); |
| recording.registerTracker(createTracker("x" ,"y")); |
| logServlet.endRecording(request, recording); |
| |
| ArgumentCaptor<String> requestIdCaptor = ArgumentCaptor.forClass(String.class); |
| verify(response).setHeader(eq(TracerLogServlet.HEADER_TRACER_REQUEST_ID), requestIdCaptor.capture()); |
| verify(response).setHeader(TracerLogServlet.HEADER_TRACER_PROTOCOL_VERSION, |
| String.valueOf(TracerLogServlet.TRACER_PROTOCOL_VERSION)); |
| |
| ByteArrayServletOutputStream sos = new ByteArrayServletOutputStream(); |
| when(response.getOutputStream()).thenReturn(sos); |
| when(request.getRequestURI()).thenReturn("/system/console/" + requestIdCaptor.getValue() + ".json" ); |
| |
| logServlet.renderContent(request, response); |
| byte[] data = IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(sos.baos.toByteArray()))); |
| JsonObject json = Json.createReader(new StringReader(new String(data, "UTF-8"))).readObject(); |
| assertEquals("GET", json.getString("method")); |
| assertEquals(2, json.getJsonArray("requestProgressLogs").size()); |
| |
| verify(response).setHeader("Content-Encoding" , "gzip"); |
| } |
| |
| private TracerLogServlet newLogServlet() { |
| return new TracerLogServlet(context.bundleContext(), 50, 60*15, true, true); |
| } |
| |
| @Test |
| public void pluginRendering() throws Exception{ |
| TracerLogServlet logServlet = newLogServlet(); |
| when(request.getRequestURI()).thenReturn("/system/console/tracer" ); |
| |
| StringWriter sw = new StringWriter(); |
| when(response.getWriter()).thenReturn(new PrintWriter(sw)); |
| logServlet.renderContent(request, response); |
| |
| assertThat(sw.toString(), containsString("Log Tracer")); |
| } |
| |
| private static class ByteArrayServletOutputStream extends ServletOutputStream { |
| final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| @Override |
| public void write(int b) throws IOException { |
| baos.write(b); |
| } |
| |
| @Override |
| public void write(@NotNull byte[] b, int off, int len) throws IOException { |
| baos.write(b, off, len); |
| } |
| } |
| } |