SQLite

Check-in [3d2de01181]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add tests to syscall.test and sysfault.test.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3d2de011814002e2e25b7645f94ff8fc7aab9cdd
User & Date: dan 2011-03-29 18:28:35.749
Context
2011-03-30
14:54
Do not generate sqlite_stat1 entries for empty tables when running ANALYZE. Ticket [83ea97620bd31016451] (check-in: 3a27af5b3c user: drh tags: trunk)
02:03
Merge in all the latest changes from trunk. (check-in: b11d941e92 user: drh tags: sessions)
2011-03-29
18:28
Add tests to syscall.test and sysfault.test. (check-in: 3d2de01181 user: dan tags: trunk)
15:40
Fix a problem whereby following an IO error in CommitPhaseTwo() of a multi-file transaction the b-tree layer could be left in TRANS_WRITE state, causing problems later on. (check-in: dbe569a099 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/test_syscall.c.
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
  return orig_stat(zPath, p);
}

/*
** A wrapper around fstat().
*/
static int ts_fstat(int fd, struct stat *p){
  if( tsIsFail() ){
    return -1;
  }
  return orig_fstat(fd, p);
}

/*
** A wrapper around ftruncate().







|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
  return orig_stat(zPath, p);
}

/*
** A wrapper around fstat().
*/
static int ts_fstat(int fd, struct stat *p){
  if( tsIsFailErrno("fstat") ){
    return -1;
  }
  return orig_fstat(fd, p);
}

