/ Check-in [efe44564]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Rationalize a common pattern in tcl test cases into proc do_multiclient_test.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: efe44564983f115017658dd8a130226366d42bab
User & Date: dan 2010-06-15 19:07:42
Context
2010-06-16
10:55
Fix a memory leak that can occur in os_unix.c if an IO error occurs within the xUnlock method. check-in: 6c5c04ee user: dan tags: trunk
2010-06-15
19:07
Rationalize a common pattern in tcl test cases into proc do_multiclient_test. check-in: efe44564 user: dan tags: trunk
18:00
Fix a problem introduced into lock2.test by the previous commit. check-in: c1c9f6fa user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to test/crash8.test.

   378    378         INSERT INTO t1 SELECT randomblob(900) FROM t1;
   379    379         INSERT INTO t1 SELECT randomblob(900) FROM t1;
   380    380         INSERT INTO t1 SELECT randomblob(900) FROM t1;
   381    381         INSERT INTO t1 SELECT randomblob(900) FROM t1;          /* 64 rows */
   382    382         BEGIN;
   383    383           UPDATE t1 SET x = randomblob(900);
   384    384       }
   385         -    file delete -force testX.db testX.db-journal
          385  +    file delete -force testX.db testX.db-journal testX.db-wal
   386    386       copy_file test.db testX.db
   387    387       copy_file test.db-journal testX.db-journal
   388    388       db close
   389    389   
   390    390       crashsql -file test.db -delay [expr ($::i%2) + 1] {
   391    391         SELECT * FROM sqlite_master;
   392    392         INSERT INTO t1 VALUES(randomblob(900));

Changes to test/lock_common.tcl.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file contains code used by several different test scripts. The
    12     12   # code in this file allows testfixture to control another process (or
    13     13   # processes) to test locking.
    14     14   #
           15  +
           16  +proc do_multiclient_test {varname script} {
           17  +
           18  +  foreach code [list {
           19  +    set ::code2_chan [launch_testfixture]
           20  +    set ::code3_chan [launch_testfixture]
           21  +    proc code2 {tcl} { testfixture $::code2_chan $tcl }
           22  +    proc code3 {tcl} { testfixture $::code3_chan $tcl }
           23  +    set tn 1
           24  +  } {
           25  +    proc code2 {tcl} { uplevel #0 $tcl }
           26  +    proc code3 {tcl} { uplevel #0 $tcl }
           27  +    set tn 2
           28  +  }] {
           29  +    faultsim_delete_and_reopen
           30  +  
           31  +    # Open connections [db2] and [db3]. Depending on which iteration this
           32  +    # is, the connections may be created in this interpreter, or in 
           33  +    # interpreters running in other OS processes. As such, the [db2] and [db3]
           34  +    # commands should only be accessed within [code2] and [code3] blocks,
           35  +    # respectively.
           36  +    #
           37  +    eval $code
           38  +    code2 { sqlite3 db2 test.db }
           39  +    code3 { sqlite3 db3 test.db }
           40  +    
           41  +    # Shorthand commands. Execute SQL using database connection [db2] or 
           42  +    # [db3]. Return the results.
           43  +    #
           44  +    proc sql1 {sql} { db eval $sql }
           45  +    proc sql2 {sql} { code2 [list db2 eval $sql] }
           46  +    proc sql3 {sql} { code3 [list db3 eval $sql] }
           47  +  
           48  +    proc csql1 {sql} { list [catch { sql1 $sql } msg] $msg }
           49  +    proc csql2 {sql} { list [catch { sql2 $sql } msg] $msg }
           50  +    proc csql3 {sql} { list [catch { sql3 $sql } msg] $msg }
           51  +
           52  +    uplevel set $varname $tn
           53  +    uplevel $script
           54  +
           55  +    code2 { db2 close }
           56  +    code3 { db3 close }
           57  +    catch { close $::code2_chan }
           58  +    catch { close $::code3_chan }
           59  +  }
           60  +}
    15     61   
    16     62   # Launch another testfixture process to be controlled by this one. A
    17     63   # channel name is returned that may be passed as the first argument to proc
    18     64   # 'testfixture' to execute a command. The child testfixture process is shut
    19     65   # down by closing the channel.
    20     66   proc launch_testfixture {} {
    21     67     set prg [info nameofexec]

Changes to test/pager1.test.

    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   source $testdir/lock_common.tcl
    16     16   source $testdir/malloc_common.tcl
    17     17   
    18         -foreach code [list {
    19         -  set ::code2_chan [launch_testfixture]
    20         -  set ::code3_chan [launch_testfixture]
    21         -  proc code2 {tcl} { testfixture $::code2_chan $tcl }
    22         -  proc code3 {tcl} { testfixture $::code3_chan $tcl }
    23         -  set tn 1
    24         -} {
    25         -  proc code2 {tcl} { uplevel #0 $tcl }
    26         -  proc code3 {tcl} { uplevel #0 $tcl }
    27         -  set tn 2
    28         -}] {
    29         -
    30         -  faultsim_delete_and_reopen
    31         -
    32         -  # Open connections [db2] and [db3]. Depending on which iteration this
    33         -  # is, the connections may be created in this interpreter, or in 
    34         -  # interpreters running in other OS processes. As such, the [db2] and [db3]
    35         -  # commands should only be accessed within [code2] and [code3] blocks,
    36         -  # respectively.
    37         -  #
    38         -  eval $code
    39         -  code2 { sqlite3 db2 test.db }
    40         -  code3 { sqlite3 db3 test.db }
    41         -  
    42         -  # Shorthand commands. Execute SQL using database connection [db2] or 
    43         -  # [db3]. Return the results.
    44         -  #
    45         -  proc sql1 {sql} { db eval $sql }
    46         -  proc sql2 {sql} { code2 [list db2 eval $sql] }
    47         -  proc sql3 {sql} { code3 [list db3 eval $sql] }
    48         -
    49         -  proc csql1 {sql} { list [catch { sql1 $sql } msg] $msg }
    50         -  proc csql2 {sql} { list [catch { sql2 $sql } msg] $msg }
    51         -  proc csql3 {sql} { list [catch { sql3 $sql } msg] $msg }
           18  +do_multiclient_test tn {
    52     19   
    53     20     # Create and populate a database table using connection [db]. Check 
    54     21     # that connections [db2] and [db3] can see the schema and content.
    55     22     #
    56     23     do_test pager1-$tn.1 {
    57     24       sql1 {
    58     25         CREATE TABLE t1(a PRIMARY KEY, b);
................................................................................
    72     39     do_test pager1-$tn.4 {
    73     40       sql1 {
    74     41         BEGIN;
    75     42           INSERT INTO t1 VALUES(3, 'three');
    76     43       }
    77     44     } {}
    78     45     do_test pager1-$tn.5 { sql2 { SELECT * FROM t1 } } {1 one 2 two}
    79         -  do_test pager1-$tn.6 { sql3 { SELECT * FROM t1 } } {1 one 2 two}
    80     46     do_test pager1-$tn.7 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three}
    81     47   
    82     48     # [db] still has an open write transaction. Check that this prevents
    83     49     # other connections (specifically [db2]) from writing to the database.
    84     50     #
    85     51     # Even if [db2] opens a transaction first, it may not write to the
    86     52     # database. After the attempt to write the db within a transaction, 
................................................................................
   179    145     # committed, all three connections can read the new content.
   180    146     #
   181    147     do_test pager1-$tn.25 { sql1 { UPDATE t1 SET a = a+10 } } {}
   182    148     do_test pager1-$tn.26 { sql1 { COMMIT } } {}
   183    149     do_test pager1-$tn.27 { sql1 { SELECT * FROM t1 } } {21 one 22 two 23 three}
   184    150     do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {21 one 22 two 23 three}
   185    151     do_test pager1-$tn.28 { sql3 { SELECT * FROM t1 } } {21 one 22 two 23 three}
   186         -
   187         -  code2 { db2 close }
   188         -  code3 { db3 close }
   189         -  catch { close $::code2_chan }
   190         -  catch { close $::code3_chan }
   191    152   }
   192    153   
   193    154   finish_test
   194    155   

Changes to test/wal.test.

    12     12   # focus of this file is testing the operation of the library in
    13     13   # "PRAGMA journal_mode=WAL" mode.
    14     14   #
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   source $testdir/lock_common.tcl
           19  +source $testdir/malloc_common.tcl
    19     20   
    20     21   ifcapable !wal {finish_test ; return }
    21     22   
    22     23   proc reopen_db {} {
    23     24     catch { db close }
    24     25     file delete -force test.db test.db-wal test.db-wal-summary
    25     26     sqlite3_wal db test.db
................................................................................
   455    456   
   456    457   #-------------------------------------------------------------------------
   457    458   # The following block of tests - wal-10.* - test that the WAL locking 
   458    459   # scheme works in simple cases. This block of tests is run twice. Once
   459    460   # using multiple connections in the address space of the current process,
   460    461   # and once with all connections except one running in external processes.
   461    462   #
   462         -foreach code [list {
   463         -  set ::code2_chan [launch_testfixture]
   464         -  set ::code3_chan [launch_testfixture]
   465         -  proc code2 {tcl} { testfixture $::code2_chan $tcl }
   466         -  proc code3 {tcl} { testfixture $::code3_chan $tcl }
   467         -  set tn 1
   468         -} {
   469         -  proc code2 {tcl} { uplevel #0 $tcl }
   470         -  proc code3 {tcl} { uplevel #0 $tcl }
   471         -  set tn 2
   472         -}] {
   473         -
   474         -  eval $code
   475         -  reopen_db
   476         -
   477         -  # Open connections [db2] and [db3]. Depending on which iteration this
   478         -  # is, the connections may be created in this interpreter, or in 
   479         -  # interpreters running in other OS processes. As such, the [db2] and [db3]
   480         -  # commands should only be accessed within [code2] and [code3] blocks,
   481         -  # respectively.
   482         -  #
   483         -  code2 { sqlite3 db2 test.db ; db2 eval { PRAGMA journal_mode = WAL } }
   484         -  code3 { sqlite3 db3 test.db ; db3 eval { PRAGMA journal_mode = WAL } }
   485         -
   486         -  # Shorthand commands. Execute SQL using database connection [db2] or 
   487         -  # [db3]. Return the results.
   488         -  #
   489         -  proc sql2 {sql} { code2 [list db2 eval $sql] }
   490         -  proc sql3 {sql} { code3 [list db3 eval $sql] }
          463  +do_multiclient_test tn {
   491    464   
   492    465     # Initialize the database schema and contents.
   493    466     #
   494    467     do_test wal-10.$tn.1 {
   495    468       execsql {
          469  +      PRAGMA journal_mode = wal;
   496    470         CREATE TABLE t1(a, b);
   497    471         INSERT INTO t1 VALUES(1, 2);
   498    472         SELECT * FROM t1;
   499    473       }
   500         -  } {1 2}
          474  +  } {wal 1 2}
   501    475   
   502    476     # Open a transaction and write to the database using [db]. Check that [db2]
   503    477     # is still able to read the snapshot before the transaction was opened.
   504    478     #
   505    479     do_test wal-10.$tn.2 {
   506    480       execsql { BEGIN; INSERT INTO t1 VALUES(3, 4); }
   507    481       sql2 {SELECT * FROM t1}
................................................................................
   688    662       sql3 { INSERT INTO t1 VALUES('e', 'f') }
   689    663       sql2 { SELECT * FROM t1 }
   690    664     } {a b c d}
   691    665     do_test wal-10.$tn.37 {
   692    666       sql2 COMMIT
   693    667       execsql { PRAGMA wal_checkpoint }
   694    668     } {}
   695         -
   696         -  catch { db close }
   697         -  catch { code2 { db2 close } }
   698         -  catch { code3 { db3 close } }
   699         -  catch { close $::code2_chan }
   700         -  catch { close $::code3_chan }
   701    669   }
   702    670   
   703    671   #-------------------------------------------------------------------------
   704    672   # This block of tests, wal-11.*, test that nothing goes terribly wrong
   705    673   # if frames must be written to the log file before a transaction is
   706    674   # committed (in order to free up memory).
   707    675   #
................................................................................
   896    864     }
   897    865     execsql { SELECT count(*) FROM t2 }
   898    866   } [expr int(pow(2, 16))]
   899    867   do_test wal-13.2.3 {
   900    868     expr [file size test.db-wal] > [log_file_size 33000 1024]
   901    869   } 1
   902    870   
   903         -foreach code [list {
   904         -  set tn 3
   905         -  proc buddy {tcl} { uplevel #0 $tcl }
   906         -} {
   907         -  set tn 4
   908         -  set ::buddy [launch_testfixture]
   909         -  proc buddy {tcl} { testfixture $::buddy $tcl }
   910         -}] {
   911         -
   912         -  eval $code
   913         -  reopen_db
          871  +do_multiclient_test tn {
          872  +  incr tn 2
   914    873   
   915    874     do_test wal-13.$tn.0 {
   916         -    buddy { sqlite3 db2 test.db }
   917         -    execsql {
          875  +    sql1 {
   918    876         PRAGMA journal_mode = WAL;
   919    877         CREATE TABLE t1(x);
   920    878         INSERT INTO t1 SELECT randomblob(800);
   921    879       }
   922         -    execsql { SELECT count(*) FROM t1 }
          880  +    sql1 { SELECT count(*) FROM t1 }
   923    881     } {1}
   924    882   
   925    883     for {set ii 1} {$ii<16} {incr ii} {
   926    884       do_test wal-13.$tn.$ii.a {
   927         -      buddy { db2 eval { INSERT INTO t1 SELECT randomblob(800) FROM t1 } }
   928         -      buddy { db2 eval { SELECT count(*) FROM t1 } }
          885  +      sql2 { INSERT INTO t1 SELECT randomblob(800) FROM t1 }
          886  +      sql2 { SELECT count(*) FROM t1 }
   929    887       } [expr (1<<$ii)]
   930    888       do_test wal-13.$tn.$ii.b {
   931         -      db eval { SELECT count(*) FROM t1 }
          889  +      sql1 { SELECT count(*) FROM t1 }
   932    890       } [expr (1<<$ii)]
   933    891       do_test wal-13.$tn.$ii.c {
   934         -      db eval { SELECT count(*) FROM t1 }
          892  +      sql1 { SELECT count(*) FROM t1 }
   935    893       } [expr (1<<$ii)]
   936    894       do_test wal-13.$tn.$ii.d {
   937         -      db eval { PRAGMA integrity_check }
          895  +      sql1 { PRAGMA integrity_check }
   938    896       } {ok}
   939    897     }
   940         -
   941         -  catch { db2 close }
   942         -  catch { close $::buddy }
   943         -  db close
   944    898   }
   945    899   
   946    900   #-------------------------------------------------------------------------
   947    901   # Check a fun corruption case has been fixed.
   948    902   #
   949    903   # The problem was that after performing a checkpoint using a connection
   950    904   # that had an out-of-date pager-cache, the next time the connection was

Changes to test/wal3.test.

   106    106     } $str
   107    107     do_test wal3-1.$i.7 {
   108    108       execsql { PRAGMA integrity_check } db2
   109    109     } {ok}
   110    110     db2 close
   111    111   }
   112    112   
   113         -db close
   114         -foreach code [list {
   115         -  proc code2 {tcl} { uplevel #0 $tcl }
   116         -  proc code3 {tcl} { uplevel #0 $tcl }
   117         -  set tn singleproc
   118         -} {
   119         -  set ::code2_chan [launch_testfixture]
   120         -  set ::code3_chan [launch_testfixture]
   121         -  proc code2 {tcl} { testfixture $::code2_chan $tcl }
   122         -  proc code3 {tcl} { testfixture $::code3_chan $tcl }
   123         -  set tn multiproc
   124         -}] {
   125         -  file delete -force test.db test.db-wal test.db-journal
   126         -  sqlite3 db test.db
   127         -  eval $code
          113  +do_multiclient_test i {
   128    114   
   129         -  # Open connections [db2] and [db3]. Depending on which iteration this
   130         -  # is, the connections may be created in this interpreter, or in 
   131         -  # interpreters running in other OS processes. As such, the [db2] and [db3]
   132         -  # commands should only be accessed within [code2] and [code3] blocks,
   133         -  # respectively.
   134         -  #
   135         -  code2 { sqlite3 db2 test.db ; db2 eval { PRAGMA journal_mode = WAL } }
   136         -  code3 { sqlite3 db3 test.db ; db3 eval { PRAGMA journal_mode = WAL } }
   137         -
   138         -  # Shorthand commands. Execute SQL using database connection [db], [db2] 
   139         -  # or [db3]. Return the results.
   140         -  #
   141         -  proc sql  {sql} { db eval $sql }
   142         -  proc sql2 {sql} { code2 [list db2 eval $sql] }
   143         -  proc sql3 {sql} { code3 [list db3 eval $sql] }
          115  +  set testname(1) multiproc
          116  +  set testname(2) singleproc
          117  +  set tn $testname($i)
   144    118   
   145    119     do_test wal3-2.$tn.1 {
   146         -    sql { 
          120  +    sql1 { 
   147    121         PRAGMA page_size = 1024;
   148    122         PRAGMA auto_vacuum = OFF; 
   149    123         PRAGMA journal_mode = WAL;
   150    124       }
   151         -    sql {
          125  +    sql1 {
   152    126         CREATE TABLE t1(a, b);
   153    127         INSERT INTO t1 VALUES(1, 'one');
   154    128         BEGIN;
   155    129           SELECT * FROM t1;
   156    130       }
   157    131     } {1 one}
   158    132     do_test wal3-2.$tn.2 {
................................................................................
   177    151     # these frames would clobber the snapshot currently being used by [db2]).
   178    152     #
   179    153     # After [db2] has committed, a checkpoint can copy the entire log to the
   180    154     # database file. Checkpointing after [db3] has committed is therefore a
   181    155     # no-op, as the entire log has already been backfilled.
   182    156     #
   183    157     do_test wal3-2.$tn.4 {
   184         -    sql {
          158  +    sql1 {
   185    159         COMMIT;
   186    160         PRAGMA wal_checkpoint;
   187    161       }
   188    162       file size test.db
   189    163     } [expr $AUTOVACUUM ? 4*1024 : 3*1024]
   190    164     do_test wal3-2.$tn.5 {
   191    165       sql2 {
................................................................................
   197    171     do_test wal3-2.$tn.6 {
   198    172       sql3 {
   199    173         COMMIT;
   200    174         PRAGMA wal_checkpoint;
   201    175       }
   202    176       file size test.db
   203    177     } [expr $AUTOVACUUM ? 5*1024 : 4*1024]
   204         -
   205         -  catch { db close }
   206         -  catch { code2 { db2 close } }
   207         -  catch { code3 { db3 close } }
   208         -  catch { close $::code2_chan }
   209         -  catch { close $::code3_chan }
   210    178   }
   211    179   catch {db close}
   212    180   
   213    181   #-------------------------------------------------------------------------
   214    182   # Test that that for the simple test:
   215    183   #
   216    184   #   CREATE TABLE x(y);