/ Check-in [11b2564e]
Login

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

Overview
Comment:Tests for the new asynchronous IO API. (CVS 6549)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:11b2564e7159168cd0815bb9bc93688586fad1e0
User & Date: danielk1977 2009-04-25 08:39:15
Context
2009-04-27
18:46
Bring the documenation and implementation of sqlite3_collation_needed() into agreement. Use a more efficient implementation of sqlite3ErrStr(). sqlite3_result_error_code() now calls sqlite3ErrStr() if no prior error string was set. (CVS 6550) check-in: cb9af829 user: drh tags: trunk
2009-04-25
08:39
Tests for the new asynchronous IO API. (CVS 6549) check-in: 11b2564e user: danielk1977 tags: trunk
2009-04-24
20:32
Add another test case for the "x IS NULL" uniqueness problem of ticket #3824. No changes to code. This just double-checks that everything is working now. (CVS 6548) check-in: 3ceae357 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to configure.ac.

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# change the argument to AC_INIT().  And disable any features that
# you don't need (for example BLT) by erasing or commenting out
# the corresponding code.
#
AC_INIT(sqlite, m4_esyscmd([cat VERSION | tr -d '\n']))

dnl Make sure the local VERSION file matches this configure script
sqlite_version_sanity_check=`cat VERSION | tr -d '\n'`
if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then
AC_MSG_ERROR([configure script is out of date:
 configure \$PACKAGE_VERSION = $PACKAGE_VERSION
 top level VERSION file     = $sqlite_version_sanity_check
please regen with autoconf])
fi

dnl Put the RCS revision string after AC_INIT so that it will also
dnl show in in configure.
# The following RCS revision string applies to configure.in
# $Revision: 1.55 $

#########
# Programs needed
#
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_AWK







|










|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# change the argument to AC_INIT().  And disable any features that
# you don't need (for example BLT) by erasing or commenting out
# the corresponding code.
#
AC_INIT(sqlite, m4_esyscmd([cat VERSION | tr -d '\n']))

dnl Make sure the local VERSION file matches this configure script
sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'`
if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then
AC_MSG_ERROR([configure script is out of date:
 configure \$PACKAGE_VERSION = $PACKAGE_VERSION
 top level VERSION file     = $sqlite_version_sanity_check
please regen with autoconf])
fi

dnl Put the RCS revision string after AC_INIT so that it will also
dnl show in in configure.
# The following RCS revision string applies to configure.in
# $Revision: 1.56 $

#########
# Programs needed
#
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_AWK

Changes to ext/async/sqlite3async.c.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
....
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
**
**    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.
**
*************************************************************************
**
** $Id: sqlite3async.c,v 1.3 2009/04/24 10:13:06 danielk1977 Exp $
**
** This file contains the implementation of an asynchronous IO backend 
** for SQLite.
*/

#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO)

................................................................................
    /* Drop the queue mutex before continuing to the next write operation
    ** in order to give other threads a chance to work with the write queue.
    */
    if( !async.pQueueFirst || !async.ioError ){
      async_mutex_leave(ASYNC_MUTEX_QUEUE);
      holdingMutex = 0;
      if( async.ioDelay>0 ){
        pVfs->xSleep(pVfs, async.ioDelay);
      }else{
        async_sched_yield();
      }
    }
  }
  
  async_mutex_leave(ASYNC_MUTEX_WRITER);







|







 







|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
....
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
**
**    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.
**
*************************************************************************
**
** $Id: sqlite3async.c,v 1.4 2009/04/25 08:39:15 danielk1977 Exp $
**
** This file contains the implementation of an asynchronous IO backend 
** for SQLite.
*/

#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO)

................................................................................
    /* Drop the queue mutex before continuing to the next write operation
    ** in order to give other threads a chance to work with the write queue.
    */
    if( !async.pQueueFirst || !async.ioError ){
      async_mutex_leave(ASYNC_MUTEX_QUEUE);
      holdingMutex = 0;
      if( async.ioDelay>0 ){
        pVfs->xSleep(pVfs, async.ioDelay*1000);
      }else{
        async_sched_yield();
      }
    }
  }
  
  async_mutex_leave(ASYNC_MUTEX_WRITER);

