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.SQLException;
010: import java.sql.Statement;
011: import java.util.ArrayList;
012:
013: import org.h2.bnf.Bnf;
014: import org.h2.bnf.RuleHead;
015: import org.h2.constant.SysProperties;
016: import org.h2.store.fs.FileSystem;
017: import org.h2.test.TestAll;
018: import org.h2.test.TestBase;
019: import org.h2.tools.DeleteDbFiles;
020: import org.h2.util.RandomUtils;
021:
022: /**
023: * This test executes random SQL statements generated using the BNF tool.
024: */
025: public class TestRandomSQL extends TestBase {
026:
027: private int dbId;
028: private boolean showSQL;
029: private ArrayList statements;
030: private int seed;
031: private boolean exitOnError = true;
032: private Bnf bnf;
033: private int success, total;
034:
035: private void processException(String sql, SQLException e) {
036: if (e.getSQLState().equals("HY000")) {
037: TestBase.logError(
038: "new TestRandomSQL().init(test).testCase(" + seed
039: + "); // FAIL: " + e.toString(), e);
040: if (exitOnError) {
041: System.exit(0);
042: }
043: }
044: }
045:
046: private String getDatabaseName() {
047: if (config.big) {
048: return "dataRandomSQL/randomSql" + dbId;
049: } else {
050: return "memFS:/randomSql" + dbId;
051: }
052: // return "dataRandomSQL/randomSql" + dbId+";TRACE_LEVEL_FILE=3";
053: }
054:
055: private Connection connect() throws Exception {
056: while (true) {
057: try {
058: return getConnection(getDatabaseName());
059: } catch (SQLException e) {
060: dbId--;
061: try {
062: deleteDb();
063: } catch (Exception e2) {
064: // ignore
065: }
066: dbId++;
067: try {
068: deleteDb();
069: } catch (Exception e2) {
070: // ignore
071: }
072: dbId++;
073: try {
074: deleteDb();
075: } catch (SQLException e2) {
076: dbId++;
077: deleteDb();
078: }
079: }
080: }
081:
082: }
083:
084: private void deleteDb() throws SQLException {
085: String name = getDatabaseName();
086: if (name.startsWith(FileSystem.MEMORY_PREFIX)) {
087: DeleteDbFiles.execute("memFS:/", name, true);
088: } else {
089: DeleteDbFiles.execute(baseDir, name, true);
090: }
091: }
092:
093: public TestBase init(TestAll conf) throws Exception {
094: super .init(conf);
095: bnf = Bnf.getInstance(null);
096: bnf.linkStatements();
097: statements = bnf.getStatements();
098:
099: // go backwards so we can append at the end
100: for (int i = statements.size() - 1; i >= 0; i--) {
101: RuleHead r = (RuleHead) statements.get(i);
102: String topic = r.getTopic();
103: int weight = 0;
104: if (topic.equals("select")) {
105: weight = 10;
106: } else if (topic.equals("createtable")) {
107: weight = 20;
108: } else if (topic.equals("insert")) {
109: weight = 5;
110: } else if (topic.startsWith("update")) {
111: weight = 3;
112: } else if (topic.startsWith("delete")) {
113: weight = 3;
114: } else if (topic.startsWith("drop")) {
115: weight = 2;
116: }
117: if (showSQL) {
118: System.out.println(r.getTopic());
119: }
120: for (int j = 0; j < weight; j++) {
121: statements.add(r);
122: }
123: }
124: return this ;
125: }
126:
127: private void testWithSeed(Bnf config) throws Exception {
128: config.getRandom().setSeed(seed);
129: Connection conn = null;
130: try {
131: conn = connect();
132: } catch (SQLException e) {
133: processException("connect", e);
134: conn = connect();
135: }
136: Statement stat = conn.createStatement();
137: for (int i = 0; i < statements.size(); i++) {
138: int sid = config.getRandom().nextInt(statements.size());
139: RuleHead r = (RuleHead) statements.get(sid);
140: String rand = r.getRule().random(config, 0).trim();
141: if (rand.length() > 0) {
142: try {
143: Thread.yield();
144: if (rand.indexOf("TRACE_LEVEL_") < 0
145: && rand.indexOf("COLLATION") < 0
146: && rand.indexOf("SCRIPT ") < 0
147: && rand.indexOf("CSVWRITE") < 0
148: && rand.indexOf("BACKUP") < 0) {
149: if (showSQL) {
150: System.out.println(i + " " + rand);
151: }
152: total++;
153: if (total % 100 == 0) {
154: printTime("total: " + total + " success: "
155: + (100 * success / total) + "%");
156: }
157: stat.execute(rand);
158: success++;
159: }
160: } catch (SQLException e) {
161: processException(rand, e);
162: }
163: }
164: }
165: try {
166: conn.close();
167: } catch (SQLException e) {
168: processException("conn.close", e);
169: }
170: }
171:
172: public void testCase(int i) throws Exception {
173: String old = SysProperties.scriptDirectory;
174: SysProperties.scriptDirectory = "dataScript/";
175: seed = i;
176: printTime("seed: " + seed);
177: try {
178: deleteDb();
179: } catch (SQLException e) {
180: processException("deleteDb", e);
181: }
182: testWithSeed(bnf);
183: SysProperties.scriptDirectory = old;
184: }
185:
186: public void test() throws Exception {
187: if (config.networked) {
188: return;
189: }
190: int len = getSize(2, 6);
191: exitOnError = false;
192: showSQL = false;
193: for (int a = 0; a < len; a++) {
194: int seed = RandomUtils.nextInt(Integer.MAX_VALUE);
195: testCase(seed);
196: }
197: }
198:
199: }
|