SQLite

Check-in [cfe60254df]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add a couple of extra coverage tests for wal.c.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: cfe60254df50f086014b115f1a2d9e31c85d67fd
User & Date: dan 2010-06-07 06:11:40.000
Context
2010-06-07
14:28
Refactor some of the global variables and commands used by tester.tcl. (check-in: c2edf8e17f user: dan tags: trunk)
06:11
Add a couple of extra coverage tests for wal.c. (check-in: cfe60254df user: dan tags: trunk)
2010-06-05
19:18
Add further test cases for the logic in sqlite3WalBeginReadTransaction(). (check-in: a49713db39 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to test/wal2.test.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34




35
36
37
38
39
40
41
42
43

proc set_tvfs_hdr {file args} {

  # Set $nHdr to the number of bytes in the wal-index header:
  set nHdr 40
  set nInt [expr {$nHdr/4}]

  if {[llength $args]>1} {
    return -code error {wrong # args: should be "set_tvfs_hdr fileName ?val?"}
  }

  set blob [tvfs shm $file]

  if {[llength $args]} {
    set ia [lindex $args 0]




    binary scan $blob a[expr $nHdr*2]a* dummy tail
    set blob [binary format i${nInt}i${nInt}a* $ia $ia $tail]
    tvfs shm $file $blob
  }

  binary scan $blob i${nInt} ints
  return $ints
}








|
|






>
>
>
>

|







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

proc set_tvfs_hdr {file args} {

  # Set $nHdr to the number of bytes in the wal-index header:
  set nHdr 40
  set nInt [expr {$nHdr/4}]

  if {[llength $args]>2} {
    error {wrong # args: should be "set_tvfs_hdr fileName ?val1? ?val2?"}
  }

  set blob [tvfs shm $file]

  if {[llength $args]} {
    set ia [lindex $args 0]
    set ib $ia
    if {[llength $args]==2} {
      set ib [lindex $args 1]
    }
    binary scan $blob a[expr $nHdr*2]a* dummy tail
    set blob [binary format i${nInt}i${nInt}a* $ia $ib $tail]
    tvfs shm $file $blob
  }

  binary scan $blob i${nInt} ints
  return $ints
}

839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862












863

864
865
866
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890

891
892
893
894
895

896
897
898
899
900
db2 close
db close

#-------------------------------------------------------------------------
# Test that even if the checksums for both are valid, if the two copies
# of the wal-index header in the wal-index do not match, the client
# runs (or at least tries to run) database recovery.
#

proc get_name {method args} { set ::filename [lindex $args 0] }
testvfs tvfs
tvfs script get_name
tvfs filter xShmOpen

file delete -force test.db test.db-wal test.db-journal
do_test wal2-9.1 {
  sqlite3 db test.db -vfs tvfs
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE x(y);
    INSERT INTO x VALUES('Barton');
    INSERT INTO x VALUES('Deakin');
  }
  set wal_index_hdr1 [string range [tvfs shm $::filename] 0 39]












  execsql { INSERT INTO x VALUES('Watson') }

} {}
do_test wal2-9.2 {
  sqlite3 db2 test.db -vfs tvfs
  execsql { SELECT * FROM x } db2
} {Barton Deakin Watson}
do_test wal2-9.3 {
  set wal_index_hdr2 [string range [tvfs shm $::filename] 0 39]
  set content [string range [tvfs shm $::filename] 80 end]
  set w [binary format a*a*a* $wal_index_hdr1 $wal_index_hdr1 $content]
  tvfs shm $::filename $w
  execsql { SELECT * FROM x } db2

} {Barton Deakin}
do_test wal2-9.4 {
  set w [binary format a*a*a* $wal_index_hdr2 $wal_index_hdr2 $content]
  tvfs shm $::filename $w
  execsql { SELECT * FROM x } db2
} {Barton Deakin Watson}
do_test wal2-9.5 {
  set w [binary format a*a*a* $wal_index_hdr1 $wal_index_hdr2 $content]
  tvfs shm $::filename $w
  execsql { SELECT * FROM x } db2
} {Barton Deakin Watson}
do_test wal2-9.6 {
  set w [binary format a*a*a* $wal_index_hdr2 $wal_index_hdr1 $content]
  tvfs shm $::filename $w
  execsql { SELECT * FROM x } db2
} {Barton Deakin Watson}

do_test wal2-9.7 {
  set w [binary format a*a*a* $wal_index_hdr1 $wal_index_hdr1 $content]
  tvfs shm $::filename $w
  execsql { SELECT * FROM x } db2
} {Barton Deakin}


db2 close
db close

finish_test







|
|
|













|
>
>
>
>
>
>
>
>
>
>
>
>

>
|
<



|
<
<
<
<
<
>
|
<
<
<
<
|
<
<
<
<
|
|
|
<
<
|
>
|
<
|
|
|
>





843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

882
883
884
885





886
887




888




889
890
891


892
893
894

895
896
897
898
899
900
901
902
903
db2 close
db close

#-------------------------------------------------------------------------
# Test that even if the checksums for both are valid, if the two copies
# of the wal-index header in the wal-index do not match, the client
# runs (or at least tries to run) database recovery.
# 
#
proc get_name {method args} { set ::filename [lindex $args 0] ; tvfs filter {} }
testvfs tvfs
tvfs script get_name
tvfs filter xShmOpen

file delete -force test.db test.db-wal test.db-journal
do_test wal2-9.1 {
  sqlite3 db test.db -vfs tvfs
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE x(y);
    INSERT INTO x VALUES('Barton');
    INSERT INTO x VALUES('Deakin');
  }

  # Set $wih(1) to the contents of the wal-index header after
  # the frames associated with the first two rows in table 'x' have
  # been inserted. Then insert one more row and set $wih(2)
  # to the new value of the wal-index header.
  #
  # If the $wih(1) is written into the wal-index before running
  # a read operation, the client will see only the first two rows. If
  # $wih(2) is written into the wal-index, the client will see
  # three rows. If an invalid header is written into the wal-index, then
  # the client will run recovery and see three rows.
  #
  set wih(1) [set_tvfs_hdr $::filename]
  execsql { INSERT INTO x VALUES('Watson') }
  set wih(2) [set_tvfs_hdr $::filename]


  sqlite3 db2 test.db -vfs tvfs
  execsql { SELECT * FROM x } db2
} {Barton Deakin Watson}






foreach {tn hdr1 hdr2 res} [list                                            \
  3  $wih(1)                $wih(1)                {Barton Deakin}          \




  4  $wih(1)                $wih(2)                {Barton Deakin Watson}   \




  5  $wih(2)                $wih(1)                {Barton Deakin Watson}   \
  6  $wih(2)                $wih(2)                {Barton Deakin Watson}   \
  7  $wih(1)                $wih(1)                {Barton Deakin}          \


  8  {0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0}   {Barton Deakin Watson}   \
] {
  do_test wal2-9.$tn {

    set_tvfs_hdr $::filename $hdr1 $hdr2
    execsql { SELECT * FROM x } db2
  } $res
}

db2 close
db close

finish_test
Changes to test/wal3.test.
630
631
632
633
634
635
636



































































































































637
638
639
do_test wal3-7.2.2 {
  set ::locks
} {{5 1 lock shared} {5 1 unlock shared} {4 1 lock shared} {4 1 unlock shared}}

db close
db2 close
T delete




































































































































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
do_test wal3-7.2.2 {
  set ::locks
} {{5 1 lock shared} {5 1 unlock shared} {4 1 lock shared} {4 1 unlock shared}}

db close
db2 close
T delete

#-------------------------------------------------------------------------
# 
do_test wal3-8.1 {
  file delete -force test.db test.db-journal test.db wal
  sqlite3 db test.db
  sqlite3 db2 test.db
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE b(c);
    INSERT INTO b VALUES('Tehran');
    INSERT INTO b VALUES('Qom');
    INSERT INTO b VALUES('Markazi');
    PRAGMA wal_checkpoint;
  }
} {wal}
do_test wal3-8.2 {
  execsql { SELECT * FROM b }
} {Tehran Qom Markazi}
do_test wal3-8.3 {
  db eval { SELECT * FROM b } {
    db eval { INSERT INTO b VALUES('Qazvin') }
    set r [db2 eval { SELECT * FROM b }]
    break
  }
  set r
} {Tehran Qom Markazi Qazvin}
do_test wal3-8.4 {
  execsql {
    INSERT INTO b VALUES('Gilan');
    INSERT INTO b VALUES('Ardabil');
  }
} {}
db2 close

