1# 2014 May 6. 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# This file implements regression tests for SQLite library. 12# 13# The tests in this file are brute force tests of the multi-threaded 14# sorter. 15# 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19set testprefix sort4 20 21catch { db close } 22sqlite3_shutdown 23sqlite3_config_worker_threads 3 24sqlite3_initialize 25reset_db 26 27#-------------------------------------------------------------------- 28# Set up a table "t1" containing $nRow rows. Each row contains also 29# contains blob fields that total to at least $nPayload bytes of 30# content. 31# 32proc populate_table {nRow nPayload} { 33 set nCol 0 34 35 set n 0 36 for {set nCol 0} {$n < $nPayload} {incr nCol} { 37 incr n [expr (4 << $nCol)] 38 } 39 40 set cols [lrange [list xxx c0 c1 c2 c3 c4 c5 c6 c7] 1 $nCol] 41 set data [lrange [list xxx \ 42 randomblob(4) randomblob(8) randomblob(16) randomblob(32) \ 43 randomblob(64) randomblob(128) randomblob(256) randomblob(512) \ 44 ] 1 $nCol] 45 46 execsql { DROP TABLE IF EXISTS t1 } 47 48 db transaction { 49 execsql "CREATE TABLE t1(a, [join $cols ,], b);" 50 set insert "INSERT INTO t1 VALUES(:k, [join $data ,], :k)" 51 for {set i 0} {$i < $nRow} {incr i} { 52 set k [expr int(rand()*1000000000)] 53 execsql $insert 54 } 55 } 56} 57 58# Helper for [do_sorter_test] 59# 60proc sorter_test {nRow nRead {nPayload 100} {cache_size 10}} { 61 db eval "PRAGMA cache_size = $cache_size" 62 set res [list] 63 64 set nLoad [expr ($nRow > $nRead) ? $nRead : $nRow] 65 66 set nPayload [expr (($nPayload+3)/4) * 4] 67 set cols [list] 68 foreach {mask col} { 69 0x04 c0 0x08 c1 0x10 c2 0x20 c3 70 0x40 c4 0x80 c5 0x100 c6 0x200 c7 71 } { 72 if {$nPayload & $mask} { lappend cols $col } 73 } 74 75 set n 0 76 db eval "SELECT a, [join $cols ,], b FROM t1 WHERE rowid<=$nRow ORDER BY a" { 77 if {$a!=$b} { error "a!=b (a=$a b=$b)" } 78 lappend res $a 79 incr n 80 if {$n==$nLoad} break 81 } 82 83 84 set sql {SELECT a FROM t1 WHERE rowid<=$nRow ORDER BY a LIMIT $nRead} 85 if {$res != [db eval $sql]} { 86 puts $res 87 puts [db eval {SELECT a FROM t1 WHERE rowid<=$nLoad ORDER BY a}] 88 error "data no good" 89 } 90 91 set {} {} 92} 93 94# Usage: 95# 96# do_sorter_test <testname> <args>... 97# 98# where <args> are any of the following switches: 99# 100# -rows N (number of rows to have sorter sort) 101# -read N (number of rows to read out of sorter) 102# -payload N (bytes of payload to read with each row) 103# -cachesize N (Value for "PRAGMA cache_size = ?") 104# -repeats N (number of times to repeat test) 105# 106proc do_sorter_test {tn args} { 107 set a(-rows) 1000 108 set a(-repeats) 1 109 set a(-read) 100 110 set a(-payload) 100 111 set a(-cachesize) 100 112 113 foreach {s val} $args { 114 if {[info exists a($s)]==0} { 115 unset a(-cachesize) 116 set optlist "[join [array names a] ,] or -cachesize" 117 error "Unknown option $s, expected $optlist" 118 } 119 set a($s) $val 120 } 121 122 for {set i 0} {$i < $a(-repeats)} {incr i} { 123 set cmd [list sorter_test $a(-rows) $a(-read) $a(-payload) $a(-cachesize)] 124 do_test $tn.$i $cmd {} 125 } 126} 127 128do_test 1 { 129 execsql "PRAGMA page_size = 4096" 130 populate_table 100000 500 131} {} 132 133do_sorter_test 2 -repeats 10 -rows 1000 -read 100 134do_sorter_test 3 -repeats 10 -rows 100000 -read 1000 135do_sorter_test 4 -repeats 10 -rows 100000 -read 1000 -payload 500 136do_sorter_test 5 -repeats 10 -rows 100000 -read 100000 -payload 8 137do_sorter_test 6 -repeats 10 -rows 100000 -read 10 -payload 8 138 139catch { db close } 140sqlite3_shutdown 141sqlite3_config_worker_threads 0 142sqlite3_initialize 143finish_test 144 145 146