blob: db09dc9828eb71a3a3419bab588d057381fc3cb7 [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.atomic.AtomicInteger;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.test.driver.Driver;
public class TestConcurrency extends DefaultTestCase {
public static final boolean debug = Boolean.getBoolean("jdbc.debug");
protected volatile DataSource ds = null;
@Before
public void setUp() throws Exception {
ds = createDefaultDataSource();
ds.getPoolProperties().setDriverClassName(Driver.class.getName());
ds.getPoolProperties().setUrl(Driver.url);
ds.getPoolProperties().setInitialSize(0);
ds.getPoolProperties().setMaxIdle(0);
ds.getPoolProperties().setMinIdle(0);
ds.getPoolProperties().setMaxActive(10);
ds.getPoolProperties().setRemoveAbandoned(true);
ds.getPoolProperties().setLogAbandoned(true);
ds.getPoolProperties().setTestWhileIdle(true);
ds.getPoolProperties().setMinEvictableIdleTimeMillis(750);
ds.getPoolProperties().setTimeBetweenEvictionRunsMillis(25);
ds.setFairQueue(true);
}
@Override
@After
public void tearDown() throws Exception {
ds.close(true);
Driver.reset();
super.tearDown();
}
@Test
public void testSimple() throws Exception {
ds.getConnection().close();
final int iter = 1000 * 10;
final AtomicInteger loopcount = new AtomicInteger(0);
final Runnable run = new Runnable() {
@Override
public void run() {
try {
while (loopcount.incrementAndGet() < iter) {
Connection con = ds.getConnection();
Thread.sleep(10);
con.close();
}
}catch (Exception x) {
loopcount.set(iter); //stops the test
x.printStackTrace();
}
}
};
Thread[] threads = new Thread[20];
for (int i=0; i<threads.length; i++) {
threads[i] = new Thread(run);
}
for (int i=0; i<threads.length; i++) {
threads[i].start();
}
try {
while (loopcount.get()<iter) {
Assert.assertTrue("Size comparison(less than 11):",ds.getPool().getSize()<=10);
if (debug) {
System.out.println("Size: "+ds.getPool().getSize());
System.out.println("Used: "+ds.getPool().getActive());
System.out.println("Idle: "+ds.getPool().getIdle());
System.out.println("Wait: "+ds.getPool().getWaitCount());
}
Thread.sleep(250);
}
}catch (Exception x) {
loopcount.set(iter); //stops the test
x.printStackTrace();
}
for (int i=0; i<threads.length; i++) {
threads[i].join();
}
Assert.assertEquals("Size comparison:",10, ds.getPool().getSize());
Assert.assertEquals("Idle comparison:",10, ds.getPool().getIdle());
Assert.assertEquals("Used comparison:",0, ds.getPool().getActive());
Assert.assertEquals("Connect count",10,Driver.connectCount.get());
}
@Test
public void testBrutal() throws Exception {
ds.getPoolProperties().setRemoveAbandoned(false);
ds.getPoolProperties().setRemoveAbandonedTimeout(1);
ds.getPoolProperties().setMinEvictableIdleTimeMillis(100);
ds.getPoolProperties().setTimeBetweenEvictionRunsMillis(10);
ds.getConnection().close();
final int iter = 100000 * 10;
final AtomicInteger loopcount = new AtomicInteger(0);
final Runnable run = new Runnable() {
@Override
public void run() {
try {
while (loopcount.incrementAndGet() < iter) {
Connection con = ds.getConnection();
con.close();
}
}catch (Exception x) {
loopcount.set(iter); //stops the test
x.printStackTrace();
}
}
};
Thread[] threads = new Thread[20];
for (int i=0; i<threads.length; i++) {
threads[i] = new Thread(run);
}
for (int i=0; i<threads.length; i++) {
threads[i].start();
}
try {
while (loopcount.get()<iter) {
Assert.assertTrue("Size comparison(less than 11):",ds.getPool().getSize()<=10);
ds.getPool().testAllIdle();
ds.getPool().checkAbandoned();
ds.getPool().checkIdle();
}
}catch (Exception x) {
loopcount.set(iter); //stops the test
x.printStackTrace();
}
for (int i=0; i<threads.length; i++) {
threads[i].join();
}
System.out.println("Connect count:"+Driver.connectCount.get());
System.out.println("DisConnect count:"+Driver.disconnectCount.get());
Assert.assertEquals("Size comparison:",10, ds.getPool().getSize());
Assert.assertEquals("Idle comparison:",10, ds.getPool().getIdle());
Assert.assertEquals("Used comparison:",0, ds.getPool().getActive());
Assert.assertEquals("Connect count",10,Driver.connectCount.get());
}
@Test
public void testBrutalNonFair() throws Exception {
ds.getPoolProperties().setRemoveAbandoned(false);
ds.getPoolProperties().setRemoveAbandonedTimeout(1);
ds.getPoolProperties().setMinEvictableIdleTimeMillis(100);
ds.getPoolProperties().setTimeBetweenEvictionRunsMillis(10);
ds.getConnection().close();
final int iter = 100000 * 10;
final AtomicInteger loopcount = new AtomicInteger(0);
final Runnable run = new Runnable() {
@Override
public void run() {
try {
while (loopcount.incrementAndGet() < iter) {
Connection con = ds.getConnection();
con.close();
}
}catch (Exception x) {
loopcount.set(iter); //stops the test
x.printStackTrace();
}
}
};
Thread[] threads = new Thread[20];
for (int i=0; i<threads.length; i++) {
threads[i] = new Thread(run);
}
for (int i=0; i<threads.length; i++) {
threads[i].start();
}
try {
while (loopcount.get()<iter) {
Assert.assertTrue("Size comparison(less than 11):",ds.getPool().getSize()<=10);
ds.getPool().testAllIdle();
ds.getPool().checkAbandoned();
ds.getPool().checkIdle();
}
}catch (Exception x) {
loopcount.set(iter); //stops the test
x.printStackTrace();
}
for (int i=0; i<threads.length; i++) {
threads[i].join();
}
System.out.println("Connect count:"+Driver.connectCount.get());
System.out.println("DisConnect count:"+Driver.disconnectCount.get());
Assert.assertEquals("Size comparison:",10, ds.getPool().getSize());
Assert.assertEquals("Idle comparison:",10, ds.getPool().getIdle());
Assert.assertEquals("Used comparison:",0, ds.getPool().getActive());
Assert.assertEquals("Connect count",10,Driver.connectCount.get());
}
}