modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/walprotocol.test (about)

     1  # 2016 February 4
     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 file is testing the operation of the library in
    13  # "PRAGMA journal_mode=WAL" mode.
    14  #
    15  # More specifically, it tests "locking protocol" errors - errors that
    16  # may be caused if one or more SQLite clients does not follow the expected
    17  # locking protocol when accessing a wal-mode database. These tests take
    18  # quite a while to run.
    19  #
    20  
    21  set testdir [file dirname $argv0]
    22  source $testdir/tester.tcl
    23  source $testdir/lock_common.tcl
    24  source $testdir/wal_common.tcl
    25  ifcapable !wal {finish_test ; return }
    26  
    27  set testprefix walprotocol
    28  
    29  #-------------------------------------------------------------------------
    30  # When recovering the contents of a WAL file, a process obtains the WRITER
    31  # lock, then locks all other bytes before commencing recovery. If it fails
    32  # to lock all other bytes (because some other process is holding a read
    33  # lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the 
    34  # caller. Test this (test case 1.3).
    35  #
    36  # Also test the effect of hitting an SQLITE_BUSY while attempting to obtain
    37  # the WRITER lock (should be the same). Test case 1.4.
    38  # 
    39  do_execsql_test 1.0 {
    40    PRAGMA journal_mode = wal;
    41    CREATE TABLE x(y);
    42    INSERT INTO x VALUES('z');
    43  } {wal}
    44  
    45  proc lock_callback {method filename handle lock} {
    46    lappend ::locks $lock
    47  }
    48  do_test 1.1 {
    49    testvfs T
    50    T filter xShmLock 
    51    T script lock_callback
    52    set ::locks [list]
    53    sqlite3 db test.db -vfs T
    54    execsql { SELECT * FROM x }
    55    lrange $::locks 0 3
    56  } [list {0 1 lock exclusive} {1 7 lock exclusive}      \
    57          {1 7 unlock exclusive} {0 1 unlock exclusive}  \
    58  ]
    59  do_test 1.2 {
    60    db close
    61    set ::locks [list]
    62    sqlite3 db test.db -vfs T
    63    execsql { SELECT * FROM x }
    64    lrange $::locks 0 3
    65  } [list {0 1 lock exclusive} {1 7 lock exclusive}      \
    66          {1 7 unlock exclusive} {0 1 unlock exclusive}  \
    67  ]
    68  proc lock_callback {method filename handle lock} {
    69    if {$lock == "1 7 lock exclusive"} { return SQLITE_BUSY }
    70    return SQLITE_OK
    71  }
    72  puts "# Warning: This next test case causes SQLite to call xSleep(1) 100 times."
    73  puts "# Normally this equates to a delay of roughly 10 seconds, but if SQLite"
    74  puts "# is built on unix without HAVE_USLEEP defined, it may be much longer."
    75  do_test 1.3 {
    76    db close
    77    set ::locks [list]
    78    sqlite3 db test.db -vfs T
    79    catchsql { SELECT * FROM x }
    80  } {1 {locking protocol}}
    81  
    82  puts "# Warning: Same again!"
    83  proc lock_callback {method filename handle lock} {
    84    if {$lock == "0 1 lock exclusive"} { return SQLITE_BUSY }
    85    return SQLITE_OK
    86  }
    87  do_test 1.4 {
    88    db close
    89    set ::locks [list]
    90    sqlite3 db test.db -vfs T
    91    catchsql { SELECT * FROM x }
    92  } {1 {locking protocol}}
    93  db close
    94  T delete
    95  
    96  #-------------------------------------------------------------------------
    97  # 
    98  do_test 2.1 {
    99    forcedelete test.db test.db-journal test.db wal
   100    sqlite3 db test.db
   101    sqlite3 db2 test.db
   102    execsql {
   103      PRAGMA auto_vacuum = off;
   104      PRAGMA journal_mode = WAL;
   105      CREATE TABLE b(c);
   106      INSERT INTO b VALUES('Tehran');
   107      INSERT INTO b VALUES('Qom');
   108      INSERT INTO b VALUES('Markazi');
   109      PRAGMA wal_checkpoint;
   110    }
   111  } {wal 0 5 5}
   112  do_test 2.2 {
   113    execsql { SELECT * FROM b }
   114  } {Tehran Qom Markazi}
   115  do_test 2.3 {
   116    db eval { SELECT * FROM b } {
   117      db eval { INSERT INTO b VALUES('Qazvin') }
   118      set r [db2 eval { SELECT * FROM b }]
   119      break
   120    }
   121    set r
   122  } {Tehran Qom Markazi Qazvin}
   123  do_test 2.4 {
   124    execsql {
   125      INSERT INTO b VALUES('Gilan');
   126      INSERT INTO b VALUES('Ardabil');
   127    }
   128  } {}
   129  db2 close
   130  
   131  faultsim_save_and_close
   132  testvfs T -default 1
   133  faultsim_restore_and_reopen
   134  T filter xShmLock
   135  T script lock_callback
   136  
   137  proc lock_callback {method file handle spec} {
   138    if {$spec == "1 7 unlock exclusive"} {
   139      T filter {}
   140      set ::r [catchsql { SELECT * FROM b } db2]
   141    }
   142  }
   143  sqlite3 db test.db
   144  sqlite3 db2 test.db
   145  do_test 2.5 {
   146    execsql { SELECT * FROM b }
   147  } {Tehran Qom Markazi Qazvin Gilan Ardabil}
   148  do_test 2.6 {
   149    set ::r
   150  } {1 {locking protocol}}
   151  
   152  db close
   153  db2 close
   154  
   155  faultsim_restore_and_reopen
   156  sqlite3 db2 test.db
   157  T filter xShmLock
   158  T script lock_callback
   159  proc lock_callback {method file handle spec} {
   160    if {$spec == "1 7 unlock exclusive"} {
   161      T filter {}
   162      set ::r [catchsql { SELECT * FROM b } db2]
   163    }
   164  }
   165  unset ::r
   166  do_test 2.7 {
   167    execsql { SELECT * FROM b }
   168  } {Tehran Qom Markazi Qazvin Gilan Ardabil}
   169  do_test 2.8 {
   170    set ::r
   171  } {1 {locking protocol}}
   172  
   173  db close
   174  db2 close
   175  T delete
   176  
   177  finish_test