Home | History | Annotate | Download | only in test
      1 # 2007 Aug 13
      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 tests aspects of the malloc failure while parsing
     13 # CREATE TABLE statements in auto_vacuum mode.
     14 #
     15 # $Id: mallocC.test,v 1.10 2009/04/11 16:27:50 drh Exp $
     16 
     17 set testdir [file dirname $argv0]
     18 source $testdir/tester.tcl
     19 source $testdir/malloc_common.tcl
     20 
     21 # Only run these tests if memory debugging is turned on.
     22 #
     23 if {!$MEMDEBUG} {
     24    puts "Skipping mallocC tests: not compiled with -DSQLITE_MEMDEBUG..."
     25    finish_test
     26    return
     27 }
     28 
     29 proc do_mallocC_test {tn args} {
     30   array set ::mallocopts $args
     31   #set sum [allcksum db]
     32 
     33   for {set ::n 1} {true} {incr ::n} {
     34 
     35     # Run the SQL. Malloc number $::n is set to fail. A malloc() failure
     36     # may or may not be reported.
     37     sqlite3_memdebug_fail $::n -repeat 1
     38     do_test mallocC-$tn.$::n.1 {
     39       set res [catchsql [string trim $::mallocopts(-sql)]]
     40       set rc [expr { 
     41         0==[string compare $res {1 {out of memory}}] ||
     42         [db errorcode] == 3082 ||
     43         0==[lindex $res 0]
     44       }]
     45       if {$rc!=1} {
     46         puts "Error: $res"
     47       }
     48       set rc
     49     } {1}
     50 
     51     # If $::n is greater than the number of malloc() calls required to
     52     # execute the SQL, then this test is finished. Break out of the loop.
     53     set nFail [sqlite3_memdebug_fail -1]
     54     if {$nFail==0} {
     55       break
     56     }
     57 
     58     # Recover from the malloc failure.
     59     #
     60     # Update: The new malloc() failure handling means that a transaction may
     61     # still be active even if a malloc() has failed. But when these tests were
     62     # written this was not the case. So do a manual ROLLBACK here so that the
     63     # tests pass.
     64     do_test mallocC-$tn.$::n.2 {
     65       catch {
     66         execsql {
     67           ROLLBACK;
     68         }
     69       }
     70       expr 0
     71     } {0}
     72 
     73     # Checksum the database.
     74     #do_test mallocC-$tn.$::n.3 {
     75     #  allcksum db
     76     #} $sum
     77 
     78     #integrity_check mallocC-$tn.$::n.4
     79   }
     80   unset ::mallocopts
     81 }
     82 
     83 sqlite3_extended_result_codes db 1
     84 
     85 execsql {
     86   PRAGMA auto_vacuum=1;
     87   CREATE TABLE t0(a, b, c);
     88 }
     89 
     90 # The number of memory allocation failures is different on 64-bit
     91 # and 32-bit systems due to larger structures on 64-bit systems
     92 # overflowing the lookaside more often.  To debug problems, it is
     93 # sometimes helpful to reduce the size of the lookaside allocation
     94 # blocks.  But this is normally disabled.
     95 #
     96 if {0} {
     97   db close
     98   sqlite3_shutdown
     99   sqlite3_config_lookaside 50 500
    100   sqlite3_initialize
    101   autoinstall_test_functions
    102   sqlite3 db test.db
    103 }
    104 
    105 do_mallocC_test 1 -sql {
    106   BEGIN;
    107   -- Allocate 32 new root pages. This will exercise the 'extract specific 
    108   -- page from the freelist' code when in auto-vacuum mode (see the
    109   -- allocatePage() routine in btree.c).
    110   CREATE TABLE t1(a UNIQUE, b UNIQUE, c UNIQUE);
    111   CREATE TABLE t2(a UNIQUE, b UNIQUE, c UNIQUE);
    112   CREATE TABLE t3(a UNIQUE, b UNIQUE, c UNIQUE);
    113   CREATE TABLE t4(a UNIQUE, b UNIQUE, c UNIQUE);
    114   CREATE TABLE t5(a UNIQUE, b UNIQUE, c UNIQUE);
    115   CREATE TABLE t6(a UNIQUE, b UNIQUE, c UNIQUE);
    116   CREATE TABLE t7(a UNIQUE, b UNIQUE, c UNIQUE);
    117   CREATE TABLE t8(a UNIQUE, b UNIQUE, c UNIQUE);
    118 
    119   ROLLBACK;
    120 }
    121 
    122 finish_test
    123