modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/rbu/rbucrash.test (about)

     1  # 2014 October 22
     2  #
     3  # The author disclaims copyright to this source code.  In place of
     4  # a legal notice, here is a blessing:
     5  #
     6  #    May you do good and not evil.
     7  #    May you find forgiveness for yourself and forgive others.
     8  #    May you share freely, never taking more than you give.
     9  #
    10  #***********************************************************************
    11  #
    12  
    13  if {![info exists testdir]} {
    14    set testdir [file join [file dirname [info script]] .. .. test]
    15  }
    16  source $testdir/tester.tcl
    17  set ::testprefix rbucrash
    18  
    19  db close
    20  forcedelete test.db-oal rbu.db
    21  sqlite3_shutdown
    22  sqlite3_config_uri 1
    23  reset_db
    24  
    25  # Set up a target database and an rbu update database. The target
    26  # db is the usual "test.db", the rbu db is "test.db2".
    27  #
    28  forcedelete test.db2
    29  do_execsql_test 1.0 {
    30    CREATE TABLE t1(a, b, c, PRIMARY KEY(a), UNIQUE(b));
    31    INSERT INTO t1 VALUES(1, 2, 3);
    32    INSERT INTO t1 VALUES(4, 5, 6);
    33    INSERT INTO t1 VALUES(7, 8, 9);
    34  
    35    ATTACH 'test.db2' AS rbu;
    36    CREATE TABLE rbu.data_t1(a, b, c, rbu_control);
    37    INSERT INTO data_t1 VALUES(10, 11, 12, 0);
    38    INSERT INTO data_t1 VALUES(13, 14, 15, 0);
    39    INSERT INTO data_t1 VALUES(4, NULL, NULL, 1);
    40    INSERT INTO data_t1 VALUES(1, NULL, 100, '..x');
    41  }
    42  db_save_and_close
    43  
    44  
    45  # Determine the number of steps in applying the rbu update to the test
    46  # target database created above. Set $::rbu_num_steps accordingly
    47  #
    48  # Check that the same number of steps are required to apply the rbu
    49  # update using many calls to sqlite3rbu_step() on a single rbu handle
    50  # as required to apply it using a series of rbu handles, on each of 
    51  # which sqlite3rbu_step() is called once.
    52  #
    53  do_test 1.1 {
    54    db_restore
    55    sqlite3rbu rbu test.db test.db2
    56    set nStep 0
    57    while {[rbu step]=="SQLITE_OK"} { incr nStep }
    58    rbu close
    59  } {SQLITE_DONE}
    60  set rbu_num_steps $nStep
    61  do_test 1.2 {
    62    db_restore
    63    set nStep 0
    64    while {1} {
    65      sqlite3rbu rbu test.db test.db2
    66      rbu step
    67      if {[rbu close]=="SQLITE_DONE"} break
    68      incr nStep
    69    }
    70    set nStep
    71  } $rbu_num_steps
    72  
    73  
    74  # Run one or more tests using the target (test.db) and rbu (test.db2)
    75  # databases created above. As follows:
    76  #
    77  #   1. This process starts the rbu update and calls sqlite3rbu_step()
    78  #      $nPre times. Then closes the rbu update handle.
    79  #
    80  #   2. A second process resumes the rbu update and attempts to call 
    81  #      sqlite3rbu_step() $nStep times before closing the handle. A
    82  #      crash is simulated during each xSync() of file test.db2.
    83  #
    84  #   3. This process attempts to resume the rbu update from whatever
    85  #      state it was left in by step (2). Test that it is successful
    86  #      in doing so and that the final target database is as expected.
    87  #
    88  # In total (nSync+1) tests are run, where nSync is the number of times
    89  # xSync() is called on test.db2.
    90  #
    91  proc do_rbu_crash_test {tn nPre nStep} {
    92  
    93    set script [subst -nocommands {
    94      sqlite3rbu rbu test.db file:test.db2?vfs=crash
    95      set i 0
    96      while {[set i] < $nStep} {
    97        if {[rbu step]!="SQLITE_OK"} break
    98        incr i
    99      }
   100      rbu close
   101    }]
   102  
   103    set bDone 0
   104    for {set iDelay 1} {$bDone==0} {incr iDelay} {
   105      forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal
   106      db_restore
   107  
   108      if {$nPre>0} {
   109        sqlite3rbu rbu test.db file:test.db2
   110        set i 0
   111        for {set i 0} {$i < $nPre} {incr i} { 
   112          if {[rbu step]!="SQLITE_OK"} break
   113        }
   114        rbu close
   115      }
   116  
   117      set res [
   118        crashsql -file test.db2 -delay $iDelay -tclbody $script -opendb {} {}
   119      ]
   120  
   121      set bDone 1
   122      if {$res == "1 {child process exited abnormally}"} {
   123        set bDone 0
   124      } elseif {$res != "0 {}"} {
   125        error "unexected catchsql result: $res"
   126      }
   127  
   128      sqlite3rbu rbu test.db test.db2
   129      while {[rbu step]=="SQLITE_OK"} {}
   130      rbu close
   131  
   132      sqlite3 db test.db
   133      do_execsql_test $tn.delay=$iDelay {
   134        SELECT * FROM t1;
   135        PRAGMA integrity_check;
   136      } {1 2 100  7 8 9  10 11 12  13 14 15  ok}
   137      db close
   138    }
   139  }
   140  
   141  for {set nPre 0} {$nPre < $rbu_num_steps} {incr nPre} {
   142    for {set is 1} {$is <= ($rbu_num_steps - $nPre)} {incr is} {
   143      do_rbu_crash_test 2.pre=$nPre.step=$is $nPre $is
   144    }
   145  }
   146  
   147  finish_test
   148