/ Check-in [b095e2cd]
Login

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

Overview
Comment:Improve the code coverage of "permutations.test coverage-pager".
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b095e2cdb61ca8487255687f58fb1024d40f3986
User & Date: dan 2013-04-05 20:40:43
Context
2013-04-06
11:03
Add tests to "permutations.test coverage-pager" to cover uncovered branches. check-in: 07a0e4e9 user: dan tags: trunk
00:19
Add a prototype TH3-script-style test harness that starts multiple processes operating on the same database file at the same time. check-in: c318fafe user: drh tags: mptest
2013-04-05
20:40
Improve the code coverage of "permutations.test coverage-pager". check-in: b095e2cd user: dan tags: trunk
2013-04-04
19:32
Add further multi-client tests to mmap1.test. check-in: a107f75d user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/test_vfs.c.

121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
...
463
464
465
466
467
468
469
470




471
472
473
474
475
476
477
478
....
1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
#define TESTVFS_DELETE_MASK       0x00000400
#define TESTVFS_CLOSE_MASK        0x00000800
#define TESTVFS_WRITE_MASK        0x00001000
#define TESTVFS_TRUNCATE_MASK     0x00002000
#define TESTVFS_ACCESS_MASK       0x00004000
#define TESTVFS_FULLPATHNAME_MASK 0x00008000
#define TESTVFS_READ_MASK         0x00010000


#define TESTVFS_ALL_MASK          0x0001FFFF


#define TESTVFS_MAX_PAGES 1024

/*
** A shared-memory buffer. There is one of these objects for each shared
** memory region opened by clients. If two clients open the same file,
................................................................................
  return sqlite3OsLock(p->pReal, eLock);
}

/*
** Unlock an tvfs-file.
*/
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
  TestvfsFd *p = tvfsGetFd(pFile);




  return sqlite3OsUnlock(p->pReal, eLock);
}

/*
** Check if another file-handle holds a RESERVED lock on an tvfs-file.
*/
static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
  TestvfsFd *p = tvfsGetFd(pFile);
................................................................................
        { "xWrite",        TESTVFS_WRITE_MASK },
        { "xRead",         TESTVFS_READ_MASK },
        { "xTruncate",     TESTVFS_TRUNCATE_MASK },
        { "xOpen",         TESTVFS_OPEN_MASK },
        { "xClose",        TESTVFS_CLOSE_MASK },
        { "xAccess",       TESTVFS_ACCESS_MASK },
        { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },

      };
      Tcl_Obj **apElem = 0;
      int nElem = 0;
      int i;
      int mask = 0;
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "LIST");







>

|







 







|
>
>
>
>
|







 







>







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
....
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
#define TESTVFS_DELETE_MASK       0x00000400
#define TESTVFS_CLOSE_MASK        0x00000800
#define TESTVFS_WRITE_MASK        0x00001000
#define TESTVFS_TRUNCATE_MASK     0x00002000
#define TESTVFS_ACCESS_MASK       0x00004000
#define TESTVFS_FULLPATHNAME_MASK 0x00008000
#define TESTVFS_READ_MASK         0x00010000
#define TESTVFS_UNLOCK_MASK       0x00020000

#define TESTVFS_ALL_MASK          0x0003FFFF


#define TESTVFS_MAX_PAGES 1024

/*
** A shared-memory buffer. There is one of these objects for each shared
** memory region opened by clients. If two clients open the same file,
................................................................................
  return sqlite3OsLock(p->pReal, eLock);
}

/*
** Unlock an tvfs-file.
*/
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
  TestvfsFd *pFd = tvfsGetFd(pFile);
  Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
  if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
    return SQLITE_IOERR_UNLOCK;
  }
  return sqlite3OsUnlock(pFd->pReal, eLock);
}

/*
** Check if another file-handle holds a RESERVED lock on an tvfs-file.
*/
static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
  TestvfsFd *p = tvfsGetFd(pFile);