Changes to src/test_async.c.

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
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
94
95
96
97
98
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
...
194
195
196
197
198
199
200









































































201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
**
**    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.
**
*************************************************************************
**
** $Id: test_async.c,v 1.60 2009/04/24 10:13:06 danielk1977 Exp $
**
** This file contains a binding of the asynchronous IO extension interface
** (defined in ext/async/sqlite3async.h) to Tcl.
*/

#define TCL_THREADS 
#include <tcl.h>
................................................................................

#ifdef SQLITE_ENABLE_ASYNCIO

#include "sqlite3async.h"
#include "sqlite3.h"
#include <assert.h>





struct TestAsyncGlobal {
  int isInstalled;                     /* True when async VFS is installed */
} testasync_g = { 0 };

TCL_DECLARE_MUTEX(testasync_g_writerMutex);

/*
** sqlite3async_enable ?YES/NO?
**
** Enable or disable the asynchronous I/O backend.  This command is
** not thread-safe.  Do not call it while any database connections
** are open.
*/
static int testAsyncEnable(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?YES/NO?");
    return TCL_ERROR;
  }
  if( objc==1 ){
    Tcl_SetObjResult(interp, Tcl_NewIntObj(testasync_g.isInstalled));
  }else{
    int enable;
    if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ) return TCL_ERROR;
    if( enable ){
      sqlite3async_initialize(0, 1);
    }else{
      sqlite3async_shutdown();
    }
    testasync_g.isInstalled = enable;





  }
  return TCL_OK;
}

/*
** sqlite3async_halt  ?"now"|"idle"|"never"?
**
** Set the conditions at which the writer thread will halt.
*/
static int testAsyncHalt(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int eWhen;
  const char *azConstant[] = { "never", "now", "idle", 0 };

  assert( SQLITEASYNC_HALT_NEVER==0 );
  assert( SQLITEASYNC_HALT_NOW==1 );
  assert( SQLITEASYNC_HALT_IDLE==2 );

  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?OPTION?");
    return TCL_ERROR;
  }
  if( objc==2 ){
    if( Tcl_GetIndexFromObj(interp, objv[1], azConstant, "option", 0, &eWhen) ){
      return TCL_ERROR;
    }
    sqlite3async_control(SQLITEASYNC_HALT, eWhen);
  }

  /* Always return the current value of the 'halt' option. */
  sqlite3async_control(SQLITEASYNC_GET_HALT, &eWhen);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(azConstant[eWhen], -1));

  return TCL_OK;
}

/*
** sqlite3async_delay ?MS?
**
** Query or set the number of milliseconds of delay in the writer
** thread after each write operation.  The default is 0.  By increasing
** the memory delay we can simulate the effect of slow disk I/O.
*/
static int testAsyncDelay(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int iMs;
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?MS?");
    return TCL_ERROR;
  }
  if( objc==2 ){
    if( Tcl_GetIntFromObj(interp, objv[1], &iMs) ){
      return TCL_ERROR;
    }
    sqlite3async_control(SQLITEASYNC_DELAY, iMs);
  }

  /* Always return the current value of the 'delay' option. */
  sqlite3async_control(SQLITEASYNC_GET_DELAY, &iMs);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(iMs));
  return TCL_OK;
}

static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){
  Tcl_MutexLock(&testasync_g_writerMutex);
  *((int *)pIsStarted) = 1;
  sqlite3async_run();
................................................................................
    return TCL_ERROR;
  }

  Tcl_MutexLock(&testasync_g_writerMutex);
  Tcl_MutexUnlock(&testasync_g_writerMutex);
  return TCL_OK;
}










































































#endif  /* SQLITE_ENABLE_ASYNCIO */

