gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/interrupt2.test (about)

     1  # 2016 Aug 12
     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  # This file implements regression tests for SQLite library.  The
    12  # focus of this script is using the sqlite_interrupt() API to 
    13  # interrupt WAL checkpoint operations.
    14  #
    15  
    16  set testdir [file dirname $argv0]
    17  source $testdir/tester.tcl
    18  source $testdir/wal_common.tcl
    19  set testprefix interrupt2
    20  
    21  if {[permutation]=="journaltest" || [permutation]=="inmemory_journal"} {
    22    finish_test
    23    return
    24  }
    25  
    26  db close
    27  testvfs tvfs -default 1
    28  
    29  tvfs filter xWrite
    30  tvfs script write_cb
    31  
    32  set ::trigger_interrupt 0
    33  proc write_cb {method args} {
    34    set filename [lindex $args 0]
    35    if {[file tail $filename]=="test.db" && $::trigger_interrupt} {
    36      if {$::trigger_interrupt} {
    37        incr ::trigger_interrupt -1
    38        if {$::trigger_interrupt==0} { sqlite3_interrupt db }
    39      }
    40    }
    41    return 0
    42  }
    43  
    44  sqlite3 db test.db 
    45  do_execsql_test 1.0 {
    46    CREATE TABLE t1(a, b);
    47    CREATE INDEX t1a ON t1(a);
    48    CREATE INDEX t1b ON t1(b);
    49    PRAGMA journal_mode = wal;
    50  
    51    WITH ii(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM ii WHERE i<1000 )
    52    INSERT INTO t1 SELECT i, i FROM ii;
    53  } {wal}
    54  
    55  foreach idelay {
    56    5
    57    10
    58    15
    59    20
    60  } {
    61  
    62    set ::trigger_interrupt $idelay
    63    do_catchsql_test 1.$idelay.1 { PRAGMA wal_checkpoint; } {1 interrupted}
    64    do_execsql_test  1.$idelay.2 { SELECT count(*) FROM t1 } 1000
    65  
    66    set ::trigger_interrupt $idelay
    67    do_test 1.$idelay.3 { 
    68      list [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] $msg
    69    } {1 {SQLITE_INTERRUPT - interrupted}}
    70    do_execsql_test  1.$idelay.4 { SELECT count(*) FROM t1 } 1000
    71  }
    72  
    73  #-------------------------------------------------------------------------
    74  # Check that if there are other SQL statements running, a checkpoint does
    75  # not clear the isInterrupted flag.
    76  #
    77  do_execsql_test 2.0 {
    78    CREATE TEMP TABLE z1(a, b);
    79    INSERT INTO z1 SELECT * FROM t1;
    80  }
    81  
    82  do_test 2.1 {
    83    set i 10
    84    set res [list [catch {
    85      set i 10
    86      db eval {SELECT * FROM z1} {
    87        incr i -1
    88        if {$i==0} {
    89          set ::trigger_interrupt 10
    90          set cres [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] 
    91          lappend cres $msg
    92        }
    93      }
    94    } msg] $msg]
    95  
    96    list $cres $res
    97  } {{1 {SQLITE_INTERRUPT - interrupted}} {1 interrupted}}
    98  
    99  do_execsql_test 2.0 {
   100    SELECT count(*) FROM t1
   101    UNION ALL
   102    SELECT count(*) FROM z1
   103  } {1000 1000}
   104  
   105  #-------------------------------------------------------------------------
   106  # Check the effect of an interrupt during sqlite3_close().
   107  #
   108  db_save_and_close
   109  
   110  db_restore_and_reopen
   111  do_test 3.1.1 {
   112    set ::trigger_interrupt 10
   113    db eval { SELECT * FROM sqlite_master }
   114    db close
   115    set {} {}
   116  } {}
   117  do_test 3.1.2 {
   118    list [file exists test.db] [file exists test.db-wal]
   119  } {1 1}
   120  
   121  db_restore_and_reopen
   122  do_test 3.2.1 {
   123    db eval { SELECT * FROM sqlite_master }
   124    db close
   125    set {} {}
   126  } {}
   127  do_test 3.2.2 {
   128    list [file exists test.db] [file exists test.db-wal]
   129  } {1 0}
   130  
   131  #-------------------------------------------------------------------------
   132  # Check the effect of an interrupt during an automatic checkpoint
   133  #
   134  db_restore_and_reopen
   135  do_test 4.0 { 
   136    execsql { PRAGMA wal_autocheckpoint = 10 }
   137    set ::trigger_interrupt 10
   138    execsql { CREATE TABLE t2(x, y) }
   139  } {}
   140  
   141  # The auto-checkpoint in test 4.0 should have been interrupted. So this
   142  # db write should cause the wal file to grow.
   143  do_test 4.1 {
   144    set nFrame1 [wal_frame_count test.db-wal 1024]
   145    execsql { CREATE TABLE t3(x, y) }
   146    set nFrame2 [wal_frame_count test.db-wal 1024]
   147    expr $nFrame2 > $nFrame1
   148  } {1}
   149  
   150  # The auto-checkpoint in test 4.0 should not have been interrupted. So 
   151  # this db write should not cause the wal file to grow.
   152  do_test 4.2 {
   153    set nFrame1 [wal_frame_count test.db-wal 1024]
   154    execsql { CREATE TABLE t4(x, y) }
   155    set nFrame2 [wal_frame_count test.db-wal 1024]
   156    expr $nFrame2 == $nFrame1
   157  } {1}
   158  
   159  finish_test