................................................................................
        { "xWrite",        TESTVFS_WRITE_MASK },
        { "xRead",         TESTVFS_READ_MASK },
        { "xTruncate",     TESTVFS_TRUNCATE_MASK },
        { "xOpen",         TESTVFS_OPEN_MASK },
        { "xClose",        TESTVFS_CLOSE_MASK },
        { "xAccess",       TESTVFS_ACCESS_MASK },
        { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
        { "xUnlock",       TESTVFS_UNLOCK_MASK },
      };
      Tcl_Obj **apElem = 0;
      int nElem = 0;
      int i;
      int mask = 0;
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "LIST");

Changes to test/pager1.test.

11
12
13
14
15
16
17

18
19
20
21
22
23
24
....
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
....
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
....
2518
2519
2520
2521
2522
2523
2524
2525















































































































































































































2526
#

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


# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec

#
................................................................................

#-------------------------------------------------------------------------
# Test that regardless of the value returned by xSectorSize(), the
# minimum effective sector-size is 512 and the maximum 65536 bytes.
#
testvfs tv -default 1
foreach sectorsize {

    32   64   128   256   512   1024   2048 
    4096 8192 16384 32768 65536 131072 262144
} {
  tv sectorsize $sectorsize
  tv devchar {}
  set eff $sectorsize
  if {$sectorsize < 512}   { set eff 512 }
................................................................................
      BEGIN;
        CREATE TABLE t1(a, b);
        CREATE TABLE t2(a, b);
        CREATE TABLE t3(a, b);
      COMMIT;
    }
    file size test.db-journal
  } [expr $sectorsize > 65536 ? 65536 : $sectorsize]

  do_test pager1-10.$sectorsize.2 {
    execsql { 
      INSERT INTO t3 VALUES(a_string(300), a_string(300));
      INSERT INTO t3 SELECT * FROM t3;        /*  2 */
      INSERT INTO t3 SELECT * FROM t3;        /*  4 */
      INSERT INTO t3 SELECT * FROM t3;        /*  8 */
................................................................................
  } {1 {disk I/O error}}

  do_test pager1-33.2 {
    file rename bak-journal test.db-journal
    execsql { SELECT * FROM t1 }
  } {one two}
}
















































































































































































































finish_test







>







 







>







 







|







 








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

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
....
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
....
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
....
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
set testprefix pager1

# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec

#
................................................................................

#-------------------------------------------------------------------------
# Test that regardless of the value returned by xSectorSize(), the
# minimum effective sector-size is 512 and the maximum 65536 bytes.
#
testvfs tv -default 1
foreach sectorsize {
    16
    32   64   128   256   512   1024   2048 
    4096 8192 16384 32768 65536 131072 262144
} {
  tv sectorsize $sectorsize
  tv devchar {}
  set eff $sectorsize
  if {$sectorsize < 512}   { set eff 512 }
................................................................................
      BEGIN;
        CREATE TABLE t1(a, b);
        CREATE TABLE t2(a, b);
        CREATE TABLE t3(a, b);
      COMMIT;
    }
    file size test.db-journal
  } [expr $sectorsize > 65536 ? 65536 : ($sectorsize<32 ? 512 : $sectorsize)]

  do_test pager1-10.$sectorsize.2 {
    execsql { 
      INSERT INTO t3 VALUES(a_string(300), a_string(300));
      INSERT INTO t3 SELECT * FROM t3;        /*  2 */
      INSERT INTO t3 SELECT * FROM t3;        /*  4 */
      INSERT INTO t3 SELECT * FROM t3;        /*  8 */
................................................................................
  } {1 {disk I/O error}}

  do_test pager1-33.2 {
    file rename bak-journal test.db-journal
    execsql { SELECT * FROM t1 }
  } {one two}
}

