SQLite

Check-in [45bb84c628]
Login

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

Overview
Comment:Test the libraries response to read-only or unreadable database, WAL and wal-index files. If a WAL file cannot be opened in read/write mode, return SQLITE_CANTOPEN to the caller.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 45bb84c6283d803fc29077fdc2d06fa50ec06a59
User & Date: dan 2010-07-14 16:37:18.000
Original Comment: Test the libaries response to read-only or unreadable database, WAL and wal-index files. If a WAL file cannot be opened in read/write mode, return SQLITE_CANTOPEN to the caller.
Context
2010-07-14
18:10
Fix an assert() failure in wal2.test caused by messing with the contents of shared memory. (check-in: 9f452514d9 user: dan tags: trunk)
16:37
Test the libraries response to read-only or unreadable database, WAL and wal-index files. If a WAL file cannot be opened in read/write mode, return SQLITE_CANTOPEN to the caller. (check-in: 45bb84c628 user: dan tags: trunk)
14:48
On unix, try to create the *-wal and *-shm files with the same permissions as the associated database file. (check-in: e5d180eed2 user: dan tags: trunk)
Changes
Unified Diff Show Whitespace Changes Patch
Changes to src/wal.c.
1222
1223
1224
1225
1226
1227
1228



1229
1230
1231
1232
1233
1234
1235
  pRet->pDbFd = pDbFd;
  pRet->readLock = -1;
  pRet->zWalName = zWalName;

  /* Open file handle on the write-ahead log file. */
  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);




  if( rc!=SQLITE_OK ){
    walIndexClose(pRet, 0);
    sqlite3OsClose(pRet->pWalFd);
    sqlite3_free(pRet);
  }else{
    *ppWal = pRet;







>
>
>







1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
  pRet->pDbFd = pDbFd;
  pRet->readLock = -1;
  pRet->zWalName = zWalName;

  /* Open file handle on the write-ahead log file. */
  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
    rc = SQLITE_CANTOPEN;
  }

  if( rc!=SQLITE_OK ){
    walIndexClose(pRet, 0);
    sqlite3OsClose(pRet->pWalFd);
    sqlite3_free(pRet);
  }else{
    *ppWal = pRet;
Changes to test/malloc_common.tcl.
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
  }
}

#-------------------------------------------------------------------------
# Procedures to save and restore the current file-system state:
#
#   faultsim_save

#   faultsim_save_and_close
#   faultsim_restore_and_reopen
#   faultsim_delete_and_reopen
#
proc faultsim_save {} {
  foreach f [glob -nocomplain sv_test.db*] { file delete -force $f }
  foreach f [glob -nocomplain test.db*] {
    set f2 "sv_$f"
    file copy -force $f $f2
  }
}
proc faultsim_save_and_close {} {
  faultsim_save
  catch { db close }
  return ""
}
proc faultsim_restore_and_reopen {{dbfile test.db}} {
  catch { db close }
  foreach f [glob -nocomplain test.db*] { file delete -force $f }
  foreach f2 [glob -nocomplain sv_test.db*] {
    set f [string range $f2 3 end]
    file copy -force $f2 $f
  }




  sqlite3 db $dbfile
  sqlite3_extended_result_codes db 1
  sqlite3_db_config_lookaside db 0 0 0
}

proc faultsim_integrity_check {{db db}} {
  set ic [$db eval { PRAGMA integrity_check }]







>
















|
<





>
>
>
>







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
  }
}

#-------------------------------------------------------------------------
# Procedures to save and restore the current file-system state:
#
#   faultsim_save
#   faultsim_restore
#   faultsim_save_and_close
#   faultsim_restore_and_reopen
#   faultsim_delete_and_reopen
#
proc faultsim_save {} {
  foreach f [glob -nocomplain sv_test.db*] { file delete -force $f }
  foreach f [glob -nocomplain test.db*] {
    set f2 "sv_$f"
    file copy -force $f $f2
  }
}
proc faultsim_save_and_close {} {
  faultsim_save
  catch { db close }
  return ""
}
proc faultsim_restore {} {

  foreach f [glob -nocomplain test.db*] { file delete -force $f }
  foreach f2 [glob -nocomplain sv_test.db*] {
    set f [string range $f2 3 end]
    file copy -force $f2 $f
  }
}
proc faultsim_restore_and_reopen {{dbfile test.db}} {
  catch { db close }
  faultsim_restore
  sqlite3 db $dbfile
  sqlite3_extended_result_codes db 1
  sqlite3_db_config_lookaside db 0 0 0
}

