001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (license2)
004: * Initial Developer: H2 Group
005: */
006: package org.h2.test.synth;
007:
008: import java.sql.Connection;
009: import java.sql.PreparedStatement;
010: import java.sql.ResultSet;
011: import java.sql.SQLException;
012: import java.sql.Statement;
013: import java.util.Random;
014:
015: import org.h2.test.TestBase;
016: import org.h2.test.unit.SelfDestructor;
017:
018: /**
019: * A random recovery test. This test starts a process that executes random
020: * operations against a database, then kills this process. Afterwards recovery
021: * is tested.
022: */
023: public class TestKill extends TestBase {
024:
025: Connection conn;
026: int accounts = 10;
027: Random random = new Random(1);
028: private static final String DIR = TestBase.getTestDir("kill");
029:
030: public void test() throws Exception {
031: String connect = "";
032:
033: connect = ";MAX_LOG_SIZE=10;THROTTLE=80";
034:
035: String url = getURL(DIR + "/kill" + connect, true);
036: String user = getUser();
037: String password = getPassword();
038: String selfDestruct = SelfDestructor.getPropertyString(60);
039: String[] procDef = new String[] { "java", selfDestruct, "-cp",
040: "bin", "org.h2.test.synth.TestKillProcess", url, user,
041: password, baseDir, "" + accounts };
042:
043: for (int i = 0;; i++) {
044: printTime("TestKill " + i);
045: if (i % 10 == 0) {
046: trace("deleting db...");
047: deleteDb(baseDir, "kill");
048: }
049: conn = getConnection(url);
050: createTables();
051: checkData();
052: initData();
053: conn.close();
054: Process proc = Runtime.getRuntime().exec(procDef);
055: // while(true) {
056: // int ch = proc.getErrorStream().read();
057: // if(ch < 0) {
058: // break;
059: // }
060: // System.out.print((char)ch);
061: // }
062: int runtime = random.nextInt(10000);
063: trace("running...");
064: Thread.sleep(runtime);
065: trace("stopping...");
066: proc.destroy();
067: proc.waitFor();
068: trace("stopped");
069: }
070: }
071:
072: private void createTables() throws SQLException {
073: trace("createTables...");
074: Statement stat = conn.createStatement();
075: stat
076: .execute("CREATE TABLE IF NOT EXISTS ACCOUNT(ID INT PRIMARY KEY, SUM INT)");
077: stat
078: .execute("CREATE TABLE IF NOT EXISTS LOG(ID IDENTITY, ACCOUNTID INT, AMOUNT INT, FOREIGN KEY(ACCOUNTID) REFERENCES ACCOUNT(ID))");
079: stat
080: .execute("CREATE TABLE IF NOT EXISTS TEST_A(ID INT PRIMARY KEY, DATA VARCHAR)");
081: stat
082: .execute("CREATE TABLE IF NOT EXISTS TEST_B(ID INT PRIMARY KEY, DATA VARCHAR)");
083: }
084:
085: private void initData() throws SQLException {
086: trace("initData...");
087: conn.createStatement().execute("DROP TABLE LOG");
088: conn.createStatement().execute("DROP TABLE ACCOUNT");
089: conn.createStatement().execute("DROP TABLE TEST_A");
090: conn.createStatement().execute("DROP TABLE TEST_B");
091: createTables();
092: PreparedStatement prep = conn
093: .prepareStatement("INSERT INTO ACCOUNT VALUES(?, 0)");
094: for (int i = 0; i < accounts; i++) {
095: prep.setInt(1, i);
096: prep.execute();
097: }
098: PreparedStatement p1 = conn
099: .prepareStatement("INSERT INTO TEST_A VALUES(?, '')");
100: PreparedStatement p2 = conn
101: .prepareStatement("INSERT INTO TEST_B VALUES(?, '')");
102: for (int i = 0; i < accounts; i++) {
103: p1.setInt(1, i);
104: p2.setInt(1, i);
105: p1.execute();
106: p2.execute();
107: }
108: }
109:
110: private void checkData() throws Exception {
111: trace("checkData...");
112: ResultSet rs = conn.createStatement().executeQuery(
113: "SELECT * FROM ACCOUNT ORDER BY ID");
114: PreparedStatement prep = conn
115: .prepareStatement("SELECT SUM(AMOUNT) FROM LOG WHERE ACCOUNTID=?");
116: while (rs.next()) {
117: int account = rs.getInt(1);
118: int sum = rs.getInt(2);
119: prep.setInt(1, account);
120: ResultSet rs2 = prep.executeQuery();
121: rs2.next();
122: int sumLog = rs2.getInt(1);
123: check(sumLog, sum);
124: trace("account=" + account + " sum=" + sum);
125: }
126: PreparedStatement p1 = conn
127: .prepareStatement("SELECT * FROM TEST_A WHERE ID=?");
128: PreparedStatement p2 = conn
129: .prepareStatement("SELECT * FROM TEST_B WHERE ID=?");
130: for (int i = 0; i < accounts; i++) {
131: p1.setInt(1, i);
132: p2.setInt(1, i);
133: ResultSet r1 = p1.executeQuery();
134: ResultSet r2 = p2.executeQuery();
135: boolean hasData = r1.next();
136: check(r2.next(), hasData);
137: if (hasData) {
138: String d1 = r1.getString("DATA");
139: String d2 = r2.getString("DATA");
140: check(d1, d2);
141: checkFalse(r1.next());
142: checkFalse(r2.next());
143: trace("test: data=" + d1);
144: } else {
145: trace("test: empty");
146: }
147: }
148: }
149:
150: }
|