t_db.sh revision 1.9 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