1 # -*- encoding: binary -*-
2 $stdout.sync = $stderr.sync = true
8 class TestTdb < Test::Unit::TestCase
15 @tmp.close! if @tmp.respond_to?(:close!)
16 @tdb.close if @tdb && ! @tdb.closed?
19 def test_create_file_null_byte_in_path
20 assert_raises(ArgumentError) { TDB.new("hello.tdb\0") }
24 assert_nothing_raised do
25 @tmp = Tempfile.new('tdb')
26 File.unlink(@tmp.path)
28 @tdb = TDB.new(@tmp.path)
29 assert_kind_of TDB, @tdb
30 assert File.exist?(@tmp.path)
35 assert_equal [], @tdb.to_a
43 rc = @tdb.each { |k,v| tmp << [k, v ] }
44 assert_equal([ %w(X Y) ], tmp)
45 assert_equal @tdb.object_id, rc.object_id
48 assert_raises(EOFError) {
49 @tdb.each { |k,v| raise EOFError, "FOO"; tmp << [ k, v ] }
54 rc = catch(:zzz) { @tdb.each { |k,v| throw(:zzz, "FOO"); tmp << [ k, v ] } }
55 assert_equal rc, "FOO"
66 rc = @tdb.each { |k,v| tmp << [k, v ] }
67 assert_equal 3, tmp.size
68 assert_equal @tdb.object_id, rc.object_id
71 assert_raises(EOFError) {
77 assert_equal 1, tmp.size
86 assert_equal rc, "FOO"
87 assert_equal 1, tmp.size
91 assert_nothing_raised do
97 assert_raises(IOError) { @tdb.close }
103 assert_equal "X", @tdb.delete("hello")
104 assert_nil @tdb["hello"]
105 assert_nil @tdb.fetch("hello")
106 assert_nil @tdb.delete("hello")
107 @tdb["hello"] = "world"
108 assert_equal "world", @tdb.delete("hello")
109 assert_nil @tdb.delete("hello")
114 assert_equal false, @tdb.nuke!("hello")
115 @tdb["hello"] = "world"
116 assert_equal true, @tdb.nuke!("hello")
117 assert ! @tdb.include?("hello")
118 assert_equal false, @tdb.nuke!("hello")
123 assert_equal false, @tdb.key?("hello")
124 assert_equal false, @tdb.include?("hello")
125 @tdb["hello"] = "world"
126 assert_equal true, @tdb.key?("hello")
129 def test_store_fetch_mem
131 assert_nothing_raised { @tdb["hello"] = "world" }
132 assert_equal "world", @tdb["hello"]
133 @tdb.store("hello", "Z")
134 assert_equal "Z", @tdb["hello"]
135 assert_equal "Z", @tdb.fetch("hello")
138 def test_store_modify_mem
140 assert_nothing_raised { @tdb["hello"] = "world" }
141 assert_equal "world", @tdb["hello"]
142 assert_equal "Z", @tdb.modify("hello", "Z")
143 assert_equal "Z", @tdb["hello"]
145 assert_nil @tdb.modify("none", "Z")
146 assert_raises(TDB::ERR::NOEXIST) { @tdb.modify!("none", "Z") }
149 def test_store_insert_mem
151 assert_equal "world", @tdb.insert("hello", "world")
152 assert_equal "world", @tdb["hello"]
153 assert_nil @tdb.insert("hello", "Z")
154 assert_raises(TDB::ERR::EXISTS) { @tdb.insert!("hello", "Z") }
155 assert_equal "world", @tdb["hello"]
159 assert_nothing_raised do
160 100000.times { TDB.new(nil) }
161 100000.times { TDB.new(Tempfile.new('tdb').path) }
163 end if ENV["TEST_GC"]
165 def test_new_with_hash_size
166 assert_nothing_raised { TDB.new(nil, :hash_size => 6) }
167 assert_raises(TypeError) { TDB.new(nil, :hash_size => "6") }
171 assert_equal 0, TDB::DEFAULT
172 assert_equal 1, TDB::CLEAR_IF_FIRST
175 def test_new_with_open_flags
176 @tmp = Tempfile.new('tdb_excl')
177 assert_raises(Errno::EEXIST) {
178 TDB.new(@tmp.path, :open_flags => IO::EXCL|IO::CREAT|IO::RDWR)
180 File.unlink(@tmp.path)
181 assert_nothing_raised {
182 @tdb = TDB.new(@tmp.path, :open_flags => IO::EXCL|IO::CREAT|IO::RDWR)
186 def test_open_with_tdb_flags
187 assert_nothing_raised do
188 @tdb = TDB.new("/non/existent/file", :tdb_flags => TDB::INTERNAL)
192 def test_alternate_hashes
194 expect = TDB::HASHES.to_a.map { |k,v| [ k.to_s, v.to_s ] }.sort
195 %w(default siphash24 jenkins_lookup3 djb2 djb3 fnv1a
196 murmur1 murmur1_aligned murmur2 murmur2a murmur2_aligned
197 murmur3a murmur3f).each do |h|
198 assert_nothing_raised do
199 tdb = TDB.new(nil, :hash => h.to_sym)
200 TDB::HASHES.each do |k,v|
203 assert_equal expect, tdb.to_a.sort
206 assert_raises(ArgumentError) do
207 TDB.new(nil, :hash => h)
212 def test_lock_unlock_all
213 @tmp = Tempfile.new('tdb')
214 File.unlink(@tmp.path)
215 @tdb = TDB.new(@tmp.path)
216 assert_equal true, @tdb.lockall
217 assert_equal true, @tdb.unlockall
218 assert_raises(TDB::ERR::LOCK) { @tdb.unlockall }
222 @tmp = Tempfile.new('tdb')
223 File.unlink(@tmp.path)
224 @tdb = TDB.new(@tmp.path)
225 assert_equal true, @tdb.lockall_read
226 assert_equal true, @tdb.unlockall_read
227 assert_raises(TDB::ERR::LOCK) { @tdb.unlockall_read }
228 assert_equal true, @tdb.trylockall_read
229 assert_equal true, @tdb.unlockall_read
230 assert_raises(TDB::ERR::LOCK) { @tdb.unlockall_read }
234 @tmp = Tempfile.new('tdb')
235 File.unlink(@tmp.path)
236 @tdb = TDB.new(@tmp.path)
237 assert_equal true, @tdb.lockall_mark
238 assert_equal true, @tdb.lockall_unmark
239 assert_raises(TDB::ERR::LOCK) { @tdb.lockall_unmark }
243 @tmp = Tempfile.new('tdb')
244 File.unlink(@tmp.path)
245 @tdb = TDB.new(@tmp.path)
252 tdb = TDB.new(@tmp.path)
253 assert_equal true, tdb.lockall
259 assert_equal "", ard.read
260 assert_equal false, @tdb.trylockall
262 assert Process.waitpid2(pid)[1].success?
263 assert_equal true, @tdb.trylockall
266 def test_check_constant_typos
268 TDB.constants.each { |const| names[const] = TDB.const_get(const) }
269 assert_equal TDB.constants.size, names.size
272 TDB.constants.each { |const| values[TDB.const_get(const)] = const }
273 assert_equal TDB.constants.size, values.size
278 @tdb["hello"] = "world"
279 assert_equal @tdb, @tdb.clear
280 assert ! @tdb.include?("hello")
284 @tmp = Tempfile.new('tdb')
285 File.unlink(@tmp.path)
286 @tdb = TDB.new(@tmp.path)
287 @tdb["hello"] = "world"
289 assert_equal "world", @tdb["hello"]
290 @tdb["hello"] = "WORLD"
294 _, status = Process.waitpid2(pid)
295 assert status.success?, status.inspect
296 assert_equal "WORLD", @tdb["hello"]
297 assert_equal "NO", @tdb[pid.to_s]
300 def test_fetch_reuse_buf
301 assert_nothing_raised do
302 @tmp = Tempfile.new('tdb')
303 File.unlink(@tmp.path)
305 @tdb = TDB.new(@tmp.path)
306 @tdb["HELLO"] = "WORLD"
308 rv = @tdb.fetch("HELLO", rbuf)
309 assert_equal rbuf.object_id, rv.object_id
311 assert_equal "WORLD", rbuf
312 assert_nil @tdb.fetch("HELLO!", rbuf)
313 assert_equal "", rbuf
315 @tdb["HELLO"] = "WORLD" * 100
316 rv = @tdb.fetch("HELLO", rbuf)
317 assert_equal rbuf.object_id, rv.object_id
318 assert_equal "WORLD" * 100, rbuf
321 def test_delete_reuse_buf
322 assert_nothing_raised do
323 @tmp = Tempfile.new('tdb')
324 File.unlink(@tmp.path)
326 @tdb = TDB.new(@tmp.path)
327 @tdb["HELLO"] = "WORLD"
329 rv = @tdb.delete("HELLO", rbuf)
330 assert_equal rbuf.object_id, rv.object_id
331 assert_equal "WORLD", rbuf
332 assert ! @tdb.include?("HELLO")
334 assert_nil @tdb.delete("HELLO!", rbuf)
335 assert_equal "", rbuf
337 @tdb["HELLO"] = "WORLD" * 100
338 rv = @tdb.delete("HELLO", rbuf)
339 assert_equal rbuf.object_id, rv.object_id
340 assert_equal "WORLD" * 100, rbuf
341 assert ! @tdb.include?("HELLO")
345 assert_nothing_raised do
346 @tmp = Tempfile.new('tdb')
347 File.unlink(@tmp.path)
349 @tdb = TDB.new(@tmp.path)
350 @tdb["hello"] = "world"
351 assert_equal @tdb, @tdb.repack
352 assert_equal "world", @tdb["hello"]
353 end if TDB.method_defined?(:repack)
357 @tdb["hello"] = "world"
358 assert_raises(TDB::ERR::EINVAL) { @tdb.repack }
359 end if TDB.method_defined?(:repack)