Merge "unittests for DatabaseConnectionPool (and fix bugs)"
This commit is contained in:
@@ -48,6 +48,9 @@ import java.util.Random;
|
||||
/** the main database connection to which this connection pool is attached */
|
||||
private final SQLiteDatabase mParentDbObj;
|
||||
|
||||
/** Random number generator used to pick a free connection out of the pool */
|
||||
private Random rand; // lazily initialized
|
||||
|
||||
/* package */ DatabaseConnectionPool(SQLiteDatabase db) {
|
||||
this.mParentDbObj = db;
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
@@ -75,50 +78,67 @@ import java.util.Random;
|
||||
* @return the Database connection that the caller can use
|
||||
*/
|
||||
/* package */ SQLiteDatabase get(String sql) {
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
doAsserts();
|
||||
}
|
||||
|
||||
SQLiteDatabase db = null;
|
||||
PoolObj poolObj = null;
|
||||
synchronized(mParentDbObj) {
|
||||
int poolSize = mPool.size();
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
assert sql != null;
|
||||
doAsserts();
|
||||
}
|
||||
if (getFreePoolSize() == 0) {
|
||||
if (mMaxPoolSize == mPool.size()) {
|
||||
// no free ( = available) connections
|
||||
if (mMaxPoolSize == poolSize) {
|
||||
// maxed out. can't open any more connections.
|
||||
// let the caller wait on one of the pooled connections
|
||||
// preferably a connection caching the pre-compiled statement of the given SQL
|
||||
if (mMaxPoolSize == 1) {
|
||||
poolObj = mPool.get(0);
|
||||
} else {
|
||||
// get a random number between 0 and (mMaxPoolSize-1)
|
||||
poolObj = mPool.get(
|
||||
new Random(SystemClock.elapsedRealtime()).nextInt(mMaxPoolSize-1));
|
||||
for (int i = 0; i < mMaxPoolSize; i++) {
|
||||
if (mPool.get(i).mDb.isSqlInStatementCache(sql)) {
|
||||
poolObj = mPool.get(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (poolObj == null) {
|
||||
// there are no database connections with the given SQL pre-compiled.
|
||||
// ok to return any of the connections.
|
||||
if (rand == null) {
|
||||
rand = new Random(SystemClock.elapsedRealtime());
|
||||
}
|
||||
poolObj = mPool.get(rand.nextInt(mMaxPoolSize));
|
||||
}
|
||||
}
|
||||
db = poolObj.mDb;
|
||||
} else {
|
||||
// create a new connection and add it to the pool, since we haven't reached
|
||||
// max pool size allowed
|
||||
int poolSize = getPoolSize();
|
||||
db = mParentDbObj.createPoolConnection((short)(poolSize + 1));
|
||||
poolObj = new PoolObj(db);
|
||||
mPool.add(poolSize, poolObj);
|
||||
}
|
||||
} else {
|
||||
// there are free connections available. pick one
|
||||
for (int i = mPool.size() - 1; i >= 0; i--) {
|
||||
poolObj = mPool.get(i);
|
||||
if (!poolObj.isFree()) {
|
||||
continue;
|
||||
}
|
||||
// it is free - but does its database object already have the given sql in its
|
||||
// statement-cache?
|
||||
db = poolObj.mDb;
|
||||
if (sql == null || db.isSqlInStatementCache(sql)) {
|
||||
// found a free connection we can use
|
||||
// preferably a connection caching the pre-compiled statement of the given SQL
|
||||
for (int i = 0; i < poolSize; i++) {
|
||||
if (mPool.get(i).isFree() && mPool.get(i).mDb.isSqlInStatementCache(sql)) {
|
||||
poolObj = mPool.get(i);
|
||||
break;
|
||||
}
|
||||
// haven't found a database object which has the given sql in its
|
||||
// statement-cache
|
||||
}
|
||||
if (poolObj == null) {
|
||||
// didn't find a free database connection with the given SQL already
|
||||
// pre-compiled. return a free connection (this means, the same SQL could be
|
||||
// pre-compiled on more than one database connection. potential wasted memory.)
|
||||
for (int i = 0; i < poolSize; i++) {
|
||||
if (mPool.get(i).isFree()) {
|
||||
poolObj = mPool.get(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
db = poolObj.mDb;
|
||||
}
|
||||
|
||||
assert poolObj != null;
|
||||
@@ -181,13 +201,10 @@ import java.util.Random;
|
||||
return list;
|
||||
}
|
||||
|
||||
/* package */ int getPoolSize() {
|
||||
synchronized(mParentDbObj) {
|
||||
return mPool.size();
|
||||
}
|
||||
}
|
||||
|
||||
private int getFreePoolSize() {
|
||||
/**
|
||||
* package level access for testing purposes only. otherwise, private should be sufficient.
|
||||
*/
|
||||
/* package */ int getFreePoolSize() {
|
||||
int count = 0;
|
||||
for (int i = mPool.size() - 1; i >= 0; i--) {
|
||||
if (mPool.get(i).isFree()) {
|
||||
@@ -197,12 +214,29 @@ import java.util.Random;
|
||||
return count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* only for testing purposes
|
||||
*/
|
||||
/* package */ ArrayList<PoolObj> getPool() {
|
||||
return mPool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "db: " + mParentDbObj.getPath() +
|
||||
", threadid = " + Thread.currentThread().getId() +
|
||||
", totalsize = " + mPool.size() + ", #free = " + getFreePoolSize() +
|
||||
", maxpoolsize = " + mMaxPoolSize;
|
||||
StringBuilder buff = new StringBuilder();
|
||||
buff.append("db: ");
|
||||
buff.append(mParentDbObj.getPath());
|
||||
buff.append(", totalsize = ");
|
||||
buff.append(mPool.size());
|
||||
buff.append(", #free = ");
|
||||
buff.append(getFreePoolSize());
|
||||
buff.append(", maxpoolsize = ");
|
||||
buff.append(mMaxPoolSize);
|
||||
for (PoolObj p : mPool) {
|
||||
buff.append("\n");
|
||||
buff.append(p.toString());
|
||||
}
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
private void doAsserts() {
|
||||
@@ -224,10 +258,21 @@ import java.util.Random;
|
||||
}
|
||||
}
|
||||
|
||||
/** only used for testing purposes. */
|
||||
/* package */ boolean isDatabaseObjFree(SQLiteDatabase db) {
|
||||
return mPool.get(db.mConnectionNum - 1).isFree();
|
||||
}
|
||||
|
||||
/** only used for testing purposes. */
|
||||
/* package */ int getSize() {
|
||||
return mPool.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* represents objects in the connection pool.
|
||||
* package-level access for testing purposes only.
|
||||
*/
|
||||
private static class PoolObj {
|
||||
/* package */ static class PoolObj {
|
||||
|
||||
private final SQLiteDatabase mDb;
|
||||
private boolean mFreeBusyFlag = FREE;
|
||||
@@ -289,6 +334,13 @@ import java.util.Random;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* only for testing purposes
|
||||
*/
|
||||
/* package */ synchronized int getNumHolders() {
|
||||
return mNumHolders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buff = new StringBuilder();
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed 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 android.database.sqlite;
|
||||
|
||||
import android.content.Context;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class DatabaseConnectionPoolTest extends AndroidTestCase {
|
||||
private static final String TAG = "DatabaseConnectionPoolTest";
|
||||
|
||||
private static final int MAX_CONN = 5;
|
||||
private static final String TEST_SQL = "select * from test where i = ? AND j = 1";
|
||||
private static final String[] TEST_SQLS = new String[] {
|
||||
TEST_SQL, TEST_SQL + 1, TEST_SQL + 2, TEST_SQL + 3, TEST_SQL + 4
|
||||
};
|
||||
|
||||
private SQLiteDatabase mDatabase;
|
||||
private File mDatabaseFile;
|
||||
private DatabaseConnectionPool mTestPool;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
File dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE);
|
||||
mDatabaseFile = new File(dbDir, "database_test.db");
|
||||
if (mDatabaseFile.exists()) {
|
||||
mDatabaseFile.delete();
|
||||
}
|
||||
mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
|
||||
assertNotNull(mDatabase);
|
||||
mDatabase.execSQL("create table test (i int, j int);");
|
||||
mTestPool = new DatabaseConnectionPool(mDatabase);
|
||||
assertNotNull(mTestPool);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
mTestPool.close();
|
||||
mDatabase.close();
|
||||
mDatabaseFile.delete();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testGetAndRelease() {
|
||||
mTestPool.setMaxPoolSize(MAX_CONN);
|
||||
// connections should be lazily created.
|
||||
assertEquals(0, mTestPool.getSize());
|
||||
// MAX pool size should be set to MAX_CONN
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// get a connection
|
||||
SQLiteDatabase db = mTestPool.get(TEST_SQL);
|
||||
// pool size should be one - since only one should be allocated for the above get()
|
||||
assertEquals(1, mTestPool.getSize());
|
||||
// no free connections should be available
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db));
|
||||
// release the connection
|
||||
mTestPool.release(db);
|
||||
assertEquals(1, mTestPool.getFreePoolSize());
|
||||
assertEquals(1, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
assertTrue(mTestPool.isDatabaseObjFree(db));
|
||||
// release the same object again and expect IllegalStateException
|
||||
try {
|
||||
mTestPool.release(db);
|
||||
fail("illegalStateException expected");
|
||||
} catch (IllegalStateException e ) {
|
||||
// expected.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get all connections from the pool and ask for one more.
|
||||
* should get one of the connections already got so far.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetAllConnAndOneMore() {
|
||||
mTestPool.setMaxPoolSize(MAX_CONN);
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
ArrayList<SQLiteDatabase> dbObjs = new ArrayList<SQLiteDatabase>();
|
||||
for (int i = 0; i < MAX_CONN; i++) {
|
||||
SQLiteDatabase db = mTestPool.get(TEST_SQL);
|
||||
assertFalse(dbObjs.contains(db));
|
||||
dbObjs.add(db);
|
||||
}
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// pool is maxed out and no free connections. ask for one more connection
|
||||
SQLiteDatabase db1 = mTestPool.get(TEST_SQL);
|
||||
// make sure db1 is one of the existing ones
|
||||
assertTrue(dbObjs.contains(db1));
|
||||
// pool size should remain at MAX_CONN
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// release db1 but since it is allocated 2 times, it should still remain 'busy'
|
||||
mTestPool.release(db1);
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db1));
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// release all connections
|
||||
for (int i = 0; i < MAX_CONN; i++) {
|
||||
mTestPool.release(dbObjs.get(i));
|
||||
}
|
||||
// all objects in the pool should be freed now
|
||||
assertEquals(MAX_CONN, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* same as above except that each connection has different SQL statement associated with it.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testConnRetrievalForPreviouslySeenSql() {
|
||||
mTestPool.setMaxPoolSize(MAX_CONN);
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
HashMap<String, SQLiteDatabase> dbObjs = new HashMap<String, SQLiteDatabase>();
|
||||
for (int i = 0; i < MAX_CONN; i++) {
|
||||
SQLiteDatabase db = mTestPool.get(TEST_SQLS[i]);
|
||||
executeSqlOnDatabaseConn(db, TEST_SQLS[i]);
|
||||
assertFalse(dbObjs.values().contains(db));
|
||||
dbObjs.put(TEST_SQLS[i], db);
|
||||
}
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// pool is maxed out and no free connections. ask for one more connection
|
||||
// use a previously seen SQL statement
|
||||
String testSql = TEST_SQLS[MAX_CONN - 1];
|
||||
SQLiteDatabase db1 = mTestPool.get(testSql);
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// make sure db1 is one of the existing ones
|
||||
assertTrue(dbObjs.values().contains(db1));
|
||||
assertEquals(db1, dbObjs.get(testSql));
|
||||
// do the same again
|
||||
SQLiteDatabase db2 = mTestPool.get(testSql);
|
||||
// make sure db1 is one of the existing ones
|
||||
assertEquals(db2, dbObjs.get(testSql));
|
||||
|
||||
// pool size should remain at MAX_CONN
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
// release db1 but since the same connection is allocated 3 times,
|
||||
// it should still remain 'busy'
|
||||
mTestPool.release(db1);
|
||||
assertFalse(mTestPool.isDatabaseObjFree(dbObjs.get(testSql)));
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
// release db2 but since the same connection is allocated 2 times,
|
||||
// it should still remain 'busy'
|
||||
mTestPool.release(db2);
|
||||
assertFalse(mTestPool.isDatabaseObjFree(dbObjs.get(testSql)));
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
// release all connections
|
||||
for (int i = 0; i < MAX_CONN; i++) {
|
||||
mTestPool.release(dbObjs.get(TEST_SQLS[i]));
|
||||
}
|
||||
// all objects in the pool should be freed now
|
||||
assertEquals(MAX_CONN, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
}
|
||||
|
||||
private void executeSqlOnDatabaseConn(SQLiteDatabase db, String sql) {
|
||||
// execute the given SQL on the given database connection so that the prepared
|
||||
// statement for SQL is cached by the given database connection
|
||||
// this will help DatabaseConenctionPool figure out if a given SQL statement
|
||||
// is already cached by a database connection.
|
||||
db.execSQL(sql, new String[]{1+""});
|
||||
}
|
||||
|
||||
/**
|
||||
* get a connection for a SQL statement 'blah'. (connection_s)
|
||||
* make sure the pool has at least one free connection even after this get().
|
||||
* and get a connection for the same SQL again.
|
||||
* this connection should be different from connection_s.
|
||||
* even though there is a connection with the given SQL pre-compiled, since is it not free
|
||||
* AND since the pool has free connections available, should get a new connection.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetConnForTheSameSql() {
|
||||
mTestPool.setMaxPoolSize(MAX_CONN);
|
||||
|
||||
SQLiteDatabase db = mTestPool.get(TEST_SQL);
|
||||
executeSqlOnDatabaseConn(db, TEST_SQL);
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(1, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db));
|
||||
|
||||
SQLiteDatabase db1 = mTestPool.get(TEST_SQL);
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(2, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db1));
|
||||
assertFalse(db1.equals(db));
|
||||
|
||||
mTestPool.release(db);
|
||||
assertEquals(1, mTestPool.getFreePoolSize());
|
||||
assertEquals(2, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
mTestPool.release(db1);
|
||||
assertEquals(2, mTestPool.getFreePoolSize());
|
||||
assertEquals(2, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* get the same connection N times and release it N times.
|
||||
* this tests DatabaseConnectionPool.PoolObj.mNumHolders
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetSameConnNtimesAndReleaseItNtimes() {
|
||||
mTestPool.setMaxPoolSize(MAX_CONN);
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
HashMap<String, SQLiteDatabase> dbObjs = new HashMap<String, SQLiteDatabase>();
|
||||
for (int i = 0; i < MAX_CONN; i++) {
|
||||
SQLiteDatabase db = mTestPool.get(TEST_SQLS[i]);
|
||||
executeSqlOnDatabaseConn(db, TEST_SQLS[i]);
|
||||
assertFalse(dbObjs.values().contains(db));
|
||||
dbObjs.put(TEST_SQLS[i], db);
|
||||
}
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// every connection in the pool should have numHolders = 1
|
||||
for (int i = 0; i < MAX_CONN; i ++) {
|
||||
assertEquals(1, mTestPool.getPool().get(i).getNumHolders());
|
||||
}
|
||||
// pool is maxed out and no free connections. ask for one more connection
|
||||
// use a previously seen SQL statement
|
||||
String testSql = TEST_SQLS[MAX_CONN - 1];
|
||||
SQLiteDatabase db1 = mTestPool.get(testSql);
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// make sure db1 is one of the existing ones
|
||||
assertTrue(dbObjs.values().contains(db1));
|
||||
assertEquals(db1, dbObjs.get(testSql));
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db1));
|
||||
DatabaseConnectionPool.PoolObj poolObj = mTestPool.getPool().get(db1.mConnectionNum - 1);
|
||||
int numHolders = poolObj.getNumHolders();
|
||||
assertEquals(2, numHolders);
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// get the same connection N times more
|
||||
int N = 100;
|
||||
for (int i = 0; i < N; i++) {
|
||||
SQLiteDatabase db2 = mTestPool.get(testSql);
|
||||
assertEquals(db1, db2);
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db2));
|
||||
// numHolders for this object should be now up by 1
|
||||
int prev = numHolders;
|
||||
numHolders = poolObj.getNumHolders();
|
||||
assertEquals(prev + 1, numHolders);
|
||||
}
|
||||
// release it N times
|
||||
for (int i = 0; i < N; i++) {
|
||||
mTestPool.release(db1);
|
||||
int prev = numHolders;
|
||||
numHolders = poolObj.getNumHolders();
|
||||
assertEquals(prev - 1, numHolders);
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db1));
|
||||
}
|
||||
// the connection should still have 2 more holders
|
||||
assertFalse(mTestPool.isDatabaseObjFree(db1));
|
||||
assertEquals(2, poolObj.getNumHolders());
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// release 2 more times
|
||||
mTestPool.release(db1);
|
||||
mTestPool.release(db1);
|
||||
assertEquals(0, poolObj.getNumHolders());
|
||||
assertEquals(1, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
assertTrue(mTestPool.isDatabaseObjFree(db1));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testStressTest() {
|
||||
mTestPool.setMaxPoolSize(MAX_CONN);
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
|
||||
HashMap<SQLiteDatabase, Integer> dbMap = new HashMap<SQLiteDatabase, Integer>();
|
||||
for (int i = 0; i < MAX_CONN; i++) {
|
||||
SQLiteDatabase db = mTestPool.get(TEST_SQLS[i]);
|
||||
assertFalse(dbMap.containsKey(db));
|
||||
dbMap.put(db, 1);
|
||||
executeSqlOnDatabaseConn(db, TEST_SQLS[i]);
|
||||
}
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// ask for lot more connections but since the pool is maxed out, we should start receiving
|
||||
// connections that we already got so far
|
||||
for (int i = MAX_CONN; i < 1000; i++) {
|
||||
SQLiteDatabase db = mTestPool.get(TEST_SQL + i);
|
||||
assertTrue(dbMap.containsKey(db));
|
||||
int k = dbMap.get(db);
|
||||
dbMap.put(db, ++k);
|
||||
}
|
||||
assertEquals(0, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
// print the distribution of the database connection handles received, should be uniform.
|
||||
for (SQLiteDatabase d : dbMap.keySet()) {
|
||||
Log.i(TAG, "connection # " + d.mConnectionNum + ", numHolders: " + dbMap.get(d));
|
||||
}
|
||||
// print the pool info
|
||||
Log.i(TAG, mTestPool.toString());
|
||||
// release all
|
||||
for (SQLiteDatabase d : dbMap.keySet()) {
|
||||
int num = dbMap.get(d);
|
||||
for (int i = 0; i < num; i++) {
|
||||
mTestPool.release(d);
|
||||
}
|
||||
}
|
||||
assertEquals(MAX_CONN, mTestPool.getFreePoolSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getSize());
|
||||
assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user