Home | History | Annotate | Download | only in test
      1 # 2010 September 1
      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 
     13 set testdir [file dirname $argv0]
     14 source $testdir/tester.tcl
     15 source $testdir/malloc_common.tcl
     16 
     17 db close
     18 
     19 do_test quota-1.1 { sqlite3_quota_initialize nosuchvfs 1 } {SQLITE_ERROR}
     20 do_test quota-1.2 { sqlite3_quota_initialize "" 1 }        {SQLITE_OK}
     21 do_test quota-1.3 { sqlite3_quota_initialize "" 1 }        {SQLITE_MISUSE}
     22 do_test quota-1.4 { sqlite3_quota_shutdown }               {SQLITE_OK}
     23 
     24 do_test quota-1.5 { sqlite3_quota_initialize "" 0 }        {SQLITE_OK}
     25 do_test quota-1.6 { sqlite3_quota_shutdown }               {SQLITE_OK}
     26 do_test quota-1.7 { sqlite3_quota_initialize "" 1 }        {SQLITE_OK}
     27 do_test quota-1.8 { sqlite3_quota_shutdown }               {SQLITE_OK}
     28 
     29 
     30 #-------------------------------------------------------------------------
     31 # Some simple warm-body tests with a single database file in rollback 
     32 # mode:
     33 #
     34 #   quota-2.1.*: Test that SQLITE_FULL is returned if the database would
     35 #                exceed the configured quota.
     36 #
     37 #   quota-2.2.*: Test that SQLITE_FULL is not returned and the database
     38 #                grows if the callback extends the quota when the database
     39 #                attempts to grow beyond the configured quota.
     40 #
     41 #   quota-2.3.*: Open and close a db that is not part of any quota group. At
     42 #                one point this was causing mutex refs to be leaked.
     43 #
     44 #   quota-2.4.*: Try to shutdown the quota system before closing the db
     45 #                file. Check that this fails and the quota system still works
     46 #                afterwards. Then close the database and successfully shut
     47 #                down the quota system.
     48 #   
     49 sqlite3_quota_initialize "" 1
     50 
     51 proc quota_check {filename limitvar size} {
     52   upvar $limitvar limit
     53 
     54   lappend ::quota [set limit] $size
     55   if {[info exists ::quota_request_ok]} { set limit $size }
     56 }
     57 
     58 do_test quota-2.1.1 {
     59   sqlite3_quota_set *test.db 4096 quota_check
     60 } {SQLITE_OK}
     61 do_test quota-2.1.2 {
     62   sqlite3 db test.db
     63   execsql {
     64     PRAGMA page_size=1024;
     65     PRAGMA auto_vacuum=OFF;
     66     PRAGMA journal_mode=DELETE;
     67   }
     68   set ::quota [list]
     69   execsql {
     70     CREATE TABLE t1(a, b);
     71     INSERT INTO t1 VALUES(1, randomblob(1100));
     72     INSERT INTO t1 VALUES(2, randomblob(1100));
     73   }
     74   set ::quota
     75 } {}
     76 do_test quota-2.1.3 { file size test.db } {4096}
     77 do_test quota-2.1.4 {
     78   catchsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
     79 } {1 {database or disk is full}}
     80 do_test quota-2.1.5 { set ::quota } {4096 5120}
     81 
     82 set ::quota_request_ok 1
     83 set ::quota [list]
     84 do_test quota-2.2.1 {
     85   execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
     86 } {}
     87 do_test quota-2.2.2 { set ::quota } {4096 5120}
     88 do_test quota-2.2.3 { file size test.db } {5120}
     89 unset ::quota_request_ok
     90 
     91 do_test quota-2.3.1 {
     92   sqlite3 db2 bak.db
     93   db2 close
     94 } {}
     95 
     96 do_test quota-2.4.1 {
     97   sqlite3_quota_shutdown
     98 } {SQLITE_MISUSE}
     99 set ::quota [list]
    100 do_test quota-2.4.2 {
    101   catchsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
    102 } {1 {database or disk is full}}
    103 do_test quota-2.4.3 { set ::quota } {5120 6144}
    104 do_test quota-2.4.4 { file size test.db } {5120}
    105 do_test quota-2.4.99 {
    106   db close
    107   sqlite3_quota_shutdown
    108 } {SQLITE_OK}
    109 
    110 #-------------------------------------------------------------------------
    111 # Try some tests with more than one connection to a database file. Still
    112 # in rollback mode.
    113 #
    114 #   quota-3.1.*: Two connections to a single database file.
    115 #
    116 #   quota-3.2.*: Two connections to each of several database files (that
    117 #                are in the same quota group).
    118 #
    119 proc quota_check {filename limitvar size} {
    120   upvar $limitvar limit
    121   lappend ::quota [set limit] $size
    122   if {[info exists ::quota_request_ok]} { set limit $size }
    123 }
    124 
    125 do_test quota-3.1.1 {
    126   file delete -force test.db
    127   sqlite3_quota_initialize "" 1
    128   sqlite3_quota_set *test.db 4096 quota_check
    129 } {SQLITE_OK}
    130 do_test quota-3.1.2 {
    131   sqlite3 db test.db
    132   execsql {
    133     PRAGMA page_size = 1024;
    134     PRAGMA journal_mode = delete;
    135     PRAGMA auto_vacuum = off;
    136     CREATE TABLE t1(a PRIMARY KEY, b);
    137     INSERT INTO t1 VALUES(1, 'one');
    138   }
    139   file size test.db
    140 } {3072}
    141 do_test quota-3.1.3 {
    142   sqlite3 db2 test.db
    143   set ::quota [list]
    144   execsql { CREATE TABLE t2(a, b) } db2
    145   set ::quota
    146 } {}
    147 do_test quota-3.1.4 {
    148   catchsql { CREATE TABLE t3(a, b) }
    149 } {1 {database or disk is full}}
    150 do_test quota-3.1.5 {
    151   set ::quota_request_ok 1
    152   execsql { CREATE TABLE t3(a, b) }
    153 } {}
    154 do_test quota-3.1.6 {
    155   db close
    156   db2 close
    157   sqlite3_quota_set *test.db 0 {}
    158 } {SQLITE_OK}
    159 
    160 do_test quota-3.2.1 {
    161   file delete force test.db test2.db 
    162 
    163   sqlite3_quota_set * 4096 {}
    164   sqlite3 db1a test.db
    165   sqlite3 db2a test2.db
    166 
    167   foreach db {db1a db2a} {
    168     execsql {
    169       PRAGMA page_size = 1024;
    170       PRAGMA journal_mode = delete;
    171       PRAGMA auto_vacuum = off;
    172       CREATE TABLE t1(a, b);
    173     } $db
    174   }
    175 
    176   sqlite3 db1b test.db
    177   sqlite3 db2b test2.db
    178 
    179   list [file size test.db] [file size test2.db]
    180 } {2048 2048}
    181 
    182 catch { unset ::quota_request_ok }
    183 
    184 do_test quota-3.2.2 { execsql { INSERT INTO t1 VALUES('x', 'y') } db1a } {}
    185 do_test quota-3.2.3 { execsql { INSERT INTO t1 VALUES('v', 'w') } db1b } {}
    186 do_test quota-3.2.4 { execsql { INSERT INTO t1 VALUES('t', 'u') } db2a } {}
    187 do_test quota-3.2.5 { execsql { INSERT INTO t1 VALUES('r', 's') } db2b } {}
    188 
    189 do_test quota-3.2.6 { 
    190   catchsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db1a
    191 } {1 {database or disk is full}}
    192 do_test quota-3.2.7 { 
    193   catchsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db1b
    194 } {1 {database or disk is full}}
    195 do_test quota-3.2.8 { 
    196   catchsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db2a
    197 } {1 {database or disk is full}}
    198 do_test quota-3.2.9 { 
    199   catchsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db2b
    200 } {1 {database or disk is full}}
    201 
    202 set ::quota [list]
    203 proc quota_callback {file limitvar size} {
    204   upvar $limitvar limit
    205   lappend ::quota $file $size
    206   set limit 0
    207 }
    208 sqlite3_quota_set * 4096 quota_callback
    209 do_test quota-3.3.1 { 
    210   execsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db1a
    211   execsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db1b
    212   execsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db2a
    213   execsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) } db2b
    214   set ::quota
    215 } [list [file join [pwd] test.db] 5120]
    216 
    217 do_test quota-3.2.X {
    218   foreach db {db1a db2a db2b db1b} { catch { $db close } }
    219   sqlite3_quota_set * 0 {}
    220 } {SQLITE_OK}
    221 
    222 #-------------------------------------------------------------------------
    223 # Quotas are deleted when unused and when there limit is set to zero
    224 #
    225 
    226 # Return a list of all currently defined quotas.  Each quota is identified
    227 # by its pattern.
    228 proc quota_list {} {
    229   set allq {}
    230   foreach q [sqlite3_quota_dump] {
    231     lappend allq [lindex $q 0]
    232   }
    233   return [lsort $allq]
    234 }
    235 
    236 do_test quota-4.1.1 {
    237   sqlite3_quota_set *test.db 0 {}
    238   quota_list
    239 } {}
    240 do_test quota-4.1.2 {
    241   sqlite3_quota_set *test.db 4096 {}
    242   quota_list
    243 } {*test.db}
    244 do_test quota-4.1.3 {
    245   sqlite3_quota_set *test2.db 0 {}
    246   quota_list
    247 } {*test.db}
    248 do_test quota-4.1.4 {
    249   sqlite3_quota_set *test2.db 100000 {}
    250   quota_list
    251 } {*test.db *test2.db}
    252 do_test quota-4.1.5 {
    253   sqlite3_quota_set *test.db 0 {}
    254   quota_list
    255 } {*test2.db}
    256 do_test quota-4.1.6 {
    257   file delete -force test2.db test2.db-journal test2.db-wal
    258   sqlite3 db test2.db
    259   db eval {CREATE TABLE t2(x); INSERT INTO t2 VALUES('tab-t2');}
    260   quota_list
    261 } {*test2.db}
    262 do_test quota-4.1.7 {
    263   catchsql {INSERT INTO t2 VALUES(zeroblob(200000))}
    264 } {1 {database or disk is full}}
    265 do_test quota-4.1.8 {
    266   sqlite3 db2 test2.db
    267   db2 eval {SELECT * FROM t2}
    268 } {tab-t2}
    269 do_test quota-4.1.9 {
    270   sqlite3_quota_set *test2.db 0 {}
    271   catchsql {INSERT INTO t2 VALUES(zeroblob(200000))}
    272 } {0 {}}
    273 do_test quota-4.1.10 {
    274   quota_list
    275 } {*test2.db}
    276 do_test quota-4.1.11 {
    277   db2 close
    278   quota_list
    279 } {*test2.db}
    280 do_test quota-4.1.12 {
    281   db close
    282   quota_list
    283 } {}
    284 
    285 do_test quota-4.2.1 {
    286   sqlite3_quota_set A 1000 {}
    287   sqlite3_quota_set B 1000 {}
    288   sqlite3_quota_set C 1000 {}
    289   sqlite3_quota_set D 1000 {}
    290   quota_list
    291 } {A B C D}
    292 do_test quota-4.2.2 {
    293   sqlite3_quota_set C 0 {}
    294   sqlite3_quota_set B 0 {}
    295   quota_list
    296 } {A D}
    297 do_test quota-4.2.3 {
    298   sqlite3_quota_set A 0 {}
    299   sqlite3_quota_set D 0 {}
    300   quota_list
    301 } {}
    302 do_test quota-4.2.4 {
    303   sqlite3_quota_set A 1000 {}
    304   sqlite3_quota_set B 1000 {}
    305   sqlite3_quota_set C 1000 {}
    306   sqlite3_quota_set A 0 {}
    307   sqlite3_quota_set B 0 {}
    308   sqlite3_quota_set C 0 {}
    309   quota_list
    310 } {}
    311 do_test quota-4.2.5 {
    312   sqlite3_quota_set A 1000 {}
    313   sqlite3_quota_set B 1000 {}
    314   sqlite3_quota_set C 1000 {}
    315   sqlite3_quota_set C 0 {}
    316   sqlite3_quota_set B 0 {}
    317   sqlite3_quota_set A 0 {}
    318   quota_list
    319 } {}
    320 
    321 do_test quota-4.3.1 {
    322   sqlite3_quota_set A 1000 quota_callback
    323   sqlite3 db A
    324   sqlite3_quota_set A 0 quota_callback
    325   db close
    326   quota_list
    327 } {}
    328 
    329 do_test quota-4.4.1 {
    330   sqlite3_quota_set A 1000 quota_callback
    331   sqlite3_quota_shutdown
    332 } {SQLITE_OK}
    333 do_test quota-4.4.2 {
    334   quota_list
    335 } {}
    336 
    337 #-------------------------------------------------------------------------
    338 # The following tests test that the quota VFS handles malloc and IO 
    339 # errors.
    340 #
    341 
    342 sqlite3_quota_initialize "" 1
    343 sqlite3_quota_set *test.db 4096 {}
    344 
    345 do_faultsim_test quota-5.1 -prep {
    346   catch {db close}
    347 } -body {
    348   sqlite3 db test2.db
    349 }
    350 do_faultsim_test quota-5.2 -prep {
    351   catch {db close}
    352 } -body {
    353   sqlite3 db test.db
    354 }
    355 
    356 catch { db close }
    357 file delete -force test.db
    358 
    359 do_test quota-5.3.prep {
    360   sqlite3 db test.db
    361   execsql {
    362     PRAGMA auto_vacuum = 1;
    363     PRAGMA page_size = 1024;
    364     CREATE TABLE t1(a, b);
    365     INSERT INTO t1 VALUES(10, zeroblob(1200));
    366   }
    367   faultsim_save_and_close
    368 } {}
    369 do_faultsim_test quota-5.3 -prep {
    370   faultsim_restore_and_reopen
    371 } -body {
    372   execsql { DELETE FROM t1 }
    373 }
    374 
    375 do_test quota-5.4.1 {
    376   catch { db close }
    377   file delete -force test.db
    378   file mkdir test.db
    379   list [catch { sqlite3 db test.db } msg] $msg
    380 } {1 {unable to open database file}}
    381 
    382 do_faultsim_test quota-5.5 -prep {
    383   catch { sqlite3_quota_shutdown }
    384 } -body {
    385   sqlite3_quota_initialize "" 1
    386 }
    387 
    388 do_faultsim_test quota-5.6 -prep {
    389   catch { sqlite3_quota_shutdown }
    390   sqlite3_quota_initialize "" 1
    391 } -body {
    392   sqlite3_quota_set * 4096 {}
    393 }
    394 
    395 catch { sqlite3_quota_shutdown }
    396 finish_test
    397