You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2009/12/14 08:36:02 UTC

svn commit: r890206 [2/2] - in /tomcat/trunk/modules/tomcat-lite: ./ java/org/apache/coyote/lite/ java/org/apache/tomcat/lite/http/ java/org/apache/tomcat/lite/io/ java/org/apache/tomcat/lite/service/ test/org/apache/coyote/lite/ test/org/apache/tomcat...

Modified: tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/LiveHttpThreadedTest.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/LiveHttpThreadedTest.java?rev=890206&r1=890205&r2=890206&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/LiveHttpThreadedTest.java (original)
+++ tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/LiveHttpThreadedTest.java Mon Dec 14 07:35:57 2009
@@ -17,101 +17,201 @@
 package org.apache.tomcat.lite.load;
 
 
+import java.io.File;
 import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
 
 import junit.framework.TestCase;
 
 import org.apache.tomcat.lite.TestMain;
-import org.apache.tomcat.lite.http.DefaultHttpConnector;
 import org.apache.tomcat.lite.http.HttpChannel;
 import org.apache.tomcat.lite.http.HttpConnector;
 import org.apache.tomcat.lite.http.HttpRequest;
-import org.apache.tomcat.lite.http.HttpChannel.HttpService;
 import org.apache.tomcat.lite.http.HttpChannel.RequestCompleted;
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.io.IOBuffer;
 
