KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyTesting > functionTests > tests > store > OnlineBackupTest3


1 /*
2
3    Derby - Class org.apache.derbyTesting.functionTests.store.OnlineBackupTest3
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derbyTesting.functionTests.tests.store;
23 import java.sql.Connection JavaDoc;
24 import java.sql.Statement JavaDoc;
25 import java.sql.PreparedStatement JavaDoc;
26 import java.sql.ResultSet JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import org.apache.derby.tools.ij;
29 import org.apache.derbyTesting.functionTests.util.TestUtil;
30
31 /*
32  * This class tests online backup when jar actions
33  * are running in parallel to the backup thread.
34  *
35  * @author <a HREF="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
36  * @version 1.0
37  */

38
39 public class OnlineBackupTest3 {
40
41     private static final String JavaDoc TEST_DATABASE_NAME = "wombat" ;
42     private static final String JavaDoc BACKUP_PATH = "extinout/onlinebackuptest3";
43
44     public static void main(String JavaDoc[] argv) throws Throwable JavaDoc {
45
46         OnlineBackupTest3 test = new OnlineBackupTest3();
47         ij.getPropertyArg(argv);
48
49         try {
50             test.runTest();
51         }
52         catch (SQLException JavaDoc sqle) {
53             dumpSQLException(sqle);
54         }
55     }
56
57
58     /*
59      * Test online backup with unlogged jar operations running in parallel.
60      */

61     private void runTest() throws Exception JavaDoc{
62         logMessage("Begin Online Backup Test3");
63         Connection JavaDoc conn = ij.startJBMS();
64         conn.setAutoCommit(false);
65         Statement JavaDoc stmt = conn.createStatement();
66         stmt.execute("create table t1(a int ) ");
67         stmt.execute("insert into t1 values(1)");
68         stmt.execute("insert into t1 values(2)");
69         stmt.execute("create table customer(id int , name varchar(100))");
70         stmt.execute("insert into customer values(1, 'ABC')");
71         stmt.execute("insert into customer values(2, 'XYZ')");
72         String JavaDoc crproc = "create procedure addCustomer(id INT, name VARCHAR(100)) " +
73             "MODIFIES SQL DATA " +
74             "external name " +
75             "'org.apache.derbyTesting.backupRestore.Customer.addCustomer' " +
76             " language java parameter style java ";
77             
78         stmt.execute(crproc);
79
80         String JavaDoc dvfunc = "create function dv(P1 INT) RETURNS INT NO SQL " +
81             " external name 'dbytesting.CodeInAJar.doubleMe' " +
82             " language java parameter style java " ;
83
84         stmt.execute(dvfunc) ;
85         conn.commit();
86         
87         logMessage("Initial Setup Complete");
88
89         // perform install jar operation with
90
// online backup running in parallel.
91
installJarTest();
92
93         // perform remove jar operation with
94
// online backup running in parallel.
95
removeJarTest();
96
97         logMessage("End Online Backup Test3");
98     }
99
100
101     /**
102      * Shutdown the datbase
103      * @param dbName Name of the database to shutdown.
104      */

105     void shutdown(String JavaDoc dbName) {
106
107         try{
108             //shutdown
109
TestUtil.getConnection(dbName, "shutdown=true");
110         }catch(SQLException JavaDoc se){
111             if (se.getSQLState() != null && se.getSQLState().equals("08006"))
112                 System.out.println("database shutdown properly");
113             else
114                 dumpSQLException(se);
115         }
116     }
117
118     /**
119      * Write message to the standard output.
120      */

121     void logMessage(String JavaDoc str){
122         System.out.println(str);
123     }
124
125     /**
126      * dump the SQLException to the standard output.
127      */

128     static private void dumpSQLException(SQLException JavaDoc sqle) {
129
130         org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(System.out, sqle);
131         sqle.printStackTrace(System.out);
132     }
133
134     
135     private int countRows(Connection JavaDoc conn,
136                           String JavaDoc tableName)
137         throws SQLException JavaDoc
138     {
139         Statement JavaDoc s = conn.createStatement();
140         ResultSet JavaDoc rs = s.executeQuery("SELECT count(*) from " + tableName );
141         rs.next();
142         int noRows = rs.getInt(1);
143         rs.close();
144         s.close();
145         return noRows;
146     }
147
148     /*
149      * Test install jar running in parallel to backup and vice versa.
150      */

151     void installJarTest() throws Exception JavaDoc{
152         logMessage("Begin Install Jar Test");
153         Connection JavaDoc conn1 = TestUtil.getConnection(TEST_DATABASE_NAME, null);
154         conn1.setAutoCommit(false);
155         Statement JavaDoc conn1_stmt = conn1.createStatement();
156         Connection JavaDoc conn2 = TestUtil.getConnection(TEST_DATABASE_NAME, null);
157         conn2.setAutoCommit(false);
158         Statement JavaDoc conn2_stmt = conn2.createStatement();
159
160         
161         conn1_stmt.execute(
162            "call sqlj.install_jar('extin/brtestjar.jar', 'math_routines', 0)");
163         
164         try {
165             // followng backup call should fail because jar operation is pending
166
conn2_stmt.execute(
167             "call SYSCS_UTIL.SYSCS_BACKUP_DATABASE_NOWAIT('extinout/mybackup')");
168         } catch (SQLException JavaDoc sqle) {
169             //above statement should have failed.
170
org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(System.out, sqle);
171         }
172
173         // invoke backup in another thread, it should block for the above install jar
174
// operation to install 'brtestjar.jar to commit.
175

176         // start a thread to perform online backup
177
OnlineBackup backup = new OnlineBackup(TEST_DATABASE_NAME, BACKUP_PATH);
178         Thread JavaDoc backupThread = new Thread JavaDoc(backup, "BACKUP1");
179         backupThread.start();
180         // wait for the backup to start
181
backup.waitForBackupToBegin();
182         logMessage("Backup-1 Started");
183
184         // sleep for few seconds just to make sure backup thread has actually
185
// gone into a wait state for unlogged actions to commit.
186
java.lang.Thread.sleep(1000);
187         
188         // backup should not even start doing real work before the
189
// unlogged transaction is commited
190
if(!backup.isRunning())
191             logMessage("Backup is not waiting for unlogged " +
192                        "install jar action to commit");
193
194         //insert some rows that should appear in the backup.
195
conn1_stmt.execute("insert into t1 values(3)");
196         conn1_stmt.execute("insert into t1 values(4)");
197         conn1_stmt.execute("insert into t1 values(5)");
198         
199         // set the database class with both the jars installed above.
200
conn1_stmt.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY( " +
201                            "'derby.database.classpath', " +
202                            "'APP.math_routines') " ) ;
203
204         //commit the transaction with jar opearation that is blocking the backup.
205
conn1.commit();
206         logMessage("The transaction that was blocking the backup has ended");
207
208         // wait for backup to finish.
209
backup.waitForBackupToEnd();
210         backupThread.join();
211         logMessage("Backup-1 Completed");
212         
213         // Case : jar op should block if backup is in progress
214
// add a index that will block the backup until it is committted.
215
conn1_stmt.execute("create index idx1 on customer(id)");
216         conn1_stmt.execute("insert into t1 values(6)");
217         
218         // start a thread to perform online backup
219
backup = new OnlineBackup(TEST_DATABASE_NAME, BACKUP_PATH);
220         backupThread = new Thread JavaDoc(backup, "BACKUP2");
221         backupThread.start();
222         // wait for the backup to start
223
backup.waitForBackupToBegin();
224         logMessage("Backup-2 Started");
225
226         // sleep for few seconds just to make sure backup thread is actually
227
// gone to a wait state for unlogged actions to commit.
228
java.lang.Thread.sleep(1000);
229
230         // backup should not even start doing real work before the
231
// unlogged transaction is commited
232
if(!backup.isRunning())
233             logMessage("Backup is not waiting for unlogged " +
234                        "index action to commit");
235
236
237         // add another jar file , this one should block and
238
// should not get into the backup. Backup does not allow new
239
// jar operation if it is already waiting for backup blocking
240
// to complete(commit/rollback).
241

242         AsyncStatementThread asyncJarActionThread =
243             new AsyncStatementThread(conn2,
244           "call sqlj.install_jar('extin/obtest_customer.jar', 'customer_app', 0)");
245         asyncJarActionThread.start();
246         logMessage("Started obtest_customer.jar addition in seperate thread");
247
248         //sleep for few seconds to give a chance for the
249
//jar addition thread to get into action.
250
java.lang.Thread.sleep(1000);
251
252         //roll back the index op. Backup should proceed now.
253
conn1.rollback();
254         logMessage("The transaction that was blocking the backup has ended");
255
256         // wait for backup to finish.
257
backup.waitForBackupToEnd();
258         backupThread.join();
259         logMessage("Backup-2 Completed");
260         
261         // wait for customer app jar installation to finish now.
262
asyncJarActionThread.join();
263         logMessage("obtest_customer.jar addition is complete");
264
265         // set the database class with both the jars installed above.
266
conn1_stmt.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY( " +
267                            "'derby.database.classpath', " +
268                            "'APP.customer_app:APP.math_routines') " ) ;
269         
270         conn1.commit();
271
272         // second jar must have got installed after the backup.
273
// call a function in the custome_app jar
274
conn1_stmt.execute("call addCustomer(3 , 'John')");
275         conn1.commit();
276         
277         logMessage("No of rows in table t1: " + countRows(conn1, "T1"));
278         logMessage("No of rows in table customer: " +
279                    countRows(conn1, "customer"));
280         conn1.commit();
281         conn2.commit();
282         conn1_stmt.close();
283         conn2_stmt.close();
284         conn1.close();
285         conn2.close();
286         
287         //shutdown the test db
288
shutdown(TEST_DATABASE_NAME);
289         // restore the database from the backup and run some checks
290
backup.restoreFromBackup();
291         logMessage("Restored From the Backup");
292         Connection JavaDoc conn = TestUtil.getConnection(TEST_DATABASE_NAME, null);
293         Statement JavaDoc stmt = conn.createStatement();
294         logMessage("No of rows in table t1: " + countRows(conn, "T1"));
295         logMessage("No of rows in table customer: " +
296                    countRows(conn, "customer"));
297         // execute select statement using the "dv" funciont.
298
stmt.execute("select dv(a) from t1");
299
300         
301         try {
302             // set the database class with both the jars installed above.
303
stmt.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY( " +
304                            "'derby.database.classpath', " +
305                            "'APP.customer_app:APP.math_routines') " ) ;
306             stmt.execute("call addCustomer(3 , 'John')");
307         }catch(SQLException JavaDoc se) {
308             //ignore for now. No sure way to
309
//check that jar did not get into backup
310
//without debug flags.
311
}
312
313         stmt.close();
314         conn.close();
315
316         //shutdown the test db
317
shutdown(TEST_DATABASE_NAME);
318         logMessage("End Of Install Jar Test.");
319
320     }
321
322
323     /*
324      * Test remove jar running in parallel to backup and vice versa.
325      */

326     void removeJarTest() throws Exception JavaDoc{
327         logMessage("Begin Remove Jar Test");
328         Connection JavaDoc conn1 = TestUtil.getConnection(TEST_DATABASE_NAME, null);
329         conn1.setAutoCommit(false);
330         Statement JavaDoc conn1_stmt = conn1.createStatement();
331         Connection JavaDoc conn2 = TestUtil.getConnection(TEST_DATABASE_NAME, null);
332         conn2.setAutoCommit(false);
333         Statement JavaDoc conn2_stmt = conn2.createStatement();
334         try {
335             conn1_stmt.execute(
336            "call sqlj.install_jar('extin/obtest_customer.jar', 'customer_app', 0)");
337         }catch(SQLException JavaDoc se) {
338             //it is ok if was jar already there.
339
}
340
341         // remove both the jars from the class path ,
342
// so that we can remove them from the database.
343
conn1_stmt.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY( " +
344                         "'derby.database.classpath', '')") ;
345         conn1.commit();
346
347         conn1_stmt.execute(
348            "call sqlj.remove_jar('APP.math_routines', 0)");
349         
350         // Case 0: backup call that is not waiting for unlogged
351
// opereation to complete should fail when a remove jar
352
// is not ended when backup started.
353

354         try {
355             // followng backup call should fail because remove
356
// jar operation is pending
357
conn2_stmt.execute(
358             "call SYSCS_UTIL.SYSCS_BACKUP_DATABASE_NOWAIT('extinout/mybackup')");
359         } catch (SQLException JavaDoc sqle) {
360             //above statement should have failed.
361
org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(System.out, sqle);
362         }
363
364
365                 
366         // Case 1: backup should block because when a remove jar
367
// is not ended when backup started.
368

369         // invoke backup in another thread, should block for
370
// the above remove jar to commit.
371

372         // start a thread to perform online backup
373
OnlineBackup backup = new OnlineBackup(TEST_DATABASE_NAME, BACKUP_PATH);
374         Thread JavaDoc backupThread = new Thread JavaDoc(backup, "BACKUP3");
375         backupThread.start();
376         // wait for the backup to start
377
backup.waitForBackupToBegin();
378         logMessage("Backup-3 Started");
379
380         // sleep for few seconds just to make sure backup thread is actually
381
// gone to a wait state for unlogged actions to commit.
382
java.lang.Thread.sleep(1000);
383
384         // backup should not even start doing real work before the
385
// unlogged transaction is commited
386
if(!backup.isRunning())
387             logMessage("Backup is not waiting for unlogged " +
388                        "remove jar action to commit");
389
390         //insert some rows that should appear in the backup.
391
conn1_stmt.execute("insert into t1 values(10)");
392         conn1_stmt.execute("insert into t1 values(11)");
393
394         //commit the transaction with jar opearation that is blocking the backup.
395
conn1.commit();
396         logMessage("The transaction that was blocking the backup has ended");
397         
398         // wait for backup to finish.
399
backup.waitForBackupToEnd();
400         backupThread.join();
401
402         logMessage("Backup-3 Completed");
403         
404         // Case 2: remove jar op should block if backup is in progress
405
// add a index that will block the backup until it is committted.
406
conn1_stmt.execute("create index idx1 on customer(id)");
407         conn1_stmt.execute("insert into t1 values(12)");
408         
409         // start a thread to perform online backup
410
backup = new OnlineBackup(TEST_DATABASE_NAME, BACKUP_PATH);
411         backupThread = new Thread JavaDoc(backup, "BACKUP4");
412         backupThread.start();
413         // wait for the backup to start
414
backup.waitForBackupToBegin();
415         logMessage("Backup-4 Started");
416
417         // sleep for few seconds just to make sure backup thread is actually
418
// gone to a wait state for unlogged actions to commit.
419
java.lang.Thread.sleep(1000);
420
421         // backup should not even start doing real work before the
422
// unlogged transaction is commited
423
if(!backup.isRunning())
424             logMessage("Backup is not waiting for unlogged " +
425                        "index action to commit");
426
427
428         // remove another jar file , this one should block and
429
// should not get into the backup. Backup does not allow new
430
// jar operation if it is already waiting for backup blocking
431
// to complete(commit/rollback).
432

433         AsyncStatementThread asyncJarActionThread =
434             new AsyncStatementThread(conn2,
435           "call sqlj.remove_jar('APP.customer_app', 0)");
436         asyncJarActionThread.start();
437         logMessage("Started obtest_customer.jar remove in seperate thread");
438
439         //sleep for few seconds to give a chance for the
440
//jar addition thread to get into action.
441
java.lang.Thread.sleep(1000);
442
443         //roll back the index op. Backup should proceed now.
444
conn1.rollback();
445         logMessage("The transaction that was blocking the backup has ended");
446         // wait for backup to finish.
447
backup.waitForBackupToEnd();
448         backupThread.join();
449         logMessage("Backup-4 Completed");
450
451         // wait for customer app jar removal to finish now.
452
asyncJarActionThread.join();
453         logMessage("obtest_customer.jar remove is complete");
454         
455         //this insert should not apprear on restore.
456
conn1_stmt.execute("insert into t1 values(13)");
457
458         logMessage("No of rows in table t1: " + countRows(conn1, "T1"));
459         logMessage("No of rows in table customer: " +
460                    countRows(conn1, "customer"));
461         conn1.commit();
462         conn2.commit();
463         conn1_stmt.close();
464         conn2_stmt.close();
465         conn1.close();
466         conn2.close();
467         
468         //shutdown the test db
469
shutdown(TEST_DATABASE_NAME);
470         // restore the database from the backup and run some checks
471
backup.restoreFromBackup();
472         logMessage("Restored From the Backup");
473         Connection JavaDoc conn = TestUtil.getConnection(TEST_DATABASE_NAME, null);
474         Statement JavaDoc stmt = conn.createStatement();
475         logMessage("No of rows in table t1: " + countRows(conn, "T1"));
476         logMessage("No of rows in table customer: " +
477                    countRows(conn, "customer"));
478
479         // check if the jar removal was successful.
480
// APP.math_routines should not be in backup.
481
try {
482             // set the database class path with the jar removed above,
483
// it should fail.
484
stmt.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY( " +
485                            "'derby.database.classpath', " +
486                            "'APP.math_routines') " ) ;
487         }catch (SQLException JavaDoc sqle) {
488             //above statement should have failed.
489
org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(System.out, sqle);
490         }
491         
492
493         stmt.close();
494         conn.close();
495
496         //shutdown the test db
497
shutdown(TEST_DATABASE_NAME);
498         logMessage("End Of Remove Jar Test.");
499
500     }
501
502
503     /*
504      * Run a sql statement in a seperate thread.
505      */

506     class AsyncStatementThread extends Thread JavaDoc {
507         Connection JavaDoc conn;
508         String JavaDoc stmt;
509     
510         AsyncStatementThread(Connection JavaDoc conn, String JavaDoc stmt) {
511             this.conn = conn;
512             this.stmt = stmt;
513         }
514
515         public void run() {
516             Statement JavaDoc aStatement = null;
517             try {
518                 aStatement = conn.createStatement();
519                 aStatement.execute(stmt);
520                 aStatement.close();
521                 // commit here, it is possible that
522
// this thread may have got into action
523
// before the backup went into wait state.
524
conn.commit();
525             } catch (SQLException JavaDoc sqle) {
526                 org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(System.out, sqle);
527                 sqle.printStackTrace(System.out);
528             }
529             aStatement = null;
530         }
531     }
532
533 }
534
Popular Tags