SQLC-1: fix behavior for PRAGMA rekey being called as first operation or before PRAGM...
[sqlcipher.git] / test / crypto.test
blob5f56719f6efa9db2bc12731018ca0ac694d8f50f
1 # SQLCipher
2 # codec.test developed by Stephen Lombardo (Zetetic LLC) 
3 # sjlombardo at zetetic dot net
4 # http://zetetic.net
5
6 # Copyright (c) 2009, ZETETIC LLC
7 # All rights reserved.
8
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are met:
11 #     * Redistributions of source code must retain the above copyright
12 #       notice, this list of conditions and the following disclaimer.
13 #     * Redistributions in binary form must reproduce the above copyright
14 #       notice, this list of conditions and the following disclaimer in the
15 #       documentation and/or other materials provided with the distribution.
16 #     * Neither the name of the ZETETIC LLC nor the
17 #       names of its contributors may be used to endorse or promote products
18 #       derived from this software without specific prior written permission.
19
20 # THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
21 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 # DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
24 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 # This file implements regression tests for SQLite library.  The
32 # focus of this script is testing code cipher features.
34 # NOTE: tester.tcl has overridden the definition of sqlite3 to 
35 # automatically pass in a key value. Thus tests in this file
36 # should explicitly close and open db with sqlite_orig in order
37 # to bypass default key assignment.
40 file delete -force test.db
41 file delete -force test2.db
42 file delete -force test3.db
43 file delete -force test4.db
45 set testdir [file dirname $argv0]
46 source $testdir/tester.tcl
48 # If the library is not compiled with has_codec support then
49 # skip all tests in this file.
50 if {![sqlite_orig -has-codec]} {
51   finish_test
52   return
55 proc setup {file key} {
56   sqlite_orig db $file
57   execsql "PRAGMA key=$key;"
58   execsql {
59     CREATE table t1(a,b);
60     INSERT INTO t1 VALUES ('test1', 'test2'); 
61   } db
62   db close
65 # The database is initially empty.
66 # set an hex key create some basic data
67 # create table and insert operations should work
68 # close database, open it again with the same
69 # hex key. verify that the table is readable
70 # and the data just inserted is visible
71 setup test.db "\"x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'\""
72 do_test codec-1.1 {
73   sqlite_orig db test.db
74   execsql {
75     PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
76     SELECT name FROM sqlite_master WHERE type='table';
77     SELECT * from t1;
78   }
79 } {t1 test1 test2}
80 db close
81 file delete -force test.db
83 # set an encryption key (non-hex) and create some basic data
84 # create table and insert operations should work
85 # close database, open it again with the same
86 # key. verify that the table is readable
87 # and the data just inserted is visible
88 setup test.db "'testkey'"
89 do_test codec-1.2 {
91   sqlite_orig db test.db
92   execsql {
93     PRAGMA key = 'testkey';
94     SELECT name FROM sqlite_master WHERE type='table';
95     SELECT * from t1;
96   }
97 } {t1 test1 test2}
98 db close
99 file delete -force test.db
101 # open the database and try to read from it without
102 # providing a passphrase. verify that the 
103 # an error is returned from the library
104 setup test.db "'testkey'"
105 do_test codec-1.3 {
106   sqlite_orig db test.db
107   catchsql {
108     SELECT name FROM sqlite_master WHERE type='table';
109   }
110 } {1 {file is encrypted or is not a database}}
111 db close
112 file delete -force test.db
114 # open the database and try to set an invalid
115 # passphrase. verify that an error is returned
116 # and that data couldn't be read
117 setup test.db "'testkey'"
118 do_test codec-1.3.1 {
119   sqlite_orig db test.db
120   catchsql {
121     PRAGMA key = 'testkey2';
122     SELECT name FROM sqlite_master WHERE type='table';
123   }
124 } {1 {file is encrypted or is not a database}}
125 db close
126 file delete -force test.db
128 setup test.db "'testkey'"
129 do_test codec-1.3.2 {
130   sqlite_orig db test.db
131   catchsql {
132     PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836480'";
133     SELECT name FROM sqlite_master WHERE type='table';
134   }
136 } {1 {file is encrypted or is not a database}}
137 db close
138 file delete -force test.db
140 # open the database and try to set an invalid
141 # hex key. verify that an error is returned
142 # and that data couldn't be read
143 setup test.db "'testkey'"
144 do_test codec-1.5 {
145   sqlite_orig db test.db
146   catchsql {
147     PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836480'";
148     SELECT name FROM sqlite_master WHERE type='table';
149   }
150 } {1 {file is encrypted or is not a database}}
151 db close
152 file delete -force test.db
154 # test a large number of inserts in a transaction to a memory database 
155 do_test codec-1.6 {
156   sqlite_orig db :memory:
157   execsql {
158     PRAGMA key = 'testkey3';
159     BEGIN;
160     CREATE TABLE t2(a,b);
161   }
162   for {set i 1} {$i<=25000} {incr i} {
163     set r [expr {int(rand()*500000)}]
164     execsql "INSERT INTO t2 VALUES($i,$r);" 
165   }
166   execsql {
167     COMMIT;
168     SELECT count(*) FROM t2;
169     DELETE FROM t2;
170     SELECT count(*) FROM t2;
171   } 
172 } {25000 0}
173 db close
175 # test a large number of inserts in a transaction for multiple pages
176 do_test codec-1.7 {
177   sqlite_orig db test.db
178   execsql {
179     PRAGMA key = 'testkey';
180     CREATE TABLE t2(a,b);
181     BEGIN;
182   }
183   for {set i 1} {$i<=25000} {incr i} {
184     set r [expr {int(rand()*500000)}]
185     execsql "INSERT INTO t2 VALUES($i,$r);" 
186   }
187   execsql {
188     COMMIT;
189     SELECT count(*) FROM t2;
190   } 
191 } {25000}
192 db close
193 file delete -force test.db
195 # test a rekey operation as the first op on a database
196 # then test that now the new key opens the database
197 # now close database re-open with new key
198 setup test.db "'testkey'"
199 do_test codec-1.8 {
200   sqlite_orig db test.db
201   execsql {
202     PRAGMA key = 'testkey';
203     PRAGMA rekey = 'testkeynew';
204   }
205   db close
207   sqlite_orig db test.db
208   execsql {
209     PRAGMA key = 'testkeynew';
210     SELECT name FROM sqlite_master WHERE type='table';
211   }
212 } {t1}
213 db close
214 file delete -force test.db
216 # attach an encrypted database
217 # where both database have the same
218 # key
219 setup test.db "'testkey'"
220 do_test codec-1.10 {
221   sqlite_orig db2 test2.db
223   execsql {
224     PRAGMA key = 'testkey';
225     CREATE TABLE t2(a,b);
226     INSERT INTO t2 VALUES ('test1', 'test2'); 
227   } db2
229   execsql {
230     SELECT count(*) FROM t2;
231     ATTACH 'test.db' AS db;
232     SELECT count(*) FROM db.t1;
233   } db2
235 } {1 1}
236 db2 close
237 file delete -force test.db
238 file delete -force test2.db
240 # attach an encrypted database
241 # where databases have different keys
242 setup test.db "'testkey'"
243 do_test codec-1.11 {
244   sqlite_orig db2 test2.db
246   execsql {
247     PRAGMA key = 'testkey2';
248     CREATE TABLE t2(a,b);
249     INSERT INTO t2 VALUES ('test1', 'test2'); 
250   } db2
251   
252   execsql {
253     ATTACH 'test.db' AS db KEY 'testkey';
254     SELECT count(*) FROM db.t1;
255     SELECT count(*) FROM t2;
256   } db2
258 } {1 1}
259 db2 close
260 file delete -force test.db
261 file delete -force test2.db
263 # test locking across multiple handles
264 setup test.db "'testkey'"
265 do_test codec-1.12 {
266   sqlite_orig db test.db
268   execsql {
269     PRAGMA key = 'testkey';
270     BEGIN EXCLUSIVE;
271     INSERT INTO t1 VALUES(1,2);
272   } 
273   
274   sqlite_orig dba test.db
275   catchsql {
276     PRAGMA key = 'testkey';
277       SELECT count(*) FROM t1;
278   } dba
280  } {1 {database is locked}} 
282 do_test codec-1.12.1 {
283  execsql {
284     COMMIT;
285   }
287   execsql {
288     SELECT count(*) FROM t1;
289   } dba
290 } {2}
291 db close
292 dba close
293 file delete -force test.db
295 # alter schema
296 setup test.db "'testkey'"
297 do_test codec-1.13 {
298   sqlite_orig db test.db
299   execsql {
300     PRAGMA key = 'testkey';
301     ALTER TABLE t1 ADD COLUMN c;
302     INSERT INTO t1 VALUES (1,2,3);
303     INSERT INTO t1 VALUES (1,2,4);
304     CREATE TABLE t1a (a);
305     INSERT INTO t1a VALUES ('teststring');
306   }
307   db close
309   sqlite_orig db test.db
310   execsql {
311     PRAGMA key = 'testkey';
312     SELECT count(*) FROM t1 WHERE a IS NOT NULL;
313     SELECT count(*) FROM t1 WHERE c IS NOT NULL;
314     SELECT * FROM t1a;
315   } 
317 } {3 2 teststring}
318 db close
319 file delete -force test.db
321 # test alterations of KDF iterations and ciphers
322 # rekey then add
323 setup test.db "'testkey'"
324 do_test codec-1.14 {
325   sqlite_orig db test.db
326   execsql {
327     PRAGMA key = 'testkey';
328     PRAGMA rekey_kdf_iter = 1000;
329     PRAGMA rekey_cipher = 'aes-256-cfb';
330     PRAGMA rekey = 'testkey2';
331     INSERT INTO t1 VALUES (1,2);
332   } 
333   db close
335   sqlite_orig db test.db
336   execsql {
337     PRAGMA key = 'testkey2';
338     PRAGMA kdf_iter = 1000;
339     PRAGMA cipher = 'aes-256-cfb';
340     SELECT count(*) FROM t1;
341   } 
343 } {2}
344 db close
345 file delete -force test.db
347 # test alterations of CIPHER from CBC Mode requiring
348 # IV to ECB mode that does not
349 setup test.db "'testkey'"
350 do_test codec-1.15 {
351   sqlite_orig db test.db
352   execsql {
353     PRAGMA key = 'testkey';
354     BEGIN;
355   }
357   for {set i 1} {$i<=1000} {incr i} {
358     set r [expr {int(rand()*500000)}]
359     execsql "INSERT INTO t1 VALUES($i,$r);" 
360   }
361   
362   execsql {
363     COMMIT;
364     PRAGMA rekey_kdf_iter = 1000;
365     PRAGMA rekey_cipher = 'aes-128-ecb';
366     PRAGMA rekey = 'testkey';
367   } 
368   db close
370   sqlite_orig db test.db
371   execsql {
372     PRAGMA key = 'testkey';
373     PRAGMA kdf_iter = 1000;
374     PRAGMA cipher = 'aes-128-ecb';
375     SELECT count(*) FROM t1;
376   } 
378 } {1001}
379 db close
380 file delete -force test.db
382 # test alterations of CIPHER from ECB Mode (no IV) to CBC Mode
383 do_test codec-1.16 {
384   sqlite_orig db test.db
385   execsql {
386     PRAGMA key = 'testkey';
387     PRAGMA cipher = 'aes-256-ecb';
388     CREATE table t1(a,b);
389     BEGIN;
390   }
392   for {set i 1} {$i<=1000} {incr i} {
393     set r [expr {int(rand()*500000)}]
394     execsql "INSERT INTO t1 VALUES($i,$r);" 
395   }
396   
397   execsql {
398     COMMIT;
399     PRAGMA rekey_cipher = 'aes-256-cbc';
400     PRAGMA rekey = 'testkey';
401   } 
402   db close
404   sqlite_orig db test.db
405   execsql {
406     PRAGMA key = 'testkey';
407     SELECT count(*) FROM t1;
408   } 
410 } {1000}
411 db close
412 file delete -force test.db
414 # create an unencrypted database, attach a new encrypted volume
415 # copy data between, verify the encypted database is good afterwards
416 do_test unencryped-attach {
417   sqlite_orig db test.db
419   execsql {
420     CREATE TABLE t1(a,b);
421     BEGIN;
422   } 
424   for {set i 1} {$i<=1000} {incr i} {
425     set r [expr {int(rand()*500000)}]
426     execsql "INSERT INTO t1 VALUES($i,$r);" 
427   }
428   
429   execsql {
430     COMMIT;
431     ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey';
432     CREATE TABLE db2.t1(a,b);
433     INSERT INTO db2.t1 SELECT * FROM t1;
434     DETACH DATABASE db2;
435   }
436   
437   sqlite_orig db2 test2.db
438   execsql {
439     PRAGMA  key='testkey';
440     SELECT count(*) FROM t1;
441   } db2 
442 } {1000}
443 db2 close
444 file delete -force test.db
445 file delete -force test2.db
447 # create an encrypted database, attach an unencrypted volume
448 # copy data between, verify the unencypted database is good afterwards
449 do_test encryped-attach-unencrypted {
450   sqlite_orig db test.db
452   execsql {
453     CREATE TABLE t1(a,b);
454   } 
456   sqlite_orig db2 test2.db
457   execsql {
458     PRAGMA  key='testkey';
459     CREATE TABLE t1(a,b);
460     BEGIN;
461   }  db2
463   for {set i 1} {$i<=1000} {incr i} {
464     set r [expr {int(rand()*500000)}]
465     execsql "INSERT INTO t1 VALUES($i,$r);" db2 
466   }
467   
468   execsql {
469     COMMIT;
470     ATTACH DATABASE 'test.db' AS test KEY '';
471     INSERT INTO test.t1 SELECT * FROM t1;
472     DETACH DATABASE test;
473   } db2
475   execsql {
476     SELECT count(*) FROM t1;
477   } 
478 } {1000}
479 db close
480 db2 close
481 file delete -force test.db
482 file delete -force test2.db
484 # create an unencrypted database, attach an unencrypted volume
485 # copy data between, verify the unencypted database is good afterwards
486 do_test unencryped-attach-unencrypted {
487   sqlite_orig db test.db
489   execsql {
490     CREATE TABLE t1(a,b);
491   } 
493   sqlite_orig db2 test2.db
494   execsql {
495     CREATE TABLE t1(a,b);
496     BEGIN;
497   }  db2
499   for {set i 1} {$i<=1000} {incr i} {
500     set r [expr {int(rand()*500000)}]
501     execsql "INSERT INTO t1 VALUES($i,$r);" db2 
502   }
503   
504   execsql {
505     COMMIT;
506     ATTACH DATABASE 'test.db' AS test;
507     INSERT INTO test.t1 SELECT * FROM t1;
508     DETACH DATABASE test;
509   } db2
511   execsql {
512     SELECT count(*) FROM t1;
513   } 
514 } {1000}
515 db close
516 db2 close
517 file delete -force test.db
518 file delete -force test2.db
520 # 1. create a database with a custom page size, 
521 # 2. create table and insert operations should work
522 # 3. close database, open it again with the same
523 #    key and page size
524 # 4. verify that the table is readable
525 #    and the data just inserted is visible
526 do_test custom-pagesize {
527   sqlite_orig db test.db
529   execsql {
530     PRAGMA key = 'testkey';
531     PRAGMA cipher_page_size = 4096;
532     CREATE table t1(a,b);
533     BEGIN;
534   }
536   for {set i 1} {$i<=1000} {incr i} {
537     set r [expr {int(rand()*500000)}]
538     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
539   }
541   execsql {
542     COMMIT;
543   } 
545   db close
546   sqlite_orig db test.db
548   execsql {
549     PRAGMA key = 'testkey';
550     PRAGMA cipher_page_size = 4096;
551     SELECT count(*) FROM t1;
552   }
554 } {1000}
555 db close
557 # open the database with the default page size
558 ## and verfiy that it is not readable 
559 do_test custom-pagesize-must-match {
560   sqlite_orig db test.db
561   catchsql {
562     PRAGMA key = 'testkey';
563     SELECT name FROM sqlite_master WHERE type='table';
564   }
565 } {1 {file is encrypted or is not a database}}
566 db close
567 file delete -force test.db
569 # 1. create a database and insert a bunch of data, close the database
570 # 2. seek to the middle of a database page and write some junk
571 # 3. Open the database and verify that the database is no longer readable
572 do_test hmac-tamper-resistence {
573   sqlite_orig db test.db
575   execsql {
576     PRAGMA key = 'testkey';
577     CREATE table t1(a,b);
578     BEGIN;
579   }
581   for {set i 1} {$i<=1000} {incr i} {
582     set r [expr {int(rand()*500000)}]
583     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
584   }
586   execsql {
587     COMMIT;
588   } 
590   db close
592   # write some junk into the middle of the page
593   hexio_write test.db 2560 00
595   sqlite_orig db test.db
597   catchsql {
598     PRAGMA key = 'testkey';
599     SELECT count(*) FROM t1;
600   }
602 } {1 {database disk image is malformed}}
603 db close
604 file delete -force test.db
606 # 1. create a database and insert a bunch of data, close the database
607 # 2. seek to the middle of a database page and write some junk
608 # 3. Open the database and verify that the database is still readable
609 do_test nohmac-not-tamper-resistent {
610   sqlite_orig db test.db
612   execsql {
613     PRAGMA key = 'testkey';
614     PRAGMA cipher_use_hmac = OFF;
615     PRAGMA cipher_page_size = 1024;
616     CREATE table t1(a,b);
617     BEGIN;
618   }
620   for {set i 1} {$i<=1000} {incr i} {
621     set r [expr {int(rand()*500000)}]
622     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
623   }
625   execsql {
626     COMMIT;
627   } 
629   db close
631   # write some junk into the middle of the page
632   hexio_write test.db 2560 00
634   sqlite_orig db test.db
636   execsql {
637     PRAGMA key = 'testkey';
638     PRAGMA cipher_use_hmac = OFF;
639     PRAGMA cipher_page_size = 1024;
640     SELECT count(*) FROM t1;
641   }
643 } {1000}
644 db close
645 file delete -force test.db
647 # open a 1.1.8 database using the new code, HMAC disabled
648 do_test open-1.1.8-database {
649   sqlite_orig db sqlcipher-1.1.8-testkey.db
650   execsql {
651     PRAGMA key = 'testkey';
652     PRAGMA cipher_use_hmac = OFF;
653     SELECT count(*) FROM t1;
654     SELECT * FROM t1;
655   } 
656 } {4 1 1 one one 1 2 one two}
657 db close
660 # open a 1.1.8 database without hmac, then copy the data
661 do_test attach-and-copy-1.1.8 {
662   sqlite_orig db sqlcipher-1.1.8-testkey.db
664   execsql {
665     PRAGMA key = 'testkey';
666     PRAGMA cipher_use_hmac = OFF;
667     ATTACH DATABASE 'test.db' AS db2 KEY 'testkey-hmac'; 
668     CREATE TABLE db2.t1(a,b);
669     INSERT INTO db2.t1 SELECT * FROM main.t1;
670     DETACH DATABASE db2;
671   }
672   db close
674   sqlite_orig db test.db
675   execsql {
676     PRAGMA key = 'testkey-hmac';
677     SELECT count(*) FROM t1;
678     SELECT * FROM t1;
679   }
680 } {4 1 1 one one 1 2 one two}
681 db close
682 file delete -force test.db
684 # open a standard database, then attach a new 
685 # database with completely different options. 
686 # copy data between them, and verify that the
687 # new database can be opened with the proper data
688 do_test attached-database-pragmas {
689   sqlite_orig db test.db
691   execsql {
692     PRAGMA key = 'testkey';
693     CREATE TABLE t1(a,b);
694     BEGIN;
695   }
697   for {set i 1} {$i<=1000} {incr i} {
698     set r [expr {int(rand()*500000)}]
699     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
700   } 
702   execsql {
703     COMMIT;
704     ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2'; 
705     PRAGMA db2.cipher_page_size = 4096;
706     PRAGMA db2.cipher = 'aes-128-cbc';
707     PRAGMA db2.kdf_iter = 1000;
708     PRAGMA db2.cipher_use_hmac = OFF;
709     CREATE TABLE db2.t1(a,b);
710     INSERT INTO db2.t1 SELECT * FROM main.t1;
711     DETACH DATABASE db2;
712   }
713   db close
715   sqlite_orig db test2.db
716   execsql {
717     PRAGMA key = 'testkey2';
718     PRAGMA cipher_page_size = 4096;
719     PRAGMA cipher = 'aes-128-cbc';
720     PRAGMA kdf_iter = 1000;
721     PRAGMA cipher_use_hmac = OFF;
722     SELECT count(*) FROM t1;
723   }
724 } {1000}
725 db close
726 file delete -force test.db
727 file delete -force test2.db
729 # use the sqlcipher_export function
730 # on a non-existent database. Verify 
731 # the error gets through.
732 do_test export-error {
733   sqlite_orig db test.db
735   catchsql {
736     PRAGMA key = 'testkey';
737     CREATE TABLE t1(a,b);
738     SELECT sqlcipher_export('nodb');
739   } 
740 } {1 {unknown database nodb}}
741 db close
742 file delete -force test.db
744 # use the sqlcipher_export function
745 # to copy a complicated database. 
746 # tests autoincrement fields,
747 # indexes, views, and triggers
748 do_test export-database {
749   sqlite_orig db test.db
751   execsql {
752     PRAGMA key = 'testkey';
753     CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
754     CREATE UNIQUE INDEX b_idx ON t1(b);
755     CREATE INDEX c_idx ON t1(c);
757     CREATE TABLE t2(a,b);
758     CREATE TRIGGER t2_after_insert AFTER INSERT ON t2
759     BEGIN 
760       INSERT INTO t1(b,c) VALUES (new.a, new.b);
761     END;
763     CREATE VIEW v1 AS
764       SELECT c FROM t1;
766     BEGIN;
767   }
769   for {set i 1} {$i<=1000} {incr i} {
770     set r [expr {int(rand()*500000)}]
771     execsql "INSERT INTO t2 VALUES($i,'value $r');" 
772   } 
774   execsql {
775     COMMIT;
776     ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2'; 
777     PRAGMA db2.cipher_page_size = 4096;
779     SELECT sqlcipher_export('db2');
781     DETACH DATABASE db2;
782   }
783   db close
785   sqlite_orig db test2.db
786   execsql {
787     PRAGMA key = 'testkey2';
788     PRAGMA cipher_page_size = 4096;
789     SELECT count(*) FROM t1;
790     SELECT count(*) FROM v1;
791     SELECT count(*) FROM sqlite_sequence;
792     SELECT seq FROM sqlite_sequence WHERE name = 't1';
793     INSERT INTO t2 VALUES(1001, 'value 938383');
794     SELECT count(*) FROM t1; -- verify the trigger worked
795     SELECT seq FROM sqlite_sequence WHERE name = 't1'; -- verify that autoincrement worked
796   }
797 } {1000 1000 1 1000 1001 1001}
798 db close
799 file delete -force test.db
800 file delete -force test2.db
802 # 1. create a database with WAL journal mode
803 # 2. create table and insert operations should work
804 # 3. close database, open it again
805 # 4. verify that the table is present, readable, and that
806 #    the journal mode is WAL
807 do_test journal-mode-wal {
808   sqlite_orig db test.db
810   execsql {
811     PRAGMA key = 'testkey';
812     PRAGMA journal_mode = WAL;
813     CREATE table t1(a,b);
814     BEGIN;
815   }
817   for {set i 1} {$i<=1000} {incr i} {
818     set r [expr {int(rand()*500000)}]
819     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
820   }
822   execsql {
823     COMMIT;
824   } 
826   db close
827   sqlite_orig db test.db
829   execsql {
830     PRAGMA key = 'testkey';
831     SELECT count(*) FROM t1;
832     PRAGMA journal_mode;
833   }
835 } {1000 wal}
836 db close
837 file delete -force test.db
839 # Test rekey as first operation on an empty database. should be a no-op
840 do_test rekey-as-first-op {
841   sqlite_orig db test.db
843   execsql {
844     PRAGMA rekey = 'testkey';
845     CREATE table t1(a,b);
846     BEGIN;
847   }
849   for {set i 1} {$i<=100} {incr i} {
850     set r [expr {int(rand()*500000)}]
851     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
852   }
854   execsql {
855     COMMIT;
856   } 
858   db close
859   sqlite_orig db test.db
861   execsql {
862     PRAGMA rekey = 'testkey';
863     SELECT count(*) FROM t1;
864   }
866 } {100}
867 db close
868 file delete -force test.db
870 # Test rekey as first operation follwed by key
871 do_test rekey-then-key-as-first-ops {
872   sqlite_orig db test.db
874   execsql {
875     PRAGMA rekey = '1234';
876     PRAGMA key = 'testkey';
877     CREATE table t1(a,b);
878     BEGIN;
879   }
881   for {set i 1} {$i<=100} {incr i} {
882     set r [expr {int(rand()*500000)}]
883     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
884   }
886   execsql {
887     COMMIT;
888   } 
890   db close
891   sqlite_orig db test.db
893   execsql {
894     PRAGMA rekey = '4321';
895     PRAGMA key = 'testkey';
896     SELECT count(*) FROM t1;
897   }
899 } {100}
900 db close
902 finish_test