1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/crashtest1.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,96 @@
1.4 +/*
1.5 +** This program tests the ability of SQLite database to recover from a crash.
1.6 +** This program runs under Unix only, but the results are applicable to all
1.7 +** systems.
1.8 +**
1.9 +** The main process first constructs a test database, then starts creating
1.10 +** subprocesses that write to that database. Each subprocess is killed off,
1.11 +** without a chance to clean up its database connection, after a random
1.12 +** delay. This killing of the subprocesses simulates a crash or power
1.13 +** failure. The next subprocess to open the database should rollback
1.14 +** whatever operation was in process at the time of the simulated crash.
1.15 +**
1.16 +** If any problems are encountered, an error is reported and the test stops.
1.17 +** If no problems are seen after a large number of tests, we assume that
1.18 +** the rollback mechanism is working.
1.19 +*/
1.20 +#include <stdio.h>
1.21 +#include <unistd.h>
1.22 +#include <sys/types.h>
1.23 +#include <sys/wait.h>
1.24 +#include <signal.h>
1.25 +#include <stdlib.h>
1.26 +#include <string.h>
1.27 +#include <sched.h>
1.28 +#include "sqlite.h"
1.29 +
1.30 +static void do_some_sql(int parent){
1.31 + char *zErr;
1.32 + int rc = SQLITE_OK;
1.33 + sqlite *db;
1.34 + int cnt = 0;
1.35 + static char zBig[] =
1.36 + "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
1.37 + "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1.38 +
1.39 + if( access("./test.db-journal",0)==0 ){
1.40 + /*printf("pid %d: journal exists. rollback will be required\n",getpid());*/ unlink("test.db-saved");
1.41 + system("cp test.db test.db-saved");
1.42 + unlink("test.db-journal-saved");
1.43 + system("cp test.db-journal test.db-journal-saved");
1.44 + }
1.45 + db = sqlite_open("./test.db", 0, &zErr);
1.46 + if( db==0 ){
1.47 + printf("ERROR: %s\n", zErr);
1.48 + if( strcmp(zErr,"database disk image is malformed")==0 ){
1.49 + kill(parent, SIGKILL);
1.50 + }
1.51 + exit(1);
1.52 + }
1.53 + srand(getpid());
1.54 + while( rc==SQLITE_OK ){
1.55 + cnt++;
1.56 + rc = sqlite_exec_printf(db,
1.57 + "INSERT INTO t1 VALUES(%d,'%d%s')", 0, 0, &zErr,
1.58 + rand(), rand(), zBig);
1.59 + }
1.60 + if( rc!=SQLITE_OK ){
1.61 + printf("ERROR #%d: %s\n", rc, zErr);
1.62 + if( rc==SQLITE_CORRUPT ){
1.63 + kill(parent, SIGKILL);
1.64 + }
1.65 + }
1.66 + printf("pid %d: cnt=%d\n", getpid(), cnt);
1.67 +}
1.68 +
1.69 +
1.70 +int main(int argc, char **argv){
1.71 + int i;
1.72 + sqlite *db;
1.73 + char *zErr;
1.74 + int status;
1.75 + int parent = getpid();
1.76 +
1.77 + unlink("test.db");
1.78 + unlink("test.db-journal");
1.79 + db = sqlite_open("test.db", 0, &zErr);
1.80 + if( db==0 ){
1.81 + printf("Cannot initialize: %s\n", zErr);
1.82 + return 1;
1.83 + }
1.84 + sqlite_exec(db, "CREATE TABLE t1(a,b)", 0, 0, 0);
1.85 + sqlite_close(db);
1.86 + for(i=0; i<10000; i++){
1.87 + int pid = fork();
1.88 + if( pid==0 ){
1.89 + sched_yield();
1.90 + do_some_sql(parent);
1.91 + return 0;
1.92 + }
1.93 + printf("test %d, pid=%d\n", i, pid);
1.94 + usleep(rand()%10000 + 1000);
1.95 + kill(pid, SIGKILL);
1.96 + waitpid(pid, &status, 0);
1.97 + }
1.98 + return 0;
1.99 +}