/*
** This routine registers the custom TCL commands defined in this
** module.  This should be the only procedure visible from outside
** of this module.
*/
int Sqlitetestasync_Init(Tcl_Interp *interp){
#if SQLITE_ENABLE_ASYNCIO
  Tcl_CreateObjCommand(interp,"sqlite3async_enable",testAsyncEnable,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_halt",testAsyncHalt,0,0);

  Tcl_CreateObjCommand(interp,"sqlite3async_delay",testAsyncDelay,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0);
#endif  /* SQLITE_ENABLE_ASYNCIO */
  return TCL_OK;
}








|







 







>
>
>








|
<
<
<
<

|





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





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<

|





<
<
<
<
<
<
<
<
<
|
<
<
<
<
<







 







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










|
|
>
|
|
|




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
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
...
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
**
**    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.
**
*************************************************************************
**
** $Id: test_async.c,v 1.61 2009/04/25 08:39:15 danielk1977 Exp $
**
** This file contains a binding of the asynchronous IO extension interface
** (defined in ext/async/sqlite3async.h) to Tcl.
*/

#define TCL_THREADS 
#include <tcl.h>
................................................................................

#ifdef SQLITE_ENABLE_ASYNCIO

#include "sqlite3async.h"
#include "sqlite3.h"
#include <assert.h>

/* From test1.c */
const char *sqlite3TestErrorName(int);


struct TestAsyncGlobal {
  int isInstalled;                     /* True when async VFS is installed */
} testasync_g = { 0 };

TCL_DECLARE_MUTEX(testasync_g_writerMutex);

/*
** sqlite3async_initialize PARENT-VFS ISDEFAULT




*/
static int testAsyncInit(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  const char *zParent;
  int isDefault;
  int rc;

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "PARENT-VFS ISDEFAULT");
    return TCL_ERROR;
  }
  zParent = Tcl_GetString(objv[1]);
  if( !*zParent ) {
    zParent = 0;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){
    return TCL_ERROR;
  }

  rc = sqlite3async_initialize(zParent, isDefault);
  if( rc!=SQLITE_OK ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3TestErrorName(rc), -1));
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*




































** sqlite3async_shutdown




*/
static int testAsyncShutdown(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){









  sqlite3async_shutdown();





  return TCL_OK;
}

static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){
  Tcl_MutexLock(&testasync_g_writerMutex);
  *((int *)pIsStarted) = 1;
  sqlite3async_run();
................................................................................
    return TCL_ERROR;
  }

  Tcl_MutexLock(&testasync_g_writerMutex);
  Tcl_MutexUnlock(&testasync_g_writerMutex);
  return TCL_OK;
}

/*
** sqlite3async_control OPTION ?VALUE?
*/
static int testAsyncControl(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = SQLITE_OK;
  int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES };
  const char *azOpt[] = { "halt", "delay", "lockfiles", 0 };
  const char *az[] = { "never", "now", "idle", 0 };
  int iVal;
  int eOpt;

  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "OPTION ?VALUE?");
    return TCL_ERROR;
  }
  if( Tcl_GetIndexFromObj(interp, objv[1], azOpt, "option", 0, &eOpt) ){
    return TCL_ERROR;
  }
  eOpt = aeOpt[eOpt];

  if( objc==3 ){
    switch( eOpt ){
      case SQLITEASYNC_HALT: {
        assert( SQLITEASYNC_HALT_NEVER==0 );
        assert( SQLITEASYNC_HALT_NOW==1 );
        assert( SQLITEASYNC_HALT_IDLE==2 );
        if( Tcl_GetIndexFromObj(interp, objv[2], az, "value", 0, &iVal) ){
          return TCL_ERROR;
        }
        break;
      }
      case SQLITEASYNC_DELAY:
        if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ){
          return TCL_ERROR;
        }
        break;

      case SQLITEASYNC_LOCKFILES:
        if( Tcl_GetBooleanFromObj(interp, objv[2], &iVal) ){
          return TCL_ERROR;
        }
        break;
    }

    rc = sqlite3async_control(eOpt, iVal);
  }

  if( rc==SQLITE_OK ){
    rc = sqlite3async_control(
        eOpt==SQLITEASYNC_HALT ? SQLITEASYNC_GET_HALT :
        eOpt==SQLITEASYNC_DELAY ? SQLITEASYNC_GET_DELAY :
        SQLITEASYNC_GET_LOCKFILES, &iVal);
  }

  if( rc!=SQLITE_OK ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3TestErrorName(rc), -1));
    return TCL_ERROR;
  }

  if( eOpt==SQLITEASYNC_HALT ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(az[iVal], -1));
  }else{
    Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
  }

  return TCL_OK;
}

