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
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
|
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
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
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
|
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix otafault
do_test 1.1 {
forcedelete ota.db
execsql {
PRAGMA encoding = utf16;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX t1cb ON t1(c, b);
INSERT INTO t1 VALUES(1, 1, 1);
INSERT INTO t1 VALUES(2, 2, 2);
INSERT INTO t1 VALUES(3, 3, 3);
CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
CREATE INDEX t2cb ON t1(c, b);
INSERT INTO t2 VALUES('a', 'a', 'a');
INSERT INTO t2 VALUES('b', 'b', 'b');
INSERT INTO t2 VALUES('c', 'c', 'c');
ATTACH 'ota.db' AS ota;
CREATE TABLE ota.data_t1(a, b, c, ota_control);
CREATE TABLE ota.data_t2(a, b, c, ota_control);
INSERT INTO data_t1 VALUES(2, NULL, NULL, 1);
INSERT INTO data_t1 VALUES(3, 'three', NULL, '.x.');
INSERT INTO data_t1 VALUES(4, 4, 4, 0);
INSERT INTO data_t2 VALUES('b', NULL, NULL, 1);
INSERT INTO data_t2 VALUES('c', 'see', NULL, '.x.');
INSERT INTO data_t2 VALUES('d', 'd', 'd', 0);
}
db close
forcecopy test.db test.db.bak
forcecopy ota.db ota.db.bak
} {}
sqlite3_shutdown
set lookaside_config [sqlite3_config_lookaside 0 0]
sqlite3_initialize
autoinstall_test_functions
foreach {tn f reslist} {
1 oom-tra* {
{0 SQLITE_DONE}
{1 {SQLITE_NOMEM - out of memory}}
{1 SQLITE_NOMEM}
{1 SQLITE_IOERR_NOMEM}
{1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}}
}
2 ioerr-* {
{0 SQLITE_DONE}
{1 {SQLITE_IOERR - disk I/O error}}
{1 SQLITE_IOERR}
{1 SQLITE_IOERR_WRITE}
{1 SQLITE_IOERR_READ}
{1 SQLITE_IOERR_FSYNC}
{1 {SQLITE_ERROR - SQL logic error or missing database}}
{1 {SQLITE_ERROR - unable to open database: ota.db}}
{1 {SQLITE_IOERR - unable to open database: ota.db}}
}
} {
do_faultsim_test 2 -faults $::f -prep {
catch { db close }
forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
forcecopy test.db.bak test.db
forcecopy ota.db.bak ota.db
} -body {
sqlite3ota ota test.db ota.db
while {[ota step]=="SQLITE_OK"} {}
ota close
} -test {
faultsim_test_result {*}$::reslist
if {$testrc==0} {
sqlite3 db test.db
faultsim_integrity_check
set res [db eval {
SELECT * FROM t1 UNION ALL SELECT * FROM t2;
}]
set expected [list {*}{
1 1 1 3 three 3 4 4 4
a a a c see c d d d
}]
if {$res != $expected} {
puts ""
puts "res: $res"
puts "exp: $expected"
error "data not as expected!"
}
}
}
}
catch {db close}
sqlite3_shutdown
sqlite3_config_lookaside {*}$lookaside_config
sqlite3_initialize
autoinstall_test_functions
proc copy_if_exists {src target} {
if {[file exists $src]} {
forcecopy $src $target
} else {
forcedelete $target
}
}
foreach {tn2 setup sql expect} {
1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX t1cb ON t1(c, b);
INSERT INTO t1 VALUES(1, 1, 1);
INSERT INTO t1 VALUES(2, 2, 2);
INSERT INTO t1 VALUES(3, 3, 3);
CREATE TABLE ota.data_t1(a, b, c, ota_control);
INSERT INTO data_t1 VALUES(2, NULL, NULL, 1);
INSERT INTO data_t1 VALUES(3, 'three', NULL, '.x.');
INSERT INTO data_t1 VALUES(4, 4, 4, 0);
} {SELECT * FROM t1} {1 1 1 3 three 3 4 4 4}
2 {
CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
CREATE INDEX t2cb ON t2(c, b);
INSERT INTO t2 VALUES('a', 'a', 'a');
INSERT INTO t2 VALUES('b', 'b', 'b');
INSERT INTO t2 VALUES('c', 'c', 'c');
CREATE TABLE ota.data_t2(a, b, c, ota_control);
INSERT INTO data_t2 VALUES('b', NULL, NULL, 1);
INSERT INTO data_t2 VALUES('c', 'see', NULL, '.x.');
INSERT INTO data_t2 VALUES('d', 'd', 'd', 0);
} {SELECT * FROM t2} {a a a c see c d d d}
3 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
CREATE INDEX t1cb ON t1(c, b);
CREATE INDEX t2cb ON t2(c, b);
CREATE TABLE ota.data_t1(a, b, c, ota_control);
CREATE TABLE ota.data_t2(a, b, c, ota_control);
INSERT INTO data_t1 VALUES(1, 2, 3, 0);
INSERT INTO data_t2 VALUES(4, 5, 6, 0);
} {SELECT * FROM t1 UNION ALL SELECT * FROM t2} {1 2 3 4 5 6}
} {
catch {db close}
forcedelete ota.db test.db
sqlite3 db test.db
execsql {
PRAGMA encoding = utf16;
ATTACH 'ota.db' AS ota;
}
execsql $setup
db close
forcecopy test.db test.db.bak
forcecopy ota.db ota.db.bak
foreach {tn f reslist} {
1 oom-tra* {
{0 SQLITE_DONE}
{1 {SQLITE_NOMEM - out of memory}}
{1 SQLITE_NOMEM}
{1 SQLITE_IOERR_NOMEM}
{1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}}
}
2 ioerr-* {
{0 SQLITE_DONE}
{1 {SQLITE_IOERR - disk I/O error}}
{1 SQLITE_IOERR}
{1 SQLITE_IOERR_WRITE}
{1 SQLITE_IOERR_READ}
{1 SQLITE_IOERR_FSYNC}
{1 {SQLITE_ERROR - SQL logic error or missing database}}
{1 {SQLITE_ERROR - unable to open database: ota.db}}
{1 {SQLITE_IOERR - unable to open database: ota.db}}
}
} {
catch {db close}
sqlite3_shutdown
set lookaside_config [sqlite3_config_lookaside 0 0]
sqlite3_initialize
autoinstall_test_functions
do_faultsim_test 2.$tn2 -faults $::f -prep {
catch { db close }
forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
forcecopy test.db.bak test.db
forcecopy ota.db.bak ota.db
} -body {
sqlite3ota ota test.db ota.db
while {[ota step]=="SQLITE_OK"} {}
ota close
} -test {
faultsim_test_result {*}$::reslist
if {$testrc==0} {
sqlite3 db test.db
faultsim_integrity_check
set res [db eval $::sql]
if {$res != [list {*}$::expect]} {
puts ""
puts "res: $res"
puts "exp: $expect"
error "data not as expected!"
}
}
}
catch {db close}
sqlite3_shutdown
sqlite3_config_lookaside {*}$lookaside_config
sqlite3_initialize
autoinstall_test_functions
}
for {set iStep 0} {$iStep<=21} {incr iStep} {
forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
copy_if_exists test.db.bak test.db
copy_if_exists ota.db.bak ota.db
sqlite3ota ota test.db ota.db
for {set x 0} {$x < $::iStep} {incr x} { ota step }
ota close
copy_if_exists test.db test.db.bak.2
copy_if_exists test.db-wal test.db.bak.2-wal
copy_if_exists test.db-oal test.db.bak.2-oal
copy_if_exists ota.db ota.db.bak.2
do_faultsim_test 3.$iStep -faults oom-trans* -prep {
catch { db close }
forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
copy_if_exists test.db.bak.2 test.db
copy_if_exists test.db.bak.2-wal test.db-wal
copy_if_exists test.db.bak.2-oal test.db-oal
copy_if_exists ota.db.bak.2 ota.db
} -body {
sqlite3ota ota test.db ota.db
while {[ota step] == "SQLITE_OK"} {}
ota close
} -test {
faultsim_test_result {0 SQLITE_DONE} \
for {set iStep 0} {$iStep<=21} {incr iStep} {
forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
copy_if_exists test.db.bak test.db
copy_if_exists ota.db.bak ota.db
sqlite3ota ota test.db ota.db
for {set x 0} {$x < $::iStep} {incr x} { ota step }
ota close
copy_if_exists test.db test.db.bak.2
copy_if_exists test.db-wal test.db.bak.2-wal
copy_if_exists test.db-oal test.db.bak.2-oal
copy_if_exists ota.db ota.db.bak.2
do_faultsim_test 3.$tn.$iStep -faults $::f -prep {
catch { db close }
forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
copy_if_exists test.db.bak.2 test.db
copy_if_exists test.db.bak.2-wal test.db-wal
copy_if_exists test.db.bak.2-oal test.db-oal
copy_if_exists ota.db.bak.2 ota.db
} -body {
sqlite3ota ota test.db ota.db
while {[ota step] == "SQLITE_OK"} {}
ota close
} -test {
faultsim_test_result {*}$::reslist
{1 {SQLITE_NOMEM - out of memory}} \
{1 SQLITE_NOMEM} \
{1 SQLITE_IOERR_NOMEM} \
{1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}}
if {$testrc==0} {
sqlite3 db test.db
faultsim_integrity_check
set res [db eval {
if {$testrc==0} {
sqlite3 db test.db
faultsim_integrity_check
set res [db eval $::sql]
SELECT * FROM t1 UNION ALL SELECT * FROM t2;
}]
set expected [list {*}{
1 1 1 3 three 3 4 4 4
a a a c see c d d d
}]
if {$res != $expected} {
puts ""
puts "res: $res"
puts "exp: $expected"
error "data not as expected!"
}
}
}
if {$res != [list {*}$::expect]} {
puts ""
puts "res: $res"
puts "exp: $expected"
error "data not as expected!"
}
}
}
}
}
finish_test
|