1*1da57d55SToomas Soome#
27c478bd9Sstevel@tonic-gate# 2001 October 12
37c478bd9Sstevel@tonic-gate#
47c478bd9Sstevel@tonic-gate# The author disclaims copyright to this source code.  In place of
57c478bd9Sstevel@tonic-gate# a legal notice, here is a blessing:
67c478bd9Sstevel@tonic-gate#
77c478bd9Sstevel@tonic-gate#    May you do good and not evil.
87c478bd9Sstevel@tonic-gate#    May you find forgiveness for yourself and forgive others.
97c478bd9Sstevel@tonic-gate#    May you share freely, never taking more than you give.
107c478bd9Sstevel@tonic-gate#
117c478bd9Sstevel@tonic-gate#***********************************************************************
127c478bd9Sstevel@tonic-gate# This file implements regression tests for SQLite library.  The
137c478bd9Sstevel@tonic-gate# focus of this file is testing for correct handling of I/O errors
147c478bd9Sstevel@tonic-gate# such as writes failing because the disk is full.
15*1da57d55SToomas Soome#
167c478bd9Sstevel@tonic-gate# The tests in this file use special facilities that are only
177c478bd9Sstevel@tonic-gate# available in the SQLite test fixture.
187c478bd9Sstevel@tonic-gate#
197c478bd9Sstevel@tonic-gate# $Id: ioerr.test,v 1.3 2003/04/25 15:37:59 drh Exp $
207c478bd9Sstevel@tonic-gate
217c478bd9Sstevel@tonic-gateset testdir [file dirname $argv0]
227c478bd9Sstevel@tonic-gatesource $testdir/tester.tcl
237c478bd9Sstevel@tonic-gate
247c478bd9Sstevel@tonic-gateset ::go 1
257c478bd9Sstevel@tonic-gatefor {set n 1} {$go} {incr n} {
267c478bd9Sstevel@tonic-gate  do_test ioerr-1.$n.1 {
277c478bd9Sstevel@tonic-gate    set ::sqlite_io_error_pending 0
287c478bd9Sstevel@tonic-gate    db close
297c478bd9Sstevel@tonic-gate    catch {file delete -force test.db}
307c478bd9Sstevel@tonic-gate    catch {file delete -force test.db-journal}
317c478bd9Sstevel@tonic-gate    sqlite db test.db
327c478bd9Sstevel@tonic-gate    execsql {SELECT * FROM sqlite_master}
337c478bd9Sstevel@tonic-gate  } {}
347c478bd9Sstevel@tonic-gate  do_test ioerr-1.$n.2 [subst {
357c478bd9Sstevel@tonic-gate    set ::sqlite_io_error_pending $n
367c478bd9Sstevel@tonic-gate  }] $n
377c478bd9Sstevel@tonic-gate  do_test ioerr-1.$n.3 {
387c478bd9Sstevel@tonic-gate    set r [catch {db eval {
397c478bd9Sstevel@tonic-gate      CREATE TABLE t1(a,b,c);
407c478bd9Sstevel@tonic-gate      SELECT * FROM sqlite_master;
417c478bd9Sstevel@tonic-gate      BEGIN TRANSACTION;
427c478bd9Sstevel@tonic-gate      INSERT INTO t1 VALUES(1,2,3);
437c478bd9Sstevel@tonic-gate      INSERT INTO t1 VALUES(4,5,6);
447c478bd9Sstevel@tonic-gate      ROLLBACK;
457c478bd9Sstevel@tonic-gate      SELECT * FROM t1;
467c478bd9Sstevel@tonic-gate      BEGIN TRANSACTION;
477c478bd9Sstevel@tonic-gate      INSERT INTO t1 VALUES(1,2,3);
487c478bd9Sstevel@tonic-gate      INSERT INTO t1 VALUES(4,5,6);
497c478bd9Sstevel@tonic-gate      COMMIT;
507c478bd9Sstevel@tonic-gate      SELECT * FROM t1;
517c478bd9Sstevel@tonic-gate      DELETE FROM t1 WHERE a<100;
527c478bd9Sstevel@tonic-gate    }} msg]
537c478bd9Sstevel@tonic-gate    # if {$r} {puts $msg}
547c478bd9Sstevel@tonic-gate    set ::go [expr {$::sqlite_io_error_pending<=0}]
557c478bd9Sstevel@tonic-gate    expr {$::sqlite_io_error_pending>0 || $r!=0}
567c478bd9Sstevel@tonic-gate  } {1}
577c478bd9Sstevel@tonic-gate}
587c478bd9Sstevel@tonic-gateset ::sqlite_io_error_pending 0
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gateproc cksum {{db db}} {
617c478bd9Sstevel@tonic-gate  set txt [$db eval {SELECT name, type, sql FROM sqlite_master}]\n
627c478bd9Sstevel@tonic-gate  foreach tbl [$db eval {SELECT name FROM sqlite_master WHERE type='table'}] {
637c478bd9Sstevel@tonic-gate    append txt [$db eval "SELECT * FROM $tbl"]\n
647c478bd9Sstevel@tonic-gate  }
657c478bd9Sstevel@tonic-gate  foreach prag {default_synchronous default_cache_size} {
667c478bd9Sstevel@tonic-gate    append txt $prag-[$db eval "PRAGMA $prag"]\n
677c478bd9Sstevel@tonic-gate  }
687c478bd9Sstevel@tonic-gate  set cksum [string length $txt]-[md5 $txt]
697c478bd9Sstevel@tonic-gate  # puts $cksum-[file size test.db]
707c478bd9Sstevel@tonic-gate  return $cksum
717c478bd9Sstevel@tonic-gate}
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gateset ::go 1
747c478bd9Sstevel@tonic-gatefor {set n 1} {$go} {incr n} {
757c478bd9Sstevel@tonic-gate  do_test ioerr-2.$n.1 {
767c478bd9Sstevel@tonic-gate    set ::sqlite_io_error_pending 0
777c478bd9Sstevel@tonic-gate    db close
787c478bd9Sstevel@tonic-gate    catch {file delete -force test.db}
797c478bd9Sstevel@tonic-gate    catch {file delete -force test.db-journal}
807c478bd9Sstevel@tonic-gate    sqlite db test.db
817c478bd9Sstevel@tonic-gate    execsql {
827c478bd9Sstevel@tonic-gate      BEGIN;
837c478bd9Sstevel@tonic-gate      CREATE TABLE t1(a, b, c);
847c478bd9Sstevel@tonic-gate      INSERT INTO t1 VALUES(1, randstr(5,50), randstr(5,50));
857c478bd9Sstevel@tonic-gate      INSERT INTO t1 SELECT a+2, b||'-'||rowid, c||'-'||rowid FROM t1;
867c478bd9Sstevel@tonic-gate      INSERT INTO t1 SELECT a+4, b||'-'||rowid, c||'-'||rowid FROM t1;
877c478bd9Sstevel@tonic-gate      INSERT INTO t1 SELECT a+8, b||'-'||rowid, c||'-'||rowid FROM t1;
887c478bd9Sstevel@tonic-gate      INSERT INTO t1 SELECT a+16, b||'-'||rowid, c||'-'||rowid FROM t1;
897c478bd9Sstevel@tonic-gate      INSERT INTO t1 SELECT a+32, b||'-'||rowid, c||'-'||rowid FROM t1;
907c478bd9Sstevel@tonic-gate      INSERT INTO t1 SELECT a+64, b||'-'||rowid, c||'-'||rowid FROM t1;
917c478bd9Sstevel@tonic-gate      INSERT INTO t1 SELECT a+128, b||'-'||rowid, c||'-'||rowid FROM t1;
927c478bd9Sstevel@tonic-gate      CREATE TABLE t2 AS SELECT * FROM t1;
937c478bd9Sstevel@tonic-gate      CREATE TABLE t3 AS SELECT * FROM t1;
947c478bd9Sstevel@tonic-gate      COMMIT;
957c478bd9Sstevel@tonic-gate      DROP TABLE t2;
967c478bd9Sstevel@tonic-gate    }
977c478bd9Sstevel@tonic-gate    set ::cksum [cksum]
987c478bd9Sstevel@tonic-gate    execsql {
997c478bd9Sstevel@tonic-gate      SELECT name FROM sqlite_master WHERE type='table'
1007c478bd9Sstevel@tonic-gate    }
1017c478bd9Sstevel@tonic-gate  } {t1 t3}
1027c478bd9Sstevel@tonic-gate  do_test ioerr-2.$n.2 [subst {
1037c478bd9Sstevel@tonic-gate    set ::sqlite_io_error_pending $n
1047c478bd9Sstevel@tonic-gate  }] $n
1057c478bd9Sstevel@tonic-gate  do_test ioerr-2.$n.3 {
1067c478bd9Sstevel@tonic-gate    set r [catch {db eval {
1077c478bd9Sstevel@tonic-gate      VACUUM;
1087c478bd9Sstevel@tonic-gate    }} msg]
1097c478bd9Sstevel@tonic-gate    # puts "error_pending=$::sqlite_io_error_pending"
1107c478bd9Sstevel@tonic-gate    # if {$r} {puts $msg}
1117c478bd9Sstevel@tonic-gate    set ::go [expr {$::sqlite_io_error_pending<=0}]
1127c478bd9Sstevel@tonic-gate    expr {$::sqlite_io_error_pending>0 || $r!=0}
1137c478bd9Sstevel@tonic-gate    set ::sqlite_io_error_pending 0
1147c478bd9Sstevel@tonic-gate    db close
1157c478bd9Sstevel@tonic-gate    sqlite db test.db
1167c478bd9Sstevel@tonic-gate    cksum
1177c478bd9Sstevel@tonic-gate  } $cksum
1187c478bd9Sstevel@tonic-gate}
1197c478bd9Sstevel@tonic-gateset ::sqlite_io_error_pending 0
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gatefinish_test
122