proc faultsim_integrity_check {{db db}} {
  set ic [$db eval { PRAGMA integrity_check }]
Changes to test/wal2.test.
1001
1002
1003
1004
1005
1006
1007
1008
1009

1010
1011
1012
1013
1014
1015
1016
#-------------------------------------------------------------------------
# If a connection is required to create a WAL or SHM file, it creates 
# the new files with the same file-system permissions as the database 
# file itself. Test this.
#
if {$::tcl_platform(platform) == "unix"} {
  faultsim_delete_and_reopen

  set umask [exec /bin/sh -c umask]

  do_test wal2-12.1 {
    sqlite3 db test.db
    execsql { 
      CREATE TABLE tx(y, z);
      PRAGMA journal_mode = WAL;
    }
    db close







<

>







1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
#-------------------------------------------------------------------------
# If a connection is required to create a WAL or SHM file, it creates 
# the new files with the same file-system permissions as the database 
# file itself. Test this.
#
if {$::tcl_platform(platform) == "unix"} {
  faultsim_delete_and_reopen

  set umask [exec /bin/sh -c umask]

  do_test wal2-12.1 {
    sqlite3 db test.db
    execsql { 
      CREATE TABLE tx(y, z);
      PRAGMA journal_mode = WAL;
    }
    db close
1041
1042
1043
1044
1045
1046
1047
1048



























































































1049
1050
    } [list $effective $effective]
    do_test wal2-12.2.$tn.5 {
      db close
      list [file exists test.db-wal] [file exists test.db-shm]
    } {0 0}
  }
}




























































































finish_test









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


1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    } [list $effective $effective]
    do_test wal2-12.2.$tn.5 {
      db close
      list [file exists test.db-wal] [file exists test.db-shm]
    } {0 0}
  }
}

#-------------------------------------------------------------------------
# Test the libraries response to discovering that one or more of the
# database, wal or shm files cannot be opened, or can only be opened
# read-only.
#
if {$::tcl_platform(platform) == "unix"} {
  proc perm {} {
    set L [list]
    foreach f {test.db test.db-wal test.db-shm} {
      if {[file exists $f]} {
        lappend L [file attr $f -perm]
      } else {
        lappend L {}
      }
    }
    set L
  }

  faultsim_delete_and_reopen
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE t1(a, b);
    PRAGMA wal_checkpoint;
    INSERT INTO t1 VALUES('3.14', '2.72');
  }
  do_test wal2-13.1.1 {
    list [file exists test.db-shm] [file exists test.db-wal]
  } {1 1}
  faultsim_save_and_close

  foreach {tn db_perm wal_perm shm_perm can_open can_read can_write} {
    2   00644   00644   00644   1   1   1
    3   00644   00400   00644   1   0   0
    4   00644   00644   00400   1   0   0
    5   00400   00644   00644   1   1   0

    7   00644   00000   00644   1   0   0
    8   00644   00644   00000   1   0   0
    9   00000   00644   00644   0   0   0
  } {
    faultsim_restore
    do_test wal2-13.$tn.1 {
      file attr test.db     -perm $db_perm
      file attr test.db-wal -perm $wal_perm
      file attr test.db-shm -perm $shm_perm

      set     L [file attr test.db -perm]
      lappend L [file attr test.db-wal -perm]
      lappend L [file attr test.db-shm -perm]
    } [list $db_perm $wal_perm $shm_perm]

    # If $can_open is true, then it should be possible to open a database
    # handle. Otherwise, if $can_open is 0, attempting to open the db
    # handle throws an "unable to open database file" exception.
    #
    set r(1) {0 ok}
    set r(0) {1 {unable to open database file}}
    do_test wal2-13.$tn.2 {
      list [catch {sqlite3 db test.db ; set {} ok} msg] $msg
    } $r($can_open)

    if {$can_open} {

      # If $can_read is true, then the client should be able to read from
      # the database file. If $can_read is false, attempting to read should
      # throw the "unable to open database file" exception. 
      #
      set a(0) {1 {unable to open database file}}
      set a(1) {0 {3.14 2.72}}
      do_test wal2-13.$tn.3 {
        catchsql { SELECT * FROM t1 }
      } $a($can_read)
  
      # Now try to write to the db file. If the client can read but not
      # write, then it should throw the familiar "unable to open db file"
      # exception. If it can read but not write, the exception should
      # be "attempt to write a read only database".
      #
      # If the client can read and write, the operation should succeed.
      #
      set b(0,0) {1 {unable to open database file}}
      set b(1,0) {1 {attempt to write a readonly database}}
      set b(1,1) {0 {}}
      do_test wal2-13.$tn.4 {
        catchsql { INSERT INTO t1 DEFAULT VALUES }
      } $b($can_read,$can_write)
    }
    catch { db close }
  }
}

finish_test