#endif  /* SQLITE_ENABLE_ASYNCIO */

/*
** This routine registers the custom TCL commands defined in this
** module.  This should be the only procedure visible from outside
** of this module.
*/
int Sqlitetestasync_Init(Tcl_Interp *interp){
#if SQLITE_ENABLE_ASYNCIO
  Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0);

  Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0);
#endif  /* SQLITE_ENABLE_ASYNCIO */
  return TCL_OK;
}

Changes to test/async.test.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
37
38
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
#    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 runs all tests.
#
# $Id: async.test,v 1.19 2009/04/11 10:25:04 danielk1977 Exp $

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

if {[catch {sqlite3async_enable}]} {
  # The async logic is not built into this system
  finish_test
  return
}

rename finish_test async_really_finish_test
proc finish_test {} {
................................................................................
  select2.test
  select3.test
  select4.test
  trans.test
}

# Enable asynchronous IO.
sqlite3async_enable 1

rename do_test async_really_do_test
proc do_test {name args} {
  uplevel async_really_do_test async_io-$name $args
  sqlite3async_start
  sqlite3async_halt idle
  sqlite3async_wait
  sqlite3async_halt never
}

foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
  set tail [file tail $testfile]
  if {[lsearch -exact $ASYNC_INCLUDE $tail]<0} continue
  source $testfile

  # Make sure everything is flushed through. This is because [source]ing 
  # the next test file will delete the database file on disk (using
  # [file delete]). If the asynchronous backend still has the file
  # open, it will become confused.
  #
  sqlite3async_halt idle
  sqlite3async_start
  sqlite3async_wait
  sqlite3async_halt never
}

# Flush the write-queue and disable asynchronous IO. This should ensure
# all allocated memory is cleaned up.
set sqlite3async_trace 1
sqlite3async_halt idle
sqlite3async_start
sqlite3async_wait
sqlite3async_halt never
sqlite3async_enable 0
set sqlite3async_trace 0

rename do_test {}
rename async_really_do_test do_test
rename finish_test {}
rename async_really_finish_test finish_test

if {[info exists ASYNC_SAVE_ISQUICK]} { set ISQUICK $ASYNC_SAVE_ISQUICK }
finish_test








|




|







 







|





|

|












|


|





|


|
|










2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
37
38
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
#    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 runs all tests.
#
# $Id: async.test,v 1.20 2009/04/25 08:39:15 danielk1977 Exp $

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

if {[info commands sqlite3async_initialize] eq ""} {
  # The async logic is not built into this system
  finish_test
  return
}

rename finish_test async_really_finish_test
proc finish_test {} {
................................................................................
  select2.test
  select3.test
  select4.test
  trans.test
}

# Enable asynchronous IO.
sqlite3async_initialize "" 1

rename do_test async_really_do_test
proc do_test {name args} {
  uplevel async_really_do_test async_io-$name $args
  sqlite3async_start
  sqlite3async_control halt idle
  sqlite3async_wait
  sqlite3async_control halt never
}

foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
  set tail [file tail $testfile]
  if {[lsearch -exact $ASYNC_INCLUDE $tail]<0} continue
  source $testfile

  # Make sure everything is flushed through. This is because [source]ing 
  # the next test file will delete the database file on disk (using
  # [file delete]). If the asynchronous backend still has the file
  # open, it will become confused.
  #
  sqlite3async_control halt idle
  sqlite3async_start
  sqlite3async_wait
  sqlite3async_control halt never
}

# Flush the write-queue and disable asynchronous IO. This should ensure
# all allocated memory is cleaned up.
set sqlite3async_trace 1
sqlite3async_control halt idle
sqlite3async_start
sqlite3async_wait
sqlite3async_control halt never
sqlite3async_shutdown
set sqlite3async_trace 0

