| /* |
| * 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; |
| } |
| } |