File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / loadext.test
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:16 2012 UTC (12 years, 4 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    1: # 2006 July 14
    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.  The
   12: # focus of this script is extension loading.
   13: #
   14: # $Id: loadext.test,v 1.1.1.1 2012/02/21 17:04:16 misho Exp $
   15: 
   16: set testdir [file dirname $argv0]
   17: source $testdir/tester.tcl
   18: 
   19: ifcapable !load_ext {
   20:   finish_test
   21:   return
   22: }
   23: 
   24: # The name of the test extension varies by operating system.
   25: #
   26: if {$::tcl_platform(platform) eq "windows" || $::tcl_platform(platform) eq "os2"} {
   27:   set testextension ./testloadext.dll
   28: } else {
   29:   set testextension ./libtestloadext.so
   30: }
   31: set gcc_shared "-shared -fPIC"
   32: if {$::tcl_platform(os) eq "Darwin"} {
   33:   set gcc_shared -dynamiclib
   34: }
   35: 
   36: # The error messages tested by this file are operating system dependent
   37: # (because they are returned by sqlite3OsDlError()). For now, they only
   38: # work with UNIX (and probably only certain kinds of UNIX).
   39: #
   40: # When a shared-object cannot be opened because it does not exist, the
   41: # format of the message returned is:
   42: #
   43: #      [format $dlerror_nosuchfile <shared-object-name>]
   44: #
   45: # When a shared-object cannot be opened because it consists of the 4
   46: # characters "blah" only, we expect the error message to be:
   47: #
   48: #      [format $dlerror_notadll <shared-object-name>]
   49: #
   50: # When a symbol cannot be found within an open shared-object, the error
   51: # message should be:
   52: #
   53: #      [format $dlerror_nosymbol <shared-object-name> <symbol-name>]
   54: #
   55: # The exact error messages are not important. The important bit is
   56: # that SQLite is correctly copying the message from xDlError().
   57: #
   58: set dlerror_nosuchfile \
   59:     {%s: cannot open shared object file: No such file or directory}
   60: set dlerror_notadll    {%s: file too short}
   61: set dlerror_nosymbol   {%s: undefined symbol: %s}
   62: 
   63: if {$::tcl_platform(os) eq "Darwin"} {
   64:   set dlerror_nosuchfile {dlopen(%s, 10): image not found}
   65:   set dlerror_notadll    {dlopen(%1$s, 10): no suitable image found.*}
   66:   set dlerror_nosymbol   {dlsym(XXX, %2$s): symbol not found}
   67: }
   68: 
   69: # Make sure the test extension actually exists.  If it does not
   70: # exist, try to create it.  If unable to create it, then skip this
   71: # test file.
   72: #
   73: if {![file exists $testextension]} {
   74:   set srcdir [file dir $testdir]/src
   75:   set testextsrc $srcdir/test_loadext.c
   76: 
   77:   set cmdline [concat exec gcc $gcc_shared]
   78:   lappend cmdline -Wall -I$srcdir -I. -g $testextsrc -o $testextension
   79:   
   80:   if {[catch $cmdline msg]} {
   81:     puts "Skipping loadext tests: Test extension not built..."
   82:     puts $msg
   83:     finish_test
   84:     return
   85:   }
   86: }
   87: 
   88: # Test that loading the extension produces the expected results - adding
   89: # the half() function to the specified database handle.
   90: #
   91: do_test loadext-1.1 {
   92:   catchsql {
   93:     SELECT half(1.0);
   94:   }
   95: } {1 {no such function: half}}
   96: do_test loadext-1.2 {
   97:   db enable_load_extension 1
   98:   sqlite3_load_extension db $testextension testloadext_init
   99:   catchsql {
  100:     SELECT half(1.0);
  101:   }
  102: } {0 0.5}
  103: 
  104: # Test that a second database connection (db2) can load the extension also.
  105: #
  106: do_test loadext-1.3 {
  107:   sqlite3 db2 test.db
  108:   sqlite3_enable_load_extension db2 1
  109:   catchsql {
  110:     SELECT half(1.0);
  111:   } db2
  112: } {1 {no such function: half}}
  113: do_test loadext-1.4 {
  114:   sqlite3_load_extension db2 $testextension testloadext_init
  115:   catchsql {
  116:     SELECT half(1.0);
  117:   } db2
  118: } {0 0.5}
  119: 
  120: # Close the first database connection. Then check that the second database
  121: # can still use the half() function without a problem.
  122: #
  123: do_test loadext-1.5 {
  124:   db close
  125:   catchsql {
  126:     SELECT half(1.0);
  127:   } db2
  128: } {0 0.5}
  129: 
  130: db2 close
  131: sqlite3 db test.db
  132: sqlite3_enable_load_extension db 1
  133: 
  134: # Try to load an extension for which the file does not exist.
  135: #
  136: do_test loadext-2.1 {
  137:   forcedelete ${testextension}xx
  138:   set rc [catch {
  139:     sqlite3_load_extension db "${testextension}xx"
  140:   } msg]
  141:   list $rc $msg
  142: } [list 1 [format $dlerror_nosuchfile ${testextension}xx]]
  143: 
  144: # Try to load an extension for which the file is not a shared object
  145: #
  146: do_test loadext-2.2 {
  147:   set fd [open "${testextension}xx" w]
  148:   puts $fd blah
  149:   close $fd
  150:   set rc [catch {
  151:     sqlite3_load_extension db "${testextension}xx"
  152:   } msg]
  153:   set expected_error_pattern [format $dlerror_notadll ${testextension}xx]
  154:   list $rc [string match $expected_error_pattern $msg]
  155: } [list 1 1]
  156: 
  157: # Try to load an extension for which the file is present but the
  158: # entry point is not.
  159: #
  160: do_test loadext-2.3 {
  161:   set rc [catch {
  162:     sqlite3_load_extension db $testextension icecream
  163:   } msg]
  164:   if {$::tcl_platform(os) eq "Darwin"} {
  165:     regsub {0x[1234567890abcdefABCDEF]*} $msg XXX msg
  166:   }
  167:   list $rc $msg
  168: } [list 1 [format $dlerror_nosymbol $testextension icecream]]
  169: 
  170: # Try to load an extension for which the entry point fails (returns non-zero) 
  171: #
  172: do_test loadext-2.4 {
  173:   set rc [catch {
  174:     sqlite3_load_extension db $testextension testbrokenext_init
  175:   } msg]
  176:   list $rc $msg
  177: } {1 {error during initialization: broken!}}
  178: 
  179: ############################################################################
  180: # Tests for the load_extension() SQL function
  181: #
  182: 
  183: db close
  184: sqlite3 db test.db
  185: sqlite3_enable_load_extension db 1
  186: do_test loadext-3.1 {
  187:   catchsql {
  188:     SELECT half(5);
  189:   }
  190: } {1 {no such function: half}}
  191: do_test loadext-3.2 {
  192:   set res [catchsql {
  193:     SELECT load_extension($::testextension)
  194:   }]
  195:   if {$::tcl_platform(os) eq "Darwin"} {
  196:     regsub {0x[1234567890abcdefABCDEF]*} $res XXX res
  197:   }
  198:   set res
  199: } [list 1 [format $dlerror_nosymbol $testextension sqlite3_extension_init]]
  200: do_test loadext-3.3 {
  201:   catchsql {
  202:     SELECT load_extension($::testextension,'testloadext_init')
  203:   }
  204: } {0 {{}}}
  205: do_test loadext-3.4 {
  206:   catchsql {
  207:     SELECT half(5);
  208:   }
  209: } {0 2.5}
  210: do_test loadext-3.5 {
  211:   db eval {
  212:     SELECT sqlite3_status('MEMORY_USED') AS mused
  213:   } break
  214:   puts -nonewline " (memory_used=$mused) "
  215:   expr {$mused>0}
  216: } {1}
  217: do_test loadext-3.6 {
  218:   catchsql {
  219:     SELECT sqlite3_status('MEMORY_USED_X') AS mused
  220:   }
  221: } {1 {unknown status property: MEMORY_USED_X}}
  222: do_test loadext-3.7 {
  223:   catchsql {
  224:     SELECT sqlite3_status(4.53) AS mused
  225:   }
  226: } {1 {unknown status type}}
  227: do_test loadext-3.8 {
  228:   catchsql {
  229:     SELECT sqlite3_status(23) AS mused
  230:   }
  231: } {1 {sqlite3_status(23,...) returns 21}}
  232: 
  233: # Ticket #1863
  234: # Make sure the extension loading mechanism will not work unless it
  235: # is explicitly enabled.
  236: #
  237: db close
  238: sqlite3 db test.db
  239: do_test loadext-4.1 {
  240:   catchsql {
  241:     SELECT load_extension($::testextension,'testloadext_init')
  242:   }
  243: } {1 {not authorized}}
  244: do_test loadext-4.2 {
  245:   sqlite3_enable_load_extension db 1
  246:   catchsql {
  247:     SELECT load_extension($::testextension,'testloadext_init')
  248:   }
  249: } {0 {{}}}
  250: 
  251: do_test loadext-4.3 {
  252:   sqlite3_enable_load_extension db 0
  253:   catchsql {
  254:     SELECT load_extension($::testextension,'testloadext_init')
  255:   }
  256: } {1 {not authorized}}
  257: 
  258: source $testdir/malloc_common.tcl
  259: 
  260: 
  261: # Malloc failure in sqlite3_auto_extension and sqlite3_load_extension
  262: #
  263: do_malloc_test loadext-5 -tclprep {
  264:   sqlite3_reset_auto_extension
  265: } -tclbody {
  266:   if {[autoinstall_test_functions]==7} {error "out of memory"}
  267: }
  268: do_malloc_test loadext-6 -tclbody {
  269:   db enable_load_extension 1
  270:   sqlite3_load_extension db $::testextension testloadext_init
  271: }
  272: autoinstall_test_functions
  273: 
  274: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>