blob: ec27d989b06f27a5345156fde752a39488f936ff [file] [log] [blame]
/*
* 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.junit.impl.servlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.junit.Renderer;
import org.apache.sling.junit.RendererSelector;
import org.apache.sling.junit.RequestParser;
import org.apache.sling.junit.TestSelector;
import org.apache.sling.junit.TestsManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ServletProcessor {
private final Logger log = LoggerFactory.getLogger(getClass());
public static final String CSS = "junit.css";
public static final String FORCE_RELOAD_PARAM = "forceReload";
private final TestsManager testsManager;
private final RendererSelector rendererSelector;
public ServletProcessor(final TestsManager testsManager,
final RendererSelector rendererSelector) {
this.testsManager = testsManager;
this.rendererSelector = rendererSelector;
}
/** Return sorted list of available tests
* @param prefix optionally select only names that match this prefix
*/
private List<String> getTestNames(TestSelector selector, boolean forceReload) {
final List<String> result = new LinkedList<String>();
if(forceReload) {
log.debug("{} is true, clearing TestsManager caches", FORCE_RELOAD_PARAM);
}
result.addAll(testsManager.getTestNames(selector));
Collections.sort(result);
return result;
}
private void sendCss(HttpServletResponse response) throws IOException {
final InputStream str = getClass().getResourceAsStream("/" + CSS);
if(str == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, CSS);
} else {
response.setContentType("text/css");
final OutputStream out = response.getOutputStream();
final byte[] buffer = new byte[16384];
int count = 0;
while( (count = str.read(buffer)) > 0) {
out.write(buffer, 0, count);
}
out.flush();
}
}
private boolean getForceReloadOption(HttpServletRequest request) {
final boolean forceReload = "true".equalsIgnoreCase(request.getParameter(FORCE_RELOAD_PARAM));
log.debug("{} option is set to {}", FORCE_RELOAD_PARAM, forceReload);
return forceReload;
}
/** GET request lists available tests */
public void doGet(final HttpServletRequest request, final HttpServletResponse response, final String servletPath)
throws ServletException, IOException {
final boolean forceReload = getForceReloadOption(request);
// Redirect to / if called without it, and serve CSS if requested
{
final String pi = request.getPathInfo();
if(pi == null) {
response.sendRedirect(request.getContextPath() + servletPath + "/");
} else if(pi.endsWith(CSS)) {
sendCss(response);
return;
}
}
final TestSelector selector = getTestSelector(request);
final Renderer renderer = rendererSelector.getRenderer(selector);
if(renderer == null) {
throw new ServletException("No Renderer found for " + selector);
}
log.debug("GET request: {}", selector);
renderer.setup(response, getClass().getSimpleName());
renderer.info("info", "Test selector: " + selector);
// Any test classes?
final List<String> testNames = getTestNames(selector, forceReload);
if(testNames.isEmpty()) {
renderer.info(
"warning",
"No test classes found for selector " + selector
+ ", check the requirements of the active " +
"TestsProvider services for how to supply tests."
);
} else {
try {
testsManager.listTests(testNames, renderer);
final String postPath = getTestExecutionPath(request, selector, renderer.getExtension());
renderer.link("Execute these tests", postPath, "POST");
} catch(Exception e) {
throw new ServletException(e);
}
}
renderer.cleanup();
}
/** POST request executes tests */
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
final TestSelector selector = getTestSelector(request);
final boolean forceReload = getForceReloadOption(request);
log.info("POST request, executing tests: {}, {}={}",
new Object[] { selector, FORCE_RELOAD_PARAM, forceReload});
final Renderer renderer = rendererSelector.getRenderer(selector);
if(renderer == null) {
throw new ServletException("No Renderer found for " + selector);
}
renderer.setup(response, getClass().getSimpleName());
final List<String> testNames = getTestNames(selector, forceReload);
if(testNames.isEmpty()) {
response.sendError(
HttpServletResponse.SC_NOT_FOUND,
"No tests found for " + selector);
}
try {
testsManager.executeTests(testNames, renderer, selector);
} catch(Exception e) {
throw new ServletException(e);
}
renderer.cleanup();
}
/** Return a TestSelector for supplied request */
private TestSelector getTestSelector(HttpServletRequest request) {
return new RequestParser(getTestSelectionPath(request));
}
/** Return subpath to use for selecting tests */
protected String getTestSelectionPath(HttpServletRequest request) {
return request.getPathInfo();
}
/** Return path to which to POST to execute specified test */
protected String getTestExecutionPath(HttpServletRequest request, TestSelector selector, String extension) {
String selectedTestMethodName = selector.getSelectedTestMethodName();
String methodStr = "";
if (selectedTestMethodName != null && !"".equals(selectedTestMethodName)) {
methodStr = "/" + selectedTestMethodName;
}
return "./"
+ selector.getTestSelectorString()
+ methodStr
+ "."
+ extension;
}
}