github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/multiplex3.test (about)

     1  
     2  # 2011 December 13
     3  #
     4  # The author disclaims copyright to this source code.  In place of
     5  # a legal notice, here is a blessing:
     6  #
     7  #    May you do good and not evil.
     8  #    May you find forgiveness for yourself and forgive others.
     9  #    May you share freely, never taking more than you give.
    10  #
    11  #***********************************************************************
    12  #
    13  # This file contains tests for error (IO, OOM etc.) handling when using
    14  # the multiplexor extension with 8.3 filenames.
    15  #
    16  
    17  set testdir [file dirname $argv0]
    18  source $testdir/tester.tcl
    19  source $testdir/malloc_common.tcl
    20  set ::testprefix multiplex3
    21  
    22  ifcapable !8_3_names {
    23    puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. "
    24    puts            "Skipping tests multiplex3-*."
    25    finish_test
    26    return
    27  }
    28  
    29  db close
    30  sqlite3_shutdown
    31  sqlite3_config_uri 1
    32  autoinstall_test_functions
    33  
    34  sqlite3_multiplex_initialize "" 1
    35  
    36  proc destroy_vfs_stack {} {
    37    generic_unregister stack
    38    sqlite3_multiplex_shutdown
    39  }
    40  
    41  proc multiplex_delete_db {} {
    42    forcedelete test.db
    43    for {set i 1} {$i <= 1000} {incr i} {
    44      forcedelete test.[format %03d $i]
    45    }
    46  }
    47  
    48  # Procs to save and restore the current muliplexed database.
    49  #
    50  proc multiplex_save_db {} {
    51    foreach f [glob -nocomplain sv_test.*] { forcedelete $f }
    52    foreach f [glob -nocomplain test.*]    { forcecopy $f "sv_$f" }
    53  }
    54  proc multiplex_restore_db {} {
    55    foreach f [glob -nocomplain test.*]    {forcedelete $f}
    56    foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} }
    57  
    58  proc setup_and_save_db {} {
    59    multiplex_delete_db
    60    sqlite3 db file:test.db?8_3_names=1
    61    sqlite3_multiplex_control db main chunk_size [expr 256*1024]
    62    execsql {
    63      CREATE TABLE t1(a PRIMARY KEY, b);
    64      INSERT INTO t1 VALUES(randomblob(15), randomblob(2000));
    65      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   2
    66      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   4
    67      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   8
    68      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  16
    69      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  32
    70      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  64
    71      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 128
    72      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 256
    73      INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 512
    74    }
    75    set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
    76    db close
    77    multiplex_save_db
    78  }
    79  
    80  do_test 1.0 { setup_and_save_db } {}
    81  do_faultsim_test 1 -prep {
    82    multiplex_restore_db
    83    sqlite3 db file:test.db?8_3_names=1
    84    sqlite3_multiplex_control db main chunk_size [expr 256*1024]
    85  } -body {
    86    execsql {
    87      UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0
    88    }
    89  } -test {
    90    faultsim_test_result {0 {}}
    91    if {$testrc!=0} {
    92      set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
    93      if {$cksum2 != $::cksum1} { error "data mismatch" }
    94    }
    95  }
    96  
    97  #-------------------------------------------------------------------------
    98  # The following tests verify that hot-journal rollback works. As follows:
    99  #
   100  #   1. Create a large database.
   101  #   2. Set the pager cache to be very small.
   102  #   3. Open a transaction. 
   103  #   4. Run the following 100 times:
   104  #      a. Update a row.
   105  #      b. Copy all files on disk to a new db location, including the journal.
   106  #      c. Verify that the new db can be opened and that the content matches
   107  #         the database created in step 1 (proving the journal was rolled
   108  #         back).
   109  
   110  do_test 2.0 { 
   111    setup_and_save_db
   112    multiplex_restore_db
   113    sqlite3 db file:test.db?8_3_names=1
   114    execsql { PRAGMA cache_size = 10 }
   115    execsql { BEGIN }
   116  } {}
   117  
   118  for {set iTest 1} {$iTest<=100} {incr iTest} {
   119    do_test 2.$iTest {
   120      execsql { 
   121        UPDATE t1 SET a=randomblob(12), b=randomblob(1400) WHERE rowid=5*$iTest
   122      }
   123      foreach f [glob -nocomplain test.*] {forcecopy $f "xx_$f"}
   124      sqlite3 db2 file:xx_test.db?8_3_names=1
   125      execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a} db2
   126    } $::cksum1
   127  
   128    db2 close
   129  }
   130  catch { db close }
   131  
   132  
   133  do_test 3.0 { setup_and_save_db } {}
   134  do_faultsim_test 3 -faults ioerr-trans* -prep {
   135  
   136    forcedelete test2.db
   137    set fd [open test2.wal w]
   138    seek $fd 4095
   139    puts -nonewline $fd x
   140    close $fd
   141  
   142    multiplex_restore_db
   143    sqlite3 db file:test.db?8_3_names=1
   144    sqlite3 db2 file:test2.db?8_3_names=1
   145    sqlite3_multiplex_control db main chunk_size [expr 256*1024]
   146    sqlite3_multiplex_control db2 main chunk_size [expr 256*1024]
   147  } -body {
   148    sqlite3_backup B db2 main db main
   149    B step 100000
   150    set rc [B finish]
   151    if { [string match SQLITE_IOERR_* $rc] } {error "disk I/O error"}
   152    set rc
   153  } -test {
   154    faultsim_test_result {0 SQLITE_OK}
   155    if {$testrc==0} {
   156      set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a} db2]
   157      if {$cksum2 != $::cksum1} { error "data mismatch" }
   158    }
   159    catch { B finish }
   160    catch { db close }
   161    catch { db2 close }
   162  }
   163  
   164  catch { db close }
   165  sqlite3_multiplex_shutdown
   166  finish_test