gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/syscall.test (about)

     1  # 2011 March 29
     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/lock_common.tcl
    16  source $testdir/malloc_common.tcl
    17  
    18  if {[llength [info commands test_syscall]]==0} {
    19    finish_test
    20    return
    21  } 
    22  
    23  if {[test_syscall defaultvfs] != "unix"} {
    24    finish_test
    25    return
    26  }
    27  set testprefix syscall
    28  
    29  #-------------------------------------------------------------------------
    30  # Tests for the xSetSystemCall method.
    31  #
    32  do_test 1.1.1 {
    33    list [catch { test_syscall reset open } msg] $msg
    34  } {0 {}}
    35  do_test 1.1.2 {
    36    list [catch { test_syscall reset nosuchcall } msg] $msg
    37  } {1 SQLITE_NOTFOUND}
    38  do_test 1.1.3 {
    39    list [catch { test_syscall reset open } msg] $msg
    40  } {0 {}}
    41  do_test 1.1.4 {
    42    list [catch { test_syscall reset ""} msg] $msg
    43  } {1 SQLITE_NOTFOUND}
    44  
    45  do_test 1.2 { test_syscall reset } {}
    46  
    47  do_test 1.3.1 { test_syscall install {open getcwd access} } {}
    48  do_test 1.3.2 { test_syscall reset } {}
    49  
    50  #-------------------------------------------------------------------------
    51  # Tests for the xGetSystemCall method.
    52  #
    53  do_test 2.1.1 { test_syscall exists open } 1
    54  do_test 2.1.2 { test_syscall exists nosuchcall } 0
    55  
    56  #-------------------------------------------------------------------------
    57  # Tests for the xNextSystemCall method.
    58  #
    59  foreach s {
    60      open close access getcwd stat fstat ftruncate
    61      fcntl read pread write pwrite fchmod fallocate
    62      pread64 pwrite64 unlink openDirectory mkdir rmdir 
    63      statvfs fchown geteuid umask mmap munmap mremap
    64      getpagesize readlink lstat ioctl
    65  } {
    66    if {[test_syscall exists $s]} {lappend syscall_list $s}
    67  }
    68  do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list]
    69  
    70  #-------------------------------------------------------------------------
    71  # This test verifies that if a call to open() fails and errno is set to
    72  # EINTR, the call is retried. If it succeeds, execution continues as if
    73  # nothing happened. 
    74  #
    75  test_syscall reset
    76  forcedelete test.db2
    77  do_execsql_test 4.1 {
    78    CREATE TABLE t1(x, y);
    79    INSERT INTO t1 VALUES(1, 2);
    80    ATTACH 'test.db2' AS aux;
    81    CREATE TABLE aux.t2(x, y);
    82    INSERT INTO t2 VALUES(3, 4);
    83  }
    84  
    85  db_save_and_close
    86  test_syscall install open
    87  foreach jrnl [list wal delete] {
    88    for {set i 1} {$i < 20} {incr i} {
    89      db_restore_and_reopen
    90      test_syscall fault $i 0
    91      test_syscall errno open EINTR
    92    
    93      do_test 4.2.$jrnl.$i {
    94        sqlite3 db test.db
    95        execsql { ATTACH 'test.db2' AS aux }
    96        execsql "PRAGMA main.journal_mode = $jrnl"
    97        execsql "PRAGMA aux.journal_mode = $jrnl"
    98        execsql {
    99          BEGIN;
   100            INSERT INTO t1 VALUES(5, 6);
   101            INSERT INTO t2 VALUES(7, 8);
   102          COMMIT;
   103        }
   104  
   105        db close
   106        sqlite3 db test.db
   107        execsql { ATTACH 'test.db2' AS aux }
   108        execsql {
   109          SELECT * FROM t1;
   110          SELECT * FROM t2;
   111        }
   112      } {1 2 5 6 3 4 7 8}
   113    }
   114  }
   115  
   116  #-------------------------------------------------------------------------
   117  # This test verifies that closing database handles does not drop locks
   118  # held by other database handles in the same process on the same file.
   119  #
   120  # The os_unix.c module has to take precautions to prevent this as the
   121  # close() system call drops locks held by other file-descriptors on the
   122  # same file. From the Linux man page:
   123  #
   124  #   close() closes a file descriptor, so that it no longer refers to any file
   125  #   and may be reused. Any record locks (see fcntl(2)) held on the file it 
   126  #   was associated with, and owned by the process, are removed (regardless 
   127  #   of the file descriptor that was used to obtain the lock).
   128  #
   129  catch { db close }
   130  forcedelete test.db test.db2
   131  
   132  do_multiclient_test tn {
   133    code1 {
   134      sqlite3 dbX1 test.db
   135      sqlite3 dbX2 test.db
   136    }
   137  
   138    do_test syscall-5.$tn.1 {
   139      sql1 {
   140        CREATE TABLE t1(a, b);
   141        INSERT INTO t1 VALUES(1, 2);
   142        BEGIN;
   143          INSERT INTO t1 VALUES(3, 4);
   144      }
   145    } {}
   146  
   147    do_test syscall-5.$tn.2 { sql2 { SELECT * FROM t1 } } {1 2}
   148    do_test syscall-5.$tn.3 { 
   149      csql2 { INSERT INTO t1 VALUES(5, 6) }
   150    } {1 {database is locked}}
   151  
   152    do_test syscall-5.$tn.4 { 
   153      code1 {
   154        dbX1 close
   155        dbX2 close
   156      }
   157    } {}
   158  
   159    do_test syscall-5.$tn.5 { 
   160      csql2 { INSERT INTO t1 VALUES(5, 6) }
   161    } {1 {database is locked}}
   162  
   163    do_test syscall-5.$tn.6 { sql1 { COMMIT } } {}
   164  
   165    do_test syscall-5.$tn.7 { 
   166      csql2 { INSERT INTO t1 VALUES(5, 6) }
   167    } {0 {}}
   168  }
   169  
   170  catch {db close}
   171  do_test 6.1 {
   172    sqlite3 db1 test.db1
   173    sqlite3 db2 test.db2
   174    sqlite3 db3 test.db3
   175    sqlite3 dbM ""
   176  
   177    db2 close
   178    db3 close
   179    dbM close
   180    db1 close
   181  } {}
   182  
   183  do_test 6.2 {
   184    sqlite3 db test.db
   185    execsql {
   186      PRAGMA temp_store = file;
   187  
   188      PRAGMA main.cache_size = 10;
   189      PRAGMA temp.cache_size = 10;
   190      CREATE TABLE temp.tt(a, b);
   191      INSERT INTO tt VALUES(randomblob(500), randomblob(600));
   192      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   193      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   194      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   195      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   196      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   197      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   198      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   199      INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
   200    }
   201  
   202    db close
   203  } {}
   204  
   205  #-------------------------------------------------------------------------
   206  # Test that a database file a single byte in size is treated as an empty
   207  # file. Whereas a file 2 bytes or larger might be considered corrupt.
   208  #
   209  catch { db close }
   210  forcedelete test.db test.db2
   211  
   212  proc create_db_file {nByte} {
   213    set fd [open test.db w]
   214    fconfigure $fd -translation binary -encoding binary
   215    puts -nonewline $fd [string range "xSQLite" 1 $nByte]
   216    close $fd
   217  }
   218  
   219  foreach {nByte res} {
   220    1      {0 {}}
   221    2      {1 {file is not a database}}
   222    3      {1 {file is not a database}}
   223  } {
   224    do_test 7.$nByte {
   225      create_db_file $nByte
   226      list [catch {
   227        sqlite3 db test.db
   228        execsql { CREATE TABLE t1(a, b) }
   229      } msg] $msg
   230    } $res
   231    catch { db close }
   232  }
   233  
   234  #-------------------------------------------------------------------------
   235  # 
   236  catch { db close }
   237  forcedelete test.db test.db2
   238  
   239  do_test 8.1 {
   240    sqlite3 db test.db
   241    file_control_chunksize_test db main 4096
   242    file size test.db
   243  } {0}
   244  foreach {tn hint size} {
   245    1  1000    4096 
   246    2  1000    4096 
   247    3  3000    4096 
   248    4  4096    4096 
   249    5  4197    8192 
   250  } {
   251    do_test 8.2.$tn {
   252      file_control_sizehint_test db main $hint
   253      file size test.db
   254    } $size
   255  }
   256  
   257  do_test 8.3 {
   258    db close
   259    forcedelete test.db test.db2
   260    sqlite3 db test.db
   261    file_control_chunksize_test db main 16
   262    file size test.db
   263  } {0}
   264  foreach {tn hint size} {
   265    1  5       16 
   266    2  13      16 
   267    3  45      48 
   268    4  48      48 
   269    5  49      64 
   270  } {
   271    do_test 8.4.$tn {
   272      file_control_sizehint_test db main $hint
   273      file size test.db
   274    } $size
   275  }
   276  
   277  test_syscall reset
   278  finish_test