persistentstorage/sqlite3api/TEST/TclScript/lock2.test
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 # 2001 September 15
       
     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 database locks between competing processes.
       
    13 #
       
    14 # $Id: lock2.test,v 1.9 2007/12/13 21:54:11 drh Exp $
       
    15 
       
    16 
       
    17 set testdir [file dirname $argv0]
       
    18 source $testdir/tester.tcl
       
    19 
       
    20 # Launch another testfixture process to be controlled by this one. A
       
    21 # channel name is returned that may be passed as the first argument to proc
       
    22 # 'testfixture' to execute a command. The child testfixture process is shut
       
    23 # down by closing the channel.
       
    24 proc launch_testfixture {} {
       
    25   set prg [info nameofexec]
       
    26   if {$prg eq ""} {
       
    27     set prg [file join . testfixture]
       
    28   }
       
    29   set chan [open "|$prg tf_main.tcl" r+]
       
    30   fconfigure $chan -buffering line
       
    31   return $chan
       
    32 }
       
    33 
       
    34 # Execute a command in a child testfixture process, connected by two-way
       
    35 # channel $chan. Return the result of the command, or an error message.
       
    36 proc testfixture {chan cmd} {
       
    37   puts $chan $cmd
       
    38   puts $chan OVER
       
    39   set r ""
       
    40   while { 1 } {
       
    41     set line [gets $chan]
       
    42     if { $line == "OVER" } { 
       
    43       return $r
       
    44     }
       
    45     append r $line
       
    46   }
       
    47 }
       
    48 
       
    49 # Write the main loop for the child testfixture processes into file
       
    50 # tf_main.tcl. The parent (this script) interacts with the child processes
       
    51 # via a two way pipe. The parent writes a script to the stdin of the child
       
    52 # process, followed by the word "OVER" on a line of its own. The child
       
    53 # process evaluates the script and writes the results to stdout, followed
       
    54 # by an "OVER" of its own.
       
    55 set f [open tf_main.tcl w]
       
    56 puts $f {
       
    57   set l [open log w]
       
    58   set script ""
       
    59   while {![eof stdin]} {
       
    60     flush stdout
       
    61     set line [gets stdin]
       
    62     puts $l "READ $line"
       
    63     if { $line == "OVER" } {
       
    64       catch {eval $script} result
       
    65       puts $result
       
    66       puts $l "WRITE $result"
       
    67       puts OVER
       
    68       puts $l "WRITE OVER"
       
    69       flush stdout
       
    70       set script ""
       
    71     } else {
       
    72       append script $line
       
    73       append script " ; "
       
    74     }
       
    75   }
       
    76   close $l
       
    77 }
       
    78 close $f
       
    79 
       
    80 # Simple locking test case:
       
    81 #
       
    82 # lock2-1.1: Connect a second process to the database.
       
    83 # lock2-1.2: Establish a RESERVED lock with this process.
       
    84 # lock2-1.3: Get a SHARED lock with the second process.
       
    85 # lock2-1.4: Try for a RESERVED lock with process 2. This fails.
       
    86 # lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so
       
    87 #            it gets PENDING.
       
    88 # lock2-1.6: Release the SHARED lock held by the second process. 
       
    89 # lock2-1.7: Attempt to reaquire a SHARED lock with the second process.
       
    90 #            this fails due to the PENDING lock.
       
    91 # lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE.
       
    92 #
       
    93 do_test lock2-1.1 {
       
    94   set ::tf1 [launch_testfixture]
       
    95   testfixture $::tf1 "set sqlite_pending_byte $::sqlite_pending_byte"
       
    96   testfixture $::tf1 {
       
    97     sqlite3 db test.db -key xyzzy
       
    98     db eval {select * from sqlite_master}
       
    99   }
       
   100 } {}
       
   101 do_test lock2-1.1.1 {
       
   102   execsql {pragma lock_status}
       
   103 } {main unlocked temp closed}
       
   104 sqlite3_soft_heap_limit 0
       
   105 do_test lock2-1.2 {
       
   106   execsql {
       
   107     BEGIN;
       
   108     CREATE TABLE abc(a, b, c);
       
   109   }
       
   110 } {}
       
   111 do_test lock2-1.3 {
       
   112   testfixture $::tf1 {
       
   113     db eval {
       
   114       BEGIN;
       
   115       SELECT * FROM sqlite_master;
       
   116     }
       
   117   }
       
   118 } {}
       
   119 do_test lock2-1.4 {
       
   120   testfixture $::tf1 {
       
   121     db eval {
       
   122       CREATE TABLE def(d, e, f)
       
   123     }
       
   124   }
       
   125 } {database is locked}
       
   126 do_test lock2-1.5 {
       
   127   catchsql {
       
   128     COMMIT;
       
   129   }
       
   130 } {1 {database is locked}}
       
   131 do_test lock2-1.6 {
       
   132   testfixture $::tf1 {
       
   133     db eval {
       
   134       SELECT * FROM sqlite_master;
       
   135       COMMIT;
       
   136     }
       
   137   }
       
   138 } {}
       
   139 do_test lock2-1.7 {
       
   140   testfixture $::tf1 {
       
   141     db eval {
       
   142       BEGIN;
       
   143       SELECT * FROM sqlite_master;
       
   144     }
       
   145   }
       
   146 } {database is locked}
       
   147 do_test lock2-1.8 {
       
   148   catchsql {
       
   149     COMMIT;
       
   150   }
       
   151 } {0 {}}
       
   152 do_test lock2-1.9 {
       
   153   execsql {
       
   154     SELECT * FROM sqlite_master;
       
   155   }
       
   156 } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}"
       
   157 do_test lock2-1.10 {
       
   158   testfixture $::tf1 {
       
   159     db eval {
       
   160       SELECT * FROM sqlite_master;
       
   161     }
       
   162   }
       
   163 } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}"
       
   164 
       
   165 catch {testfixture $::tf1 {db close}}
       
   166 catch {close $::tf1}
       
   167 sqlite3_soft_heap_limit $soft_limit
       
   168 
       
   169 finish_test