Home | History | Annotate | Download | only in test
      1 # 2008 June 18
      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 # This file contains tests of the memory allocation subsystem
     13 #
     14 
     15 set testdir [file dirname $argv0]
     16 source $testdir/tester.tcl
     17 sqlite3_reset_auto_extension
     18 
     19 # This test assumes that no page-cache or scratch buffers are installed
     20 # by default when a new database connection is opened. As a result, it
     21 # will not work with the "memsubsys1" permutation.
     22 #
     23 if {[permutation] == "memsubsys1"} {
     24   finish_test
     25   return
     26 }
     27 
     28 # This procedure constructs a new database in test.db.  It fills
     29 # this database with many small records (enough to force multiple
     30 # rebalance operations in the btree-layer and to require a large
     31 # page cache), verifies correct results, then returns.
     32 #
     33 proc build_test_db {testname pragmas} {
     34   catch {db close}
     35   file delete -force test.db test.db-journal
     36   sqlite3 db test.db
     37   sqlite3_db_config_lookaside db 0 0 0
     38   db eval $pragmas
     39   db eval {
     40     CREATE TABLE t1(x, y);
     41     CREATE TABLE t2(a, b);
     42     CREATE INDEX i1 ON t1(x,y);
     43     INSERT INTO t1 VALUES(1, 100);
     44     INSERT INTO t1 VALUES(2, 200);
     45   }
     46   for {set i 2} {$i<5000} {incr i $i} {
     47     db eval {INSERT INTO t2 SELECT * FROM t1}
     48     db eval {INSERT INTO t1 SELECT a+$i, a+b*100 FROM t2}
     49     db eval {DELETE FROM t2}
     50   }
     51   do_test $testname.1 {
     52     db eval {SELECT count(*) FROM t1}
     53   } 8192
     54   integrity_check $testname.2
     55 }
     56 
     57 # Reset all of the highwater marks.
     58 #
     59 proc reset_highwater_marks {} {
     60   sqlite3_status SQLITE_STATUS_MEMORY_USED 1
     61   sqlite3_status SQLITE_STATUS_MALLOC_SIZE 1
     62   sqlite3_status SQLITE_STATUS_PAGECACHE_USED 1
     63   sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 1
     64   sqlite3_status SQLITE_STATUS_PAGECACHE_SIZE 1
     65   sqlite3_status SQLITE_STATUS_SCRATCH_USED 1
     66   sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 1
     67   sqlite3_status SQLITE_STATUS_SCRATCH_SIZE 1
     68   sqlite3_status SQLITE_STATUS_PARSER_STACK 1
     69 }
     70 
     71 set xtra_size 256
     72 
     73 # Test 1:  Both PAGECACHE and SCRATCH are shut down.
     74 #
     75 db close
     76 sqlite3_shutdown
     77 sqlite3_config_lookaside 0 0
     78 sqlite3_initialize
     79 reset_highwater_marks
     80 build_test_db memsubsys1-1 {PRAGMA page_size=1024}
     81 do_test memsubsys1-1.3 {
     82   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
     83 } 0
     84 do_test memsubsys1-1.4 {
     85   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
     86 } 0
     87 set max_pagecache [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
     88 #show_memstats
     89 
     90 # Test 2:  Activate PAGECACHE with 20 pages
     91 #
     92 db close
     93 sqlite3_shutdown
     94 sqlite3_config_pagecache [expr 1024+$xtra_size] 20
     95 sqlite3_initialize
     96 reset_highwater_marks
     97 build_test_db memsubsys1-2 {PRAGMA page_size=1024}
     98 #show_memstats
     99 set MEMORY_MANAGEMENT $sqlite_options(memorymanage)
    100 do_test memsubsys1-2.3 {
    101   set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
    102 } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
    103 do_test memsubsys1-2.4 {
    104   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    105 } 20
    106 do_test memsubsys1-2.5 {
    107   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    108 } 0
    109 
    110 # Test 3:  Activate PAGECACHE with 20 pages but use the wrong page size
    111 # so that PAGECACHE is not used.
    112 #
    113 db close
    114 sqlite3_shutdown
    115 sqlite3_config_pagecache [expr 512+$xtra_size] 20
    116 sqlite3_initialize
    117 reset_highwater_marks
    118 build_test_db memsubsys1-3.1 {PRAGMA page_size=1024}
    119 #show_memstats
    120 do_test memsubsys1-3.1.3 {
    121   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    122 } 0
    123 do_test memsubsys1-3.1.4 {
    124   set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
    125 } $max_pagecache
    126 do_test memsubsys1-3.1.5 {
    127   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    128 } 0
    129 db close
    130 sqlite3_shutdown
    131 sqlite3_config_pagecache [expr 2048+$xtra_size] 20
    132 sqlite3_initialize
    133 reset_highwater_marks
    134 build_test_db memsubsys1-3.2 {PRAGMA page_size=2048}
    135 #show_memstats
    136 do_test memsubsys1-3.2.3 {
    137   db eval {PRAGMA page_size}
    138 } 2048
    139 do_test memsubsys1-3.2.4 {
    140   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    141 } 20
    142 do_test memsubsys1-3.2.5 {
    143   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    144 } 0
    145 
    146 # Test 4:  Activate both PAGECACHE and SCRATCH.
    147 #
    148 db close
    149 sqlite3_shutdown
    150 sqlite3_config_pagecache [expr 1024+$xtra_size] 50
    151 sqlite3_config_scratch 6000 2
    152 sqlite3_initialize
    153 reset_highwater_marks
    154 build_test_db memsubsys1-4 {PRAGMA page_size=1024}
    155 #show_memstats
    156 do_test memsubsys1-4.3 {
    157   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    158   expr {$pg_used>=45 && $pg_used<=50}
    159 } 1
    160 do_test memsubsys1-4.4 {
    161   set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
    162 } 0
    163 do_test memsubsys1-4.5 {
    164   set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
    165   expr {$maxreq<7000}
    166 } 1
    167 do_test memsubsys1-4.6 {
    168   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    169 } 1
    170 
    171 # Test 5:  Activate both PAGECACHE and SCRATCH.  But make the page size
    172 # such that the SCRATCH allocations are too small.
    173 #
    174 db close
    175 sqlite3_shutdown
    176 sqlite3_config_pagecache [expr 4096+$xtra_size] 24
    177 sqlite3_config_scratch 6000 2
    178 sqlite3_initialize
    179 reset_highwater_marks
    180 build_test_db memsubsys1-5 {PRAGMA page_size=4096}
    181 #show_memstats
    182 do_test memsubsys1-5.3 {
    183   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    184 } 24
    185 do_test memsubsys1-5.4 {
    186   set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
    187   expr {$maxreq>4096}
    188 } 1
    189 do_test memsubsys1-5.5 {
    190   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    191 } 0
    192 do_test memsubsys1-5.6 {
    193   set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
    194   expr {$s_ovfl>6000}
    195 } 1
    196 
    197 # Test 6:  Activate both PAGECACHE and SCRATCH with a 4k page size.
    198 # Make it so that SCRATCH is large enough
    199 #
    200 db close
    201 sqlite3_shutdown
    202 sqlite3_config_pagecache [expr 4096+$xtra_size] 24
    203 sqlite3_config_scratch 25300 1
    204 sqlite3_initialize
    205 reset_highwater_marks
    206 build_test_db memsubsys1-6 {PRAGMA page_size=4096}
    207 #show_memstats
    208 do_test memsubsys1-6.3 {
    209   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    210 } 24
    211 #do_test memsubsys1-6.4 {
    212 #  set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
    213 #  expr {$maxreq>4096 && $maxreq<=(4096+$xtra_size)}
    214 #} 1
    215 do_test memsubsys1-6.5 {
    216   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    217 } 1
    218 do_test memsubsys1-6.6 {
    219   set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
    220 } 0
    221 
    222 # Test 7:  Activate both PAGECACHE and SCRATCH with a 4k page size.
    223 # Set cache_size small so that no PAGECACHE overflow occurs.  Verify
    224 # that maximum allocation size is small.
    225 #
    226 db close
    227 sqlite3_shutdown
    228 sqlite3_config_pagecache [expr 4096+$xtra_size] 24
    229 sqlite3_config_scratch 25300 1
    230 sqlite3_initialize
    231 reset_highwater_marks
    232 build_test_db memsubsys1-7 {
    233   PRAGMA page_size=4096;
    234   PRAGMA cache_size=10;
    235   PRAGMA temp_store=memory;
    236 }
    237 #show_memstats
    238 do_test memsubsys1-7.3 {
    239   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
    240   expr {$pg_used<24}
    241 } 1
    242 do_test memsubsys1-7.4 {
    243   set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
    244 } 0
    245 do_test memsubsys1-7.5 {
    246   set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
    247   expr {$maxreq<4100}
    248 } 1
    249 do_test memsubsys1-7.6 {
    250   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    251 } 1
    252 do_test memsubsys1-7.7 {
    253   set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
    254 } 0
    255 
    256 # Test 8:  Disable PAGECACHE.  Make available SCRATCH zero.  Verify that
    257 # the SCRATCH overflow logic works.
    258 #
    259 db close
    260 sqlite3_shutdown
    261 sqlite3_config_pagecache 0 0
    262 sqlite3_config_scratch 25000 0
    263 sqlite3_initialize
    264 reset_highwater_marks
    265 do_test memsubsys1-8.1 {
    266   set pg_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
    267 } 0
    268 do_test memsubsys1-8.2 {
    269   set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
    270 } 0
    271 do_test memsubsys1-8.3 {
    272   sqlite3 db :memory:
    273   db eval {
    274     CREATE TABLE t1(x);
    275     INSERT INTO t1 VALUES(zeroblob(400));
    276     INSERT INTO t1 VALUES(zeroblob(400));
    277     INSERT INTO t1 SELECT * FROM t1;
    278     INSERT INTO t1 SELECT * FROM t1;
    279     INSERT INTO t1 SELECT * FROM t1;
    280   }
    281   expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0}
    282 } 1
    283 db close
    284 sqlite3_shutdown
    285 sqlite3_config_memstatus 0
    286 sqlite3_initialize
    287 do_test memsubsys1-8.4 {
    288   sqlite3 db :memory:
    289   db eval {
    290     CREATE TABLE t1(x);
    291     INSERT INTO t1 VALUES(zeroblob(400));
    292     INSERT INTO t1 VALUES(zeroblob(400));
    293     INSERT INTO t1 SELECT * FROM t1;
    294     INSERT INTO t1 SELECT * FROM t1;
    295     INSERT INTO t1 SELECT * FROM t1;
    296     SELECT rowid FROM t1;
    297   }
    298 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
    299 
    300 
    301 db close
    302 sqlite3_shutdown
    303 sqlite3_config_memstatus 1
    304 sqlite3_config_pagecache 0 0
    305 sqlite3_config_scratch 0 0
    306 sqlite3_config_lookaside 100 500
    307 sqlite3_initialize
    308 autoinstall_test_functions
    309 finish_test
    310