+/*
+  Notes on memory use ( from heap dumps ): 
+    - buffers are not yet recycled ( the BBuffers used in channels )
+  
+    - each active connection consumes at least 26k - 2 buffers + head buffer
+     ( 8k each )
+     TODO: could 'peak' in the In buffer and move headRecv to HttpChannel
+     
+     
+    - HttpChannel keeps about 64K ( for the hello world ).
+    -- res is 25k
+    -- req is 32k, BufferedIOReader 16k,
+    
+   TODO:
+    - leak in NioThread.active - closed sockets not removed
+    - need to rate-limit and queue requests - OOM
+    - timeouts
+    - seems few responses missing on large async requests (URL works)     
+ */
+
+/**
+ * Long running test - async tests are failing since rate control
+ * is not implemented ( too many outstanding requests - OOM ), 
+ * it seems there is a bug as well.
+ */
 public class LiveHttpThreadedTest extends TestCase {
-  HttpConnector staticMain = TestMain.initTestEnv();
+  HttpConnector clientCon = TestMain.getClientAndInit();
+  ThreadRunner tr;
+  static MBeanServer server;
   
+  AtomicInteger ok = new AtomicInteger();
+  Object lock = new Object();
+  int reqCnt;
+
+  Map<HttpRequest, HttpRequest> active = new HashMap();
   
-  int tCount = 1;
-  Thread[] threads = new Thread[tCount];
-  int[] ok = new int[tCount];
-  private int rCount = 100;
-  
-  public void xtestSimpleRequest() throws Exception {
-    long t0 = System.currentTimeMillis();
-    for (int i = 0; i < tCount; i++) {
-      final int j = i;
-      threads[i] = new Thread(new Runnable() {
-        public void run() {
-          makeRequests(j, true);
-        }
-      });
-      threads[i].start();
-    }
-    
-    int res = 0;
-    for (int i = 0; i < tCount; i++) {
-      threads[i].join();
-      res += ok[i];
-    }
-    long t1 = System.currentTimeMillis();
-    System.err.println("Time: " + (t1 - t0) + " " + res);
+  public void xtest1000Async() throws Exception {
+      try {
+          asyncRequest(10, 100);
+      } finally {
+          dumpHeap("heapAsync.bin");
+      }
+      
   }
 
-  public void testSimpleRequestNB() throws Exception {
-    long t0 = System.currentTimeMillis();
-    for (int i = 0; i < tCount; i++) {
-      final int j = i;
-      threads[i] = new Thread(new Runnable() {
-        public void run() {
-          makeRequests(j, false);
-        }
-      });
-      threads[i].start();
-    }
-    
-    int res = 0;
-    for (int i = 0; i < tCount; i++) {
-      threads[i].join();
-      res += ok[i];
-    }
-    long t1 = System.currentTimeMillis();
-    System.err.println("TimeNB: " + (t1 - t0) + " " + res);
+  public void xtest10000Async() throws Exception {
+      try {
+          asyncRequest(20, 500);
+      } finally {
+          dumpHeap("heapAsync.bin");
+      }
   }
   
-  void makeRequests(int t, boolean b) {
-    for (int i = 0; i < rCount ; i++) {
+  public void asyncRequest(int thr, int perthr) throws Exception {
+      reqCnt = thr * perthr;
+      long t0 = System.currentTimeMillis();
+      tr = new ThreadRunner(thr, perthr) {
+          public void makeRequest(int i) throws Exception {
+              HttpRequest cstate = clientCon.request("localhost", 8802);
+              synchronized (active) {
+                  active.put(cstate, cstate);
+              }
+              
+              cstate.requestURI().set("/hello");
+              cstate.setCompletedCallback(reqCallback);
+              
+              // Send the request, wait response
+              Thread.currentThread().sleep(20);
+              cstate.send();
+            }
+      };
+      tr.run();
+      assertEquals(0, tr.errors.get());
+      synchronized (lock) {
+          lock.wait(reqCnt * 100);
+      }
+      assertEquals(reqCnt, ok.get());
+      System.err.println(reqCnt + " Async requests: " + (System.currentTimeMillis() - t0));
+  }
+  
+  public void xtestURLRequest() throws Exception {
+      urlRequest(10, 200);
+  }
+
+  public void testURLRequest2() throws Exception {
+      urlRequest(40, 500);
+  }
+  
+  public void urlRequest(int thr, int cnt) throws Exception {
+          
+      
       try {
-        //System.err.println("MakeReq " + t + " " + i);
-        makeRequest(t, b);
-      } catch (Exception e) {
-        e.printStackTrace();
+          HttpConnector testServer = TestMain.testServer;
+          
+          tr = new ThreadRunner(thr, cnt) {
+
+              public void makeRequest(int i) throws Exception {
+                  try {
+                      URL url = new URL("http://localhost:8802/hello");
+                      HttpURLConnection con = (HttpURLConnection) url.openConnection();
+                      con.setReadTimeout(4000000);
+                      con.connect();
+                      if (con.getResponseCode() != 200) {
+                          errors.incrementAndGet();
+                      }
+                      BBuffer out = new IOBuffer().append(con.getInputStream()).copyAll(null);
+                      if (!"Hello world".equals(out.toString())) {
+                          errors.incrementAndGet();
+                          System.err.println("bad result " + out);
+                      }
+                  } catch(Throwable t) {
+                      t.printStackTrace();
+                      errors.incrementAndGet();
+                  }
+              }
+          };
+          tr.run();
+          assertEquals(0, tr.errors.get());
+          
+          //assertEquals(testServer., actual)
+      } finally {
+          dumpHeap("heapURLReq.bin");
       }
-    }
+  }
+  
+  // TODO: move to a servlet
+  private void dumpHeap(String file) throws InstanceNotFoundException,
+      MBeanException, ReflectionException, MalformedObjectNameException {
+
+      if (server == null) {
+          server = ManagementFactory.getPlatformMBeanServer();
+          
+      }
+      File f1 = new java.io.File(file);
+      if (f1.exists()) {
+          f1.delete();
+      }
+      server.invoke(new ObjectName("com.sun.management:type=HotSpotDiagnostic"),
+              "dumpHeap",
+              new Object[] {file, Boolean.FALSE /* live */}, 
+              new String[] {String.class.getName(), "boolean"});
   }
 
-  static RequestCompleted reqCallback = new RequestCompleted() {
+
+  RequestCompleted reqCallback = new RequestCompleted() {
     @Override
     public void handle(HttpChannel data, Object extraData) 
         throws IOException {
-        //dumpHead(cstate);  
-        //System.err.println("DATA\n" + cstate.output.toString() + "\n----");
-        //assertTrue(cstate.bodyRecvBuffer.toString().indexOf("AAA") >= 0);
-    
+        String out = data.getIn().copyAll(null).toString();
+        if (200 != data.getResponse().getStatus()) {
+            System.err.println("Wrong status");
+            tr.errors.incrementAndGet();            
+        }
+        if (!"Hello world".equals(out)) {
+            tr.errors.incrementAndGet();
+            System.err.println("bad result " + out);
+        }        
+        synchronized (active) {
+            active.remove(data.getRequest());
+        }
         data.release();
+        int okres = ok.incrementAndGet();
+        if (okres >= reqCnt) {
+            synchronized (lock) {
+                lock.notify();
+            }
+        }
     }
-      
   };
   
-  void makeRequest(int i, boolean block) throws Exception {
-    HttpRequest cstate = DefaultHttpConnector.get().request("localhost", 8802);
-    
-    cstate.requestURI().set("/hello");
-    cstate.setCompletedCallback(reqCallback);
-    
-    // Send the request, wait response
-    cstate.send();
-  }
   
 }

Added: tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/ThreadRunner.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/ThreadRunner.java?rev=890206&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/ThreadRunner.java (added)
+++ tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/ThreadRunner.java Mon Dec 14 07:35:57 2009
@@ -0,0 +1,65 @@
+/*
+ */
+package org.apache.tomcat.lite.load;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ThreadRunner {
+    int tCount = 10;
+    int rCount = 100;
+    Thread[] threads;
+    int[] ok;
+    
+    int sleepTime = 0;
+    
+    long time;
+    protected AtomicInteger errors = new AtomicInteger();
+    
+    public ThreadRunner(int threads, int count) {
+        tCount = threads;
+        rCount = count;
+        this.threads = new Thread[tCount];
+        ok = new int[tCount];
+    }
+
+    public void run() {
+        long t0 = System.currentTimeMillis();
+        for (int i = 0; i < tCount; i++) {
+          final int j = i;
+          threads[i] = new Thread(new Runnable() {
+            public void run() {
+              makeRequests(j);
+            }
+          });
+          threads[i].start();
+        }
+        
+        int res = 0;
+        for (int i = 0; i < tCount; i++) {
+          try {
+            threads[i].join();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+          res += ok[i];
+        }
+        long t1 = System.currentTimeMillis();
+        time = t1 - t0;
+        System.err.println("TimeNB: " + (t1 - t0) + " " + res);
+    }
+    
+    public void makeRequests(int cnt) {
+        for (int i = 0; i < rCount ; i++) {
+            try {
+              //System.err.println("MakeReq " + t + " " + i);
+              makeRequest(cnt);
+            } catch (Exception e) {
+              e.printStackTrace();
+            }
+          }
+    }
+    
+    public void makeRequest(int i) throws Exception {
+        
+    }
+}
\ No newline at end of file

Propchange: tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/ThreadRunner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteWatchdog.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteWatchdog.java?rev=890206&r1=890205&r2=890206&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteWatchdog.java (original)
+++ tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteWatchdog.java Mon Dec 14 07:35:57 2009
@@ -30,6 +30,7 @@
 public abstract class TomcatLiteWatchdog extends WatchdogClient {
   
   public TomcatLiteWatchdog() {
+      super();
       goldenDir = getWatchdogdir() + "/src/clients/org/apache/jcheck/servlet/client/";
       testMatch = 
           //"HttpServletResponseWrapperSetStatusMsgTest";
@@ -40,6 +41,11 @@
       targetMatch = "gtestservlet-test";
   }
   
+  public TomcatLiteWatchdog(String s) {
+      this();
+      super.single = s;
+  }
+  
   protected void beforeSuite() {
       // required for the tests
       System.setProperty("org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER",
@@ -58,10 +64,10 @@
   
   protected abstract void addConnector(TomcatLite liteServer);
   
-  TomcatLite tomcatForWatchdog;
-  
   public void initServerWithWatchdog(String wdDir) throws ServletException, 
           IOException {
+      TomcatLite tomcatForWatchdog;
+      
       File f = new File(wdDir + "/build/webapps");
       
       tomcatForWatchdog = new TomcatLite();

Modified: tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogClient.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogClient.java?rev=890206&r1=890205&r2=890206&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogClient.java (original)
+++ tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogClient.java Mon Dec 14 07:35:57 2009
@@ -33,7 +33,7 @@
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
-public class WatchdogClient {
+public class WatchdogClient implements Test {
         
   protected String goldenDir; 
   protected String testMatch;
@@ -45,8 +45,9 @@
   };  
 
   protected String targetMatch;
-    
-
+  
+  protected int port;
+  
   Properties props = new Properties();
   
   protected void beforeSuite() {
@@ -56,7 +57,7 @@
   }
   
   public Test getSuite() {
-      return getSuite(8080);
+      return getSuite(port);
   }
   
   /** 
@@ -95,6 +96,9 @@
         for (int j = 0; j < watchDogL.getLength(); j++) {
           Element watchE = (Element) watchDogL.item(j);
           String testName = watchE.getAttribute("testName");
+          if (single != null && !testName.equals(single)) {
+              continue;
+          }
           if (testMatch != null) {
               if (!testName.startsWith(testMatch)) {
                   continue;
@@ -112,9 +116,13 @@
                   continue;
               }
           }
-          testName = testName + ";" + this.getClass().getName();
+          testName = testName + "(" + this.getClass().getName() + ")";
           WatchdogTestCase test = new WatchdogTestCase(watchE, props, testName);
           tests.addTest(test);
+          if (single != null) {
+              singleTest = test;
+              break;
+          }
         }
       }
       
@@ -154,4 +162,24 @@
       }
   }
 
+  // Support for running a single test in the suite
+  
+  protected String single;
+  WatchdogTestCase singleTest;
+  
+  @Override
+  public int countTestCases() {
+      return 1;
+  }
+
+  @Override
+  public void run(TestResult result) {
+      getSuite();
+      if (singleTest != null) {
+          beforeSuite();
+          singleTest.run(result);
+          afterSuite(result);
+      }
+  }
+
 }

Modified: tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogHttpClient.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogHttpClient.java?rev=890206&r1=890205&r2=890206&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogHttpClient.java (original)
+++ tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogHttpClient.java Mon Dec 14 07:35:57 2009
@@ -52,7 +52,7 @@
             System.out.println( " Socket Exception: " + ex );
             return;
         }
-        //socket.setSoTimeout(2000);
+        socket.setSoTimeout(10000);
         
         //socket obtained, rebuild the request.
         rebuildRequest(client, client.request, socket);

Modified: tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogTestCase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogTestCase.java?rev=890206&r1=890205&r2=890206&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogTestCase.java (original)
+++ tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/test/watchdog/WatchdogTestCase.java Mon Dec 14 07:35:57 2009
@@ -7,7 +7,6 @@
 import junit.framework.AssertionFailedError;
 import junit.framework.Test;
 import junit.framework.TestResult;
-import junit.framework.TestSuite;
 
 import org.apache.tomcat.integration.DynamicObject;
 import org.apache.tomcat.integration.simple.AntProperties;
@@ -22,30 +21,12 @@
 
     private Properties props;
 
-    private WatchdogTestCase delegate;
     private WatchdogClient wc;
     
-    public WatchdogTestCase(String s) throws Throwable {
-        String[] comp = s.split(";");
-        if (comp.length < 2) {
-            return;
-        }
-        Class c = Class.forName(comp[1]);
-        wc = (WatchdogClient) c.newInstance();
-        TestSuite suite = (TestSuite) wc.getSuite();
-        // need to encode the base, file, etc in the test name
-
-        System.err.println(s);
-
-        for (int i = 0; i < suite.testCount(); i++) {
-            WatchdogTestCase t = (WatchdogTestCase) suite.testAt(i);
-            if (s.equals(t.getName())) {
-                delegate = t;
-                return;
-            }
-        }
+    public WatchdogTestCase() {
+        
     }
-
+    
     public WatchdogTestCase(Element watchE, Properties props, String testName) {
         this.testName = testName;
         this.watchE = watchE;
@@ -57,20 +38,17 @@
     }
 
     public String getName() {
-        return testName;
+        return testName == null ? "WatchdogTest" : testName;
     }
 
+    public String toString() {
+        return getName();
+    }
+    
     public void testDummy() {
     }
     
     public void run(TestResult res) {
-        if (delegate != null) {
-            // Single method run
-            wc.beforeSuite();
-            delegate.run(res);
-            wc.afterSuite(res);
-            return;
-        }
         if (watchE == null) {
             res.endTest(this);
             return;



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org