xref: /sqlite-3.40.0/test/zerodamage.test (revision 69aedc8d)
1# 2011 December 21
2#
3# The author disclaims copyright to this source code.  In place of
4# 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# This file implements tests of the SQLITE_IOCAP_POWERSAFE_OVERWRITE property
13# and the SQLITE_FCNTL_POWERSAFE_OVERWRITE file-control for manipulating it.
14#
15# The name of this file comes from the fact that we used to call the
16# POWERSAFE_OVERWRITE property ZERO_DAMAGE.
17#
18
19set testdir [file dirname $argv0]
20source $testdir/tester.tcl
21set testprefix zerodamage
22
23ifcapable !vtab {
24  finish_test
25  return
26}
27
28# POWERSAFE_OVERWRITE defaults to true
29#
30do_test zerodamage-1.0 {
31  file_control_powersafe_overwrite db -1
32} {0 1}
33
34# Check the ability to turn zero-damage on and off.
35#
36do_test zerodamage-1.1 {
37  file_control_powersafe_overwrite db 0
38  file_control_powersafe_overwrite db -1
39} {0 0}
40do_test zerodamage-1.2 {
41  file_control_powersafe_overwrite db 1
42  file_control_powersafe_overwrite db -1
43} {0 1}
44
45# Run a transaction with zero-damage on, a small page size and a much larger
46# sectorsize.  Verify that the maximum journal size is small - that the
47# rollback journal is not being padded.
48#
49do_test zerodamage-2.0 {
50  db close
51  testvfs tv -default 1
52  tv sectorsize 8192
53  sqlite3 db file:test.db?psow=TRUE -uri 1
54  unset -nocomplain ::max_journal_size
55  set ::max_journal_size 0
56  proc xDeleteCallback {method file args} {
57    set sz [file size $file]
58    if {$sz>$::max_journal_size} {set ::max_journal_size $sz}
59  }
60  tv filter xDelete
61  tv script xDeleteCallback
62  load_static_extension db wholenumber
63  db eval {
64    PRAGMA page_size=1024;
65    PRAGMA journal_mode=DELETE;
66    PRAGMA cache_size=5;
67    CREATE VIRTUAL TABLE nums USING wholenumber;
68    CREATE TABLE t1(x, y);
69    INSERT INTO t1 SELECT value, randomblob(100) FROM nums
70                    WHERE value BETWEEN 1 AND 400;
71  }
72  set ::max_journal_size 0
73  db eval {
74    UPDATE t1 SET y=randomblob(50) WHERE x=123;
75  }
76  concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
77} [list 0 1 [expr ([atomic_batch_write test.db]==0)*2576]]
78
79# Repeat the previous step with zero-damage turned off.  This time the
80# maximum rollback journal size should be much larger.
81#
82do_test zerodamage-2.1 {
83  set ::max_journal_size 0
84  db close
85  sqlite3 db file:test.db?psow=FALSE -uri 1
86  db eval {
87    UPDATE t1 SET y=randomblob(50) WHERE x=124;
88  }
89  concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
90} [list 0 0 [expr ([atomic_batch_write test.db]==0)*24704]]
91
92if {[wal_is_capable]} {
93  # Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
94  # WAL file does not get too big.
95  #
96  do_test zerodamage-3.0 {
97    db eval {
98       PRAGMA journal_mode=WAL;
99    }
100    db close
101    sqlite3 db file:test.db?psow=TRUE -uri 1
102    db eval {
103       UPDATE t1 SET y=randomblob(50) WHERE x=124;
104    }
105    file size test.db-wal
106  } {1080}
107
108  # Repeat the previous with POWERSAFE_OVERWRITE off.  Verify that the WAL file
109  # is padded.
110  #
111  do_test zerodamage-3.1 {
112    db close
113    sqlite3 db file:test.db?psow=FALSE -uri 1
114    db eval {
115       PRAGMA synchronous=FULL;
116       UPDATE t1 SET y=randomblob(50) WHERE x=124;
117    }
118    file size test.db-wal
119  } {16800}
120}
121
122finish_test
123