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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org