faultsim_save_and_close
testvfs T -default 1
faultsim_restore_and_reopen
T filter xShmLock
T script lock_callback

proc lock_callback {method file handle spec} {
  if {$spec == "4 1 unlock exclusive"} {
    T filter {}
    set ::r [catchsql { SELECT * FROM b } db2]
  }
}
sqlite3 db test.db
sqlite3 db2 test.db
do_test wal3-8.5 {
  execsql { SELECT * FROM b }
} {Tehran Qom Markazi Qazvin Gilan Ardabil}
do_test wal3-8.6 {
  set ::r
} {1 {locking protocol}}

db close
db2 close

faultsim_restore_and_reopen
sqlite3 db2 test.db
T filter xShmLock
T script lock_callback
proc lock_callback {method file handle spec} {
  if {$spec == "1 7 unlock exclusive"} {
    T filter {}
    set ::r [catchsql { SELECT * FROM b } db2]
  }
}
unset ::r
do_test wal3-8.5 {
  execsql { SELECT * FROM b }
} {Tehran Qom Markazi Qazvin Gilan Ardabil}
do_test wal3-8.6 {
  set ::r
} {1 {locking protocol}}

db close
db2 close
T delete

#-------------------------------------------------------------------------
# When a connection opens a read-lock on the database, it searches for
# an aReadMark[] slot that is already set to the mxFrame value for the
# new transaction. If it cannot find one, it attempts to obtain an 
# exclusive lock on an aReadMark[] slot for the purposes of modifying
# the value, then drops back to a shared-lock for the duration of the
# transaction.
#
# This test case verifies that if an exclusive lock cannot be obtained
# on any aReadMark[] slot (because there are already several readers),
# the client takes a shared-lock on a slot without modifying the value
# and continues.
#
do_test wal3-9.0 {
  file delete -force test.db test.db-journal test.db wal
  sqlite3 db test.db
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE whoami(x);
    INSERT INTO whoami VALUES('nobody');
  }
} {wal}
for {set i 0} {$i < 50} {incr i} {
  set c db$i
  do_test wal3-9.1.$i {
    sqlite3 $c test.db
    execsql { UPDATE whoami SET x = $c }
    execsql {
      BEGIN;
      SELECT * FROM whoami
    } $c
  } $c
}
for {set i 0} {$i < 50} {incr i} {
  set c db$i
  do_test wal3-9.2.$i {
    execsql { SELECT * FROM whoami } $c
  } $c
}
do_test wal3-9.3 {
  for {set i 0} {$i < 49} {incr i} { db$i close }
  execsql { PRAGMA wal_checkpoint } 
  set sz1 [file size test.db]
  db49 close
  execsql { PRAGMA wal_checkpoint } 
  set sz2 [file size test.db]
  expr {$sz2 > $sz1}
} {1}

db close

finish_test