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