CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
pendingrace.test124 linesDownload Raw Back to test
1# 2023 January 312#3# The author disclaims copyright to this source code.  In place of4# 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 13set testdir [file dirname $argv0]14source $testdir/tester.tcl15set testprefix pendingrace16 17# This test file tests that a race condition surrounding hot-journal18# rollback that once existed has been resolved. The problem was that19# if, when attempting to upgrade from a SHARED to EXCLUSIVE lock in20# order to roll back a hot journal, a connection failed to take the21# lock, the file-descriptor was left holding a PENDING lock for 22# a very short amount of time. In a multi-threaded deployment, this23# could allow a second connection to read the database without rolling24# back the hot journal.25#26 27testvfs tvfs 28db close29sqlite3 db test.db -vfs tvfs30 31# Create a 20 page database using connection [db]. Connection [db] uses32# Tcl VFS wrapper "tvfs", but it is configured to do straight pass-through33# for now.34#35do_execsql_test 1.0 {36  PRAGMA cache_size = 5;37  CREATE TABLE t1(a, b);38  CREATE INDEX i1 ON t1(a, b);39  WITH s(i) AS (40    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1041  )42  INSERT INTO t1 SELECT hex(randomblob(100)), hex(randomblob(100)) FROM s;43} {}44do_test 1.1a {45  set nPg [db one { PRAGMA page_count }]46  expr ($nPg==20 || $nPg==21)47} 148 49# Simulate a crash in another process. This leaves the db with a hot-journal.50# Without the journal the db is corrupt.51#52sqlite3 db2 test.db53do_execsql_test -db db2 1.1 {54  PRAGMA cache_size = 5;55  BEGIN;56    UPDATE t1 SET b=hex(randomblob(100));57}58db_save59db2 close60proc my_db_restore {} {61  forcecopy sv_test.db-journal test.db-journal62 63  set fd1 [open sv_test.db r]64  fconfigure $fd1 -translation binary65  set data [read $fd1]66  close $fd167 68  set fd1 [open test.db w]69  fconfigure $fd1 -translation binary70  puts -nonewline $fd1 $data71  close $fd172}73my_db_restore74do_test 1.2 {75  file exists test.db-journal76} {1}77 78# Set up connection [db2] to use Tcl VFS wrapper [tvfs2]. Which is configured79# so that the first call to xUnlock() fails. And then all VFS calls thereafter80# fail as well.81#82testvfs tvfs283tvfs2 filter xUnlock84tvfs2 script xUnlock85set ::seen_unlock 086proc xUnlock {args} {87  if {$::seen_unlock==0} {88    set ::seen_unlock 189    tvfs2 ioerr 1 190    tvfs2 filter {xLock xUnlock}91  }92  return ""93}94sqlite3 db2 test.db -vfs tvfs295 96# Configure [tvfs] (used by [db]) so that within the first call to xAccess,97# [db2] attempts to read the db. This causes [db2] to fail to upgrade to98# EXCLUSIVE, leaving it with a PENDING lock. Which it holds on to, 99# as the xUnlock() and all subsequent VFS calls fail.100#101tvfs filter xAccess102tvfs script xAccess103set ::seen_access 0104proc xAccess {args} {105  if {$::seen_access==0} {106    set ::seen_access 1107    catch { db2 eval { SELECT count(*)+0 FROM t1 } }108    breakpoint109  }110  return ""111}112 113# Run an integrity check using [db].114do_catchsql_test 1.3 {115  PRAGMA integrity_check116} {1 {database is locked}}117 118db close119db2 close120tvfs delete121tvfs2 delete122 123finish_test124