about summary refs log tree commit homepage
path: root/test/test_tdb.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_tdb.rb')
-rw-r--r--test/test_tdb.rb260
1 files changed, 260 insertions, 0 deletions
diff --git a/test/test_tdb.rb b/test/test_tdb.rb
new file mode 100644
index 0000000..188e219
--- /dev/null
+++ b/test/test_tdb.rb
@@ -0,0 +1,260 @@
+# -*- encoding: binary -*-
+$stdout.sync = $stderr.sync = true
+require 'test/unit'
+require 'tempfile'
+$-w = true
+require 'tdb'
+
+class TestTdb < Test::Unit::TestCase
+
+  def setup
+    @tmp = @tdb = nil
+  end
+
+  def teardown
+    @tmp.close! if @tmp.respond_to?(:close!)
+    @tdb.close if @tdb && ! @tdb.closed?
+  end
+
+  def test_create_file
+    assert_nothing_raised do
+      @tmp = Tempfile.new('tdb')
+      File.unlink(@tmp.path)
+    end
+    @tdb = TDB.new(@tmp.path)
+    assert_kind_of TDB, @tdb
+    assert File.exist?(@tmp.path)
+  end
+
+  def test_to_a
+    @tdb = TDB.new(nil)
+    assert_equal [], @tdb.to_a
+  end
+
+  def test_each
+    @tdb = TDB.new(nil)
+    @tdb["X"] = "Y"
+
+    tmp = []
+    rc = @tdb.each { |k,v| tmp << [k, v ] }
+    assert_equal([ %w(X Y) ], tmp)
+    assert_equal @tdb.object_id, rc.object_id
+
+    tmp = []
+    assert_raises(EOFError) {
+      @tdb.each { |k,v| raise EOFError, "FOO"; tmp << [ k, v ] }
+    }
+    assert tmp.empty?
+
+    tmp = []
+    rc = catch(:zzz) { @tdb.each { |k,v| throw(:zzz, "FOO"); tmp << [ k, v ] } }
+    assert_equal rc, "FOO"
+    assert tmp.empty?
+  end
+
+  def test_each_bigger
+    @tdb = TDB.new(nil)
+    @tdb["a"] = "A"
+    @tdb["b"] = "B"
+    @tdb["c"] = "C"
+
+    tmp = []
+    rc = @tdb.each { |k,v| tmp << [k, v ] }
+    assert_equal 3, tmp.size
+    assert_equal @tdb.object_id, rc.object_id
+
+    tmp = []
+    assert_raises(EOFError) {
+      @tdb.each { |k,v|
+        tmp << [ k, v ]
+        raise EOFError, "FOO"
+      }
+    }
+    assert_equal 1, tmp.size
+
+    tmp = []
+    rc = catch(:zzz) {
+      @tdb.each { |k,v|
+        tmp << [ k, v ]
+        throw(:zzz, "FOO")
+      }
+    }
+    assert_equal rc, "FOO"
+    assert_equal 1, tmp.size
+  end
+
+  def test_memory
+    assert_nothing_raised do
+      @tdb = TDB.new(nil)
+    end
+    assert ! @tdb.closed?
+    assert_nil @tdb.close
+    assert @tdb.closed?
+    assert_raises(IOError) { @tdb.close }
+  end
+
+  def test_delete
+    @tdb = TDB.new(nil)
+    @tdb["hello"] = "X"
+    assert_equal "X", @tdb.delete("hello")
+    assert_nil @tdb["hello"]
+    assert_nil @tdb.fetch("hello")
+    assert_nil @tdb.delete("hello")
+    @tdb["hello"] = "world"
+    assert_equal "world", @tdb.delete("hello")
+    assert_nil @tdb.delete("hello")
+  end
+
+  def test_nuke!
+    @tdb = TDB.new(nil)
+    assert_equal false, @tdb.nuke!("hello")
+    @tdb["hello"] = "world"
+    assert_equal true, @tdb.nuke!("hello")
+    assert ! @tdb.include?("hello")
+    assert_equal false, @tdb.nuke!("hello")
+  end
+
+  def test_exists?
+    @tdb = TDB.new(nil)
+    assert_equal false, @tdb.key?("hello")
+    assert_equal false, @tdb.include?("hello")
+    @tdb["hello"] = "world"
+    assert_equal true, @tdb.key?("hello")
+  end
+
+  def test_store_fetch_mem
+    @tdb = TDB.new(nil)
+    assert_nothing_raised { @tdb["hello"] = "world" }
+    assert_equal "world", @tdb["hello"]
+    @tdb.store("hello", "Z")
+    assert_equal "Z", @tdb["hello"]
+    assert_equal "Z", @tdb.fetch("hello")
+  end
+
+  def test_store_modify_mem
+    @tdb = TDB.new(nil)
+    assert_nothing_raised { @tdb["hello"] = "world" }
+    assert_equal "world", @tdb["hello"]
+    assert_equal "Z", @tdb.modify("hello", "Z")
+    assert_equal "Z", @tdb["hello"]
+
+    assert_nil @tdb.modify("none", "Z")
+    assert_raises(TDB::ERR::NOEXIST) { @tdb.modify!("none", "Z") }
+  end
+
+  def test_store_insert_mem
+    @tdb = TDB.new(nil)
+    assert_equal "world", @tdb.insert("hello", "world")
+    assert_equal "world", @tdb["hello"]
+    assert_nil @tdb.insert("hello", "Z")
+    assert_raises(TDB::ERR::EXISTS) { @tdb.insert!("hello", "Z") }
+    assert_equal "world", @tdb["hello"]
+  end
+
+  def test_gc
+    assert_nothing_raised do
+      100000.times { TDB.new(nil) }
+      100000.times { TDB.new(Tempfile.new('tdb').path) }
+    end
+  end if ENV["TEST_GC"]
+
+  def test_new_with_hash_size
+    assert_nothing_raised { TDB.new(nil, :hash_size => 6) }
+    assert_raises(TypeError) { TDB.new(nil, :hash_size => "6") }
+  end
+
+  def test_const
+    assert_equal 0, TDB::DEFAULT
+    assert_equal 1, TDB::CLEAR_IF_FIRST
+  end
+
+  def test_new_with_open_flags
+    @tmp = Tempfile.new('tdb_excl')
+    assert_raises(Errno::EEXIST) {
+      TDB.new(@tmp.path, :open_flags => IO::EXCL|IO::CREAT|IO::RDWR)
+    }
+    File.unlink(@tmp.path)
+    assert_nothing_raised {
+      @tdb = TDB.new(@tmp.path, :open_flags => IO::EXCL|IO::CREAT|IO::RDWR)
+    }
+  end
+
+  def test_open_with_tdb_flags
+    assert_nothing_raised do
+      @tdb = TDB.new("/non/existent/file", :tdb_flags => TDB::INTERNAL)
+    end
+  end
+
+  def test_alternate_hashes
+    results = {}
+    expect = TDB::HASHES.to_a.map { |k,v| [ k.to_s, v.to_s ] }.sort
+    %w(default jenkins_lookup3 djb2 djb3 fnv1a
+       murmur1 murmur1_aligned murmur2 murmur2a murmur2_aligned).each do |h|
+      assert_nothing_raised do
+        tdb = TDB.new(nil, :hash => h.to_sym)
+        TDB::HASHES.each do |k,v|
+          tdb[k.to_s] = v.to_s
+        end
+        assert_equal expect, tdb.to_a.sort
+        assert_nil tdb.close
+      end
+      assert_raises(ArgumentError) do
+        TDB.new(nil, :hash => h)
+      end
+    end
+  end
+
+  def test_lock_unlock_all
+    @tmp = Tempfile.new('tdb')
+    File.unlink(@tmp.path)
+    @tdb = TDB.new(@tmp.path)
+    assert_equal true, @tdb.lockall
+    assert_equal true, @tdb.unlockall
+    assert_raises(TDB::ERR::LOCK) { @tdb.unlockall }
+  end
+
+  def test_read_locks
+    @tmp = Tempfile.new('tdb')
+    File.unlink(@tmp.path)
+    @tdb = TDB.new(@tmp.path)
+    assert_equal true, @tdb.lockall_read
+    assert_equal true, @tdb.unlockall_read
+    assert_raises(TDB::ERR::LOCK) { @tdb.unlockall_read }
+    assert_equal true, @tdb.trylockall_read
+    assert_equal true, @tdb.unlockall_read
+    assert_raises(TDB::ERR::LOCK) { @tdb.unlockall_read }
+  end
+
+  def test_mark_locks
+    @tmp = Tempfile.new('tdb')
+    File.unlink(@tmp.path)
+    @tdb = TDB.new(@tmp.path)
+    assert_equal true, @tdb.lockall_mark
+    assert_equal true, @tdb.lockall_unmark
+    assert_raises(TDB::ERR::LOCK) { @tdb.lockall_unmark }
+  end
+
+  def test_trylockall
+    @tmp = Tempfile.new('tdb')
+    File.unlink(@tmp.path)
+    @tdb = TDB.new(@tmp.path)
+    ard, awr = IO.pipe
+    brd, bwr = IO.pipe
+    pid = fork do
+      @tdb.close
+      ard.close
+      bwr.close
+      tdb = TDB.new(@tmp.path)
+      assert_equal true, tdb.lockall
+      awr.close
+      brd.read
+    end
+    awr.close
+    brd.close
+    assert_equal "", ard.read
+    assert_equal false, @tdb.trylockall
+    bwr.close
+    assert Process.waitpid2(pid)[1].success?
+    assert_equal true, @tdb.trylockall
+  end
+end