DEFINITIONS
This source file includes following functions.
1 require 'runit/testcase'
2 require 'runit/cui/testrunner'
3
4 if $".grep(/\bgdbm.so\b/).empty?
5 begin
6 require './gdbm'
7 rescue LoadError
8 require 'gdbm'
9 end
10 end
11
12 def uname_s
13 require 'rbconfig'
14 case Config::CONFIG['host_os']
15 when 'cygwin'
16 require 'Win32API'
17 uname = Win32API.new 'cygwin1', 'uname', 'P', 'I'
18 utsname = ' ' * 100
19 raise 'cannot get system name' if uname.call(utsname) == -1
20
21 utsname.unpack('A20' * 5)[0]
22 else
23 Config::CONFIG['host_os']
24 end
25 end
26
27 SYSTEM = uname_s
28
29 class TestGDBM < RUNIT::TestCase
30 def setup
31 @path = "tmptest_gdbm_"
32 assert_instance_of(GDBM, @gdbm = GDBM.new(@path))
33
34 # prepare to make readonly GDBM file
35 GDBM.open("tmptest_gdbm_rdonly", 0400) {|gdbm|
36 gdbm['foo'] = 'FOO'
37 }
38 assert_instance_of(GDBM, @gdbm_rdonly = GDBM.new("tmptest_gdbm_rdonly", nil))
39 end
40 def teardown
41 assert_nil(@gdbm.close)
42 assert_nil(@gdbm_rdonly.close)
43 GC.start
44 File.delete *Dir.glob("tmptest_gdbm*").to_a
45 p Dir.glob("tmptest_gdbm*") if $DEBUG
46 end
47
48 def check_size(expect, gdbm=@gdbm)
49 assert_equals(expect, gdbm.size)
50 n = 0
51 gdbm.each { n+=1 }
52 assert_equals(expect, n)
53 if expect == 0
54 assert_equals(true, gdbm.empty?)
55 else
56 assert_equals(false, gdbm.empty?)
57 end
58 end
59
60 def test_version
61 STDERR.print GDBM::VERSION
62 end
63
64 def test_s_new_has_no_block
65 # GDBM.new ignore the block
66 foo = true
67 assert_instance_of(GDBM, gdbm = GDBM.new("tmptest_gdbm") { foo = false })
68 assert_equals(foo, true)
69 assert_nil(gdbm.close)
70 end
71 def test_s_open_create_new
72 return if /^CYGWIN_9/ =~ SYSTEM
73
74 save_mask = File.umask(0)
75 begin
76 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm"))
77 gdbm.close
78 assert_equals(File.stat("tmptest_gdbm").mode & 0777, 0666)
79 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm2", 0644))
80 gdbm.close
81 assert_equals(File.stat("tmptest_gdbm2").mode & 0777, 0644)
82 ensure
83 File.umask save_mask
84 end
85 end
86 def test_s_open_no_create
87 # this test is failed on libgdbm 1.8.0
88 assert_nil(gdbm = GDBM.open("tmptest_gdbm", nil))
89 ensure
90 gdbm.close if gdbm
91 end
92 def test_s_open_3rd_arg
93 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
94 GDBM::FAST))
95 gdbm.close
96
97 # gdbm 1.8.0 specific
98 if defined? GDBM::SYNC
99 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
100 GDBM::SYNC))
101 gdbm.close
102 end
103 # gdbm 1.8.0 specific
104 if defined? GDBM::NOLOCK
105 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
106 GDBM::NOLOCK))
107 gdbm.close
108 end
109 end
110 def test_s_open_with_block
111 assert_equals(GDBM.open("tmptest_gdbm") { :foo }, :foo)
112 end
113 def test_s_open_lock
114 fork() {
115 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644))
116 sleep 2
117 }
118 begin
119 sleep 1
120 assert_exception(Errno::EWOULDBLOCK) {
121 begin
122 assert_instance_of(GDBM, gdbm2 = GDBM.open("tmptest_gdbm", 0644))
123 rescue Errno::EAGAIN, Errno::EACCES
124 raise Errno::EWOULDBLOCK
125 end
126 }
127 ensure
128 Process.wait
129 end
130 end
131
132 =begin
133 # Is it guaranteed on many OS?
134 def test_s_open_lock_one_process
135 # locking on one process
136 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644))
137 assert_exception(Errno::EWOULDBLOCK) {
138 begin
139 GDBM.open("tmptest_gdbm", 0644)
140 rescue Errno::EAGAIN
141 raise Errno::EWOULDBLOCK
142 end
143 }
144 end
145 =end
146
147 def test_s_open_nolock
148 # gdbm 1.8.0 specific
149 if not defined? GDBM::NOLOCK
150 return
151 end
152
153 fork() {
154 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
155 GDBM::NOLOCK))
156 sleep 2
157 }
158 sleep 1
159 begin
160 gdbm2 = nil
161 assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
162 assert_instance_of(GDBM, gdbm2 = GDBM.open("tmptest_gdbm", 0644))
163 }
164 ensure
165 Process.wait
166 gdbm2.close if gdbm2
167 end
168
169 p Dir.glob("tmptest_gdbm*") if $DEBUG
170
171 fork() {
172 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644))
173 sleep 2
174 }
175 begin
176 sleep 1
177 gdbm2 = nil
178 assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
179 # this test is failed on Cygwin98 (???)
180 assert_instance_of(GDBM, gdbm2 = GDBM.open("tmptest_gdbm", 0644,
181 GDBM::NOLOCK))
182 }
183 ensure
184 Process.wait
185 gdbm2.close if gdbm2
186 end
187 end
188
189 def test_s_open_error
190 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0))
191 assert_exception(Errno::EACCES) {
192 GDBM.open("tmptest_gdbm", 0)
193 }
194 gdbm.close
195 end
196
197 def test_close
198 assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm"))
199 assert_nil(gdbm.close)
200
201 # closed GDBM file
202 assert_exception(RuntimeError) { gdbm.close }
203 end
204
205 def test_aref
206 assert_equals('bar', @gdbm['foo'] = 'bar')
207 assert_equals('bar', @gdbm['foo'])
208
209 assert_nil(@gdbm['bar'])
210 end
211
212 def test_fetch
213 assert_equals('bar', @gdbm['foo']='bar')
214 assert_equals('bar', @gdbm.fetch('foo'))
215
216 # key not found
217 assert_exception(IndexError) {
218 @gdbm.fetch('bar')
219 }
220
221 # test for `ifnone' arg
222 assert_equals('baz', @gdbm.fetch('bar', 'baz'))
223
224 # test for `ifnone' block
225 assert_equals('foobar', @gdbm.fetch('bar') {|key| 'foo' + key })
226 end
227
228 def test_aset
229 num = 0
230 2.times {|i|
231 assert_equals('foo', @gdbm['foo'] = 'foo')
232 assert_equals('foo', @gdbm['foo'])
233 assert_equals('bar', @gdbm['foo'] = 'bar')
234 assert_equals('bar', @gdbm['foo'])
235
236 num += 1 if i == 0
237 assert_equals(num, @gdbm.size)
238
239 # assign nil
240 assert_equals('', @gdbm['bar'] = '')
241 assert_equals('', @gdbm['bar'])
242
243 num += 1 if i == 0
244 assert_equals(num, @gdbm.size)
245
246 # empty string
247 assert_equals('', @gdbm[''] = '')
248 assert_equals('', @gdbm[''])
249
250 num += 1 if i == 0
251 assert_equals(num, @gdbm.size)
252
253 # Fixnum
254 assert_equals('200', @gdbm['100'] = '200')
255 assert_equals('200', @gdbm['100'])
256
257 num += 1 if i == 0
258 assert_equals(num, @gdbm.size)
259
260 # Big key and value
261 assert_equals('y' * 100, @gdbm['x' * 100] = 'y' * 100)
262 assert_equals('y' * 100, @gdbm['x' * 100])
263
264 num += 1 if i == 0
265 assert_equals(num, @gdbm.size)
266 }
267 end
268
269 def test_index
270 assert_equals('bar', @gdbm['foo'] = 'bar')
271 assert_equals('foo', @gdbm.index('bar'))
272 assert_nil(@gdbm['bar'])
273 end
274
275 def test_indexes
276 keys = %w(foo bar baz)
277 values = %w(FOO BAR BAZ)
278 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
279 assert_equals(values.reverse, @gdbm.indexes(*keys.reverse))
280 end
281
282 def test_select
283 keys = %w(foo bar baz)
284 values = %w(FOO BAR BAZ)
285 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
286 assert_equals(values.reverse, @gdbm.select(*keys.reverse))
287 end
288
289 def test_select_with_block
290 keys = %w(foo bar baz)
291 values = %w(FOO BAR BAZ)
292 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
293 ret = @gdbm.select {|k,v|
294 assert_equals(k.upcase, v)
295 k != "bar"
296 }
297 assert_equals([['baz', 'BAZ'], ['foo', 'FOO']],
298 ret.sort)
299 end
300
301 def test_length
302 num = 10
303 assert_equals(0, @gdbm.size)
304 num.times {|i|
305 i = i.to_s
306 @gdbm[i] = i
307 }
308 assert_equals(num, @gdbm.size)
309
310 @gdbm.shift
311
312 assert_equals(num - 1, @gdbm.size)
313 end
314
315 def test_empty?
316 assert_equals(true, @gdbm.empty?)
317 @gdbm['foo'] = 'FOO'
318 assert_equals(false, @gdbm.empty?)
319 end
320
321 def test_each_pair
322 n = 0
323 @gdbm.each_pair { n += 1 }
324 assert_equals(0, n)
325
326 keys = %w(foo bar baz)
327 values = %w(FOO BAR BAZ)
328
329 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
330
331 n = 0
332 ret = @gdbm.each_pair {|key, val|
333 assert_not_nil(i = keys.index(key))
334 assert_equals(val, values[i])
335
336 n += 1
337 }
338 assert_equals(keys.size, n)
339 assert_equals(@gdbm, ret)
340 end
341
342 def test_each_value
343 n = 0
344 @gdbm.each_value { n += 1 }
345 assert_equals(0, n)
346
347 keys = %w(foo bar baz)
348 values = %w(FOO BAR BAZ)
349
350 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
351
352 n = 0
353 ret = @gdbm.each_value {|val|
354 assert_not_nil(key = @gdbm.index(val))
355 assert_not_nil(i = keys.index(key))
356 assert_equals(val, values[i])
357
358 n += 1
359 }
360 assert_equals(keys.size, n)
361 assert_equals(@gdbm, ret)
362 end
363
364 def test_each_key
365 n = 0
366 @gdbm.each_key { n += 1 }
367 assert_equals(0, n)
368
369 keys = %w(foo bar baz)
370 values = %w(FOO BAR BAZ)
371
372 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
373
374 n = 0
375 ret = @gdbm.each_key {|key|
376 assert_not_nil(i = keys.index(key))
377 assert_equals(@gdbm[key], values[i])
378
379 n += 1
380 }
381 assert_equals(keys.size, n)
382 assert_equals(@gdbm, ret)
383 end
384
385 def test_keys
386 assert_equals([], @gdbm.keys)
387
388 keys = %w(foo bar baz)
389 values = %w(FOO BAR BAZ)
390
391 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
392
393 assert_equals(keys.sort, @gdbm.keys.sort)
394 assert_equals(values.sort, @gdbm.values.sort)
395 end
396
397 def test_values
398 test_keys
399 end
400
401 def test_shift
402 assert_nil(@gdbm.shift)
403 assert_equals(0, @gdbm.size)
404
405 keys = %w(foo bar baz)
406 values = %w(FOO BAR BAZ)
407
408 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
409
410 ret_keys = []
411 ret_values = []
412 while ret = @gdbm.shift
413 ret_keys.push ret[0]
414 ret_values.push ret[1]
415
416 assert_equals(keys.size - ret_keys.size, @gdbm.size)
417 end
418
419 assert_equals(keys.sort, ret_keys.sort)
420 assert_equals(values.sort, ret_values.sort)
421 end
422
423 def test_delete
424 keys = %w(foo bar baz)
425 values = %w(FOO BAR BAZ)
426 key = keys[1]
427
428 assert_nil(@gdbm.delete(key))
429 assert_equals(0, @gdbm.size)
430
431 @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
432
433 assert_equals('BAR', @gdbm.delete(key))
434 assert_nil(@gdbm[key])
435 assert_equals(2, @gdbm.size)
436
437 assert_nil(@gdbm.delete(key))
438
439 if /^CYGWIN_9/ !~ SYSTEM
440 assert_exception(GDBMError) {
441 @gdbm_rdonly.delete("foo")
442 }
443
444 assert_nil(@gdbm_rdonly.delete("bar"))
445 end
446 end
447 def test_delete_with_block
448 key = 'no called block'
449 @gdbm[key] = 'foo'
450 assert_equals('foo', @gdbm.delete(key) {|k| k.replace 'called block'})
451 assert_equals('no called block', key)
452 assert_equals(0, @gdbm.size)
453
454 key = 'no called block'
455 assert_equals(:blockval,
456 @gdbm.delete(key) {|k| k.replace 'called block'; :blockval})
457 assert_equals('called block', key)
458 assert_equals(0, @gdbm.size)
459 end
460
461 def test_delete_if
462 v = "0"
463 100.times {@gdbm[v] = v; v = v.next}
464
465 ret = @gdbm.delete_if {|key, val| key.to_i < 50}
466 assert_equals(@gdbm, ret)
467 check_size(50, @gdbm)
468
469 ret = @gdbm.delete_if {|key, val| key.to_i >= 50}
470 assert_equals(@gdbm, ret)
471 check_size(0, @gdbm)
472
473 # break
474 v = "0"
475 100.times {@gdbm[v] = v; v = v.next}
476 check_size(100, @gdbm)
477 n = 0;
478 @gdbm.delete_if {|key, val|
479 break if n > 50
480 n+=1
481 true
482 }
483 assert_equals(51, n)
484 check_size(49, @gdbm)
485
486 @gdbm.clear
487
488 # raise
489 v = "0"
490 100.times {@gdbm[v] = v; v = v.next}
491 check_size(100, @gdbm)
492 n = 0;
493 begin
494 @gdbm.delete_if {|key, val|
495 raise "runtime error" if n > 50
496 n+=1
497 true
498 }
499 rescue
500 end
501 assert_equals(51, n)
502 check_size(49, @gdbm)
503 end
504
505 def test_reject
506 v = "0"
507 100.times {@gdbm[v] = v; v = v.next}
508
509 hash = @gdbm.reject {|key, val| key.to_i < 50}
510 assert_instance_of(Hash, hash)
511 assert_equals(100, @gdbm.size)
512
513 assert_equals(50, hash.size)
514 hash.each_pair {|key,val|
515 assert_equals(false, key.to_i < 50)
516 assert_equals(key, val)
517 }
518
519 hash = @gdbm.reject {|key, val| key.to_i < 100}
520 assert_instance_of(Hash, hash)
521 assert_equals(true, hash.empty?)
522 end
523
524 def test_clear
525 v = "1"
526 100.times {v = v.next; @gdbm[v] = v}
527
528 assert_equals(@gdbm, @gdbm.clear)
529
530 # validate GDBM#size
531 i = 0
532 @gdbm.each { i += 1 }
533 assert_equals(@gdbm.size, i)
534 assert_equals(0, i)
535 end
536
537 def test_invert
538 v = "0"
539 100.times {@gdbm[v] = v; v = v.next}
540
541 hash = @gdbm.invert
542 assert_instance_of(Hash, hash)
543 assert_equals(100, hash.size)
544 hash.each_pair {|key, val|
545 assert_equals(key.to_i, val.to_i)
546 }
547 end
548
549 def test_update
550 hash = {}
551 v = "0"
552 100.times {v = v.next; hash[v] = v}
553
554 @gdbm["101"] = "101"
555 @gdbm.update hash
556 assert_equals(101, @gdbm.size)
557 @gdbm.each_pair {|key, val|
558 assert_equals(key.to_i, val.to_i)
559 }
560 end
561
562 def test_replace
563 hash = {}
564 v = "0"
565 100.times {v = v.next; hash[v] = v}
566
567 @gdbm["101"] = "101"
568 @gdbm.replace hash
569 assert_equals(100, @gdbm.size)
570 @gdbm.each_pair {|key, val|
571 assert_equals(key.to_i, val.to_i)
572 }
573 end
574
575 def test_reorganize
576 size1 = File.size(@path)
577 i = "1"
578 1000.times {i = i.next; @gdbm[i] = i}
579 @gdbm.clear
580 @gdbm.sync
581
582 size2 = File.size(@path)
583 @gdbm.reorganize
584 size3 = File.size(@path)
585
586 # p [size1, size2, size3]
587 assert_equals(true, size1 < size2)
588 # this test is failed on Cygwin98. `GDBM version 1.8.0, as of May 19, 1999'
589 assert_equals(true, size3 < size2)
590 assert_equals(size1, size3)
591 end
592
593 def test_sync
594 assert_instance_of(GDBM, gdbm = GDBM.open('tmptest_gdbm', 0666, GDBM::FAST))
595 assert_equals(gdbm.sync, gdbm)
596 gdbm.close
597 assert_instance_of(GDBM, gdbm = GDBM.open('tmptest_gdbm', 0666))
598 assert_equals(gdbm.sync, gdbm)
599 gdbm.close
600 end
601
602 def test_cachesize=
603 assert_equals(@gdbm.cachesize = 1024, 1024)
604 end
605
606 def test_fastmode=
607 assert_equals(@gdbm.fastmode = true, true)
608 end
609
610 def test_syncmode=
611 assert_equals(@gdbm.syncmode = true, true)
612 end
613
614 def test_haskey?
615 assert_equals('bar', @gdbm['foo']='bar')
616 assert_equals(true, @gdbm.has_key?('foo'))
617 assert_equals(false, @gdbm.has_key?('bar'))
618 end
619
620 def test_has_value?
621 assert_equals('bar', @gdbm['foo']='bar')
622 assert_equals(true, @gdbm.has_value?('bar'))
623 assert_equals(false, @gdbm.has_value?('foo'))
624 end
625
626 def test_to_a
627 v = "0"
628 100.times {v = v.next; @gdbm[v] = v}
629
630 ary = @gdbm.to_a
631 assert_instance_of(Array, ary)
632 assert_equals(100, ary.size)
633 ary.each {|key,val|
634 assert_equals(key.to_i, val.to_i)
635 }
636 end
637
638 def test_to_hash
639 v = "0"
640 100.times {v = v.next; @gdbm[v] = v}
641
642 hash = @gdbm.to_hash
643 assert_instance_of(Hash, hash)
644 assert_equals(100, hash.size)
645 hash.each {|key,val|
646 assert_equals(key.to_i, val.to_i)
647 }
648 end
649 end
650
651 if $0 == __FILE__
652 if ARGV.size == 0
653 suite = RUNIT::TestSuite.new
654 suite.add_test(TestGDBM.suite)
655 else
656 suite = RUNIT::TestSuite.new
657 ARGV.each do |testmethod|
658 suite.add_test(TestGDBM.new(testmethod))
659 end
660 end
661
662 RUNIT::CUI::TestRunner.run(suite)
663 end