#-------------------------------------------------------------------------
# Test that appending pages to the database file then moving those pages
# to the free-list before the transaction is committed does not cause
# an error.
#
foreach {tn pragma strsize} {
  1 { PRAGMA mmap_limit = 0 } 2400
  2 { }                       2400
  3 { PRAGMA mmap_limit = 0 } 4400
  4 { }                       4400
} {
  reset_db
  db func a_string a_string
  db eval $pragma
  do_execsql_test 34.$tn.1 {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 2);
  }
  breakpoint
  do_execsql_test 34.$tn.2 {
    BEGIN;
    INSERT INTO t1 VALUES(2, a_string($strsize));
    DELETE FROM t1 WHERE oid=2;
    COMMIT;
    PRAGMA integrity_check;
  } {ok}
}

#-------------------------------------------------------------------------
#
reset_db
do_test 35 {
  sqlite3 db test.db

  execsql {
    CREATE TABLE t1(x, y);
    PRAGMA journal_mode = WAL;
    INSERT INTO t1 VALUES(1, 2);
  }

  execsql {
    BEGIN;
      CREATE TABLE t2(a, b);
  }

  hexio_write test.db-shm [expr 16*1024] [string repeat 0055 8192]
  catchsql ROLLBACK
} {0 {}}

do_multiclient_test tn {
  sql1 {
    PRAGMA auto_vacuum = 0;
    CREATE TABLE t1(x, y);
    INSERT INTO t1 VALUES(1, 2);
  }

  do_test 36.$tn.1 { 
    sql2 { PRAGMA max_page_count = 2 }
    list [catch { sql2 { CREATE TABLE t2(x) } } msg] $msg
  } {1 {database or disk is full}}

  sql1 { PRAGMA checkpoint_fullfsync = 1 }
  sql1 { CREATE TABLE t2(x) }

  do_test 36.$tn.2 { 
    sql2 { INSERT INTO t2 VALUES('xyz') }
    list [catch { sql2 { CREATE TABLE t3(x) } } msg] $msg
  } {1 {database or disk is full}}
}

forcedelete test1 test2
foreach {tn uri} {
  1   {file:?mode=memory&cache=shared}
  2   {file:one?mode=memory&cache=shared}
  3   {file:test1?cache=shared}
  4   {file:test2?another=parameter&yet=anotherone}
} {
  do_test 37.$tn {
    catch { db close }
    sqlite3_shutdown
      sqlite3_config_uri 1
      sqlite3 db $uri
    db eval {
      CREATE TABLE t1(x);
      INSERT INTO t1 VALUES(1);
      SELECT * FROM t1;
    }
  } {1}
  db close
  sqlite3_shutdown
  sqlite3_config_uri 0
}

do_test 38.1 {
  catch { db close }
  forcedelete test.db
  set fd [open test.db w]
  puts $fd "hello world"
  close $fd
  sqlite3 db test.db
  catchsql { CREATE TABLE t1(x) }
} {1 {file is encrypted or is not a database}}
do_test 38.2 {
  catch { db close }
  forcedelete test.db
} {}

do_test 39.1 {
  sqlite3 db test.db
  execsql {
    PRAGMA auto_vacuum = 1;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES('xxx');
    INSERT INTO t1 VALUES('two');
    INSERT INTO t1 VALUES(randomblob(400));
    INSERT INTO t1 VALUES(randomblob(400));
    INSERT INTO t1 VALUES(randomblob(400));
    INSERT INTO t1 VALUES(randomblob(400));
    BEGIN;
    UPDATE t1 SET x = 'one' WHERE rowid=1;
  }
  set ::stmt [sqlite3_prepare db "SELECT * FROM t1 ORDER BY rowid" -1 dummy]
  sqlite3_step $::stmt
  sqlite3_column_text $::stmt 0
} {one}
do_test 39.2 {
  execsql { CREATE TABLE t2(x) }
  sqlite3_step $::stmt
  sqlite3_column_text $::stmt 0
} {two}
do_test 39.3 {
  sqlite3_finalize $::stmt
  execsql COMMIT
} {}