rename do_test {}
rename async_really_do_test do_test
rename finish_test {}
rename async_really_finish_test finish_test

if {[info exists ASYNC_SAVE_ISQUICK]} { set ISQUICK $ASYNC_SAVE_ISQUICK }
finish_test

Changes to test/async2.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
#
#    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.
#
#***********************************************************************
#
# $Id: async2.test,v 1.11 2009/04/23 18:41:26 shane Exp $


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

if {
  [info commands sqlite3async_enable]=="" ||
  [info command sqlite3_memdebug_fail]==""
} {
  # The async logic is not built into this system
  puts "Skipping async2 tests: not compiled with required features"
  finish_test
  return
}
................................................................................
    set ::sqlite_io_error_pending 0
    sqlite3_memdebug_fail -1
    file delete -force test.db test.db-journal
    sqlite3 db test.db
    execsql $::setup_script
    db close
  
    sqlite3async_enable 1
    sqlite3 db test.db
    sqlite3_db_config_lookaside db 0 0 0
  
    switch -- $err {
      ioerr             { set ::sqlite_io_error_pending $n }
      malloc-persistent { sqlite3_memdebug_fail $n -repeat 1 }
      malloc-transient  { sqlite3_memdebug_fail $n -repeat 0 }
    }

    catchsql $::sql_script
    db close

    sqlite3async_halt idle
    sqlite3async_start
    sqlite3async_wait
    sqlite3async_halt never
    sqlite3async_enable 0

    set ::sqlite_io_error_pending 0
    sqlite3_memdebug_fail -1

    sqlite3 db test.db
    set c [db one {SELECT c FROM counter LIMIT 1}]
    switch -- $c {







|






|







 







|












|


|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
#
#    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.
#
#***********************************************************************
#
# $Id: async2.test,v 1.12 2009/04/25 08:39:15 danielk1977 Exp $


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

if {
  [info commands sqlite3async_initialize]=="" ||
  [info command sqlite3_memdebug_fail]==""
} {
  # The async logic is not built into this system
  puts "Skipping async2 tests: not compiled with required features"
  finish_test
  return
}
................................................................................
    set ::sqlite_io_error_pending 0
    sqlite3_memdebug_fail -1
    file delete -force test.db test.db-journal
    sqlite3 db test.db
    execsql $::setup_script
    db close
  
    sqlite3async_initialize "" 1
    sqlite3 db test.db
    sqlite3_db_config_lookaside db 0 0 0
  
    switch -- $err {
      ioerr             { set ::sqlite_io_error_pending $n }
      malloc-persistent { sqlite3_memdebug_fail $n -repeat 1 }
      malloc-transient  { sqlite3_memdebug_fail $n -repeat 0 }
    }

    catchsql $::sql_script
    db close

    sqlite3async_control halt idle
    sqlite3async_start
    sqlite3async_wait
    sqlite3async_control halt never
    sqlite3async_shutdown

    set ::sqlite_io_error_pending 0
    sqlite3_memdebug_fail -1

    sqlite3 db test.db
    set c [db one {SELECT c FROM counter LIMIT 1}]
    switch -- $c {

Changes to test/async3.test.

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
..
65
66
67
68
69
70
71
72
73
74
75
76
#
#***********************************************************************
#
# The focus of this file is testing the code in test_async.c.
# Specifically, it tests that the xFullPathname() method of
# of the asynchronous vfs works correctly.
#
# $Id: async3.test,v 1.4 2009/03/28 18:56:14 drh Exp $

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

if { [info commands sqlite3async_enable]==""  } {
  # The async logic is not built into this system
  puts "Skipping async3 tests: not compiled with required features"
  finish_test
  return
}

db close
sqlite3async_enable 1
#set sqlite3async_trace 1
sqlite3async_start

set paths {
  chocolate/banana/vanilla/file.db
  chocolate//banana/vanilla/file.db
  chocolate/./banana//vanilla/file.db
................................................................................
  } {1 {database is locked}}
  db2 close
  incr N
}

db close

sqlite3async_halt idle
sqlite3async_wait
sqlite3async_halt never
sqlite3async_enable 0
finish_test







|




|







|







 







|

|
|

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
..
65
66
67
68
69
70
71
72
73
74
75
76
#
#***********************************************************************
#
# The focus of this file is testing the code in test_async.c.
# Specifically, it tests that the xFullPathname() method of
# of the asynchronous vfs works correctly.
#
# $Id: async3.test,v 1.5 2009/04/25 08:39:15 danielk1977 Exp $

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

if { [info commands sqlite3async_initialize]==""  } {
  # The async logic is not built into this system
  puts "Skipping async3 tests: not compiled with required features"
  finish_test
  return
}

db close
sqlite3async_initialize "" 1
#set sqlite3async_trace 1
sqlite3async_start

set paths {
  chocolate/banana/vanilla/file.db
  chocolate//banana/vanilla/file.db
  chocolate/./banana//vanilla/file.db
................................................................................
  } {1 {database is locked}}
  db2 close
  incr N
}

