/ Check-in [44e56f0b]
Login

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

Overview
Comment:Additional code to test the SQLITE_FULL return when the disk is full. (CVS 1994)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:44e56f0bba61245d342d6e75510d6c35785efd49
User & Date: drh 2004-10-01 14:38:03
Context
2004-10-01
18:21
make diskfull test work on Windows; see check-in (1994) (CVS 1996) check-in: 4493e287 user: dougcurrie tags: trunk
14:38
Additional code to test the SQLITE_FULL return when the disk is full. (CVS 1994) check-in: 44e56f0b user: drh tags: trunk
03:02
Fully release exclusive locks in the Unlock primitive of Unix. Ticket #913. (CVS 1993) check-in: 11a37a74 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_common.h.

77
78
79
80
81
82
83

84
85
86
87
88
89



90
91

92
93
94
95
96
97
98
99
100
101
102
/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/
#ifdef SQLITE_TEST
int sqlite3_io_error_pending = 0;

#define SimulateIOError(A)  \
   if( sqlite3_io_error_pending ) \
     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
static void local_ioerr(){
  sqlite3_io_error_pending = 0;  /* Really just a place to set a breakpoint */
}



#else
#define SimulateIOError(A)

#endif

/*
** When testing, keep a count of the number of open files.
*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif







>






>
>
>


>











77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/
#ifdef SQLITE_TEST
int sqlite3_io_error_pending = 0;
int sqlite3_diskfull_pending = 0;
#define SimulateIOError(A)  \
   if( sqlite3_io_error_pending ) \
     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
static void local_ioerr(){
  sqlite3_io_error_pending = 0;  /* Really just a place to set a breakpoint */
}
#define SimulateDiskfullError \
   if( sqlite3_diskfull_pending ) \
     if( sqlite3_diskfull_pending-- == 1 ){ local_ioerr(); return SQLITE_FULL; }
#else
#define SimulateIOError(A)
#define SimulateDiskfullError
#endif

/*
** When testing, keep a count of the number of open files.
*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif

Changes to src/os_unix.c.

642
643
644
645
646
647
648

649
650
651
652
653
654
655
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
  int wrote = 0;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);

  TIMER_START;
  while( amt>0 && (wrote = write(id->h, pBuf, amt))>0 ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  TIMER_END;
  TRACE4("WRITE   %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED);







>







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
  int wrote = 0;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  SimulateDiskfullError;
  TIMER_START;
  while( amt>0 && (wrote = write(id->h, pBuf, amt))>0 ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  TIMER_END;
  TRACE4("WRITE   %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED);

Changes to src/test2.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
529
530
531
532
533
534
535

536
537
538
539
540
541
542
...
556
557
558
559
560
561
562


563
564
565
566
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.26 2004/10/01 02:00:31 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
}

/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest2_Init(Tcl_Interp *interp){
  extern int sqlite3_io_error_pending;

  static struct {
    char *zName;
    Tcl_CmdProc *xProc;
  } aCmd[] = {
    { "pager_open",              (Tcl_CmdProc*)pager_open          },
    { "pager_close",             (Tcl_CmdProc*)pager_close         },
    { "pager_commit",            (Tcl_CmdProc*)pager_commit        },
................................................................................
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "sqlite_io_error_pending",
     (char*)&sqlite3_io_error_pending, TCL_LINK_INT);


  Tcl_LinkVar(interp, "pager_pagesize",
     (char*)&test_pagesize, TCL_LINK_INT);
  return TCL_OK;
}







|







 







>







 







>
>




9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
...
557
558
559
560
561
562
563
564
565
566
567
568
569
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.27 2004/10/01 14:38:03 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
}

/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest2_Init(Tcl_Interp *interp){
  extern int sqlite3_io_error_pending;
  extern int sqlite3_diskfull_pending;
  static struct {
    char *zName;
    Tcl_CmdProc *xProc;
  } aCmd[] = {
    { "pager_open",              (Tcl_CmdProc*)pager_open          },
    { "pager_close",             (Tcl_CmdProc*)pager_close         },
    { "pager_commit",            (Tcl_CmdProc*)pager_commit        },
................................................................................
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "sqlite_io_error_pending",
     (char*)&sqlite3_io_error_pending, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_diskfull_pending",
     (char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
  Tcl_LinkVar(interp, "pager_pagesize",
     (char*)&test_pagesize, TCL_LINK_INT);
  return TCL_OK;
}

Added test/diskfull.test.

















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 2001 October 12
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of disk full
# errors.
# 
# $Id: diskfull.test,v 1.1 2004/10/01 14:38:03 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test diskfull-1.1 {
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(randstr(1000,1000));
    INSERT INTO t1 SELECT * FROM t1;
  }
} {}
do_test diskfull-1.2 {
  set sqlite_diskfull_pending 1
  catchsql {
    INSERT INTO t1 SELECT * FROM t1;
  }
} {1 {database is full}}
do_test diskfull-1.3 {
  set sqlite_diskfull_pending 1
  catchsql {
    DELETE FROM t1;
  }
} {1 {database is full}}

finish_test

Changes to test/ioerr.test.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
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
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
# 
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: ioerr.test,v 1.5 2004/06/19 00:16:31 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set ::go 1
for {set n 1} {$go} {incr n} {
  do_test ioerr-1.$n.1 {
................................................................................
      SELECT name FROM sqlite_master WHERE type='table'
    }
  } {t1 t3}
  do_test ioerr-2.$n.2 [subst {
    set ::sqlite_io_error_pending $n
  }] $n
  do_test ioerr-2.$n.3 {
if {$n==41} {
  # set sqlite_os_trace 1
  breakpoint
}
    set r [catch {db eval {
      VACUUM;
    }} msg]
    # puts "error_pending=$::sqlite_io_error_pending"
    # if {$r} {puts $msg}
set sqlite_os_trace 0
    set ::go [expr {$::sqlite_io_error_pending<=0}]
    expr {$::sqlite_io_error_pending>0 || $r!=0}
    set ::sqlite_io_error_pending 0
    db close
    sqlite3 db test.db
    cksum
  } $cksum
}
set ::sqlite_io_error_pending 0

finish_test







|







 







<
<
<
<



<
<
<











11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
102
103
104
105
106
107
108




109
110
111



112
113
114
115
116
117
118
119
120
121
122
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
# 
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: ioerr.test,v 1.6 2004/10/01 14:38:03 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set ::go 1
for {set n 1} {$go} {incr n} {
  do_test ioerr-1.$n.1 {
................................................................................
      SELECT name FROM sqlite_master WHERE type='table'
    }
  } {t1 t3}
  do_test ioerr-2.$n.2 [subst {
    set ::sqlite_io_error_pending $n
  }] $n
  do_test ioerr-2.$n.3 {




    set r [catch {db eval {
      VACUUM;
    }} msg]



    set ::go [expr {$::sqlite_io_error_pending<=0}]
    expr {$::sqlite_io_error_pending>0 || $r!=0}
    set ::sqlite_io_error_pending 0
    db close
    sqlite3 db test.db
    cksum
  } $cksum
}
set ::sqlite_io_error_pending 0

finish_test