do_execsql_test 39.4 {
  PRAGMA auto_vacuum = 2;
  CREATE TABLE t3(x);
  CREATE TABLE t4(x);

  DROP TABLE t2;
  DROP TABLE t3;
  DROP TABLE t4;
}
do_test 39.5 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA cache_size = 1;
    PRAGMA incremental_vacuum;
    PRAGMA integrity_check;
  }
} {ok}

do_test 40.1 {
  reset_db
  execsql {
    PRAGMA auto_vacuum = 1;
    CREATE TABLE t1(x PRIMARY KEY);
    INSERT INTO t1 VALUES(randomblob(1200));
    PRAGMA page_count;
  }
} {6}
do_test 40.2 {
  execsql {
    INSERT INTO t1 VALUES(randomblob(1200));
    INSERT INTO t1 VALUES(randomblob(1200));
    INSERT INTO t1 VALUES(randomblob(1200));
  }
} {}
do_test 40.3 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA cache_size = 1;
    CREATE TABLE t2(x);
    PRAGMA integrity_check;
  }
} {ok}

do_test 41.1 {
  reset_db
  execsql {
    CREATE TABLE t1(x PRIMARY KEY);
    INSERT INTO t1 VALUES(randomblob(200));
    INSERT INTO t1 SELECT randomblob(200) FROM t1;
    INSERT INTO t1 SELECT randomblob(200) FROM t1;
    INSERT INTO t1 SELECT randomblob(200) FROM t1;
    INSERT INTO t1 SELECT randomblob(200) FROM t1;
    INSERT INTO t1 SELECT randomblob(200) FROM t1;
    INSERT INTO t1 SELECT randomblob(200) FROM t1;
  }
} {}
do_test 41.2 {
  testvfs tv -default 1
  tv sectorsize 16384;
  tv devchar [list]
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA cache_size = 1;
    DELETE FROM t1 WHERE rowid%4;
    PRAGMA integrity_check;
  }
} {ok}


finish_test

Changes to test/pagerfault.test.

1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
....
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
....
1298
1299
1300
1301
1302
1303
1304
1305




















































































































































































1306
1307
  flush $::channel
} -test {
  catchsql { UPDATE t2 SET a = a_string(800), b = a_string(800) }
  catch { close $::channel }
  catchsql { ROLLBACK }
  faultsim_integrity_check
}


#-------------------------------------------------------------------------
#
do_test pagerfault-28-pre {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
................................................................................
    COMMIT;
    CREATE TABLE t1(a PRIMARY KEY, b);
  }
  expr {[file size test.db-shm] >= 96*1024}
} {1}
faultsim_save_and_close

do_faultsim_test pagerfault-28 -faults oom* -prep {
  faultsim_restore_and_reopen
  execsql { PRAGMA mmap_limit=0 }

  sqlite3 db2 test.db
  db2 eval { SELECT count(*) FROM t2 }

  db func a_string a_string
................................................................................
  execsql { ROLLBACK }
} -test {
  db2 close
  sqlite3_finalize $::STMT
  catchsql { ROLLBACK }
  faultsim_integrity_check
}





















































































































































































finish_test








>







 







|







 








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


1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
....
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
....
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
  flush $::channel
} -test {
  catchsql { UPDATE t2 SET a = a_string(800), b = a_string(800) }
  catch { close $::channel }
  catchsql { ROLLBACK }
  faultsim_integrity_check
}


#-------------------------------------------------------------------------
#
do_test pagerfault-28-pre {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
................................................................................
    COMMIT;
    CREATE TABLE t1(a PRIMARY KEY, b);
  }
  expr {[file size test.db-shm] >= 96*1024}
} {1}
faultsim_save_and_close

