blob: 5a0a71fc09c0178e8c79768bbd7ea366ab7ce7c9 [file] [log] [blame]
/*
* 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.tomcat.jdbc.test;
import java.sql.Connection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Test;
import org.apache.tomcat.jdbc.pool.DataSourceProxy;
import org.apache.tomcat.jdbc.test.driver.Driver;
public class ConnectCountTest extends DefaultTestCase {
protected boolean run = true;
protected long sleep = Long.getLong("sleep", 10).longValue();
protected long complete = Long.getLong("complete",20000).longValue();
protected boolean printthread = Boolean.getBoolean("printthread");
CountDownLatch latch = null;
@Override
public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
// TODO Auto-generated method stub
org.apache.tomcat.jdbc.pool.DataSource ds = super.createDefaultDataSource();
ds.getPoolProperties().setDriverClassName(Driver.class.getName());
ds.getPoolProperties().setUrl(Driver.url);
ds.getPoolProperties().setInitialSize(0);
ds.getPoolProperties().setMaxIdle(10);
ds.getPoolProperties().setMinIdle(10);
ds.getPoolProperties().setMaxActive(10);
return ds;
}
@Override
@After
public void tearDown() throws Exception {
Driver.reset();
super.tearDown();
}
protected void printThreadResults(TestThread[] threads, String name, int active, int expected) {
long minfetch = Long.MAX_VALUE, maxfetch = Long.MIN_VALUE, totalfetch = 0;
long maxwait = 0, minwait = Long.MAX_VALUE, totalwait = 0;
for (int i=0; i<threads.length; i++) {
TestThread t = threads[i];
totalfetch += t.nroffetch;
totalwait += t.totalwait;
maxwait = Math.max(maxwait,t.maxwait);
minwait = Math.min(minwait, t.minwait);
minfetch = Math.min(minfetch, t.nroffetch);
maxfetch = Math.max(maxfetch, t.nroffetch);
if (ConnectCountTest.this.printthread)
System.out.println(t.getName()+" : Nr-of-fetch:"+t.nroffetch+ " Max fetch Time:"+t.maxwait/1000000f+"ms. :Max close time:"+t.cmax/1000000f+"ms.");
}
System.out.println("["+name+"] Max fetch:"+(maxfetch)+" Min fetch:"+(minfetch)+" Average fetch:"+
(((float)totalfetch))/(float)threads.length);
System.out.println("["+name+"] Max wait:"+maxwait/1000000f+"ms. Min wait:"+minwait/1000000f+"ms. Average wait:"+(((((float)totalwait))/(float)totalfetch)/1000000f)+" ms.");
System.out.println("["+name+"] Max active:"+active+" Expected Active:"+expected);
}
@Test
public void testDBCPThreads20Connections10() throws Exception {
System.out.println("[testDBCPThreads20Connections10] Starting fairness - DBCP");
this.threadcount = 20;
this.transferProperties();
this.tDatasource.getConnection().close();
latch = new CountDownLatch(threadcount);
long start = System.currentTimeMillis();
TestThread[] threads = new TestThread[threadcount];
for (int i=0; i<threadcount; i++) {
threads[i] = new TestThread();
threads[i].setName("tomcat-dbcp-"+i);
threads[i].d = this.tDatasource;
}
for (int i=0; i<threadcount; i++) {
threads[i].start();
}
if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
System.out.println("Latch timed out.");
}
this.run = false;
long delta = System.currentTimeMillis() - start;
printThreadResults(threads,"testDBCPThreads20Connections10",Driver.connectCount.get(),10);
System.out.println("Test completed in: " + delta + "ms.");
}
@Test
public void testPoolThreads20Connections10() throws Exception {
System.out.println("[testPoolThreads20Connections10] Starting fairness - Tomcat JDBC - Non Fair");
this.threadcount = 20;
this.transferProperties();
this.datasource.getConnection().close();
latch = new CountDownLatch(threadcount);
long start = System.currentTimeMillis();
TestThread[] threads = new TestThread[threadcount];
for (int i=0; i<threadcount; i++) {
threads[i] = new TestThread();
threads[i].setName("tomcat-pool-"+i);
threads[i].d = this.datasource;
}
for (int i=0; i<threadcount; i++) {
threads[i].start();
}
if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
System.out.println("Latch timed out.");
}
this.run = false;
long delta = System.currentTimeMillis() - start;
printThreadResults(threads,"testPoolThreads20Connections10",Driver.connectCount.get(),10);
System.out.println("Test completed in: " + delta + "ms.");
}
@Test
public void testPoolThreads20Connections10Fair() throws Exception {
System.out.println("[testPoolThreads20Connections10Fair] Starting fairness - Tomcat JDBC - Fair");
this.threadcount = 20;
this.datasource.getPoolProperties().setFairQueue(true);
this.transferProperties();
this.datasource.getConnection().close();
latch = new CountDownLatch(threadcount);
long start = System.currentTimeMillis();
TestThread[] threads = new TestThread[threadcount];
for (int i=0; i<threadcount; i++) {
threads[i] = new TestThread();
threads[i].setName("tomcat-pool-"+i);
threads[i].d = this.datasource;
}
for (int i=0; i<threadcount; i++) {
threads[i].start();
}
if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
System.out.println("Latch timed out.");
}
this.run = false;
long delta = System.currentTimeMillis() - start;
printThreadResults(threads,"testPoolThreads20Connections10Fair",Driver.connectCount.get(),10);
System.out.println("Test completed in: " + delta + "ms.");
}
@Test
public void testPoolThreads20Connections10FairAsync() throws Exception {
System.out.println("[testPoolThreads20Connections10FairAsync] Starting fairness - Tomcat JDBC - Fair - Async");
this.threadcount = 20;
this.datasource.getPoolProperties().setFairQueue(true);
this.datasource.getPoolProperties().setInitialSize(this.datasource.getPoolProperties().getMaxActive());
this.transferProperties();
this.datasource.getConnection().close();
latch = new CountDownLatch(threadcount);
long start = System.currentTimeMillis();
TestThread[] threads = new TestThread[threadcount];
for (int i=0; i<threadcount; i++) {
threads[i] = new TestThread();
threads[i].setName("tomcat-pool-"+i);
threads[i].async = true;
threads[i].d = this.datasource;
}
for (int i=0; i<threadcount; i++) {
threads[i].start();
}
if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
System.out.println("Latch timed out.");
}
this.run = false;
long delta = System.currentTimeMillis() - start;
printThreadResults(threads,"testPoolThreads20Connections10FairAsync",Driver.connectCount.get(),10);
System.out.println("Test completed in: " + delta + "ms.");
}
// @Test
// public void testC3P0Threads20Connections10() throws Exception {
// System.out.println("[testC3P0Threads20Connections10] Starting fairness - C3P0");
// this.threadcount = 20;
// this.transferPropertiesToC3P0();
// this.datasource.getConnection().close();
// latch = new CountDownLatch(threadcount);
// long start = System.currentTimeMillis();
// TestThread[] threads = new TestThread[threadcount];
// for (int i=0; i<threadcount; i++) {
// threads[i] = new TestThread();
// threads[i].setName("tomcat-pool-"+i);
// threads[i].d = this.c3p0Datasource;
//
// }
// for (int i=0; i<threadcount; i++) {
// threads[i].start();
// }
// if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
// System.out.println("Latch timed out.");
// }
// this.run = false;
// long delta = System.currentTimeMillis() - start;
// printThreadResults(threads,"testC3P0Threads20Connections10",Driver.connectCount.get(),10);
// }
public class TestThread extends Thread {
protected DataSource d;
protected long sleep = 10;
protected boolean async = false;
long minwait = Long.MAX_VALUE, maxwait = -1, totalwait=0, totalcmax=0, cmax = -1, nroffetch = 0, totalruntime = 0;
@Override
public void run() {
try {
long now = System.currentTimeMillis();
while (ConnectCountTest.this.run) {
if ((System.currentTimeMillis()-now)>=ConnectCountTest.this.complete) break;
long start = System.nanoTime();
Connection con = null;
try {
if (async) {
Future<Connection> cf = ((DataSourceProxy)d).getConnectionAsync();
con = cf.get();
} else {
con = d.getConnection();
}
long delta = System.nanoTime() - start;
totalwait += delta;
maxwait = Math.max(delta, maxwait);
minwait = Math.min(delta, minwait);
nroffetch++;
try {
if (ConnectCountTest.this.sleep>0) sleep(ConnectCountTest.this.sleep);
} catch (InterruptedException x) {
interrupted();
}
} finally {
long cstart = System.nanoTime();
if (con!=null) try {con.close();}catch(Exception x) {x.printStackTrace();}
long cdelta = System.nanoTime() - cstart;
totalcmax += cdelta;
cmax = Math.max(cdelta, cmax);
}
totalruntime+=(System.nanoTime()-start);
}
} catch (Exception x) {
x.printStackTrace();
} finally {
ConnectCountTest.this.latch.countDown();
}
if (System.getProperty("print-thread-stats")!=null) {
System.out.println("["+getName()+"] "+
"\n\tMax time to retrieve connection:"+maxwait/1000000f+" ms."+
"\n\tTotal time to retrieve connection:"+totalwait/1000000f+" ms."+
"\n\tAverage time to retrieve connection:"+totalwait/1000000f/nroffetch+" ms."+
"\n\tMax time to close connection:"+cmax/1000000f+" ms."+
"\n\tTotal time to close connection:"+totalcmax/1000000f+" ms."+
"\n\tAverage time to close connection:"+totalcmax/1000000f/nroffetch+" ms."+
"\n\tRun time:"+totalruntime/1000000f+" ms."+
"\n\tNr of fetch:"+nroffetch);
}
}
}
}