db close

sqlite3async_control halt idle
sqlite3async_wait
sqlite3async_control halt never
sqlite3async_shutdown
finish_test

Added test/async4.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
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
94
95
96
97
98
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
# 2009 April 25
#
# 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.
#
#***********************************************************************
#
# $Id: async4.test,v 1.1 2009/04/25 08:39:15 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {[info commands sqlite3async_initialize] eq ""} {
  # The async logic is not built into this system
  finish_test
  return
}
db close

# Test layout:
#
#   async4.1.*: Test the lockfiles parameter.
#   async4.2.*: Test the delay parameter.

do_test async4.1.1 {
  sqlite3async_initialize {} 0
  sqlite3async_control lockfiles
} {1}
do_test async4.1.2 {
  sqlite3async_control lockfiles false
} {0}
do_test async4.1.3 {
  sqlite3async_control lockfiles
} {0}
do_test async4.1.4 {
  sqlite3async_control lockfiles true
} {1}

do_test async4.1.5 {
  sqlite3 db test.db -vfs sqlite3async
  execsql { CREATE TABLE t1(a, b, c) }
} {}
do_test async4.1.6 {
  list [file exists test.db] [file size test.db]
} {1 0}
do_test async4.1.7 {
  sqlite3 db2 test.db
  catchsql { CREATE TABLE t2(a, b, c) } db2
} {1 {database is locked}}
do_test async4.1.8 {
  sqlite3async_control halt idle
  sqlite3async_start
  sqlite3async_wait
} {}
do_test async4.1.9 {
  catchsql { CREATE TABLE t2(a, b, c) } db2
} {0 {}}
do_test async4.1.10 {
  list [catch {sqlite3async_control lockfiles false} msg] $msg
} {1 SQLITE_MISUSE}
do_test async4.1.11 {
  db close
  list [catch {sqlite3async_control lockfiles false} msg] $msg
} {1 SQLITE_MISUSE}
do_test async4.1.12 {
  sqlite3async_start
  sqlite3async_wait
  sqlite3async_control lockfiles false
} {0}
do_test async4.1.13 {
  sqlite3 db test.db -vfs sqlite3async
  execsql { CREATE TABLE t3(a, b, c) } db
} {}
do_test async4.1.14 {
  execsql { 
    CREATE INDEX i1 ON t2(a);
    CREATE INDEX i2 ON t1(a);
  } db2
} {}
do_test async4.1.15 {
  sqlite3async_start
  sqlite3async_wait
  execsql { pragma integrity_check } db2
} {{*** in database main ***
Page 5 is never used}}
do_test async4.1.16 {
  db close
  db2 close
  sqlite3async_start
  sqlite3async_wait
} {}

do_test async4.2.1 {
  sqlite3async_control delay
} {0}
do_test async4.2.2 {
  sqlite3async_control delay 23
} {23}
do_test async4.2.3 {
  sqlite3async_control delay
} {23}
do_test async4.2.4 {
  sqlite3async_control delay 0
} {0}
do_test async4.2.5 {
  sqlite3 db test.db -vfs sqlite3async

  execsql { CREATE TABLE t4(a, b) }
  set T1 [lindex [time {
    sqlite3async_start
    sqlite3async_wait
  }] 0]

  sqlite3async_control delay 100
  execsql { CREATE TABLE t5(a, b) }
  set T2 [lindex [time {
    sqlite3async_start
    sqlite3async_wait
  }] 0]

  expr {($T1+1000000) < $T2}
} {1}