/*
** A wrapper around ftruncate().
530
531
532
533
534
535
536


537
538
539
540
541
542
543
  struct Errno {
    const char *z;
    int i;
  } aErrno[] = {
    { "EACCES", EACCES },
    { "EINTR", EINTR },
    { "EIO", EIO },


    { 0, 0 }
  };

  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 2, objv, "SYSCALL ERRNO");
    return TCL_ERROR;
  }







>
>







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
  struct Errno {
    const char *z;
    int i;
  } aErrno[] = {
    { "EACCES", EACCES },
    { "EINTR", EINTR },
    { "EIO", EIO },
    { "EOVERFLOW", EOVERFLOW },
    { "ENOMEM", ENOMEM },
    { 0, 0 }
  };

  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 2, objv, "SYSCALL ERRNO");
    return TCL_ERROR;
  }
Changes to test/syscall.test.
99
100
101
102
103
104
105
106
107
























































































108
109
110
111
      execsql { ATTACH 'test.db2' AS aux }
      execsql {
        SELECT * FROM t1;
        SELECT * FROM t2;
      }
    } {1 2 5 6 3 4 7 8}
  }

}



























































































finish_test







|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
      execsql { ATTACH 'test.db2' AS aux }
      execsql {
        SELECT * FROM t1;
        SELECT * FROM t2;
      }
    } {1 2 5 6 3 4 7 8}
  }
}

#-------------------------------------------------------------------------
# This test verifies that closing database handles does not drop locks
# held by other database handles in the same process on the same file.
#
# The os_unix.c module has to take precautions to prevent this as the
# close() system call drops locks held by other file-descriptors on the
# same file. From the Linux man page:
#
#   close() closes a file descriptor, so that it no longer refers to any file
#   and may be reused. Any record locks (see fcntl(2)) held on the file it 
#   was associated with, and owned by the process, are removed (regardless 
#   of the file descriptor that was used to obtain the lock).
#
catch { db close }
forcedelete test.db test.db2

do_multiclient_test tn {
  code1 {
    sqlite3 dbX1 test.db
    sqlite3 dbX2 test.db
  }

  do_test syscall-5.$tn.1 {
    sql1 {
      CREATE TABLE t1(a, b);
      INSERT INTO t1 VALUES(1, 2);
      BEGIN;
        INSERT INTO t1 VALUES(3, 4);
    }
  } {}

  do_test syscall-5.$tn.2 { sql2 { SELECT * FROM t1 } } {1 2}
  do_test syscall-5.$tn.3 { 
    csql2 { INSERT INTO t1 VALUES(5, 6) }
  } {1 {database is locked}}

  do_test syscall-5.$tn.4 { 
    code1 {
      dbX1 close
      dbX2 close
    }
  } {}

  do_test syscall-5.$tn.5 { 
    csql2 { INSERT INTO t1 VALUES(5, 6) }
  } {1 {database is locked}}

  do_test syscall-5.$tn.6 { sql1 { COMMIT } } {}

  do_test syscall-5.$tn.7 { 
    csql2 { INSERT INTO t1 VALUES(5, 6) }
  } {0 {}}
}

catch {db close}
do_test 6.1 {
  sqlite3 db1 test.db1
  sqlite3 db2 test.db2
  sqlite3 db3 test.db3
  sqlite3 dbM ""

  db2 close
  db3 close
  dbM close
  db1 close
} {}

do_test 6.2 {
  sqlite3 db test.db
  execsql {
    PRAGMA temp_store = file;

    PRAGMA main.cache_size = 10;
    PRAGMA temp.cache_size = 10;
    CREATE TABLE temp.tt(a, b);
    INSERT INTO tt VALUES(randomblob(500), randomblob(600));
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
    INSERT INTO tt SELECT randomblob(500), randomblob(600) FROM tt;
  }

  db close
} {}



finish_test
Changes to test/sysfault.test.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63




64
65
66
67



















68
69
70
71
72
73
74

proc vfsfault_injectstart_t {iFail} { test_syscall fault $iFail 0 }
proc vfsfault_injectstart_p {iFail} { test_syscall fault $iFail 1 }
proc vfsfault_injectstop    {}      { test_syscall fault }

faultsim_save_and_close

proc vfsfault_install {} { 
  test_syscall install {open getcwd}
}

do_faultsim_test 1 -faults vfsfault-* -prep {
  faultsim_restore
} -body {
  sqlite3 db test.db
  db eval {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 2);
    PRAGMA journal_mode = WAL;
    INSERT INTO t1 VALUES(3, 4);
    SELECT * FROM t1;
    CREATE TEMP TABLE t2(x);
    INSERT INTO t2 VALUES('y');
  }

} -test {




  faultsim_test_result {0 {wal 1 2 3 4}}       \
    {1 {unable to open database file}}         \
    {1 {attempt to write a readonly database}}
}




















#-------------------------------------------------------------------------
# Check that a single EINTR error does not affect processing.
#
proc vfsfault_install {} { 
  test_syscall reset
  test_syscall install {open ftruncate close}







<
<
|
<
<
<
|










>
|
>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







39
40
41
42
43
44
45


46



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

proc vfsfault_injectstart_t {iFail} { test_syscall fault $iFail 0 }
proc vfsfault_injectstart_p {iFail} { test_syscall fault $iFail 1 }
proc vfsfault_injectstop    {}      { test_syscall fault }

faultsim_save_and_close







set open_and_write_body {
  sqlite3 db test.db
  db eval {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 2);
    PRAGMA journal_mode = WAL;
    INSERT INTO t1 VALUES(3, 4);
    SELECT * FROM t1;
    CREATE TEMP TABLE t2(x);
    INSERT INTO t2 VALUES('y');
  }
}

proc vfsfault_install {} { test_syscall install {open getcwd} }
do_faultsim_test 1 -faults vfsfault-* -prep {
  faultsim_restore
} -body $open_and_write_body -test {
  faultsim_test_result {0 {wal 1 2 3 4}}       \
    {1 {unable to open database file}}         \
    {1 {attempt to write a readonly database}}
}

# Errors in the fstat() function when opening and writing a file.
#
foreach {tn errno errlist} {
  1 ENOMEM       {{disk I/O error}}
  2 EOVERFLOW    {{disk I/O error} {large file support is disabled}}
} {
  proc vfsfault_install {} { test_syscall install fstat }
  set errs [list]
  foreach e $errlist { lappend errs [list 1 $e] }
  do_faultsim_test 1.2.$tn -faults vfsfault-* -prep {
    faultsim_restore
  } -body "
    test_syscall errno fstat $errno
    $open_and_write_body 
  " -test "
    faultsim_test_result {0 {wal 1 2 3 4}} $errs
  "
}

#-------------------------------------------------------------------------
# Check that a single EINTR error does not affect processing.
#
proc vfsfault_install {} { 
  test_syscall reset
  test_syscall install {open ftruncate close}
134
135
136
137
138
139
140



141
142
143
144
} -test {
  faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}} \
    {1 {unable to open database file}}                                      \
    {1 {unable to open database: test.db2}}                                 \
    {1 {attempt to write a readonly database}}                              \
    {1 {disk I/O error}}                                                  
}





finish_test








>
>
>




153
154
155
156
157
158
159
160
161
162
163
164
165
166
} -test {
  faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}} \
    {1 {unable to open database file}}                                      \
    {1 {unable to open database: test.db2}}                                 \
    {1 {attempt to write a readonly database}}                              \
    {1 {disk I/O error}}                                                  
}

#-------------------------------------------------------------------------
# 


finish_test