persistentstorage/sqlite3api/TEST/TclScript/pager.test
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1  # 2001 September 15
       
     2 #
       
     3 # Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
       
     4 #
       
     5 # The author disclaims copyright to this source code.  In place of
       
     6 # a legal notice, here is a blessing:
       
     7 #
       
     8 #    May you do good and not evil.
       
     9 #    May you find forgiveness for yourself and forgive others.
       
    10 #    May you share freely, never taking more than you give.
       
    11 #
       
    12 #***********************************************************************
       
    13 # This file implements regression tests for SQLite library.  The
       
    14 # focus of this script is page cache subsystem.
       
    15 #
       
    16 # $Id: pager.test,v 1.31 2008/08/20 14:49:25 danielk1977 Exp $
       
    17 
       
    18 
       
    19 set testdir [file dirname $argv0]
       
    20 source $testdir/tester.tcl
       
    21 
       
    22 if {[info commands pager_open]!=""} {
       
    23 db close
       
    24 
       
    25 # Basic sanity check.  Open and close a pager.
       
    26 #
       
    27 do_test pager-1.0 {
       
    28   catch {file delete -force ptf1.db}
       
    29   catch {file delete -force ptf1.db-journal}
       
    30   set v [catch {
       
    31     set ::p1 [pager_open ptf1.db 10]
       
    32   } msg]
       
    33 } {0}
       
    34 do_test pager-1.1 {
       
    35   pager_stats $::p1
       
    36 } {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0}
       
    37 do_test pager-1.2 {
       
    38   pager_pagecount $::p1
       
    39 } {0}
       
    40 do_test pager-1.3 {
       
    41   pager_stats $::p1
       
    42 } {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0}
       
    43 do_test pager-1.4 {
       
    44   pager_close $::p1
       
    45 } {}
       
    46 
       
    47 # Try to write a few pages.
       
    48 #
       
    49 do_test pager-2.1 {
       
    50   set v [catch {
       
    51     set ::p1 [pager_open ptf1.db 10]
       
    52   } msg]
       
    53 } {0}
       
    54 #do_test pager-2.2 {
       
    55 #  set v [catch {
       
    56 #    set ::g1 [page_get $::p1 0]
       
    57 #  } msg]
       
    58 #  lappend v $msg
       
    59 #} {1 SQLITE_ERROR}
       
    60 do_test pager-2.3.1 {
       
    61   set ::gx [page_lookup $::p1 1]
       
    62 } {}
       
    63 do_test pager-2.3.2 {
       
    64   pager_stats $::p1
       
    65 } {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0}
       
    66 do_test pager-2.3.3 {
       
    67   set v [catch {
       
    68     set ::g1 [page_get $::p1 1]
       
    69   } msg]
       
    70   if {$v} {lappend v $msg}
       
    71   set v
       
    72 } {0}
       
    73 do_test pager-2.3.3 {
       
    74   pager_stats $::p1
       
    75 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
       
    76 do_test pager-2.3.4 {
       
    77   set ::gx [page_lookup $::p1 1]
       
    78   expr {$::gx!=""}
       
    79 } {1}
       
    80 do_test pager-2.3.5 {
       
    81   page_unref $::gx
       
    82   pager_stats $::p1
       
    83 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
       
    84 do_test pager-2.3.6 {
       
    85   expr {$::g1==$::gx}
       
    86 } {1}
       
    87 do_test pager-2.3.7 {
       
    88   pager_stats $::p1
       
    89 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
       
    90 do_test pager-2.4 {
       
    91   pager_stats $::p1
       
    92 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
       
    93 do_test pager-2.5 {
       
    94   pager_pagecount $::p1
       
    95 } {0}
       
    96 do_test pager-2.6 {
       
    97   pager_stats $::p1
       
    98 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
       
    99 do_test pager-2.7 {
       
   100   page_number $::g1
       
   101 } {1}
       
   102 do_test pager-2.8 {
       
   103   page_read $::g1
       
   104 } {}
       
   105 do_test pager-2.9 {
       
   106   page_unref $::g1
       
   107 } {}
       
   108 
       
   109 # Update 24/03/2007: Even though the ref-count has dropped to zero, the
       
   110 # pager-cache still contains some pages. Previously, it was always true
       
   111 # that if there were no references to a pager it was empty.
       
   112 do_test pager-2.10 {
       
   113   pager_stats $::p1
       
   114 } {ref 0 page 1 max 10 size -1 state 0 err 0 hit 0 miss 1 ovfl 0}
       
   115 do_test pager-2.11 {
       
   116   set ::g1 [page_get $::p1 1]
       
   117   expr {$::g1!=0}
       
   118 } {1}
       
   119 do_test pager-2.12 {
       
   120   page_number $::g1
       
   121 } {1}
       
   122 do_test pager-2.13 {
       
   123   pager_stats $::p1
       
   124 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 1 miss 1 ovfl 0}
       
   125 do_test pager-2.14 {
       
   126   set v [catch {
       
   127     page_write $::g1 "Page-One"
       
   128   } msg]
       
   129   lappend v $msg
       
   130 } {0 {}}
       
   131 do_test pager-2.15 {
       
   132   pager_stats $::p1
       
   133 } {ref 1 page 1 max 10 size 1 state 2 err 0 hit 1 miss 1 ovfl 0}
       
   134 do_test pager-2.16 {
       
   135   page_read $::g1
       
   136 } {Page-One}
       
   137 do_test pager-2.17 {
       
   138   set v [catch {
       
   139     pager_commit $::p1
       
   140   } msg]
       
   141   lappend v $msg
       
   142 } {0 {}}
       
   143 do_test pager-2.20 {
       
   144   pager_stats $::p1
       
   145 } {ref 1 page 1 max 10 size -1 state 1 err 0 hit 2 miss 1 ovfl 0}
       
   146 do_test pager-2.19 {
       
   147   pager_pagecount $::p1
       
   148 } {1}
       
   149 do_test pager-2.21 {
       
   150   pager_stats $::p1
       
   151 } {ref 1 page 1 max 10 size 1 state 1 err 0 hit 2 miss 1 ovfl 0}
       
   152 do_test pager-2.22 {
       
   153   page_unref $::g1
       
   154 } {}
       
   155 do_test pager-2.23 {
       
   156   pager_stats $::p1
       
   157 } {ref 0 page 1 max 10 size -1 state 0 err 0 hit 2 miss 1 ovfl 0}
       
   158 do_test pager-2.24 {
       
   159   set v [catch {
       
   160     page_get $::p1 1
       
   161   } ::g1]
       
   162   if {$v} {lappend v $::g1}
       
   163   set v
       
   164 } {0}
       
   165 do_test pager-2.25 {
       
   166   page_read $::g1
       
   167 } {Page-One}
       
   168 do_test pager-2.26 {
       
   169   set v [catch {
       
   170     page_write $::g1 {page-one}
       
   171   } msg]
       
   172   lappend v $msg
       
   173 } {0 {}}
       
   174 do_test pager-2.27 {
       
   175   page_read $::g1
       
   176 } {page-one}
       
   177 do_test pager-2.28 {
       
   178   set v [catch {
       
   179     pager_rollback $::p1
       
   180   } msg]
       
   181   lappend v $msg
       
   182 } {0 {}}
       
   183 do_test pager-2.29 {
       
   184   page_unref $::g1
       
   185   set ::g1 [page_get $::p1 1]
       
   186   page_read $::g1
       
   187 } {Page-One}
       
   188 do_test pager-2.99 {
       
   189   page_unref $::g1
       
   190   pager_close $::p1
       
   191 } {}
       
   192 
       
   193 do_test pager-3.1 {
       
   194   set v [catch {
       
   195     set ::p1 [pager_open ptf1.db 15]
       
   196   } msg]
       
   197   if {$v} {lappend v $msg}
       
   198   set v
       
   199 } {0}
       
   200 do_test pager-3.2 {
       
   201   pager_pagecount $::p1
       
   202 } {1}
       
   203 do_test pager-3.3 {
       
   204   set v [catch {
       
   205     set ::g(1) [page_get $::p1 1]
       
   206   } msg]
       
   207   if {$v} {lappend v $msg}
       
   208   set v
       
   209 } {0}
       
   210 do_test pager-3.4 {
       
   211   page_read $::g(1)
       
   212 } {Page-One}
       
   213 do_test pager-3.5 {
       
   214   for {set i 2} {$i<=20} {incr i} {
       
   215     set gx [page_get $::p1 $i]
       
   216     page_write $gx "Page-$i"
       
   217     page_unref $gx
       
   218   }
       
   219   pager_commit $::p1
       
   220   page_unref $::g(1)
       
   221 } {}
       
   222 for {set i 2} {$i<=20} {incr i} {
       
   223   do_test pager-3.6.[expr {$i-1}] [subst {
       
   224     set gx \[page_get $::p1 $i\]
       
   225     set v \[page_read \$gx\]
       
   226     page_unref \$gx
       
   227     set v
       
   228   }] "Page-$i"
       
   229 }
       
   230 for {set i 1} {$i<=20} {incr i} {
       
   231   regsub -all CNT {
       
   232     set ::g1 [page_get $::p1 CNT]
       
   233     set ::g2 [page_get $::p1 CNT]
       
   234     set ::vx [page_read $::g2]
       
   235     expr {$::g1==$::g2}
       
   236   } $i body;
       
   237   do_test pager-3.7.$i.1 $body {1}
       
   238   regsub -all CNT {
       
   239     page_unref $::g2
       
   240     set vy [page_read $::g1]
       
   241     expr {$vy==$::vx}
       
   242   } $i body;
       
   243   do_test pager-3.7.$i.2 $body {1}
       
   244   regsub -all CNT {
       
   245     page_unref $::g1
       
   246     set gx [page_get $::p1 CNT]
       
   247     set vy [page_read $gx]
       
   248     page_unref $gx
       
   249     expr {$vy==$::vx}
       
   250   } $i body;
       
   251   do_test pager-3.7.$i.3 $body {1}
       
   252 }
       
   253 do_test pager-3.99 {
       
   254   pager_close $::p1
       
   255 } {}
       
   256 
       
   257 # tests of the checkpoint mechanism and api
       
   258 #
       
   259 do_test pager-4.0 {
       
   260   set v [catch {
       
   261     file delete -force ptf1.db
       
   262     set ::p1 [pager_open ptf1.db 15]
       
   263   } msg]
       
   264   if {$v} {lappend v $msg}
       
   265   set v
       
   266 } {0}
       
   267 do_test pager-4.1 {
       
   268   set g1 [page_get $::p1 1]
       
   269   page_write $g1 "Page-1 v0"
       
   270   for {set i 2} {$i<=20} {incr i} {
       
   271     set gx [page_get $::p1 $i]
       
   272     page_write $gx "Page-$i v0"
       
   273     page_unref $gx
       
   274   }
       
   275   pager_commit $::p1
       
   276 } {}
       
   277 for {set i 1} {$i<=20} {incr i} {
       
   278   do_test pager-4.2.$i {
       
   279     set gx [page_get $p1 $i]
       
   280     set v [page_read $gx]
       
   281     page_unref $gx
       
   282     set v
       
   283   } "Page-$i v0"
       
   284 }
       
   285 do_test pager-4.3 {
       
   286   lrange [pager_stats $::p1] 0 1
       
   287 } {ref 1}
       
   288 do_test pager-4.4 {
       
   289   lrange [pager_stats $::p1] 8 9
       
   290 } {state 1}
       
   291 
       
   292 for {set i 1} {$i<20} {incr i} {
       
   293   do_test pager-4.5.$i.0 {
       
   294     set res {}
       
   295     for {set j 2} {$j<=20} {incr j} {
       
   296       set gx [page_get $p1 $j]
       
   297       set value [page_read $gx]
       
   298       page_unref $gx
       
   299       set shouldbe "Page-$j v[expr {$i-1}]"
       
   300       if {$value!=$shouldbe} {
       
   301         lappend res $value $shouldbe
       
   302       }
       
   303     }
       
   304     set res
       
   305   } {}
       
   306   do_test pager-4.5.$i.1 {
       
   307     page_write $g1 "Page-1 v$i"
       
   308     lrange [pager_stats $p1] 8 9
       
   309   } {state 2}
       
   310   do_test pager-4.5.$i.2 {
       
   311     for {set j 2} {$j<=20} {incr j} {
       
   312       set gx [page_get $p1 $j]
       
   313       page_write $gx "Page-$j v$i"
       
   314       page_unref $gx
       
   315       if {$j==$i} {
       
   316         pager_stmt_begin $p1
       
   317       }
       
   318     }
       
   319   } {}
       
   320   do_test pager-4.5.$i.3 {
       
   321     set res {}
       
   322     for {set j 2} {$j<=20} {incr j} {
       
   323       set gx [page_get $p1 $j]
       
   324       set value [page_read $gx]
       
   325       page_unref $gx
       
   326       set shouldbe "Page-$j v$i"
       
   327       if {$value!=$shouldbe} {
       
   328         lappend res $value $shouldbe
       
   329       }
       
   330     }
       
   331     set res
       
   332   } {}
       
   333   do_test pager-4.5.$i.4 {
       
   334     pager_rollback $p1
       
   335     set res {}
       
   336     for {set j 2} {$j<=20} {incr j} {
       
   337       set gx [page_get $p1 $j]
       
   338       set value [page_read $gx]
       
   339       page_unref $gx
       
   340       set shouldbe "Page-$j v[expr {$i-1}]"
       
   341       if {$value!=$shouldbe} {
       
   342         lappend res $value $shouldbe
       
   343       }
       
   344     }
       
   345     set res
       
   346   } {}
       
   347   do_test pager-4.5.$i.5 {
       
   348     page_write $g1 "Page-1 v$i"
       
   349     lrange [pager_stats $p1] 8 9
       
   350   } {state 2}
       
   351   do_test pager-4.5.$i.6 {
       
   352     for {set j 2} {$j<=20} {incr j} {
       
   353       set gx [page_get $p1 $j]
       
   354       page_write $gx "Page-$j v$i"
       
   355       page_unref $gx
       
   356       if {$j==$i} {
       
   357         pager_stmt_begin $p1
       
   358       }
       
   359     }
       
   360   } {}
       
   361   do_test pager-4.5.$i.7 {
       
   362     pager_stmt_rollback $p1
       
   363     for {set j 2} {$j<=20} {incr j} {
       
   364       set gx [page_get $p1 $j]
       
   365       set value [page_read $gx]
       
   366       page_unref $gx
       
   367       if {$j<=$i || $i==1} {
       
   368         set shouldbe "Page-$j v$i"
       
   369       } else {
       
   370         set shouldbe "Page-$j v[expr {$i-1}]"
       
   371       }
       
   372       if {$value!=$shouldbe} {
       
   373         lappend res $value $shouldbe
       
   374       }
       
   375     }
       
   376     set res
       
   377   } {}
       
   378   do_test pager-4.5.$i.8 {
       
   379     for {set j 2} {$j<=20} {incr j} {
       
   380       set gx [page_get $p1 $j]
       
   381       page_write $gx "Page-$j v$i"
       
   382       page_unref $gx
       
   383       if {$j==$i} {
       
   384         pager_stmt_begin $p1
       
   385       }
       
   386     }
       
   387   } {}
       
   388   do_test pager-4.5.$i.9 {
       
   389     pager_stmt_commit $p1
       
   390     for {set j 2} {$j<=20} {incr j} {
       
   391       set gx [page_get $p1 $j]
       
   392       set value [page_read $gx]
       
   393       page_unref $gx
       
   394       set shouldbe "Page-$j v$i"
       
   395       if {$value!=$shouldbe} {
       
   396         lappend res $value $shouldbe
       
   397       }
       
   398     }
       
   399     set res
       
   400   } {}
       
   401   do_test pager-4.5.$i.10 {
       
   402     pager_commit $p1
       
   403     lrange [pager_stats $p1] 8 9
       
   404   } {state 1}
       
   405 }
       
   406 
       
   407 # Test that nothing bad happens when sqlite3pager_set_cachesize() is
       
   408 # called with a negative argument.
       
   409 do_test pager-4.6.1 {
       
   410   pager_close [pager_open ptf2.db -15]
       
   411 } {}
       
   412 
       
   413 # Test truncate on an in-memory database is Ok.
       
   414 ifcapable memorydb {
       
   415   do_test pager-4.6.2 {
       
   416     set ::p2 [pager_open :memory: 10]
       
   417     pager_truncate $::p2 5
       
   418   } {}
       
   419   do_test pager-4.6.3 {
       
   420     for {set i 1} {$i<5} {incr i} {
       
   421       set p [page_get $::p2 $i]
       
   422       page_write $p "Page $i"
       
   423       pager_commit $::p2
       
   424       page_unref $p
       
   425     }
       
   426     # pager_truncate $::p2 3
       
   427   } {}
       
   428   do_test pager-4.6.4 {
       
   429     pager_close $::p2
       
   430   } {}
       
   431 }
       
   432 
       
   433 do_test pager-4.99 {
       
   434   page_unref $::g1
       
   435   pager_close $::p1
       
   436 } {}
       
   437 
       
   438 
       
   439 
       
   440   file delete -force ptf1.db
       
   441 
       
   442 } ;# end if( not mem: and has pager_open command );
       
   443 
       
   444 if 0 {
       
   445 # Ticket #615: an assertion fault inside the pager.  It is a benign
       
   446 # fault, but we might as well test for it.
       
   447 #
       
   448 do_test pager-5.1 {
       
   449   sqlite3 db test.db
       
   450   execsql {
       
   451     BEGIN;
       
   452     CREATE TABLE t1(x);
       
   453     PRAGMA synchronous=off;
       
   454     COMMIT;
       
   455   }
       
   456 } {}
       
   457 }
       
   458 
       
   459 # The following tests cover rolling back hot journal files. 
       
   460 # They can't be run on windows because the windows version of 
       
   461 # SQLite holds a mandatory exclusive lock on journal files it has open.
       
   462 #
       
   463 if {$tcl_platform(platform)!="windows" && $tcl_platform(platform)!="symbian"} {
       
   464 do_test pager-6.1 {
       
   465   file delete -force test2.db
       
   466   file delete -force test2.db-journal
       
   467   sqlite3 db2 test2.db
       
   468   execsql {
       
   469     PRAGMA synchronous = 0;
       
   470     CREATE TABLE abc(a, b, c);
       
   471     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   472     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   473     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   474     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   475     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   476     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   477     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   478     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   479     INSERT INTO abc VALUES(1, 2, randstr(200,200));
       
   480     BEGIN;
       
   481     UPDATE abc SET c = randstr(200,200);
       
   482   } db2
       
   483   copy_file test2.db test.db
       
   484   copy_file test2.db-journal test.db-journal
       
   485 
       
   486   set f [open test.db-journal a]
       
   487   fconfigure $f -encoding binary
       
   488   seek $f [expr [file size test.db-journal] - 1032] start
       
   489   puts -nonewline $f "\00\00\00\00"
       
   490   close $f
       
   491 
       
   492   sqlite3 db test.db
       
   493   execsql {
       
   494     SELECT sql FROM sqlite_master
       
   495   }
       
   496 } {{CREATE TABLE abc(a, b, c)}}
       
   497 
       
   498 do_test pager-6.2 {
       
   499   copy_file test2.db test.db
       
   500   copy_file test2.db-journal test.db-journal
       
   501 
       
   502   set f [open test.db-journal a]
       
   503   fconfigure $f -encoding binary
       
   504   seek $f [expr [file size test.db-journal] - 1032] start
       
   505   puts -nonewline $f "\00\00\00\FF"
       
   506   close $f
       
   507 
       
   508   sqlite3 db test.db
       
   509   execsql {
       
   510     SELECT sql FROM sqlite_master
       
   511   }
       
   512 } {{CREATE TABLE abc(a, b, c)}}
       
   513 
       
   514 do_test pager-6.3 {
       
   515   copy_file test2.db test.db
       
   516   copy_file test2.db-journal test.db-journal
       
   517 
       
   518   set f [open test.db-journal a]
       
   519   fconfigure $f -encoding binary
       
   520   seek $f [expr [file size test.db-journal] - 4] start
       
   521   puts -nonewline $f "\00\00\00\00"
       
   522   close $f
       
   523 
       
   524   sqlite3 db test.db
       
   525   execsql {
       
   526     SELECT sql FROM sqlite_master
       
   527   }
       
   528 } {{CREATE TABLE abc(a, b, c)}}
       
   529 
       
   530 do_test pager-6.4.1 {
       
   531   execsql {
       
   532     BEGIN;
       
   533     SELECT sql FROM sqlite_master;
       
   534   }
       
   535   copy_file test2.db-journal test.db-journal;
       
   536   sqlite3 db3 test.db
       
   537   catchsql {
       
   538     BEGIN;
       
   539     SELECT sql FROM sqlite_master;
       
   540   } db3;
       
   541 } {1 {database is locked}}
       
   542 do_test pager-6.4.2 {
       
   543   file delete -force test.db-journal
       
   544   catchsql {
       
   545     SELECT sql FROM sqlite_master;
       
   546   } db3;
       
   547 } {0 {{CREATE TABLE abc(a, b, c)}}}
       
   548 do_test pager-6.4.3 {
       
   549   db3 close
       
   550   execsql {
       
   551     COMMIT;
       
   552   }
       
   553 } {}
       
   554 
       
   555 do_test pager-6.5 {
       
   556   copy_file test2.db test.db
       
   557   copy_file test2.db-journal test.db-journal
       
   558 
       
   559   set f [open test.db-journal a]
       
   560   fconfigure $f -encoding binary
       
   561   puts -nonewline $f "hello"
       
   562   puts -nonewline $f "\x00\x00\x00\x05\x01\x02\x03\x04"
       
   563   puts -nonewline $f "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7"
       
   564   close $f
       
   565 
       
   566   sqlite3 db test.db
       
   567   execsql {
       
   568     SELECT sql FROM sqlite_master
       
   569   }
       
   570 } {{CREATE TABLE abc(a, b, c)}}
       
   571 
       
   572 do_test pager-6.5 {
       
   573   db2 close
       
   574 } {}
       
   575 }
       
   576 finish_test