tdb/mt: fix tests under Ruby 1.8
[ruby-tdb.git] / test / test_tdb_mt.rb
blob781e2bd782a0b434b78b8d33ba0b0070a466f0e7
1 # -*- encoding: binary -*-
2 $stdout.sync = $stderr.sync = true
3 require 'test/unit'
4 require 'tempfile'
5 $-w = true
6 require 'tdb'
8 class Test_TDB_MT < Test::Unit::TestCase
9   def setup
10     @tdb = @tmp = nil
11     @start_pid = $$
12   end
14   def teardown
15     return if @start_pid != $$
16     @tmp.close! if @tmp.respond_to?(:close!)
17     @tdb.close if @tdb && ! @tdb.closed?
18   end
20   def test_make_threadsafe
21     @tdb = TDB.new(nil)
22     assert_kind_of TDB, @tdb
23     assert ! @tdb.threadsafe?
24     assert_nothing_raised { @tdb.threadsafe! }
25     assert @tdb.threadsafe?
26   end
28   def test_init_threadsafe
29     @tdb = TDB.new(nil, :threadsafe => true)
30     assert @tdb.threadsafe?
31     @tdb.close
32     @tdb = TDB.new(nil, :threadsafe => false)
33     assert ! @tdb.threadsafe?
34     @tdb.close
35     @tdb = TDB.new(nil)
36     assert ! @tdb.threadsafe?
37     @tdb.close
38   end
40   def test_thread_safe_torture_test
41     return
42     @tmp = Tempfile.new('tdb_test')
43     File.unlink(@tmp.path)
44     @tdb = TDB.new(@tmp.path)
45     assert_nothing_raised { @tdb.threadsafe! }
46     Thread.abort_on_exception = true
47     nr = 10000
48     blob = 'foo' * 1000
49     crazy = proc do
50       threads = []
51       t = Thread.new do
52         while true
53           Thread.pass
54           @tdb.to_a
55         end
56       end
57       threads << Thread.new { nr.times { |i| @tdb[i.to_s] = blob } }
58       threads << Thread.new { nr.times { |i| @tdb[i.to_s] = blob } }
59       threads << Thread.new { nr.times { |i| @tdb[i.to_s] = blob } }
60       threads << Thread.new { nr.times { |i| @tdb[i.to_s] = blob } }
61       threads << Thread.new { nr.times { |i| @tdb[i.to_s] = blob } }
62       threads << t
63       sleep 1
64       t.kill
65       threads.each { |t| t.join }
66     end
67     10.times { fork &crazy }
68     Process.waitall.each do |(pid,status)|
69       assert status.success?, status.inspect
70     end
71     nr.times { |i| assert_equal blob, @tdb[i.to_s] }
72   end
74   def test_check_methods
75     m = TDB.instance_methods.sort
76     if String === m[0]
77       warn "skipping test under Ruby 1.8"
78       return
79     end
80     m -= Object.instance_methods
81     m -= Enumerable.instance_methods
82     m.map! { |x| x.to_sym }
83     mt = TDB::MT.instance_methods.sort
84     m -= [ :threadsafe! ]
85     m += [ :include?, :member? ]
86     m.sort!
87     unwrapped = ( (m - mt) | (mt - m)).uniq
88     unwrapped -= [ :initialize ]
89     assert unwrapped.empty?, "unwrapped methods: #{unwrapped.inspect}"
90     @tdb = TDB.new(nil)
91     respond_to?(:refute_match) and
92       m.each { |meth| refute_match(/\bTDB::MT\b/, @tdb.method(meth).to_s) }
93     @tdb.threadsafe!
94     m.each { |meth| assert_match(/\bTDB::MT\b/, @tdb.method(meth).to_s) }
95   end
96 end