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");
   
       }
   
  
  
  

Reply via email to