Home | History | Annotate | Line # | Download | only in db
      1  1.9    martin # $NetBSD: t_db.sh,v 1.9 2020/03/12 14:10:59 martin Exp $
      2  1.1  pgoyette #
      3  1.1  pgoyette # Copyright (c) 2008 The NetBSD Foundation, Inc.
      4  1.1  pgoyette # All rights reserved.
      5  1.1  pgoyette #
      6  1.1  pgoyette # Redistribution and use in source and binary forms, with or without
      7  1.1  pgoyette # modification, are permitted provided that the following conditions
      8  1.1  pgoyette # are met:
      9  1.1  pgoyette # 1. Redistributions of source code must retain the above copyright
     10  1.1  pgoyette #    notice, this list of conditions and the following disclaimer.
     11  1.1  pgoyette # 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  pgoyette #    notice, this list of conditions and the following disclaimer in the
     13  1.1  pgoyette #    documentation and/or other materials provided with the distribution.
     14  1.1  pgoyette #
     15  1.1  pgoyette # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     16  1.1  pgoyette # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     17  1.1  pgoyette # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  1.1  pgoyette # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     19  1.1  pgoyette # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  1.1  pgoyette # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  1.1  pgoyette # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  1.1  pgoyette # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  1.1  pgoyette # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  1.1  pgoyette # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1  pgoyette # POSSIBILITY OF SUCH DAMAGE.
     26  1.1  pgoyette #
     27  1.1  pgoyette 
     28  1.6  christos prog_db()
     29  1.1  pgoyette {
     30  1.1  pgoyette 	echo $(atf_get_srcdir)/h_db
     31  1.1  pgoyette }
     32  1.1  pgoyette 
     33  1.6  christos prog_lfsr()
     34  1.6  christos {
     35  1.6  christos 	echo $(atf_get_srcdir)/h_lfsr
     36  1.6  christos }
     37  1.6  christos 
     38  1.1  pgoyette dict()
     39  1.1  pgoyette {
     40  1.1  pgoyette 	if [ -f /usr/share/dict/words ]; then
     41  1.1  pgoyette 		echo /usr/share/dict/words
     42  1.1  pgoyette 	elif [ -f /usr/dict/words ]; then
     43  1.1  pgoyette 		echo /usr/dict/words
     44  1.1  pgoyette 	else
     45  1.1  pgoyette 		atf_fail "no dictionary found"
     46  1.1  pgoyette 	fi
     47  1.1  pgoyette }
     48  1.1  pgoyette 
     49  1.1  pgoyette SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg"
     50  1.1  pgoyette 
     51  1.1  pgoyette atf_test_case small_btree
     52  1.1  pgoyette small_btree_head()
     53  1.1  pgoyette {
     54  1.1  pgoyette 	atf_set "descr" \
     55  1.1  pgoyette 		"Checks btree database using small keys and small data" \
     56  1.1  pgoyette 		"pairs: takes the first hundred entries in the dictionary," \
     57  1.1  pgoyette 		"and makes them be key/data pairs."
     58  1.1  pgoyette }
     59  1.1  pgoyette small_btree_body()
     60  1.1  pgoyette {
     61  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
     62  1.1  pgoyette 	mkdir ${TMPDIR}
     63  1.1  pgoyette 
     64  1.1  pgoyette 	sed 200q $(dict) >exp
     65  1.1  pgoyette 
     66  1.1  pgoyette 	for i in `sed 200q $(dict)`; do
     67  1.1  pgoyette 		echo p
     68  1.1  pgoyette 		echo k$i
     69  1.1  pgoyette 		echo d$i
     70  1.1  pgoyette 		echo g
     71  1.1  pgoyette 		echo k$i
     72  1.1  pgoyette 	done >in
     73  1.1  pgoyette 
     74  1.6  christos 	atf_check -o file:exp "$(prog_db)" btree in
     75  1.1  pgoyette }
     76  1.1  pgoyette 
     77  1.1  pgoyette atf_test_case small_hash
     78  1.1  pgoyette small_hash_head()
     79  1.1  pgoyette {
     80  1.1  pgoyette 	atf_set "descr" \
     81  1.1  pgoyette 		"Checks hash database using small keys and small data" \
     82  1.1  pgoyette 		"pairs: takes the first hundred entries in the dictionary," \
     83  1.1  pgoyette 		"and makes them be key/data pairs."
     84  1.1  pgoyette }
     85  1.1  pgoyette small_hash_body()
     86  1.1  pgoyette {
     87  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
     88  1.1  pgoyette 	mkdir ${TMPDIR}
     89  1.1  pgoyette 
     90  1.1  pgoyette 	sed 200q $(dict) >exp
     91  1.1  pgoyette 
     92  1.1  pgoyette 	for i in `sed 200q $(dict)`; do
     93  1.1  pgoyette 		echo p
     94  1.1  pgoyette 		echo k$i
     95  1.1  pgoyette 		echo d$i
     96  1.1  pgoyette 		echo g
     97  1.1  pgoyette 		echo k$i
     98  1.1  pgoyette 	done >in
     99  1.1  pgoyette 
    100  1.6  christos 	atf_check -o file:exp "$(prog_db)" hash in
    101  1.1  pgoyette }
    102  1.1  pgoyette 
    103  1.1  pgoyette atf_test_case small_recno
    104  1.1  pgoyette small_recno_head()
    105  1.1  pgoyette {
    106  1.1  pgoyette 	atf_set "descr" \
    107  1.1  pgoyette 		"Checks recno database using small keys and small data" \
    108  1.1  pgoyette 		"pairs: takes the first hundred entries in the dictionary," \
    109  1.1  pgoyette 		"and makes them be key/data pairs."
    110  1.1  pgoyette }
    111  1.1  pgoyette small_recno_body()
    112  1.1  pgoyette {
    113  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    114  1.1  pgoyette 	mkdir ${TMPDIR}
    115  1.1  pgoyette 
    116  1.1  pgoyette 	sed 200q $(dict) >exp
    117  1.1  pgoyette 
    118  1.1  pgoyette 	sed 200q $(dict) |
    119  1.1  pgoyette 	awk '{ 
    120  1.1  pgoyette 		++i;
    121  1.1  pgoyette 		printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
    122  1.1  pgoyette 	}' >in
    123  1.1  pgoyette 
    124  1.6  christos 	atf_check -o file:exp "$(prog_db)" recno in
    125  1.1  pgoyette }
    126  1.1  pgoyette 
    127  1.1  pgoyette atf_test_case medium_btree
    128  1.1  pgoyette medium_btree_head()
    129  1.1  pgoyette {
    130  1.1  pgoyette 	atf_set "descr" \
    131  1.1  pgoyette 		"Checks btree database using small keys and medium" \
    132  1.1  pgoyette 		"data pairs: takes the first 200 entries in the" \
    133  1.1  pgoyette 		"dictionary, and gives them each a medium size data entry."
    134  1.1  pgoyette }
    135  1.1  pgoyette medium_btree_body()
    136  1.1  pgoyette {
    137  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    138  1.1  pgoyette 	mkdir ${TMPDIR}
    139  1.1  pgoyette 
    140  1.1  pgoyette 	mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
    141  1.1  pgoyette 	echo $mdata |
    142  1.1  pgoyette 	awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
    143  1.1  pgoyette 
    144  1.1  pgoyette 	for i in $(sed 200q $(dict)); do
    145  1.1  pgoyette 		echo p
    146  1.1  pgoyette 		echo k$i
    147  1.1  pgoyette 		echo d$mdata
    148  1.1  pgoyette 		echo g
    149  1.1  pgoyette 		echo k$i
    150  1.1  pgoyette 	done >in
    151  1.1  pgoyette 
    152  1.6  christos 	atf_check -o file:exp "$(prog_db)" btree in
    153  1.1  pgoyette }
    154  1.1  pgoyette 
    155  1.1  pgoyette atf_test_case medium_hash
    156  1.1  pgoyette medium_hash_head()
    157  1.1  pgoyette {
    158  1.1  pgoyette 	atf_set "descr" \
    159  1.1  pgoyette 		"Checks hash database using small keys and medium" \
    160  1.1  pgoyette 		"data pairs: takes the first 200 entries in the" \
    161  1.1  pgoyette 		"dictionary, and gives them each a medium size data entry."
    162  1.1  pgoyette }
    163  1.1  pgoyette medium_hash_body()
    164  1.1  pgoyette {
    165  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    166  1.1  pgoyette 	mkdir ${TMPDIR}
    167  1.1  pgoyette 
    168  1.1  pgoyette 	mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
    169  1.1  pgoyette 	echo $mdata |
    170  1.1  pgoyette 	awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
    171  1.1  pgoyette 
    172  1.1  pgoyette 	for i in $(sed 200q $(dict)); do
    173  1.1  pgoyette 		echo p
    174  1.1  pgoyette 		echo k$i
    175  1.1  pgoyette 		echo d$mdata
    176  1.1  pgoyette 		echo g
    177  1.1  pgoyette 		echo k$i
    178  1.1  pgoyette 	done >in
    179  1.1  pgoyette 
    180  1.6  christos 	atf_check -o file:exp "$(prog_db)" hash in
    181  1.1  pgoyette }
    182  1.1  pgoyette 
    183  1.1  pgoyette atf_test_case medium_recno
    184  1.1  pgoyette medium_recno_head()
    185  1.1  pgoyette {
    186  1.1  pgoyette 	atf_set "descr" \
    187  1.1  pgoyette 		"Checks recno database using small keys and medium" \
    188  1.1  pgoyette 		"data pairs: takes the first 200 entries in the" \
    189  1.1  pgoyette 		"dictionary, and gives them each a medium size data entry."
    190  1.1  pgoyette }
    191  1.1  pgoyette medium_recno_body()
    192  1.1  pgoyette {
    193  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    194  1.1  pgoyette 	mkdir ${TMPDIR}
    195  1.1  pgoyette 
    196  1.1  pgoyette 	mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
    197  1.1  pgoyette 	echo $mdata |
    198  1.1  pgoyette 	awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
    199  1.1  pgoyette 
    200  1.1  pgoyette 	echo $mdata | 
    201  1.1  pgoyette 	awk '{  for (i = 1; i < 201; ++i)
    202  1.1  pgoyette 		printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
    203  1.1  pgoyette 	}' >in
    204  1.1  pgoyette 
    205  1.6  christos 	atf_check -o file:exp "$(prog_db)" recno in
    206  1.1  pgoyette }
    207  1.1  pgoyette 
    208  1.1  pgoyette atf_test_case big_btree
    209  1.1  pgoyette big_btree_head()
    210  1.1  pgoyette {
    211  1.1  pgoyette 	atf_set "descr" \
    212  1.1  pgoyette 		"Checks btree database using small keys and big data" \
    213  1.1  pgoyette 		"pairs: inserts the programs in /bin with their paths" \
    214  1.1  pgoyette 		"as their keys."
    215  1.1  pgoyette }
    216  1.1  pgoyette big_btree_body()
    217  1.1  pgoyette {
    218  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    219  1.1  pgoyette 	mkdir ${TMPDIR}
    220  1.1  pgoyette 
    221  1.1  pgoyette 	(find /bin -type f -print | xargs cat) >exp
    222  1.1  pgoyette 
    223  1.1  pgoyette 	for psize in 512 16384 65536; do
    224  1.1  pgoyette 		echo "checking page size: $psize"
    225  1.1  pgoyette 
    226  1.1  pgoyette 		for i in `find /bin -type f -print`; do
    227  1.1  pgoyette 			echo p
    228  1.1  pgoyette 			echo k$i
    229  1.1  pgoyette 			echo D$i
    230  1.1  pgoyette 			echo g
    231  1.1  pgoyette 			echo k$i
    232  1.1  pgoyette 		done >in
    233  1.1  pgoyette 
    234  1.6  christos 		atf_check "$(prog_db)" -o out btree in
    235  1.1  pgoyette 		cmp -s exp out || atf_fail "test failed for page size: $psize"
    236  1.1  pgoyette 	done
    237  1.1  pgoyette }
    238  1.1  pgoyette 
    239  1.1  pgoyette atf_test_case big_hash
    240  1.1  pgoyette big_hash_head()
    241  1.1  pgoyette {
    242  1.1  pgoyette 	atf_set "descr" \
    243  1.1  pgoyette 		"Checks hash database using small keys and big data" \
    244  1.1  pgoyette 		"pairs: inserts the programs in /bin with their paths" \
    245  1.1  pgoyette 		"as their keys."
    246  1.1  pgoyette }
    247  1.1  pgoyette big_hash_body()
    248  1.1  pgoyette {
    249  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    250  1.1  pgoyette 	mkdir ${TMPDIR}
    251  1.1  pgoyette 
    252  1.1  pgoyette 	(find /bin -type f -print | xargs cat) >exp
    253  1.1  pgoyette 
    254  1.1  pgoyette 	for i in `find /bin -type f -print`; do
    255  1.1  pgoyette 		echo p
    256  1.1  pgoyette 		echo k$i
    257  1.1  pgoyette 		echo D$i
    258  1.1  pgoyette 		echo g
    259  1.1  pgoyette 		echo k$i
    260  1.1  pgoyette 	done >in
    261  1.1  pgoyette 
    262  1.6  christos 	atf_check "$(prog_db)" -o out hash in
    263  1.1  pgoyette 	cmp -s exp out || atf_fail "test failed"
    264  1.1  pgoyette }
    265  1.1  pgoyette 
    266  1.1  pgoyette atf_test_case big_recno
    267  1.1  pgoyette big_recno_head()
    268  1.1  pgoyette {
    269  1.1  pgoyette 	atf_set "descr" \
    270  1.1  pgoyette 		"Checks recno database using small keys and big data" \
    271  1.1  pgoyette 		"pairs: inserts the programs in /bin with their paths" \
    272  1.1  pgoyette 		"as their keys."
    273  1.1  pgoyette }
    274  1.1  pgoyette big_recno_body()
    275  1.1  pgoyette {
    276  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    277  1.1  pgoyette 	mkdir ${TMPDIR}
    278  1.1  pgoyette 
    279  1.1  pgoyette 	(find /bin -type f -print | xargs cat) >exp
    280  1.1  pgoyette 
    281  1.1  pgoyette 	find /bin -type f -print | 
    282  1.1  pgoyette 	awk '{
    283  1.1  pgoyette 		++i;
    284  1.1  pgoyette 		printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
    285  1.1  pgoyette 	}' >in
    286  1.1  pgoyette 
    287  1.1  pgoyette 	for psize in 512 16384 65536; do
    288  1.1  pgoyette 		echo "checking page size: $psize"
    289  1.1  pgoyette 
    290  1.6  christos 		atf_check "$(prog_db)" -o out recno in
    291  1.1  pgoyette 		cmp -s exp out || atf_fail "test failed for page size: $psize"
    292  1.1  pgoyette 	done
    293  1.1  pgoyette }
    294  1.1  pgoyette 
    295  1.1  pgoyette atf_test_case random_recno
    296  1.1  pgoyette random_recno_head()
    297  1.1  pgoyette {
    298  1.1  pgoyette 	atf_set "descr" "Checks recno database using random entries"
    299  1.1  pgoyette }
    300  1.1  pgoyette random_recno_body()
    301  1.1  pgoyette {
    302  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    303  1.1  pgoyette 	mkdir ${TMPDIR}
    304  1.1  pgoyette 
    305  1.1  pgoyette 	echo $SEVEN_SEVEN |
    306  1.1  pgoyette 	awk '{
    307  1.1  pgoyette 		for (i = 37; i <= 37 + 88 * 17; i += 17) {
    308  1.1  pgoyette 			if (i % 41)
    309  1.1  pgoyette 				s = substr($0, 1, i % 41);
    310  1.1  pgoyette 			else
    311  1.1  pgoyette 				s = substr($0, 1);
    312  1.1  pgoyette 			printf("input key %d: %s\n", i, s);
    313  1.1  pgoyette 		}
    314  1.1  pgoyette 		for (i = 1; i <= 15; ++i) {
    315  1.1  pgoyette 			if (i % 41)
    316  1.1  pgoyette 				s = substr($0, 1, i % 41);
    317  1.1  pgoyette 			else
    318  1.1  pgoyette 				s = substr($0, 1);
    319  1.1  pgoyette 			printf("input key %d: %s\n", i, s);
    320  1.1  pgoyette 		}
    321  1.1  pgoyette 		for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
    322  1.1  pgoyette 			if (i % 41)
    323  1.1  pgoyette 				s = substr($0, 1, i % 41);
    324  1.1  pgoyette 			else
    325  1.1  pgoyette 				s = substr($0, 1);
    326  1.1  pgoyette 			printf("input key %d: %s\n", i, s);
    327  1.1  pgoyette 		}
    328  1.1  pgoyette 		exit
    329  1.1  pgoyette 	}' >exp
    330  1.1  pgoyette 
    331  1.1  pgoyette 	cat exp |
    332  1.1  pgoyette 	awk 'BEGIN {
    333  1.1  pgoyette 			i = 37;
    334  1.1  pgoyette 			incr = 17;
    335  1.1  pgoyette 		}
    336  1.1  pgoyette 		{
    337  1.1  pgoyette 			printf("p\nk%d\nd%s\n", i, $0);
    338  1.1  pgoyette 			if (i == 19234 + 61 * 27)
    339  1.1  pgoyette 				exit;
    340  1.1  pgoyette 			if (i == 37 + 88 * 17) {
    341  1.1  pgoyette 				i = 1;
    342  1.1  pgoyette 				incr = 1;
    343  1.1  pgoyette 			} else if (i == 15) {
    344  1.1  pgoyette 				i = 19234;
    345  1.1  pgoyette 				incr = 27;
    346  1.1  pgoyette 			} else
    347  1.1  pgoyette 				i += incr;
    348  1.1  pgoyette 		}
    349  1.1  pgoyette 		END {
    350  1.1  pgoyette 			for (i = 37; i <= 37 + 88 * 17; i += 17)
    351  1.1  pgoyette 				printf("g\nk%d\n", i);
    352  1.1  pgoyette 			for (i = 1; i <= 15; ++i)
    353  1.1  pgoyette 				printf("g\nk%d\n", i);
    354  1.1  pgoyette 			for (i = 19234; i <= 19234 + 61 * 27; i += 27)
    355  1.1  pgoyette 				printf("g\nk%d\n", i);
    356  1.1  pgoyette 		}' >in
    357  1.1  pgoyette 
    358  1.6  christos 	atf_check -o file:exp "$(prog_db)" recno in
    359  1.1  pgoyette }
    360  1.1  pgoyette 
    361  1.1  pgoyette atf_test_case reverse_recno
    362  1.1  pgoyette reverse_recno_head()
    363  1.1  pgoyette {
    364  1.1  pgoyette 	atf_set "descr" "Checks recno database using reverse order entries"
    365  1.1  pgoyette }
    366  1.1  pgoyette reverse_recno_body()
    367  1.1  pgoyette {
    368  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    369  1.1  pgoyette 	mkdir ${TMPDIR}
    370  1.1  pgoyette 
    371  1.1  pgoyette 	echo $SEVEN_SEVEN |
    372  1.1  pgoyette 	awk ' {
    373  1.1  pgoyette 		for (i = 1500; i; --i) {
    374  1.1  pgoyette 			if (i % 34)
    375  1.1  pgoyette 				s = substr($0, 1, i % 34);
    376  1.1  pgoyette 			else
    377  1.1  pgoyette 				s = substr($0, 1);
    378  1.1  pgoyette 			printf("input key %d: %s\n", i, s);
    379  1.1  pgoyette 		}
    380  1.1  pgoyette 		exit;
    381  1.1  pgoyette 	}' >exp
    382  1.1  pgoyette 
    383  1.1  pgoyette 	cat exp |
    384  1.1  pgoyette 	awk 'BEGIN {
    385  1.1  pgoyette 			i = 1500;
    386  1.1  pgoyette 		}
    387  1.1  pgoyette 		{
    388  1.1  pgoyette 			printf("p\nk%d\nd%s\n", i, $0);
    389  1.1  pgoyette 			--i;
    390  1.1  pgoyette 		}
    391  1.1  pgoyette 		END {
    392  1.1  pgoyette 			for (i = 1500; i; --i) 
    393  1.1  pgoyette 				printf("g\nk%d\n", i);
    394  1.1  pgoyette 		}' >in
    395  1.1  pgoyette 
    396  1.6  christos 	atf_check -o file:exp "$(prog_db)" recno in
    397  1.1  pgoyette }
    398  1.1  pgoyette 		
    399  1.1  pgoyette atf_test_case alternate_recno
    400  1.1  pgoyette alternate_recno_head()
    401  1.1  pgoyette {
    402  1.1  pgoyette 	atf_set "descr" "Checks recno database using alternating order entries"
    403  1.1  pgoyette }
    404  1.1  pgoyette alternate_recno_body()
    405  1.1  pgoyette {
    406  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    407  1.1  pgoyette 	mkdir ${TMPDIR}
    408  1.1  pgoyette 
    409  1.1  pgoyette 	echo $SEVEN_SEVEN |
    410  1.1  pgoyette 	awk ' {
    411  1.1  pgoyette 		for (i = 1; i < 1200; i += 2) {
    412  1.1  pgoyette 			if (i % 34)
    413  1.1  pgoyette 				s = substr($0, 1, i % 34);
    414  1.1  pgoyette 			else
    415  1.1  pgoyette 				s = substr($0, 1);
    416  1.1  pgoyette 			printf("input key %d: %s\n", i, s);
    417  1.1  pgoyette 		}
    418  1.1  pgoyette 		for (i = 2; i < 1200; i += 2) {
    419  1.1  pgoyette 			if (i % 34)
    420  1.1  pgoyette 				s = substr($0, 1, i % 34);
    421  1.1  pgoyette 			else
    422  1.1  pgoyette 				s = substr($0, 1);
    423  1.1  pgoyette 			printf("input key %d: %s\n", i, s);
    424  1.1  pgoyette 		}
    425  1.1  pgoyette 		exit;
    426  1.1  pgoyette 	}' >exp
    427  1.1  pgoyette 
    428  1.1  pgoyette 	cat exp |
    429  1.1  pgoyette 	awk 'BEGIN {
    430  1.1  pgoyette 			i = 1;
    431  1.1  pgoyette 			even = 0;
    432  1.1  pgoyette 		}
    433  1.1  pgoyette 		{
    434  1.1  pgoyette 			printf("p\nk%d\nd%s\n", i, $0);
    435  1.1  pgoyette 			i += 2;
    436  1.1  pgoyette 			if (i >= 1200) {
    437  1.1  pgoyette 				if (even == 1)
    438  1.1  pgoyette 					exit;
    439  1.1  pgoyette 				even = 1;
    440  1.1  pgoyette 				i = 2;
    441  1.1  pgoyette 			}
    442  1.1  pgoyette 		}
    443  1.1  pgoyette 		END {
    444  1.1  pgoyette 			for (i = 1; i < 1200; ++i) 
    445  1.1  pgoyette 				printf("g\nk%d\n", i);
    446  1.1  pgoyette 		}' >in
    447  1.1  pgoyette 
    448  1.6  christos 	atf_check "$(prog_db)" -o out recno in
    449  1.1  pgoyette 	
    450  1.1  pgoyette 	sort -o exp exp
    451  1.1  pgoyette 	sort -o out out
    452  1.1  pgoyette 
    453  1.1  pgoyette 	cmp -s exp out || atf_fail "test failed"
    454  1.1  pgoyette }
    455  1.1  pgoyette 
    456  1.1  pgoyette h_delete()
    457  1.1  pgoyette {
    458  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    459  1.1  pgoyette 	mkdir ${TMPDIR}
    460  1.1  pgoyette 
    461  1.1  pgoyette 	type=$1
    462  1.1  pgoyette 
    463  1.1  pgoyette 	echo $SEVEN_SEVEN |
    464  1.1  pgoyette 	awk '{
    465  1.1  pgoyette 		for (i = 1; i <= 120; ++i)
    466  1.1  pgoyette 			printf("%05d: input key %d: %s\n", i, i, $0);
    467  1.1  pgoyette 	}' >exp
    468  1.1  pgoyette 
    469  1.1  pgoyette 	cat exp |
    470  1.1  pgoyette 	awk '{
    471  1.1  pgoyette 		printf("p\nk%d\nd%s\n", ++i, $0);
    472  1.1  pgoyette 	}
    473  1.1  pgoyette 	END {
    474  1.1  pgoyette 		printf("fR_NEXT\n");
    475  1.1  pgoyette 		for (i = 1; i <= 120; ++i)
    476  1.1  pgoyette 			printf("s\n");
    477  1.2  pgoyette 		printf("fR_CURSOR\ns\nkXX\n");
    478  1.1  pgoyette 		printf("r\n");
    479  1.1  pgoyette 		printf("fR_NEXT\ns\n");
    480  1.1  pgoyette 		printf("fR_CURSOR\ns\nk1\n");
    481  1.1  pgoyette 		printf("r\n");
    482  1.1  pgoyette 		printf("fR_FIRST\ns\n");
    483  1.1  pgoyette 	}' >in
    484  1.1  pgoyette 
    485  1.2  pgoyette 	# For btree, the records are ordered by the string representation
    486  1.2  pgoyette 	# of the key value.  So sort the expected output file accordingly,
    487  1.2  pgoyette 	# and set the seek_last key to the last expected key value.
    488  1.2  pgoyette 
    489  1.2  pgoyette 	if [ "$type" = "btree" ] ; then
    490  1.2  pgoyette 		sed -e 's/kXX/k99/' < in > tmp
    491  1.2  pgoyette 		mv tmp in
    492  1.2  pgoyette 		sort -d -k4 < exp > tmp
    493  1.2  pgoyette 		mv tmp exp
    494  1.2  pgoyette 		echo $SEVEN_SEVEN |
    495  1.2  pgoyette 		awk '{
    496  1.2  pgoyette 			printf("%05d: input key %d: %s\n", 99, 99, $0);
    497  1.2  pgoyette 			printf("seq failed, no such key\n");
    498  1.2  pgoyette 			printf("%05d: input key %d: %s\n", 1, 1, $0);
    499  1.2  pgoyette 			printf("%05d: input key %d: %s\n", 10, 10, $0);
    500  1.2  pgoyette 			exit;
    501  1.2  pgoyette 		}' >> exp
    502  1.2  pgoyette 	else
    503  1.2  pgoyette 	# For recno, records are ordered by numerical key value.  No sort
    504  1.2  pgoyette 	# is needed, but still need to set proper seek_last key value.
    505  1.2  pgoyette 		sed -e 's/kXX/k120/' < in > tmp
    506  1.2  pgoyette 		mv tmp in
    507  1.2  pgoyette 		echo $SEVEN_SEVEN |
    508  1.2  pgoyette 		awk '{
    509  1.2  pgoyette 			printf("%05d: input key %d: %s\n", 120, 120, $0);
    510  1.2  pgoyette 			printf("seq failed, no such key\n");
    511  1.2  pgoyette 			printf("%05d: input key %d: %s\n", 1, 1, $0);
    512  1.2  pgoyette 			printf("%05d: input key %d: %s\n", 2, 2, $0);
    513  1.2  pgoyette 			exit;
    514  1.2  pgoyette 		}' >> exp
    515  1.2  pgoyette 	fi
    516  1.2  pgoyette 
    517  1.6  christos 	atf_check "$(prog_db)" -o out $type in
    518  1.1  pgoyette 	atf_check -o file:exp cat out
    519  1.1  pgoyette }
    520  1.1  pgoyette 
    521  1.1  pgoyette atf_test_case delete_btree
    522  1.1  pgoyette delete_btree_head()
    523  1.1  pgoyette {
    524  1.1  pgoyette 	atf_set "descr" "Checks removing records in btree database"
    525  1.1  pgoyette }
    526  1.1  pgoyette delete_btree_body()
    527  1.1  pgoyette {
    528  1.1  pgoyette 	h_delete btree
    529  1.1  pgoyette }
    530  1.1  pgoyette 
    531  1.1  pgoyette atf_test_case delete_recno
    532  1.1  pgoyette delete_recno_head()
    533  1.1  pgoyette {
    534  1.1  pgoyette 	atf_set "descr" "Checks removing records in recno database"
    535  1.1  pgoyette }
    536  1.1  pgoyette delete_recno_body()
    537  1.1  pgoyette {
    538  1.1  pgoyette 	h_delete recno
    539  1.1  pgoyette }
    540  1.1  pgoyette 
    541  1.1  pgoyette h_repeated()
    542  1.1  pgoyette {
    543  1.7  christos 	local type="$1"
    544  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    545  1.1  pgoyette 	mkdir ${TMPDIR}
    546  1.1  pgoyette 
    547  1.1  pgoyette 	echo "" | 
    548  1.1  pgoyette 	awk 'BEGIN {
    549  1.1  pgoyette 		for (i = 1; i <= 10; ++i) {
    550  1.1  pgoyette 			printf("p\nkkey1\nD/bin/sh\n");
    551  1.1  pgoyette 			printf("p\nkkey2\nD/bin/csh\n");
    552  1.1  pgoyette 			if (i % 8 == 0) {
    553  1.1  pgoyette 				printf("c\nkkey2\nD/bin/csh\n");
    554  1.1  pgoyette 				printf("c\nkkey1\nD/bin/sh\n");
    555  1.1  pgoyette 				printf("e\t%d of 10 (comparison)\n", i);
    556  1.1  pgoyette 			} else
    557  1.1  pgoyette 				printf("e\t%d of 10             \n", i);
    558  1.1  pgoyette 			printf("r\nkkey1\nr\nkkey2\n");
    559  1.1  pgoyette 		}
    560  1.1  pgoyette 	}' >in
    561  1.1  pgoyette 
    562  1.7  christos 	$(prog_db) $type in
    563  1.1  pgoyette }
    564  1.1  pgoyette 
    565  1.1  pgoyette atf_test_case repeated_btree
    566  1.1  pgoyette repeated_btree_head()
    567  1.1  pgoyette {
    568  1.1  pgoyette 	atf_set "descr" \
    569  1.1  pgoyette 		"Checks btree database with repeated small keys and" \
    570  1.1  pgoyette 		"big data pairs. Makes sure that overflow pages are reused"
    571  1.1  pgoyette }
    572  1.1  pgoyette repeated_btree_body()
    573  1.1  pgoyette {
    574  1.1  pgoyette 	h_repeated btree
    575  1.1  pgoyette }
    576  1.1  pgoyette 
    577  1.1  pgoyette atf_test_case repeated_hash
    578  1.1  pgoyette repeated_hash_head()
    579  1.1  pgoyette {
    580  1.1  pgoyette 	atf_set "descr" \
    581  1.1  pgoyette 		"Checks hash database with repeated small keys and" \
    582  1.1  pgoyette 		"big data pairs. Makes sure that overflow pages are reused"
    583  1.1  pgoyette }
    584  1.1  pgoyette repeated_hash_body()
    585  1.1  pgoyette {
    586  1.1  pgoyette 	h_repeated hash
    587  1.1  pgoyette }
    588  1.1  pgoyette 
    589  1.1  pgoyette atf_test_case duplicate_btree
    590  1.1  pgoyette duplicate_btree_head()
    591  1.1  pgoyette {
    592  1.1  pgoyette 	atf_set "descr" "Checks btree database with duplicate keys"
    593  1.1  pgoyette }
    594  1.1  pgoyette duplicate_btree_body()
    595  1.1  pgoyette {
    596  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    597  1.1  pgoyette 	mkdir ${TMPDIR}
    598  1.1  pgoyette 
    599  1.1  pgoyette 	echo $SEVEN_SEVEN |
    600  1.1  pgoyette 	awk '{
    601  1.1  pgoyette 		for (i = 1; i <= 543; ++i)
    602  1.1  pgoyette 			printf("%05d: input key %d: %s\n", i, i, $0);
    603  1.1  pgoyette 		exit;
    604  1.1  pgoyette 	}' >exp
    605  1.1  pgoyette 
    606  1.1  pgoyette 	cat exp | 
    607  1.1  pgoyette 	awk '{
    608  1.1  pgoyette 		if (i++ % 2)
    609  1.1  pgoyette 			printf("p\nkduplicatekey\nd%s\n", $0);
    610  1.1  pgoyette 		else
    611  1.1  pgoyette 			printf("p\nkunique%dkey\nd%s\n", i, $0);
    612  1.1  pgoyette 	}
    613  1.1  pgoyette 	END {
    614  1.1  pgoyette 			printf("o\n");
    615  1.1  pgoyette 	}' >in
    616  1.1  pgoyette 
    617  1.6  christos 	atf_check -o file:exp -x "$(prog_db) -iflags=1 btree in | sort"
    618  1.1  pgoyette }
    619  1.1  pgoyette 
    620  1.1  pgoyette h_cursor_flags()
    621  1.1  pgoyette {
    622  1.7  christos 	local type=$1
    623  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    624  1.1  pgoyette 	mkdir ${TMPDIR}
    625  1.1  pgoyette 
    626  1.1  pgoyette 	echo $SEVEN_SEVEN |
    627  1.1  pgoyette 	awk '{
    628  1.1  pgoyette 		for (i = 1; i <= 20; ++i)
    629  1.1  pgoyette 			printf("%05d: input key %d: %s\n", i, i, $0);
    630  1.1  pgoyette 		exit;
    631  1.1  pgoyette 	}' >exp
    632  1.1  pgoyette 
    633  1.1  pgoyette 	# Test that R_CURSOR doesn't succeed before cursor initialized
    634  1.1  pgoyette 	cat exp |
    635  1.1  pgoyette 	awk '{
    636  1.1  pgoyette 		if (i == 10)
    637  1.1  pgoyette 			exit;
    638  1.1  pgoyette 		printf("p\nk%d\nd%s\n", ++i, $0);
    639  1.1  pgoyette 	}
    640  1.1  pgoyette 	END {
    641  1.1  pgoyette 		printf("fR_CURSOR\nr\n");
    642  1.1  pgoyette 		printf("eR_CURSOR SHOULD HAVE FAILED\n");
    643  1.1  pgoyette 	}' >in
    644  1.1  pgoyette 
    645  1.6  christos 	atf_check -o ignore -e ignore -s ne:0 "$(prog_db)" -o out $type in
    646  1.1  pgoyette 	atf_check -s ne:0 test -s out
    647  1.1  pgoyette 
    648  1.1  pgoyette 	cat exp |
    649  1.1  pgoyette 	awk '{
    650  1.1  pgoyette 		if (i == 10)
    651  1.1  pgoyette 			exit;
    652  1.1  pgoyette 		printf("p\nk%d\nd%s\n", ++i, $0);
    653  1.1  pgoyette 	}
    654  1.1  pgoyette 	END {
    655  1.1  pgoyette 		printf("fR_CURSOR\np\nk1\ndsome data\n");
    656  1.1  pgoyette 		printf("eR_CURSOR SHOULD HAVE FAILED\n");
    657  1.1  pgoyette 	}' >in
    658  1.1  pgoyette 
    659  1.6  christos 	atf_check -o ignore -e ignore -s ne:0 "$(prog_db)" -o out $type in
    660  1.1  pgoyette 	atf_check -s ne:0 test -s out
    661  1.1  pgoyette }
    662  1.1  pgoyette 
    663  1.1  pgoyette atf_test_case cursor_flags_btree
    664  1.1  pgoyette cursor_flags_btree_head()
    665  1.1  pgoyette {
    666  1.1  pgoyette 	atf_set "descr" \
    667  1.1  pgoyette 		"Checks use of cursor flags without initialization in btree database"
    668  1.1  pgoyette }
    669  1.1  pgoyette cursor_flags_btree_body()
    670  1.1  pgoyette {
    671  1.1  pgoyette 	h_cursor_flags btree
    672  1.1  pgoyette }
    673  1.1  pgoyette 
    674  1.1  pgoyette atf_test_case cursor_flags_recno
    675  1.1  pgoyette cursor_flags_recno_head()
    676  1.1  pgoyette {
    677  1.1  pgoyette 	atf_set "descr" \
    678  1.1  pgoyette 		"Checks use of cursor flags without initialization in recno database"
    679  1.1  pgoyette }
    680  1.1  pgoyette cursor_flags_recno_body()
    681  1.1  pgoyette {
    682  1.1  pgoyette 	h_cursor_flags recno
    683  1.1  pgoyette }
    684  1.1  pgoyette 
    685  1.1  pgoyette atf_test_case reverse_order_recno
    686  1.1  pgoyette reverse_order_recno_head()
    687  1.1  pgoyette {
    688  1.1  pgoyette 	atf_set "descr" "Checks reverse order inserts in recno database"
    689  1.1  pgoyette }
    690  1.1  pgoyette reverse_order_recno_body()
    691  1.1  pgoyette {
    692  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    693  1.1  pgoyette 	mkdir ${TMPDIR}
    694  1.1  pgoyette 
    695  1.1  pgoyette 	echo $SEVEN_SEVEN |
    696  1.1  pgoyette 	awk '{
    697  1.1  pgoyette 		for (i = 1; i <= 779; ++i)
    698  1.1  pgoyette 			printf("%05d: input key %d: %s\n", i, i, $0);
    699  1.1  pgoyette 		exit;
    700  1.1  pgoyette 	}' >exp
    701  1.1  pgoyette 
    702  1.1  pgoyette 	cat exp |
    703  1.1  pgoyette 	awk '{
    704  1.1  pgoyette 		if (i == 0) {
    705  1.1  pgoyette 			i = 1;
    706  1.1  pgoyette 			printf("p\nk1\nd%s\n", $0);
    707  1.1  pgoyette 			printf("%s\n", "fR_IBEFORE");
    708  1.1  pgoyette 		} else
    709  1.1  pgoyette 			printf("p\nk1\nd%s\n", $0);
    710  1.1  pgoyette 	}
    711  1.1  pgoyette 	END {
    712  1.1  pgoyette 			printf("or\n");
    713  1.1  pgoyette 	}' >in
    714  1.1  pgoyette 
    715  1.6  christos 	atf_check -o file:exp "$(prog_db)" recno in
    716  1.1  pgoyette }
    717  1.1  pgoyette 
    718  1.1  pgoyette atf_test_case small_page_btree
    719  1.1  pgoyette small_page_btree_head()
    720  1.1  pgoyette {
    721  1.1  pgoyette 	atf_set "descr" \
    722  1.1  pgoyette 		"Checks btree database with lots of keys and small page" \
    723  1.1  pgoyette 		"size: takes the first 20000 entries in the dictionary," \
    724  1.1  pgoyette 		"reverses them, and gives them each a small size data" \
    725  1.1  pgoyette 		"entry. Uses a small page size to make sure the btree" \
    726  1.1  pgoyette 		"split code gets hammered."
    727  1.1  pgoyette }
    728  1.1  pgoyette small_page_btree_body()
    729  1.1  pgoyette {
    730  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    731  1.1  pgoyette 	mkdir ${TMPDIR}
    732  1.1  pgoyette 
    733  1.1  pgoyette 	mdata=abcdefghijklmnopqrstuvwxy
    734  1.1  pgoyette 	echo $mdata |
    735  1.1  pgoyette 	awk '{ for (i = 1; i < 20001; ++i) print $0 }' >exp
    736  1.1  pgoyette 
    737  1.1  pgoyette 	for i in `sed 20000q $(dict) | rev`; do
    738  1.1  pgoyette 		echo p
    739  1.1  pgoyette 		echo k$i
    740  1.1  pgoyette 		echo d$mdata
    741  1.1  pgoyette 		echo g
    742  1.1  pgoyette 		echo k$i
    743  1.1  pgoyette 	done >in
    744  1.1  pgoyette 
    745  1.6  christos 	atf_check -o file:exp "$(prog_db)" -i psize=512 btree in
    746  1.1  pgoyette }
    747  1.1  pgoyette 
    748  1.1  pgoyette h_byte_orders()
    749  1.1  pgoyette {
    750  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    751  1.1  pgoyette 	mkdir ${TMPDIR}
    752  1.1  pgoyette 
    753  1.1  pgoyette 	type=$1
    754  1.1  pgoyette 
    755  1.1  pgoyette 	sed 50q $(dict) >exp
    756  1.1  pgoyette 	for order in 1234 4321; do
    757  1.1  pgoyette 		for i in `sed 50q $(dict)`; do
    758  1.1  pgoyette 			echo p
    759  1.1  pgoyette 			echo k$i
    760  1.1  pgoyette 			echo d$i
    761  1.7  christos 			echo S
    762  1.1  pgoyette 			echo g
    763  1.1  pgoyette 			echo k$i
    764  1.1  pgoyette 		done >in
    765  1.1  pgoyette 
    766  1.6  christos 		atf_check -o file:exp "$(prog_db)" -ilorder=$order -f byte.file $type in
    767  1.1  pgoyette 
    768  1.1  pgoyette 		for i in `sed 50q $(dict)`; do
    769  1.1  pgoyette 			echo g
    770  1.1  pgoyette 			echo k$i
    771  1.1  pgoyette 		done >in
    772  1.1  pgoyette 
    773  1.6  christos 		atf_check -o file:exp "$(prog_db)" -s -ilorder=$order -f byte.file $type in
    774  1.1  pgoyette 	done
    775  1.1  pgoyette }
    776  1.1  pgoyette 
    777  1.1  pgoyette atf_test_case byte_orders_btree
    778  1.1  pgoyette byte_orders_btree_head()
    779  1.1  pgoyette {
    780  1.1  pgoyette 	atf_set "descr" "Checks btree database using differing byte orders"
    781  1.1  pgoyette }
    782  1.1  pgoyette byte_orders_btree_body()
    783  1.1  pgoyette {
    784  1.1  pgoyette 	h_byte_orders btree
    785  1.1  pgoyette }
    786  1.1  pgoyette 
    787  1.1  pgoyette atf_test_case byte_orders_hash
    788  1.1  pgoyette byte_orders_hash_head()
    789  1.1  pgoyette {
    790  1.1  pgoyette 	atf_set "descr" "Checks hash database using differing byte orders"
    791  1.1  pgoyette }
    792  1.1  pgoyette byte_orders_hash_body()
    793  1.1  pgoyette {
    794  1.1  pgoyette 	h_byte_orders hash
    795  1.1  pgoyette }
    796  1.1  pgoyette 
    797  1.1  pgoyette h_bsize_ffactor()
    798  1.1  pgoyette {
    799  1.1  pgoyette 	bsize=$1
    800  1.1  pgoyette 	ffactor=$2
    801  1.1  pgoyette 
    802  1.1  pgoyette 	echo "bucketsize $bsize, fill factor $ffactor"
    803  1.6  christos 	atf_check -o file:exp "$(prog_db)" "-ibsize=$bsize,\
    804  1.1  pgoyette ffactor=$ffactor,nelem=25000,cachesize=65536" hash in
    805  1.1  pgoyette }
    806  1.1  pgoyette 
    807  1.1  pgoyette atf_test_case bsize_ffactor
    808  1.1  pgoyette bsize_ffactor_head()
    809  1.1  pgoyette {
    810  1.5    martin 	atf_set "timeout" "1800"
    811  1.1  pgoyette 	atf_set "descr" "Checks hash database with various" \
    812  1.1  pgoyette 					"bucketsizes and fill factors"
    813  1.1  pgoyette }
    814  1.1  pgoyette bsize_ffactor_body()
    815  1.1  pgoyette {
    816  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    817  1.1  pgoyette 	mkdir ${TMPDIR}
    818  1.1  pgoyette 
    819  1.1  pgoyette 	echo $SEVEN_SEVEN |
    820  1.1  pgoyette 	awk '{
    821  1.1  pgoyette 		for (i = 1; i <= 10000; ++i) {
    822  1.1  pgoyette 			if (i % 34)
    823  1.1  pgoyette 				s = substr($0, 1, i % 34);
    824  1.1  pgoyette 			else
    825  1.1  pgoyette 				s = substr($0, 1);
    826  1.1  pgoyette 			printf("%s\n", s);
    827  1.1  pgoyette 		}
    828  1.1  pgoyette 		exit;
    829  1.1  pgoyette 
    830  1.1  pgoyette 	}' >exp
    831  1.1  pgoyette 
    832  1.1  pgoyette 	sed 10000q $(dict) |
    833  1.1  pgoyette 	awk 'BEGIN {
    834  1.1  pgoyette 		ds="'$SEVEN_SEVEN'"
    835  1.1  pgoyette 	}
    836  1.1  pgoyette 	{
    837  1.1  pgoyette 		if (++i % 34)
    838  1.1  pgoyette 			s = substr(ds, 1, i % 34);
    839  1.1  pgoyette 		else
    840  1.1  pgoyette 			s = substr(ds, 1);
    841  1.1  pgoyette 		printf("p\nk%s\nd%s\n", $0, s);
    842  1.1  pgoyette 	}' >in
    843  1.1  pgoyette 
    844  1.1  pgoyette 	sed 10000q $(dict) |
    845  1.1  pgoyette 	awk '{
    846  1.1  pgoyette 		++i;
    847  1.1  pgoyette 		printf("g\nk%s\n", $0);
    848  1.1  pgoyette 	}' >>in
    849  1.1  pgoyette 
    850  1.1  pgoyette 	h_bsize_ffactor 256 11
    851  1.1  pgoyette 	h_bsize_ffactor 256 14
    852  1.1  pgoyette 	h_bsize_ffactor 256 21
    853  1.1  pgoyette 
    854  1.1  pgoyette 	h_bsize_ffactor 512 21
    855  1.1  pgoyette 	h_bsize_ffactor 512 28
    856  1.1  pgoyette 	h_bsize_ffactor 512 43
    857  1.1  pgoyette 
    858  1.1  pgoyette 	h_bsize_ffactor 1024 43
    859  1.1  pgoyette 	h_bsize_ffactor 1024 57
    860  1.1  pgoyette 	h_bsize_ffactor 1024 85
    861  1.1  pgoyette 
    862  1.1  pgoyette 	h_bsize_ffactor 2048 85
    863  1.1  pgoyette 	h_bsize_ffactor 2048 114
    864  1.1  pgoyette 	h_bsize_ffactor 2048 171
    865  1.1  pgoyette 
    866  1.1  pgoyette 	h_bsize_ffactor 4096 171
    867  1.1  pgoyette 	h_bsize_ffactor 4096 228
    868  1.1  pgoyette 	h_bsize_ffactor 4096 341
    869  1.1  pgoyette 
    870  1.1  pgoyette 	h_bsize_ffactor 8192 341
    871  1.1  pgoyette 	h_bsize_ffactor 8192 455
    872  1.1  pgoyette 	h_bsize_ffactor 8192 683
    873  1.6  christos 
    874  1.6  christos 	h_bsize_ffactor 16384 341
    875  1.6  christos 	h_bsize_ffactor 16384 455
    876  1.6  christos 	h_bsize_ffactor 16384 683
    877  1.6  christos 
    878  1.6  christos 	h_bsize_ffactor 32768 341
    879  1.6  christos 	h_bsize_ffactor 32768 455
    880  1.6  christos 	h_bsize_ffactor 32768 683
    881  1.6  christos 
    882  1.6  christos 	h_bsize_ffactor 65536 341
    883  1.6  christos 	h_bsize_ffactor 65536 455
    884  1.6  christos 	h_bsize_ffactor 65536 683
    885  1.1  pgoyette }
    886  1.1  pgoyette 
    887  1.6  christos # This tests 64K block size addition/removal
    888  1.1  pgoyette atf_test_case four_char_hash
    889  1.1  pgoyette four_char_hash_head()
    890  1.1  pgoyette {
    891  1.1  pgoyette 	atf_set "descr" \
    892  1.1  pgoyette 		"Checks hash database with 4 char key and" \
    893  1.1  pgoyette 		"value insert on a 65536 bucket size"
    894  1.1  pgoyette }
    895  1.1  pgoyette four_char_hash_body()
    896  1.1  pgoyette {
    897  1.1  pgoyette 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    898  1.1  pgoyette 	mkdir ${TMPDIR}
    899  1.1  pgoyette 
    900  1.1  pgoyette 	cat >in <<EOF
    901  1.1  pgoyette p
    902  1.1  pgoyette k1234
    903  1.1  pgoyette d1234
    904  1.1  pgoyette r
    905  1.1  pgoyette k1234
    906  1.1  pgoyette EOF
    907  1.1  pgoyette 
    908  1.6  christos 	atf_check "$(prog_db)" -i bsize=65536 hash in
    909  1.6  christos }
    910  1.6  christos 
    911  1.6  christos 
    912  1.6  christos atf_test_case bsize_torture
    913  1.6  christos bsize_torture_head()
    914  1.6  christos {
    915  1.6  christos 	atf_set "timeout" "36000"
    916  1.6  christos 	atf_set "descr" "Checks hash database with various bucket sizes"
    917  1.6  christos }
    918  1.6  christos bsize_torture_body()
    919  1.6  christos {
    920  1.6  christos 	TMPDIR="$(pwd)/db_dir"; export TMPDIR
    921  1.6  christos 	mkdir ${TMPDIR}
    922  1.9    martin 	AVAIL=$( df -m ${TMPDIR} | awk '{if (int($4) > 0) print $4}' )
    923  1.9    martin 	LIST="2048 4096 8192 16384"
    924  1.9    martin 	if [ $AVAIL -gt 30 ]; then
    925  1.9    martin 		LIST="$LIST 32768"
    926  1.9    martin 	fi
    927  1.9    martin 	if [ $AVAIL -gt 60 ]; then
    928  1.9    martin 		LIST="$LIST 65536"
    929  1.9    martin 	fi
    930  1.9    martin 	for i in $LIST
    931  1.6  christos 	do
    932  1.6  christos 		atf_check "$(prog_lfsr)" $i
    933  1.6  christos 	done
    934  1.1  pgoyette }
    935  1.1  pgoyette 
    936  1.7  christos atf_test_case btree_weird_page_split
    937  1.7  christos btree_weird_page_split_head()
    938  1.7  christos {
    939  1.7  christos 	atf_set "descr"  \
    940  1.7  christos 	    "Test for a weird page split condition where an insertion " \
    941  1.7  christos 	    "into index 0 of a page that would cause the new item to " \
    942  1.7  christos 	    "be the only item on the left page results in index 0 of " \
    943  1.7  christos 	    "the right page being erroneously skipped; this only " \
    944  1.7  christos 	    "happens with one particular key+data length for each page size."
    945  1.8    martin 	atf_set "timeout" "900"
    946  1.7  christos }
    947  1.7  christos btree_weird_page_split_body()
    948  1.7  christos {
    949  1.7  christos 	for psize in 512 1024 2048 4096 8192; do
    950  1.7  christos 		echo "    page size $psize"
    951  1.7  christos 		kdsizes=`awk 'BEGIN {
    952  1.7  christos 			psize = '$psize'; hsize = int(psize/2);
    953  1.7  christos 			for (kdsize = hsize-40; kdsize <= hsize; kdsize++) {
    954  1.7  christos 				print kdsize;
    955  1.7  christos 			}
    956  1.7  christos 		}' /dev/null`
    957  1.7  christos 
    958  1.7  christos 		# Use a series of keylen+datalen values in the right
    959  1.7  christos 		# neighborhood to find the one that triggers the bug.
    960  1.7  christos 		# We could compute the exact size that triggers the
    961  1.7  christos 		# bug but this additional fuzz may be useful.
    962  1.7  christos 
    963  1.7  christos 		# Insert keys in reverse order to maximize the chances
    964  1.7  christos 		# for a split on index 0.
    965  1.7  christos 
    966  1.7  christos 		for kdsize in $kdsizes; do
    967  1.7  christos 			awk 'BEGIN {
    968  1.7  christos 				kdsize = '$kdsize';
    969  1.7  christos 				for (i = 8; i-- > 0; ) {
    970  1.7  christos 					s = sprintf("a%03d:%09d", i, kdsize);
    971  1.7  christos 					for (j = 0; j < kdsize-20; j++) {
    972  1.7  christos 						s = s "x";
    973  1.7  christos 					}
    974  1.7  christos 					printf("p\nka%03d\nd%s\n", i, s);
    975  1.7  christos 				}
    976  1.7  christos 				print "o";
    977  1.7  christos 			}' /dev/null > in
    978  1.7  christos 			sed -n 's/^d//p' in | sort > exp
    979  1.7  christos 			atf_check -o file:exp \
    980  1.7  christos 			    "$(prog_db)" -i psize=$psize btree in
    981  1.7  christos 		done
    982  1.7  christos 	done
    983  1.7  christos }
    984  1.7  christos 
    985  1.7  christos # Extremely tricky test attempting to replicate some unusual database
    986  1.7  christos # corruption seen in the field: pieces of the database becoming
    987  1.7  christos # inaccessible to random access, sequential access, or both.  The
    988  1.7  christos # hypothesis is that at least some of these are triggered by the bug
    989  1.7  christos # in page splits on index 0 with a particular exact keylen+datalen.
    990  1.7  christos # (See Test 40.)  For psize=4096, this size is exactly 2024.
    991  1.7  christos 
    992  1.7  christos # The order of operations here relies on very specific knowledge of
    993  1.7  christos # the internals of the btree access method in order to place records
    994  1.7  christos # at specific offsets in a page and to create certain keys on internal
    995  1.7  christos # pages.  The to-be-split page immediately prior to the bug-triggering
    996  1.7  christos # split has the following properties:
    997  1.7  christos #
    998  1.7  christos # * is not the leftmost leaf page
    999  1.7  christos # * key on the parent page is compares less than the key of the item
   1000  1.7  christos #   on index 0
   1001  1.7  christos # * triggering record's key also compares greater than the key on the
   1002  1.7  christos #   parent page
   1003  1.7  christos 
   1004  1.7  christos # Additionally, we prime the mpool LRU chain so that the head page on
   1005  1.7  christos # the chain has the following properties:
   1006  1.7  christos #
   1007  1.7  christos # * record at index 0 is located where it will not get overwritten by
   1008  1.7  christos #   items written to the right-hand page during the split
   1009  1.7  christos # * key of the record at index 0 compares less than the key of the
   1010  1.7  christos #   bug-triggering record
   1011  1.7  christos 
   1012  1.7  christos # If the page-split bug exists, this test appears to create a database
   1013  1.7  christos # where some records are inaccessible to a search, but still remain in
   1014  1.7  christos # the file and are accessible by sequential traversal.  At least one
   1015  1.7  christos # record gets duplicated out of sequence.
   1016  1.7  christos 
   1017  1.7  christos atf_test_case btree_tricky_page_split
   1018  1.7  christos btree_tricky_page_split_head()
   1019  1.7  christos {
   1020  1.7  christos 	atf_set "descr"  \
   1021  1.7  christos 	    "btree: no unsearchables due to page split on index 0"
   1022  1.7  christos }
   1023  1.7  christos btree_tricky_page_split_body()
   1024  1.7  christos {
   1025  1.7  christos 	list=`(for i in a b c d; do
   1026  1.7  christos 			for j in 990 998 999; do
   1027  1.7  christos 				echo g ${i}${j} 1024
   1028  1.7  christos 			done
   1029  1.7  christos 		done;
   1030  1.7  christos 		echo g y997 2014
   1031  1.7  christos 		for i in y z; do
   1032  1.7  christos 			for j in 998 999; do
   1033  1.7  christos 				echo g ${i}${j} 1024
   1034  1.7  christos 			done
   1035  1.7  christos 		done)`
   1036  1.7  christos 	# Exact number for trigger condition accounts for newlines
   1037  1.7  christos 	# retained by dbtest with -ofile but not without; we use
   1038  1.7  christos 	# -ofile, so count newlines.  keylen=5,datalen=5+2014 for
   1039  1.7  christos 	# psize=4096 here.
   1040  1.7  christos 	(cat - <<EOF
   1041  1.7  christos p z999 1024
   1042  1.7  christos p z998 1024
   1043  1.7  christos p y999 1024
   1044  1.7  christos p y990 1024
   1045  1.7  christos p d999 1024
   1046  1.7  christos p d990 1024
   1047  1.7  christos p c999 1024
   1048  1.7  christos p c990 1024
   1049  1.7  christos p b999 1024
   1050  1.7  christos p b990 1024
   1051  1.7  christos p a999 1024
   1052  1.7  christos p a990 1024
   1053  1.7  christos p y998 1024
   1054  1.7  christos r y990
   1055  1.7  christos p d998 1024
   1056  1.7  christos p d990 1024
   1057  1.7  christos p c998 1024
   1058  1.7  christos p c990 1024
   1059  1.7  christos p b998 1024
   1060  1.7  christos p b990 1024
   1061  1.7  christos p a998 1024
   1062  1.7  christos p a990 1024
   1063  1.7  christos p y997 2014
   1064  1.7  christos S
   1065  1.7  christos o
   1066  1.7  christos EOF
   1067  1.7  christos 	echo "$list") |
   1068  1.7  christos 	# awk script input:
   1069  1.7  christos 	# {p|g|r} key [datasize]
   1070  1.7  christos 	awk '/^[pgr]/{
   1071  1.7  christos 		printf("%s\nk%s\n", $1, $2);
   1072  1.7  christos 	}
   1073  1.7  christos 	/^p/{
   1074  1.7  christos 		s = $2;
   1075  1.7  christos 		for (i = 0; i < $3; i++) {
   1076  1.7  christos 			s = s "x";
   1077  1.7  christos 		}
   1078  1.7  christos 		printf("d%s\n", s);
   1079  1.7  christos 	}
   1080  1.7  christos 	!/^[pgr]/{
   1081  1.7  christos 		print $0;
   1082  1.7  christos 	}' > in
   1083  1.7  christos 	(echo "$list"; echo "$list") | awk '{
   1084  1.7  christos 		s = $2;
   1085  1.7  christos 		for (i = 0; i < $3; i++) {
   1086  1.7  christos 			s = s "x";
   1087  1.7  christos 		}
   1088  1.7  christos 		print s;
   1089  1.7  christos 	}' > exp 
   1090  1.7  christos 	atf_check -o file:exp \
   1091  1.7  christos 	    "$(prog_db)" -i psize=4096 btree in
   1092  1.7  christos }
   1093  1.7  christos 
   1094  1.7  christos atf_test_case btree_recursive_traversal
   1095  1.7  christos btree_recursive_traversal_head()
   1096  1.7  christos {
   1097  1.7  christos 	atf_set "descr"  \
   1098  1.7  christos 	    "btree: Test for recursive traversal successfully " \
   1099  1.7  christos 	    "retrieving records that are inaccessible to normal " \
   1100  1.7  christos 	    "sequential 'sibling-link' traversal. This works by " \
   1101  1.7  christos 	    "unlinking a few leaf pages but leaving their parent " \
   1102  1.7  christos 	    "links intact. To verify that the unlink actually makes " \
   1103  1.7  christos 	    "records inaccessible, the test first uses 'o' to do a " \
   1104  1.7  christos 	    "normal sequential traversal, followed by 'O' to do a " \
   1105  1.7  christos 	    "recursive traversal."
   1106  1.7  christos }
   1107  1.7  christos btree_recursive_traversal_body()
   1108  1.7  christos {
   1109  1.7  christos 	fill="abcdefghijklmnopqrstuvwxyzy"
   1110  1.7  christos 	script='{
   1111  1.7  christos 		for (i = 0; i < 20000; i++) {
   1112  1.7  christos 			printf("p\nkAA%05d\nd%05d%s\n", i, i, $0);
   1113  1.7  christos 		}
   1114  1.7  christos 		print "u";
   1115  1.7  christos 		print "u";
   1116  1.7  christos 		print "u";
   1117  1.7  christos 		print "u";
   1118  1.7  christos 	}'
   1119  1.7  christos 	(echo $fill | awk "$script"; echo o) > in1
   1120  1.7  christos 	echo $fill |
   1121  1.7  christos 	awk '{
   1122  1.7  christos 		for (i = 0; i < 20000; i++) {
   1123  1.7  christos 			if (i >= 5 && i <= 40)
   1124  1.7  christos 				continue;
   1125  1.7  christos 			printf("%05d%s\n", i, $0);
   1126  1.7  christos 		}
   1127  1.7  christos 	}' > exp1
   1128  1.7  christos 	atf_check -o file:exp1 \
   1129  1.7  christos 	    "$(prog_db)" -i psize=512 btree in1
   1130  1.7  christos 	echo $fill |
   1131  1.7  christos 	awk '{
   1132  1.7  christos 		for (i = 0; i < 20000; i++) {
   1133  1.7  christos 			printf("%05d%s\n", i, $0);
   1134  1.7  christos 		}
   1135  1.7  christos 	}' > exp2
   1136  1.7  christos 	(echo $fill | awk "$script"; echo O) > in2
   1137  1.7  christos 	atf_check -o file:exp2 \
   1138  1.7  christos 	    "$(prog_db)" -i psize=512 btree in2
   1139  1.7  christos }
   1140  1.7  christos 
   1141  1.7  christos atf_test_case btree_byteswap_unaligned_access_bksd
   1142  1.7  christos btree_byteswap_unaligned_access_bksd_head()
   1143  1.7  christos {
   1144  1.7  christos 	atf_set "descr"  \
   1145  1.7  christos 	    "btree: big key, small data, byteswap unaligned access"
   1146  1.7  christos }
   1147  1.7  christos btree_byteswap_unaligned_access_bksd_body()
   1148  1.7  christos {
   1149  1.7  christos 	(echo foo; echo bar) |
   1150  1.7  christos 	awk '{
   1151  1.7  christos 		s = $0
   1152  1.7  christos 		for (i = 0; i < 488; i++) {
   1153  1.7  christos 			s = s "x";
   1154  1.7  christos 		}
   1155  1.7  christos 		printf("p\nk%s\ndx\n", s);
   1156  1.7  christos 	}' > in
   1157  1.7  christos 	for order in 1234 4321; do
   1158  1.7  christos 		atf_check \
   1159  1.7  christos 		    "$(prog_db)" -o out -i psize=512,lorder=$order btree in
   1160  1.7  christos 	done
   1161  1.7  christos }
   1162  1.7  christos 
   1163  1.7  christos atf_test_case btree_byteswap_unaligned_access_skbd
   1164  1.7  christos btree_byteswap_unaligned_access_skbd_head()
   1165  1.7  christos {
   1166  1.7  christos 	atf_set "descr"  \
   1167  1.7  christos 	    "btree: small key, big data, byteswap unaligned access"
   1168  1.7  christos }
   1169  1.7  christos btree_byteswap_unaligned_access_skbd_body()
   1170  1.7  christos {
   1171  1.7  christos 	# 484 = 512 - 20 (header) - 7 ("foo1234") - 1 (newline)
   1172  1.7  christos 	(echo foo1234; echo bar1234) |
   1173  1.7  christos 	awk '{
   1174  1.7  christos 		s = $0
   1175  1.7  christos 		for (i = 0; i < 484; i++) {
   1176  1.7  christos 			s = s "x";
   1177  1.7  christos 		}
   1178  1.7  christos 		printf("p\nk%s\nd%s\n", $0, s);
   1179  1.7  christos 	}' > in
   1180  1.7  christos 	for order in 1234 4321; do
   1181  1.7  christos 		atf_check \
   1182  1.7  christos 		    "$(prog_db)" -o out -i psize=512,lorder=$order btree in
   1183  1.7  christos 	done
   1184  1.7  christos }
   1185  1.7  christos 
   1186  1.7  christos atf_test_case btree_known_byte_order
   1187  1.7  christos btree_known_byte_order_head()
   1188  1.7  christos {
   1189  1.7  christos 	atf_set "descr"  \
   1190  1.7  christos 	    "btree: small key, big data, known byte order"
   1191  1.7  christos }
   1192  1.7  christos btree_known_byte_order_body()
   1193  1.7  christos {
   1194  1.7  christos 	local a="-i psize=512,lorder="
   1195  1.7  christos 
   1196  1.7  christos 	(echo foo1234; echo bar1234) |
   1197  1.7  christos 	awk '{
   1198  1.7  christos 		s = $0
   1199  1.7  christos 		for (i = 0; i < 484; i++) {
   1200  1.7  christos 			s = s "x";
   1201  1.7  christos 		}
   1202  1.7  christos 		printf("%s\n", s);
   1203  1.7  christos 	}' > exp
   1204  1.7  christos 	(echo foo1234; echo bar1234) |
   1205  1.7  christos 	awk '{
   1206  1.7  christos 		s = $0
   1207  1.7  christos 		for (i = 0; i < 484; i++) {
   1208  1.7  christos 			s = s "x";
   1209  1.7  christos 		}
   1210  1.7  christos 		printf("p\nk%s\nd%s\n", $0, s);
   1211  1.7  christos 	}' > in1
   1212  1.7  christos 	for order in 1234 4321; do
   1213  1.7  christos 		atf_check \
   1214  1.7  christos 		    "$(prog_db)" -f out.$order $a$order btree in1
   1215  1.7  christos 	done
   1216  1.7  christos 	(echo g; echo kfoo1234; echo g; echo kbar1234) > in2
   1217  1.7  christos 	for order in 1234 4321; do
   1218  1.7  christos 		atf_check -o file:exp \
   1219  1.7  christos 		    "$(prog_db)" -s -f out.$order $a$order btree in2
   1220  1.7  christos 	done
   1221  1.7  christos }
   1222  1.7  christos 
   1223  1.1  pgoyette atf_init_test_cases()
   1224  1.1  pgoyette {
   1225  1.1  pgoyette 	atf_add_test_case small_btree
   1226  1.1  pgoyette 	atf_add_test_case small_hash
   1227  1.1  pgoyette 	atf_add_test_case small_recno
   1228  1.1  pgoyette 	atf_add_test_case medium_btree
   1229  1.1  pgoyette 	atf_add_test_case medium_hash
   1230  1.1  pgoyette 	atf_add_test_case medium_recno
   1231  1.1  pgoyette 	atf_add_test_case big_btree
   1232  1.1  pgoyette 	atf_add_test_case big_hash
   1233  1.1  pgoyette 	atf_add_test_case big_recno
   1234  1.1  pgoyette 	atf_add_test_case random_recno
   1235  1.1  pgoyette 	atf_add_test_case reverse_recno
   1236  1.1  pgoyette 	atf_add_test_case alternate_recno
   1237  1.1  pgoyette 	atf_add_test_case delete_btree
   1238  1.1  pgoyette 	atf_add_test_case delete_recno
   1239  1.1  pgoyette 	atf_add_test_case repeated_btree
   1240  1.1  pgoyette 	atf_add_test_case repeated_hash
   1241  1.1  pgoyette 	atf_add_test_case duplicate_btree
   1242  1.1  pgoyette 	atf_add_test_case cursor_flags_btree
   1243  1.1  pgoyette 	atf_add_test_case cursor_flags_recno
   1244  1.1  pgoyette 	atf_add_test_case reverse_order_recno
   1245  1.1  pgoyette 	atf_add_test_case small_page_btree
   1246  1.1  pgoyette 	atf_add_test_case byte_orders_btree
   1247  1.1  pgoyette 	atf_add_test_case byte_orders_hash
   1248  1.1  pgoyette 	atf_add_test_case bsize_ffactor
   1249  1.1  pgoyette 	atf_add_test_case four_char_hash
   1250  1.6  christos 	atf_add_test_case bsize_torture
   1251  1.7  christos 	atf_add_test_case btree_weird_page_split
   1252  1.7  christos 	atf_add_test_case btree_tricky_page_split
   1253  1.7  christos 	atf_add_test_case btree_recursive_traversal
   1254  1.7  christos 	atf_add_test_case btree_byteswap_unaligned_access_bksd
   1255  1.7  christos 	atf_add_test_case btree_byteswap_unaligned_access_skbd
   1256  1.7  christos 	atf_add_test_case btree_known_byte_order
   1257  1.1  pgoyette }
   1258