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

     1  # 2018 July 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  #
    12  
    13  set testdir [file dirname $argv0]
    14  source $testdir/tester.tcl
    15  source $testdir/lock_common.tcl
    16  source $testdir/wal_common.tcl
    17  ifcapable !wal {finish_test ; return }
    18  
    19  set testprefix walprotocol2
    20  
    21  #-------------------------------------------------------------------------
    22  # When recovering the contents of a WAL file, a process obtains the WRITER
    23  # lock, then locks all other bytes before commencing recovery. If it fails
    24  # to lock all other bytes (because some other process is holding a read
    25  # lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the 
    26  # caller. Test this (test case 1.3).
    27  #
    28  # Also test the effect of hitting an SQLITE_BUSY while attempting to obtain
    29  # the WRITER lock (should be the same). Test case 1.4.
    30  # 
    31  do_execsql_test 1.0 {
    32    PRAGMA journal_mode = wal;
    33    CREATE TABLE x(y);
    34    INSERT INTO x VALUES('z');
    35  } {wal}
    36  
    37  db close
    38  
    39  proc lock_callback {method filename handle lock} {
    40    # puts "$method $filename $handle $lock"
    41  }
    42  testvfs T
    43  T filter xShmLock 
    44  T script lock_callback
    45  
    46  sqlite3 db  test.db -vfs T
    47  sqlite3 db2 test.db -vfs T
    48  
    49  do_execsql_test 2.0 {
    50    SELECT * FROM x;
    51  } {z}
    52  do_execsql_test -db db2 2.1 {
    53    SELECT * FROM x;
    54  } {z}
    55  
    56  #---------------------------------------------------------------
    57  # Attempt a "BEGIN EXCLUSIVE" using connection handle [db]. This
    58  # causes SQLite to open a read transaction, then a write transaction.
    59  # Rig the xShmLock() callback so that just before the EXCLUSIVE lock
    60  # for the write transaction is taken, connection [db2] jumps in and
    61  # modifies the database. This causes the "BEGIN EXCLUSIVE" to throw
    62  # an SQLITE_BUSY_SNAPSHOT error.
    63  #
    64  proc lock_callback {method filename handle lock} {
    65    if {$lock=="0 1 lock exclusive"} {
    66      proc lock_callback {method filename handle lock} {}
    67      db2 eval { INSERT INTO x VALUES('y') }
    68    }
    69  }
    70  do_catchsql_test 2.2 {
    71    BEGIN EXCLUSIVE;
    72  } {1 {database is locked}}
    73  do_test 2.3 {
    74    sqlite3_extended_errcode db
    75  } {SQLITE_BUSY}
    76  
    77  #---------------------------------------------------------------
    78  # Same again, but with a busy-handler. This time, following the
    79  # SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 
    80  # whole thing retried from the beginning. This time it succeeds.
    81  #
    82  proc lock_callback {method filename handle lock} {
    83    if {$lock=="0 1 lock exclusive"} {
    84      proc lock_callback {method filename handle lock} {}
    85      db2 eval { INSERT INTO x VALUES('x') }
    86    }
    87  }
    88  db timeout 10
    89  do_catchsql_test 2.4 {
    90    BEGIN EXCLUSIVE;
    91  } {0 {}}
    92  do_execsql_test 2.5 {
    93    SELECT * FROM x;
    94    COMMIT;
    95  } {z y x}
    96  
    97  finish_test