do_faultsim_test pagerfault-28a -faults oom* -prep {
  faultsim_restore_and_reopen
  execsql { PRAGMA mmap_limit=0 }

  sqlite3 db2 test.db
  db2 eval { SELECT count(*) FROM t2 }

  db func a_string a_string
................................................................................
  execsql { ROLLBACK }
} -test {
  db2 close
  sqlite3_finalize $::STMT
  catchsql { ROLLBACK }
  faultsim_integrity_check
}

faultsim_restore_and_reopen
sqlite3 db2 test.db
db2 eval {SELECT count(*) FROM t2}
db close

do_faultsim_test pagerfault-28b -faults oom* -prep {
  sqlite3 db test.db
} -body {
  execsql { SELECT count(*) FROM t2 }
} -test {
  faultsim_test_result {0 2048}
  db close
}

db2 close

#-------------------------------------------------------------------------
# Try this:
#
#    1) Put the pager in ERROR state (error during rollback)
#
#    2) Next time the connection is used inject errors into all xWrite() and
#       xUnlock() calls. This causes the hot-journal rollback to fail and
#       the pager to declare its locking state UNKNOWN.
#
#    3) Same again.
#
#    4a) Stop injecting errors. Allow the rollback to succeed. Check that
#        the database is Ok. Or, 
#
#    4b) Close and reopen the db. Check that the db is Ok.
#
proc custom_injectinstall {} {
  testvfs custom -default true
  custom filter {xWrite xUnlock}
}
proc custom_injectuninstall {} {
  catch {db  close}
  catch {db2 close}
  custom delete
}
proc custom_injectstart {iFail} {
  custom ioerr $iFail 1
}
proc custom_injectstop {} {
  custom ioerr
}
set ::FAULTSIM(custom)          [list      \
  -injectinstall   custom_injectinstall    \
  -injectstart     custom_injectstart      \
  -injectstop      custom_injectstop       \
  -injecterrlist   {{1 {disk I/O error}}}  \
  -injectuninstall custom_injectuninstall  \
]

do_test pagerfault-29-pre {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
    PRAGMA page_size = 1024;
    PRAGMA cache_size = 5;

    BEGIN;
      CREATE TABLE t2(a UNIQUE, b UNIQUE);
      INSERT INTO t2 VALUES( a_string(800), a_string(800) );
      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
    COMMIT;
  }
  expr {[file size test.db] >= 50*1024}
} {1}
faultsim_save_and_close
foreach {tn tt} {
  29 { catchsql ROLLBACK }
  30 { db close ; sqlite3 db test.db }
} {
  do_faultsim_test pagerfault-$tn -faults custom -prep {
    faultsim_restore_and_reopen
      db func a_string a_string
      execsql {
        PRAGMA cache_size = 5;
        BEGIN;
        UPDATE t2 SET a = a_string(799);
      }
  } -body {
    catchsql ROLLBACK
    catchsql ROLLBACK
    catchsql ROLLBACK
  } -test {
    eval $::tt
    if {"ok" != [db one {PRAGMA integrity_check}]} {
      error "integrity check failed"
    }
  }
}

do_test pagerfault-31-pre {
  sqlite3_shutdown
  sqlite3_config_uri 1
} {SQLITE_OK}
do_faultsim_test pagerfault-31 -faults oom* -body {
  sqlite3 db {file:one?mode=memory&cache=shared}
  db eval {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
    SELECT * FROM t1;
  }
} -test {
  faultsim_test_result {0 1} {1 {}}
  catch { db close }
}
sqlite3_shutdown
sqlite3_config_uri 0

do_test pagerfault-32-pre {
  reset_db
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES('one');
  }
} {}
faultsim_save_and_close

do_faultsim_test pagerfault-32 -prep {
  faultsim_restore_and_reopen
  db eval { SELECT * FROM t1; }
} -body {
  execsql { SELECT * FROM t1; }
} -test {
  faultsim_test_result {0 one}
}
sqlite3_shutdown
sqlite3_config_uri 0

