You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2013/04/05 16:48:35 UTC
svn commit: r1464994 -
/sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/impl/servlet/JacocoServlet.java
Author: bdelacretaz
Date: Fri Apr 5 14:48:35 2013
New Revision: 1464994
URL: http://svn.apache.org/r1464994
Log:
SLING-2810 - include usage info in JacocoServlet, and a few other tweaks
Modified:
sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/impl/servlet/JacocoServlet.java
Modified: sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/impl/servlet/JacocoServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/impl/servlet/JacocoServlet.java?rev=1464994&r1=1464993&r2=1464994&view=diff
==============================================================================
--- sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/impl/servlet/JacocoServlet.java (original)
+++ sling/trunk/testing/junit/core/src/main/java/org/apache/sling/junit/impl/servlet/JacocoServlet.java Fri Apr 5 14:48:35 2013
@@ -39,40 +39,44 @@ import java.lang.management.ManagementFa
import java.util.Dictionary;
/**
- * SUMMARY:
- * A JaCoCo agent REST Servlet, which exposes code coverage data to HTTP clients by calling
- * {@link IAgent#getExecutionData(boolean)}. A POST method will reset the agent after returning the execution data.
- * A GET method calls the operation without resetting the agent.
- *
- * Requests to this servlet will return 404 if the JaCoCo JVM agent is not attached and registered as an {@link IAgent}
- * MBean.
- *
- * IMPORTANT SECURITY CONSIDERATION:
- * "The ports and connections opened in tcpserver and tcpclient mode and the JMX interface do not provide any
- * authentication mechanism. If you run JaCoCo on production systems make sure that no untrusted sources have access to
- * the TCP server port, or JaCoCo TCP clients only connect to trusted targets. Otherwise internal information of the
- * application might be revealed or DOS attacks are possible." - eclemma.org
- *
- * INSTRUCTIONS:
- * To configure jacoco on a standalone integration test server:
- * 1. extract jacocoagent.jar from org.jacoco:org.jacoco.agent:jar:$VERSION to /path/to/jacocoagent.jar
- * e.g.
- * {@code jar -xf ~/.m2/repository/org/jacoco/org.jacoco.agent/$VERSION/org.jacoco.agent-$VERSION.jar -C /path/to jacocoagent.jar}
- * 2. add the following option to server's java args:
- * {@code -javaagent:/path/to/jacocoagent.jar=dumponexit=false,jmx=true}
- * 3. add additional jacoco option args as necessary (see: http://www.eclemma.org/jacoco/trunk/doc/agent.html)
+ * This servlet exposes JaCoCo code coverage data over HTTP. See {@link #EXPLAIN} for usage information,
+ * which is also available at /system/sling/jacoco after installing this servlet with the default settings.
*/
@SuppressWarnings("serial")
@Component(immediate = true, metatype = true)
public class JacocoServlet extends HttpServlet {
- private static final String JMX_NAME = "org.jacoco:type=Runtime";
private static final String PARAM_SESSION_ID = ":sessionId";
-
+ private static final String JMX_NAME = "org.jacoco:type=Runtime";
+
+ public static final String EXPLAIN =
+ "This servlet exposes JaCoCo (http://www.eclemma.org/jacoco) code coverage data to HTTP clients by calling "
+ + "JaCoCo's IAgent.getExecutionData(...).\n\n"
+ + "POST requests reset the agent after returning the execution data, whereas GET "
+ + "requests just return the data.\n"
+ + "JaCoCo's session ID can be set via a " + PARAM_SESSION_ID + " request parameter.\n"
+ + "The servlet returns 404 if the IAgent MBean is not available.\n\n"
+ + "Please keep the JaCoCo security considerations in mind before enabling its agent: "
+ + "JaCoCo's tcpserver and tcpclient modes and its JMX interface open ports that do "
+ + "not require any authentication. See the JaCoCo documentation for details.\n\n"
+ + "To activate JaCoCo on a Sling instance, start its JVM with the following option:\n\n"
+ + "-javaagent:/path/to/jacoco-agent.jar,dumponexit=false,jmx=true\n\n"
+ + "The JaCoCo jar is a Maven dependency of this module, so you can get it using "
+ + "mvn dependency:copy-dependencies if you have this module's source code.\n\n"
+ + "With this servlet installed, you can generate a JaCoCo coverage report "
+ + "as follows (for example), from a folder that contains a pom.xml:\n\n"
+ + " curl http://localhost:8080/system/sling/jacoco/exec > target/jacoco.exec\n"
+ + " mvn org.jacoco:jacoco-maven-plugin:report\n"
+ + " open target/site/jacoco/index.html\n\n"
+ ;
+
private final Logger log = LoggerFactory.getLogger(getClass());
- @Property(value="/system/sling/jacoco.exec")
+ @Property(value="/system/sling/jacoco")
static final String SERVLET_PATH_NAME = "servlet.path";
+ /** Requests ending with this subpath send the jacoco data */
+ public static final String EXEC_PATH = "/exec";
+
/** Non-null if we are registered with HttpService */
private String servletPath;
@@ -118,13 +122,20 @@ public class JacocoServlet extends HttpS
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- IAgent agent = getAgent();
- if (agent == null) {
- resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ if(EXEC_PATH.equals(req.getPathInfo())) {
+ final IAgent agent = getAgent();
+ if (agent == null) {
+ final String msg = "The Jacoco agent MBean is not available\n\n";
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, msg + getUsageInfo());
+ } else {
+ sendJacocoData(req, resp, false);
+ resp.setContentType("application/octet-stream");
+ }
} else {
- resp.setContentType("application/octet-stream");
- byte[] data = agent.getExecutionData(false);
- resp.getOutputStream().write(data);
+ resp.setContentType("text/plain");
+ resp.setCharacterEncoding("UTF-8");
+ resp.getWriter().write(getUsageInfo());
+ resp.getWriter().flush();
}
}
@@ -137,19 +148,38 @@ public class JacocoServlet extends HttpS
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- IAgent agent = getAgent();
+ sendJacocoData(req, resp, true);
+ }
+
+ private void sendJacocoData(HttpServletRequest req, HttpServletResponse resp, boolean resetAgent) throws IOException {
+ final IAgent agent = getAgent();
if (agent == null) {
- resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ final String msg = "The Jacoco agent MBean is not available\n\n";
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, msg + getUsageInfo());
} else {
resp.setContentType("application/octet-stream");
- String sessionId = req.getParameter(PARAM_SESSION_ID);
- byte[] data = agent.getExecutionData(true);
- if (sessionId != null) {
+ final String sessionId = req.getParameter(PARAM_SESSION_ID);
+ log.info("Getting JaCoCo execution data, resetAgent={}", resetAgent);
+ byte[] data = agent.getExecutionData(resetAgent);
+ if(sessionId != null) {
+ log.info("Setting JaCoCo sessionId={}", sessionId);
agent.setSessionId(sessionId);
}
resp.getOutputStream().write(data);
+ resp.getOutputStream().flush();
}
}
+
+ private String getUsageInfo() {
+ return new StringBuilder()
+ .append("This is ")
+ .append(getClass().getName())
+ .append("\n\n")
+ .append("To get the jacoco data, use " + servletPath + EXEC_PATH)
+ .append("\n\n")
+ .append(EXPLAIN)
+ .toString();
+ }
/**
* Lookup the jacoco agent mbean and return it if it exists. Return null otherwise.