vmassol 01/06/17 06:39:46
Modified: cactus/src/framework/share/org/apache/commons/cactus/server
ServletTestCaller.java ServletTestRedirector.java
Log:
correction of bug #1612 + added some logs
Revision Changes Path
1.4 +43 -9
jakarta-commons/cactus/src/framework/share/org/apache/commons/cactus/server/ServletTestCaller.java
Index: ServletTestCaller.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/cactus/src/framework/share/org/apache/commons/cactus/server/ServletTestCaller.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ServletTestCaller.java 2001/05/05 14:38:44 1.3
+++ ServletTestCaller.java 2001/06/17 13:39:45 1.4
@@ -62,6 +62,7 @@
import javax.servlet.http.*;
import org.apache.commons.cactus.*;
+import org.apache.commons.cactus.util.log.*;
/**
* Call the test method on the server side after assigning the servlet implicit
@@ -78,6 +79,11 @@
private final static String TEST_RESULTS = "ServletTestRedirector_TestResults";
/**
+ * The logger
+ */
+ private static Log logger =
LogService.getInstance().getLog(ServletTestRedirector.class.getName());
+
+ /**
* Call the method to test.
*
* @param theClassName the name of the test class to call
@@ -87,6 +93,8 @@
*/
private void callTestMethod(String theClassName, String theMethod,
ServletImplicitObjects theObjects) throws Throwable
{
+ logger.entry("callTestMethod(...)");
+
// Get the class to call and build an instance of it.
Class testClass = null;
ServletTestCase testInstance = null;
@@ -139,6 +147,7 @@
// Call the test method
testInstance.runBareServerTest();
+ logger.exit("callTestMethod");
}
/**
@@ -152,10 +161,23 @@
*/
public void doTest(ServletImplicitObjects theObjects) throws ServletException
{
- ServletTestResult result = null;
+ logger.entry("doTest(...)");
+ ServletTestResult result = null;
+
+ // Reset TEST_RESULTS to a new results holder to prevent premature
+ // requests for results from seeing either no results or old results
+ ResultHolder holder = new ResultHolder();
+ theObjects.m_Config.getServletContext().setAttribute(TEST_RESULTS, holder);
+
+ logger.debug("Result holder semaphore is in place");
+
+ // From this point forward, any thread trying to access the result
+ // stored in the holder, itself stored in the application scope, will
+ // block and wait until a result is set.
+
try {
-
+
// Extract from the HTTP request the test class name and method to call.
String testClassName =
theObjects.m_Request.getParameter(ServiceDefinition.CLASS_NAME_PARAM);
@@ -164,12 +186,16 @@
ServiceDefinition.CLASS_NAME_PARAM + "] in HTTP request.");
}
+ logger.debug("Class to call = " + testClassName);
+
String methodName =
theObjects.m_Request.getParameter(ServiceDefinition.METHOD_NAME_PARAM);
if (methodName == null) {
throw new ServletException("Missing parameter [" +
ServiceDefinition.METHOD_NAME_PARAM + "] in HTTP request.");
}
+ logger.debug("Method to call = " + methodName);
+
// Call the method to test
callTestMethod(testClassName, methodName, theObjects);
@@ -184,10 +210,13 @@
result = new ServletTestResult(e);
}
+
+ // Set the test result.
+ holder.setResult(result);
- // Save the test result.
- theObjects.m_Config.getServletContext().setAttribute(TEST_RESULTS, result);
+ logger.debug("Result holder semaphore inactive (result set in holder)");
+ logger.exit("doTest");
}
/**
@@ -199,11 +228,15 @@
*/
public void doGetResults(ServletImplicitObjects theObjects) throws
ServletException
{
- ServletTestResult result =
(ServletTestResult)theObjects.m_Config.getServletContext().getAttribute(TEST_RESULTS);
- if (result == null) {
- throw new ServletException("No test results found in the application
scope");
- }
+ logger.entry("doGetResults(...)");
+
+ logger.debug("Try to read results from Holder ...");
+ ResultHolder holder =
(ResultHolder)(theObjects.m_Config.getServletContext().getAttribute(TEST_RESULTS));
+ ServletTestResult result = holder.getResult();
+
+ logger.debug("... results read");
+
// Write back the results as a serialized object to the outgoing stream.
try {
@@ -218,6 +251,7 @@
} catch (IOException e) {
throw new ServletException("Error writing ServletTestResult instance to
output stream", e);
}
- }
+ logger.exit("doGetResults");
+ }
}
1.2 +74 -2
jakarta-commons/cactus/src/framework/share/org/apache/commons/cactus/server/ServletTestRedirector.java
Index: ServletTestRedirector.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/cactus/src/framework/share/org/apache/commons/cactus/server/ServletTestRedirector.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ServletTestRedirector.java 2001/04/09 11:52:37 1.1
+++ ServletTestRedirector.java 2001/06/17 13:39:45 1.2
@@ -62,6 +62,7 @@
import javax.servlet.http.*;
import org.apache.commons.cactus.*;
+import org.apache.commons.cactus.util.log.*;
/**
* Generic Servlet redirector that calls a test method on the server side.
@@ -72,6 +73,28 @@
public class ServletTestRedirector extends HttpServlet
{
/**
+ * Initialize the logging subsystem so that it can get it's configuration
+ * details from the correct properties file. Initialization is done here
+ * as this servlet is the first point of entry to the server code.
+ */
+ static {
+ LogService.getInstance().init("/log_server.properties");
+ }
+
+ /**
+ * The logger
+ */
+ private static Log logger =
LogService.getInstance().getLog(ServletTestRedirector.class.getName());
+
+ /**
+ * Some magic keyword that is prepended to the servlet output stream in
+ * order to never have an empty stream returned to the client side. This is
+ * needed because the client side will try to read all the returned data and
+ * if there is none will block ...
+ */
+ static final String MAGIC_KEYWORD = "C*&()C$$";
+
+ /**
* Handle GET requests.
*
* @param theRequest the incoming HTTP client request
@@ -80,10 +103,14 @@
* @exception ServletException if an error occurred when sending back
* the response to the client.
*/
- public void doGet(HttpServletRequest theRequest, HttpServletResponse
theResponse) throws ServletException
+ public void doGet(HttpServletRequest theRequest, HttpServletResponse
theResponse) throws ServletException, IOException
{
+ logger.entry("doGet(...)");
+
// Same handling than for a POST
doPost(theRequest, theResponse);
+
+ logger.exit("doGet");
}
/**
@@ -95,8 +122,12 @@
*
* @exception ServletException if an unexpected error occurred
*/
- public void doPost(HttpServletRequest theRequest, HttpServletResponse
theResponse) throws ServletException
+ public void doPost(HttpServletRequest theRequest, HttpServletResponse
theResponse) throws ServletException, IOException
{
+ logger.entry("doPost(...)");
+
+ logger.debug("Default buffer size = " + theResponse.getBufferSize());
+
// Call the correct Service method
String serviceName =
theRequest.getParameter(ServiceDefinition.SERVICE_NAME_PARAM);
if (serviceName == null) {
@@ -104,6 +135,8 @@
ServiceDefinition.SERVICE_NAME_PARAM + "] in HTTP request.");
}
+ logger.debug("Service called = " + serviceName);
+
ServletTestCaller caller = new ServletTestCaller();
ServletImplicitObjects objects = new ServletImplicitObjects();
objects.m_Config = getServletConfig();
@@ -115,6 +148,43 @@
caller.doTest(objects);
+ // Ugly hack here : The client side need to read all the data
+ // returned on the servlet output stream. Otherwise the servlet
+ // engine might do an io block, waiting for the client to read
+ // more data. Is this happens, then we are stuck because the client
+ // side is waiting for the test result to be committed but the
+ // latter will only be committed when all the data has been sent
+ // on the servlet output stream. So we need to read the data from
+ // the client side. However, some tests do not return any data and
+ // thus the read would block ... So we always send at the end of
+ // the stream a magic keyword so that the returned stream is never
+ // empty. This magic keyword will be ignored by the client side
+ // ... ugly, no ?
+
+ // This can easily be corrected with the Servlet API 2.3 (by
+ // doing all the read on the server side instead of the client side
+ // ). However it does not work on some 2.2 API servlet engines
+ // (like Tomcat 3.2 ...).
+
+ // Send magic keyword ... well at least try ... Yes, you read it
+ // correctly ! I said 'try' because if the test has done a forward
+ // for example, then the Writer or OutputStream will have already
+ // been used and thus it would lead to an error to try to write to
+ // them ... In that case, we won't write anything back but that
+ // should be fine as a forward is supposed to return something ...
+
+ // Note: There might still be the case where I get a Writer in my
+ // test case but don't use it ... hum ... To verify ... later ...
+
+ // Try sending the magic keyword ...
+ logger.debug("Sending magic keyword ...");
+ try {
+ theResponse.getOutputStream().print(MAGIC_KEYWORD);
+ } catch (Exception e) {
+ logger.debug("Failed to to send magic keyword (this is normal)", e);
+ // It failed ... Do nothing
+ }
+
// Is it the get test results service ?
} else if (ServiceEnumeration.GET_RESULTS_SERVICE.equals(serviceName)) {
@@ -124,6 +194,8 @@
throw new ServletException("Unknown service [" + serviceName +
"] in HTTP request.");
}
+
+ logger.exit("doPost");
}