do_faultsim_test pagerfault-33a -prep {
  sqlite3 db :memory:
  execsql {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 2);
  }
} -body {
  execsql { VACUUM }
} -test {
  faultsim_test_result {0 {}}
} 
do_faultsim_test pagerfault-33b -prep {
  sqlite3 db ""
  execsql {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 2);
  }
} -body {
  execsql { VACUUM }
} -test {
  faultsim_test_result {0 {}}
} 

do_test pagerfault-34-pre {
  reset_db
  execsql {
    CREATE TABLE t1(x PRIMARY KEY);
  }
} {}
faultsim_save_and_close
do_faultsim_test pagerfault-34 -prep {
  faultsim_restore_and_reopen
  execsql {
    BEGIN;
      INSERT INTO t1 VALUES( randomblob(4000) );
      DELETE FROM t1;
  }
} -body {
  execsql COMMIT
} -test {
  faultsim_test_result {0 {}}
} 


finish_test

Changes to test/wal.test.

1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
  # WAL file now contains a single frame - the new root page for table t1.
  # It would be two frames (the new root page and a padding frame) if the
  # ZERO_DAMAGE flag were not set.
  do_test 24.5 {
    file size test.db-wal
  } [wal_file_size 1 1024]
}

reset_db
do_test 25 {
  sqlite3 db test.db

  execsql {
    CREATE TABLE t1(x, y);
    PRAGMA journal_mode = WAL;
    INSERT INTO t1 VALUES(1, 2);
  }

  execsql {
    BEGIN;
      CREATE TABLE t2(a, b);
  }

  hexio_write test.db-shm [expr 16*1024] [string repeat 0055 8192]
  catchsql ROLLBACK
} {0 {}}


db close
sqlite3_shutdown
test_sqlite3_log
sqlite3_initialize

finish_test







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1564
1565
1566
1567
1568
1569
1570




















1571
1572
1573
1574
1575
1576
1577
  # WAL file now contains a single frame - the new root page for table t1.
  # It would be two frames (the new root page and a padding frame) if the
  # ZERO_DAMAGE flag were not set.
  do_test 24.5 {
    file size test.db-wal
  } [wal_file_size 1 1024]
}





















db close
sqlite3_shutdown
test_sqlite3_log
sqlite3_initialize

finish_test

Changes to test/walfault.test.

544
545
546
547
548
549
550


































551



552

553
  }
} -test {
  faultsim_test_result {0 {0 9 9}}
  faultsim_integrity_check
  set nRow [db eval {SELECT count(*) FROM abc}]
  if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" }
}


































finish_test





finish_test







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

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
  }
} -test {
  faultsim_test_result {0 {0 9 9}}
  faultsim_integrity_check
  set nRow [db eval {SELECT count(*) FROM abc}]
  if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" }
}

#-------------------------------------------------------------------------
# Test fault-handling when switching out of exclusive-locking mode.
#
do_test walfault-14-pre {
  faultsim_delete_and_reopen
  execsql {
    PRAGMA auto_vacuum = 0;
    PRAGMA journal_mode = WAL;
    BEGIN;
      CREATE TABLE abc(a PRIMARY KEY);
      INSERT INTO abc VALUES(randomblob(1500));
      INSERT INTO abc VALUES(randomblob(1500));
    COMMIT;
  }
  faultsim_save_and_close
} {}
do_faultsim_test walfault-14 -prep {
  faultsim_restore_and_reopen
  breakpoint
  execsql {
    SELECT count(*) FROM abc;
    PRAGMA locking_mode = exclusive;
    BEGIN;
      INSERT INTO abc VALUES(randomblob(1500));
    COMMIT;
  }
} -body {
  db eval { 
    PRAGMA locking_mode = normal;
    BEGIN;
      INSERT INTO abc VALUES(randomblob(1500));
    COMMIT;
  }
} -test {
  faultsim_integrity_check
  set nRow [db eval {SELECT count(*) FROM abc}]
  if {$nRow!=3 && $nRow!=4} { error "Bad db content" }
}

finish_test