summaryrefslogtreecommitdiffstats
path: root/test/mjournal.test
blob: 7aaa86bae02a78a3e1cb95246de0ff5fb37271ee (plain)
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
150
151
152
153
154
155
156
157
158
159
160
161
162
# 2017 September 15
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#

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

if {[permutation]=="inmemory_journal"} {
  finish_test
  return
}

# Test that nothing bad happens if a journal file contains a pointer to
# a master journal file that does not have a "-" in the name. At one point
# this was causing a segfault on unix.
#
do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
}

do_test 1.1 {
  forcedelete test.db2journal test.db-journal

  close [open test.db-journal w]
  
  hexio_write test.db-journal 0 746573742e6462326a6f75726e616c00
  hexio_write test.db-journal 16 00000010
  hexio_write test.db-journal 20 000005e1
  hexio_write test.db-journal 24 d9d505f920a163d7

  close [open test.db2journal w]
  hexio_write test.db2journal 0 abcd
} {2}

do_execsql_test 1.2 {
  SELECT * FROM t1;
}

do_test 1.3 {
  forcedelete test0db2journal test.db-journal
  close [open test.db-journal w]
  hexio_write test.db-journal 0 74657374306462326a6f75726e616c00
  hexio_write test.db-journal 16 00000010
  hexio_write test.db-journal 20 000005e3
  hexio_write test.db-journal 24 d9d505f920a163d7

  close [open test0db2journal w]
  hexio_write test0db2journal 0 abcd
} {2}

do_execsql_test 1.4 {
  SELECT * FROM t1;
}

# And now test that nothing bad happens if a master journal contains a
# pointer to a journal file that does not have a "-" in the name. 
#
do_test 1.5 {
  forcedelete test.db2-master test.db-journal test1
  close [open test.db-journal w]
  hexio_write test.db-journal 0 746573742e6462322d6d617374657200
  hexio_write test.db-journal 16 00000010
  hexio_write test.db-journal 20 0000059f
  hexio_write test.db-journal 24 d9d505f920a163d7

  close [open test.db2-master w]
  hexio_write test.db2-master 0 746573743100

  close [open test1 w]
  hexio_write test1 0 abcd
} {2}

do_execsql_test 1.6 {
  SELECT * FROM t1;
}

#-------------------------------------------------------------------------
# Check that master journals are not created if the transaction involves
# multiple temp files.
#
db close
testvfs tvfs
tvfs filter xOpen
tvfs script open_cb
set ::open ""
proc open_cb {method file arglist} {
  lappend ::open $file
}

proc contains_mj {} {
  foreach f $::open {
    set t [file tail $f]
    if {[string match *mj* $t]} { return 1 }
  }
  return 0
}

# Like [do_execsql_test], except that a boolean indicating whether or
# not a master journal file was opened ([file tail] contains "mj") or
# not. Example:
#
#   do_hasmj_test 1.0 { SELECT 'a', 'b' } {0 a b}
#
proc do_hasmj_test {tn sql expected} {
  set ::open [list]
  uplevel [list do_test $tn [subst -nocommands {
    set res [execsql "$sql"]
    concat [contains_mj] [set res]
  }] [list {*}$expected]]
}

forcedelete test.db
forcedelete test.db2
forcedelete test.db3
sqlite3 db test.db -vfs tvfs

do_execsql_test 2.0 {
  ATTACH 'test.db2' AS dbfile;
  ATTACH ''         AS dbtemp;
  ATTACH ':memory:'  AS dbmem;

  CREATE TABLE t1(x);
  CREATE TABLE dbfile.t2(x);
  CREATE TABLE dbtemp.t3(x);
  CREATE TABLE dbmem.t4(x);
}

# Two real files.
do_hasmj_test 2.1 {
  BEGIN;
    INSERT INTO t1 VALUES(1);
    INSERT INTO t2 VALUES(1);
  COMMIT;
} {1}

# One real, one temp file.
do_hasmj_test 2.2 {
  BEGIN;
    INSERT INTO t1 VALUES(1);
    INSERT INTO t3 VALUES(1);
  COMMIT;
} {0}

# One file, one :memory: db.
do_hasmj_test 2.3 {
  BEGIN;
    INSERT INTO t1 VALUES(1);
    INSERT INTO t4 VALUES(1);
  COMMIT;
} {0}

finish_test