1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2001,2008 Oracle. All rights reserved. 4# 5# $Id: si006.tcl,v 12.9 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST si006 8# TEST 9# TEST Test -immutable_key interface. 10# TEST 11# TEST DB_IMMUTABLE_KEY is an optimization to be used when a 12# TEST secondary key will not be changed. It does not prevent 13# TEST a deliberate change to the secondary key, it just does not 14# TEST propagate that change when it is made to the primary. 15# TEST This test verifies that a change to the primary is propagated 16# TEST to the secondary or not as specified by -immutable_key. 17 18proc si006 { methods {nentries 200} {tnum "006"} args } { 19 source ./include.tcl 20 global dict 21 22 # Primary method/args. 23 set pmethod [lindex $methods 0] 24 set pargs [convert_args $pmethod $args] 25 set pomethod [convert_method $pmethod] 26 27 # Renumbering recno databases can't be used as primaries. 28 if { [is_rrecno $pmethod] == 1 } { 29 puts "Skipping si$tnum for method $pmethod" 30 return 31 } 32 33 # Method/args for all the secondaries. If only one method 34 # was specified, assume the same method (for btree or hash) 35 # and a standard number of secondaries. If primary is not 36 # btree or hash, force secondaries to be one btree, one hash. 37 set methods [lrange $methods 1 end] 38 set nsecondaries 2 39 if { [llength $methods] == 0 } { 40 for { set i 0 } { $i < $nsecondaries } { incr i } { 41 if { [is_btree $pmethod] || [is_hash $pmethod] } { 42 lappend methods $pmethod 43 } else { 44 if { [expr $i % 2] == 0 } { 45 lappend methods "-btree" 46 } else { 47 lappend methods "-hash" 48 } 49 } 50 } 51 } 52 53 set argses [convert_argses $methods $args] 54 set omethods [convert_methods $methods] 55 56 # If we are given an env, use it. Otherwise, open one. 57 set eindex [lsearch -exact $args "-env"] 58 if { $eindex == -1 } { 59 env_cleanup $testdir 60 set env [berkdb_env -create -home $testdir] 61 error_check_good env_open [is_valid_env $env] TRUE 62 } else { 63 incr eindex 64 set env [lindex $args $eindex] 65 set envflags [$env get_open_flags] 66 if { [lsearch -exact $envflags "-thread"] != -1 &&\ 67 [is_queue $pmethod] == 1 } { 68 puts "Skipping si$tnum for threaded env" 69 return 70 } 71 set testdir [get_home $env] 72 } 73 74 puts "si$tnum \{\[ list $pmethod $methods \]\} $nentries" 75 cleanup $testdir $env 76 77 set pname "primary$tnum.db" 78 set snamebase "secondary$tnum" 79 80 # Open the primary. 81 set pdb [eval {berkdb_open -create -env} $env $pomethod $pargs $pname] 82 error_check_good primary_open [is_valid_db $pdb] TRUE 83 84 # Open and associate the secondaries, without -immutable_key. 85 puts "\tSi$tnum.a: Open primary and secondary databases and associate." 86 set sdbs {} 87 88 set sdb1 [eval {berkdb_open -create -env} $env \ 89 [lindex $omethods 0] [lindex $argses 0] $snamebase.1.db] 90 error_check_good open_sdb1 [is_valid_db $sdb1] TRUE 91 error_check_good sdb1_associate \ 92 [$pdb associate [callback_n 0] $sdb1] 0 93 lappend sdbs $sdb1 94 95 set sdb2 [eval {berkdb_open -create -env} $env \ 96 [lindex $omethods 1] [lindex $argses 1] $snamebase.2.db] 97 error_check_good open_sdb2 [is_valid_db $sdb2] TRUE 98 error_check_good sdb2_associate \ 99 [$pdb associate [callback_n 1] $sdb2] 0 100 lappend sdbs $sdb2 101 102 puts "\tSi$tnum.b: Put loop on primary database." 103 set did [open $dict] 104 for { set n 0 } { [gets $did str] != -1 && $n < $nentries } { incr n } { 105 if { [is_record_based $pmethod] == 1 } { 106 set key [expr $n + 1] 107 set datum $str 108 } else { 109 set key $str 110 gets $did datum 111 } 112 set keys($n) $key 113 set data($n) [pad_data $pmethod $datum] 114 115 set ret [eval {$pdb put} {$key [chop_data $pmethod $datum]}] 116 error_check_good put($n) $ret 0 117 } 118 close $did 119 120 puts "\tSi$tnum.c: Check secondaries." 121 check_secondaries $pdb $sdbs $nentries keys data "Si$tnum.c" 122 123 puts "\tSi$tnum.d: Closing/disassociating primary first" 124 error_check_good primary_close [$pdb close] 0 125 foreach sdb $sdbs { 126 error_check_good secondary_close [$sdb close] 0 127 } 128 129 puts "\tSi$tnum.e: Reopen databases." 130 # Reopen the primary. 131 set pdb [eval {berkdb_open -env} $env $pname] 132 error_check_good primary_reopen [is_valid_db $pdb] TRUE 133 134 # Reopen and associate secondary without -immutable_key. 135 set mutable {} 136 set sdb1 [eval {berkdb_open -create -env} $env \ 137 [lindex $omethods 0] [lindex $argses 0] $snamebase.1.db] 138 error_check_good open_sdb1 [is_valid_db $sdb1] TRUE 139 error_check_good sdb1_associate \ 140 [$pdb associate [callback_n 0] $sdb1] 0 141 lappend goodsdbs $mutable 142 143 # Reopen and associate second secondary with -immutable_key. 144 set immutable {} 145 set sdb2 [eval {berkdb_open -env} $env \ 146 [lindex $omethods 1] [lindex $argses 1] $snamebase.2.db] 147 error_check_good reopen_sdb2 [is_valid_db $sdb2] TRUE 148 error_check_good sdb2_associate \ 149 [$pdb associate -immutable_key [callback_n 1] $sdb2] 0 150 lappend immutable $sdb2 151 152 # Update primary. This should write to sdb1, but not sdb2. 153 puts "\tSi$tnum.f: Put loop on primary database." 154 set str "OVERWRITTEN" 155 for { set n 0 } { $n < $nentries } { incr n } { 156 if { [is_record_based $pmethod] == 1 } { 157 set key [expr $n + 1] 158 } else { 159 set key $keys($n) 160 } 161 set datum $str.$n 162 set data($n) [pad_data $pmethod $datum] 163 set ret [eval {$pdb put} {$key [chop_data $pmethod $datum]}] 164 error_check_good put($n) $ret 0 165 } 166 167 puts "\tSi$tnum.g: Check secondaries without -immutable_key." 168 check_secondaries $pdb $mutable $nentries keys data "Si$tnum.g" 169 170 puts "\tSi$tnum.h: Check secondaries with -immutable_key." 171 if { [catch {check_secondaries \ 172 $pdb $immutable $nentries keys data "Si$tnum.h"} res] != 1 } { 173 puts "FAIL: Immutable secondary key was changed." 174 } 175 176 puts "\tSi$tnum.i: Closing/disassociating primary first" 177 error_check_good primary_close [$pdb close] 0 178 error_check_good secondary1_close [$sdb1 close] 0 179 error_check_good secondary2_close [$sdb2 close] 0 180 181 # Don't close the env if this test was given one. 182 if { $eindex == -1 } { 183 error_check_good env_close [$env close] 0 184 } 185} 186 187