xref: /sqlite-3.40.0/test/atomic2.test (revision 140a5987)
1# 2018-07-15
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# This file implements regression tests for SQLite library.  The
12# focus of this file is testing that if an IO error is encountered
13# as part of an atomic F2FS commit, an attempt is made to commit the
14# transaction using a legacy journal commit.
15#
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19source $testdir/malloc_common.tcl
20set ::testprefix atomic2
21
22db close
23if {[atomic_batch_write test.db]==0} {
24  puts "No f2fs atomic-batch-write support. Skipping tests..."
25  finish_test
26  return
27}
28
29reset_db
30
31do_execsql_test 1.0 {
32  CREATE TABLE t1(x, y);
33  CREATE INDEX i1x ON t1(x);
34  CREATE INDEX i2x ON t1(y);
35
36  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 )
37  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
38}
39
40set setup [list \
41  -injectstart at_injectstart \
42  -injectstop  at_injectstop  \
43]
44
45set ::at_fail  0
46set ::at_nfail 0
47
48proc at_injectstart {iFail} {
49  set ::at_fail $iFail
50  set ::at_nfail 0
51}
52proc at_injectstop {} {
53  set ::at_fail 0
54  return $::at_nfail
55}
56
57proc at_vfs_callback {method file z args} {
58  if {$::at_fail>0} {
59    incr ::at_fail -1
60    if {$::at_fail==0} {
61      incr ::at_nfail
62      return SQLITE_IOERR
63    } elseif {$method=="xFileControl" && $z=="COMMIT_ATOMIC_WRITE"} {
64      set ::at_fail 0
65    }
66  }
67  return SQLITE_OK
68}
69
70testvfs tvfs -default 1
71tvfs script at_vfs_callback
72tvfs filter {xFileControl xWrite}
73
74faultsim_save_and_close
75
76do_one_faultsim_test 2.0 {*}$setup -prep {
77  faultsim_restore_and_reopen
78} -body {
79  execsql {
80    WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 )
81    INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
82  }
83} -test {
84  faultsim_test_result {0 {}}
85
86  set res [execsql {SELECT count(*) FROM t1; PRAGMA integrity_check}]
87  if {$res!="200 ok"} {
88    error "expected {200 ok}, got $res"
89  }
90}
91
92db close
93tvfs delete
94
95finish_test
96