blob: 947777be16a4dd9534eb9d0990e23e15c67624df [file] [log] [blame]
/*
* Copyright (C) 2007 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 tests.java.sql;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import tests.support.DatabaseCreator;
import tests.support.Support_SQL;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import tests.support.ThreadPool;
public class MultiThreadAccessTest extends TestCase {
private static Connection conn;
private static Statement statement;
private static final int numThreads = 10;
private static final int numOfRecords = 20;
private ThreadPool threadPool;
public void setUp() throws Exception {
super.setUp();
Support_SQL.loadDriver();
try {
conn = Support_SQL.getConnection();
statement = conn.createStatement();
createTestTables();
} catch (SQLException e) {
fail("Unexpected SQLException " + e.toString());
}
threadPool = new ThreadPool(numThreads);
}
public void tearDown() throws Exception {
threadPool.join();
deleteTestTables();
conn.close();
statement.close();
super.tearDown();
}
public void createTestTables() {
try {
ResultSet userTab = conn.getMetaData().getTables(null,
null, null, null);
while (userTab.next()) {
String tableName = userTab.getString("TABLE_NAME");
if (tableName.equals(DatabaseCreator.TEST_TABLE1)) {
statement.execute(DatabaseCreator.DROP_TABLE1);
} else if (tableName
.equals(DatabaseCreator.TEST_TABLE2)) {
statement.execute(DatabaseCreator.DROP_TABLE2);
} else if (tableName
.equals(DatabaseCreator.TEST_TABLE4)) {
statement.execute(DatabaseCreator.DROP_TABLE4);
} else if (tableName
.equals(DatabaseCreator.TEST_TABLE3)) {
statement.execute(DatabaseCreator.DROP_TABLE3);
}
}
userTab.close();
statement.execute(DatabaseCreator.CREATE_TABLE3);
statement.execute(DatabaseCreator.CREATE_TABLE4);
statement.execute(DatabaseCreator.CREATE_TABLE1);
statement.execute(DatabaseCreator.CREATE_TABLE2);
DatabaseCreator.fillTestTable1(conn, numOfRecords);
DatabaseCreator.fillTestTable2(conn, numOfRecords);
DatabaseCreator.fillTestTable4(conn, numOfRecords);
} catch (SQLException e) {
fail("Unexpected SQLException " + e.toString());
}
}
public void deleteTestTables() {
try {
statement.execute(DatabaseCreator.DROP_TABLE1);
statement.execute(DatabaseCreator.DROP_TABLE2);
statement.execute(DatabaseCreator.DROP_TABLE3);
statement.execute(DatabaseCreator.DROP_TABLE4);
} catch (SQLException e) {
fail("Unexpected SQLException " + e.toString());
}
}
/**
* A few threads execute select operation in the same time for one table in
* the database. Number of threads is defined by numThreads variable
*
* @throws SQLException
*/
public void test_MultipleAccessToOneTable() throws SQLException {
for (int i = 0; i < numThreads; i++) {
threadPool.runTask(createTask1(i));
}
}
/**
* A few threads execute select operation in the same time for different
* tables in the database. Number of threads is defined by numThreads
* variable
*
* @throws SQLException
*/
public void test_MultipleAccessToSeveralTables() throws SQLException {
threadPool.runTask(createTask1(1));
threadPool.runTask(createTask2(2));
threadPool.runTask(createTask3(3));
}
/**
* A few threads execute update, insert and delete operations in the same
* time for one table in the database. Number of threads is defined by
* numThreads variable
*
* @throws SQLException
*/
public void test_MultipleOperationsInSeveralTables() throws SQLException {
int id1 = numOfRecords - 1;
threadPool.runTask(createTask4(id1));
int id2 = numOfRecords + 1;
threadPool.runTask(createTask5(id2));
int oldID = 5;
int newID = 100;
threadPool.runTask(createTask6(oldID, newID));
threadPool.join();
Statement statement = conn.createStatement();
String selectQuery = "SELECT * FROM " + DatabaseCreator.TEST_TABLE1
+ " WHERE id=";
ResultSet result = statement.executeQuery(selectQuery + id1);
assertFalse("The record was not deleted", result.next());
result = statement.executeQuery(selectQuery + id2);
assertTrue("The record was not inserted", result.next());
assertEquals("Wrong value of field1", DatabaseCreator.defaultString
+ id2, result.getString("field1"));
// TODO getBigDecimal is not supported
assertEquals("Wrong value of field2", Integer.valueOf(id2).intValue(), result
.getInt("field2"));
assertEquals("Wrong value of field3", Integer.valueOf(id2).intValue(), result
.getInt("field3"));
result.close();
result = statement.executeQuery(selectQuery + oldID);
assertFalse("The record was not deleted", result.next());
result.close();
result = statement.executeQuery(selectQuery + newID);
assertTrue("The record was not updated", result.next());
assertEquals("Wrong value of field1", DatabaseCreator.defaultString
+ newID, result.getString("field1"));
// TODO getBigDecimal is not supported
assertEquals("Wrong value of field2", Integer.valueOf(newID).intValue(), result
.getInt("field2"));
assertEquals("Wrong value of field3", Integer.valueOf(newID).intValue(), result
.getInt("field3"));
result.close();
}
/**
* A few threads execute update operation in the same time for one tables in
* the database. Number of threads is defined by numThreads variable
*
* @throws SQLException
*/
public void test_MultipleUpdatesInOneTables() throws SQLException {
int id = 1;
String field = "field3";
String selectQuery = "SELECT * FROM " + DatabaseCreator.TEST_TABLE1
+ " WHERE id=" + id;
Statement statement = conn.createStatement();
ResultSet result = statement.executeQuery(selectQuery);
assertTrue("There is no records with id = " + id, result.next());
// TODO getBigDecimal is not supported
// assertEquals("Wrong value of field " + field, BigDecimal.valueOf(id),
// result.getBigDecimal(field));
result.close();
for (int i = 0; i < numThreads; i++) {
threadPool.runTask(createTask7(id, field));
}
threadPool.join();
double expectedVal = id + numThreads;
result = statement.executeQuery(selectQuery);
assertTrue("There is no records with id = " + id, result.next());
// TODO getBigDecimal is not supported ->
// assertEquals("Wrong value of field " + field, expectedVal, result
// .getBigDecimal(field).doubleValue());
result.close();
}
/**
* This method creates a Runnable that executes select operation for the
* first table
*
* @param taskID
* @return
*/
private static Runnable createTask1(final int taskID) {
return new Runnable() {
public void run() {
try {
Statement statement = conn.createStatement();
ResultSet result = statement.executeQuery("SELECT * FROM "
+ DatabaseCreator.TEST_TABLE1);
while (result.next()) {
assertEquals("Wrong value of id ",
DatabaseCreator.defaultString
+ result.getInt("id"), result
.getString("field1"));
assertEquals("Wrong value of field2 ", result.getInt("id"), result
.getInt("field2"));
assertEquals("Wrong value of field3 ",result.getInt("id"), result
.getInt("field3"));
}
result.close();
} catch (Exception e) {
System.err.println("Task 1 "+e.getMessage());
}
}
};
}
/**
* This method creates a Runnable that execute select operation for the
* second table
*
* @param taskID
*/
private static Runnable createTask2(final int taskID) {
return new Runnable() {
public void run() {
try {
Statement statement = conn.createStatement();
ResultSet result = statement.executeQuery("SELECT * FROM "
+ DatabaseCreator.TEST_TABLE2);
while (result.next()) {
while (result.next()) {
int id = result.getInt("finteger");
assertEquals("Wrong value of ftext",
DatabaseCreator.defaultString + id, result
.getString("ftext"));
assertEquals("Wrong value of fcharacter",
DatabaseCreator.defaultCharacter + id,
result.getString("fcharacter"));
assertEquals("Wrong value of fdecimal",
DatabaseCreator.defaultDouble + id, result
.getDouble("fdecimal"));
assertEquals("Wrong value of fnumeric",
DatabaseCreator.defaultDouble + id, result
.getDouble("fnumeric"));
assertEquals("Wrong value of fsmallint", result
.getInt("finteger"), result
.getShort("fsmallint"));
assertEquals("Wrong value of ffloat",
(float) DatabaseCreator.defaultDouble + id,
result.getFloat("ffloat"));
assertEquals("Wrong value of freal",
(float) DatabaseCreator.defaultDouble + id,
result.getFloat("freal"));
assertEquals("Wrong value of fdouble",
DatabaseCreator.defaultDouble + id, result
.getDouble("fdouble"));
}
}
result.close();
} catch (Exception e) {
System.err.println("Task2 "+e.getMessage());
}
}
};
}
/**
* This method creates a Runnable that execute select operation for the
* third table
*
* @param taskID
*/
private static Runnable createTask3(final int taskID) {
return new Runnable() {
public void run() {
try {
Statement statement = conn.createStatement();
ResultSet result = statement.executeQuery("SELECT * FROM "
+ DatabaseCreator.TEST_TABLE4);
while (result.next()) {
assertEquals("Wrong value of field1",
DatabaseCreator.defaultString
+ result.getInt("fk"), result
.getString("field1"));
}
result.close();
} catch (Exception e) {
System.err.println("Task 3 "+e.getMessage());
}
}
};
}
/**
* This method creates a Runnable that executes delete operation for the
* first table
*
* @param taskID
*/
private static Runnable createTask4(final int id) {
return new Runnable() {
public void run() {
try {
Statement statement = conn.createStatement();
statement.execute("DELETE FROM "
+ DatabaseCreator.TEST_TABLE1 + " WHERE id=" + id);
} catch (Exception e) {
System.err.println("Task 4 "+e.getMessage());
}
}
};
}
/**
* This method creates a Runnable that executes insert operation for the
* first table
*
* @param taskID
*/
private static Runnable createTask5(final int id) {
return new Runnable() {
public void run() {
try {
Statement statement = conn.createStatement();
String value = DatabaseCreator.defaultString + id;
String insertQuery = "INSERT INTO "
+ DatabaseCreator.TEST_TABLE1
+ " (id, field1, field2, field3) VALUES(" + id
+ ", '" + value + "', " + id + ", " + id + ")";
statement.execute(insertQuery);
} catch (Exception e) {
System.err.println("Task 5 "+e.getMessage());
}
}
};
}
/**
* This method creates a Runnable that executes update operation for the one
* record of the first table
*
* @param taskID
*/
private static Runnable createTask6(final int oldID, final int newID) {
return new Runnable() {
public void run() {
try {
Statement statement = conn.createStatement();
String value = DatabaseCreator.defaultString + newID;
String updateQuery = "UPDATE "
+ DatabaseCreator.TEST_TABLE1 + " SET id=" + newID
+ ", field1='" + value + "', field2=" + newID
+ ", field3=" + newID + " WHERE id=" + oldID;
statement.execute(updateQuery);
} catch (Exception e) {
System.err.println("Task 6 "+e.getMessage());
}
}
};
}
/**
* This method creates a Runnable that executes update operation for the one
* field of one record with identifier id in the first table
*
* @param taskID
*/
private static Runnable createTask7(final int id, final String field) {
return new Runnable() {
public void run() {
try {
Statement statement = conn.createStatement();
String updateQuery = "UPDATE "
+ DatabaseCreator.TEST_TABLE1 + " SET " + field
+ "= " + field + "+ 1 WHERE id=" + id;
statement.execute(updateQuery);
} catch (Exception e) {
System.err.println("Task 7 "+e.getMessage());
}
}
};
}
}