do_test async4.2.6 {
  sqlite3async_control delay 0
  execsql { CREATE TABLE t6(a, b) }
  set T1 [lindex [time {
    sqlite3async_start
    sqlite3async_wait
  }] 0]

  expr {($T1+1000000) < $T2}
} {1}

do_test async4.2.7 {
  list [catch { sqlite3async_control delay -1 } msg] $msg
} {1 SQLITE_MISUSE}

do_test async4.2.8 {
  db close
  sqlite3async_start
  sqlite3async_wait
} {}

finish_test

Changes to test/main.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#    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 exercising the code in main.c.
#
# $Id: main.test,v 1.30 2008/09/18 18:18:29 drh Exp $

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

# Only do the next group of tests if the sqlite3_complete API is available
#
ifcapable {complete} {
................................................................................
do_test main-3.6 {
  catchsql {SELECT 'abc' + #9}
} {1 {near "#9": syntax error}}

# The following test-case tests the linked list code used to manage
# sqlite3_vfs structures.
if {$::tcl_platform(platform)=="unix" 
     && [info command sqlite3async_enable]!=""} {
  ifcapable threadsafe {
    do_test main-4.1 {
      sqlite3_crash_enable 1
      sqlite3_crash_enable 0
    
      sqlite3async_enable 1
      sqlite3async_enable 0
    
      sqlite3_crash_enable 1
      sqlite3async_enable 1
      sqlite3_crash_enable 0
      sqlite3async_enable 0
    
      sqlite3_crash_enable 1
      sqlite3async_enable 1
      sqlite3async_enable 0
      sqlite3_crash_enable 0
    
      sqlite3async_enable 1
      sqlite3_crash_enable 1
      sqlite3_crash_enable 0
      sqlite3async_enable 0
    
      sqlite3async_enable 1
      sqlite3_crash_enable 1
      sqlite3async_enable 0
      sqlite3_crash_enable 0
    } {}
    do_test main-4.2 {
      set rc [catch {sqlite3 db test.db -vfs crash} msg]
      list $rc $msg
    } {1 {no such vfs: crash}}
    do_test main-4.3 {







|







 







|





|
|


|

|


|
|


|


|

|

|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#    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 exercising the code in main.c.
#
# $Id: main.test,v 1.31 2009/04/25 08:39:15 danielk1977 Exp $

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

# Only do the next group of tests if the sqlite3_complete API is available
#
ifcapable {complete} {
................................................................................
do_test main-3.6 {
  catchsql {SELECT 'abc' + #9}
} {1 {near "#9": syntax error}}

# The following test-case tests the linked list code used to manage
# sqlite3_vfs structures.
if {$::tcl_platform(platform)=="unix" 
     && [info command sqlite3async_initialize]!=""} {
  ifcapable threadsafe {
    do_test main-4.1 {
      sqlite3_crash_enable 1
      sqlite3_crash_enable 0
    
      sqlite3async_initialize "" 1
      sqlite3async_shutdown
    
      sqlite3_crash_enable 1
      sqlite3async_initialize "" 1
      sqlite3_crash_enable 0
      sqlite3async_shutdown
    
      sqlite3_crash_enable 1
      sqlite3async_initialize "" 1
      sqlite3async_shutdown
      sqlite3_crash_enable 0
    
      sqlite3async_initialize "" 1
      sqlite3_crash_enable 1
      sqlite3_crash_enable 0
      sqlite3async_shutdown
    
      sqlite3async_initialize "" 1
      sqlite3_crash_enable 1
      sqlite3async_shutdown
      sqlite3_crash_enable 0
    } {}
    do_test main-4.2 {
      set rc [catch {sqlite3 db test.db -vfs crash} msg]
      list $rc $msg
    } {1 {no such vfs: crash}}
    do_test main-4.3 {