diff options
Diffstat (limited to 'test/unit/test_semaphore.rb')
-rw-r--r-- | test/unit/test_semaphore.rb | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/test/unit/test_semaphore.rb b/test/unit/test_semaphore.rb new file mode 100644 index 0000000..5ce70f7 --- /dev/null +++ b/test/unit/test_semaphore.rb @@ -0,0 +1,118 @@ +root_dir = File.join(File.dirname(__FILE__), "../..") +require File.join(root_dir, "test/test_helper") +require File.join(root_dir, "lib/mongrel/semaphore") + +class TestSemaphore < Test::Unit::TestCase + def setup + super + + @semaphore = Semaphore.new + end + + def test_wait_prevents_thread_from_running + thread = Thread.new { @semaphore.wait } + give_up_my_time_slice + + assert thread.stop? + end + + def test_signal_allows_waiting_thread_to_run + ran = false + thread = Thread.new { @semaphore.wait; ran = true } + give_up_my_time_slice + + @semaphore.signal + give_up_my_time_slice + + assert ran + end + + def test_wait_allows_only_specified_number_of_resources + @semaphore = Semaphore.new(1) + + run_count = 0 + thread1 = Thread.new { @semaphore.wait; run_count += 1 } + thread2 = Thread.new { @semaphore.wait; run_count += 1 } + give_up_my_time_slice + + assert_equal 1, run_count + end + + def test_semaphore_serializes_threads + @semaphore = Semaphore.new(1) + + result = "" + thread1 = Thread.new do + @semaphore.wait + 4.times do |i| + give_up_my_time_slice + result << i.to_s + end + @semaphore.signal + end + + thread2 = Thread.new do + @semaphore.wait + ("a".."d").each do |char| + give_up_my_time_slice + result << char + end + @semaphore.signal + end + + give_up_my_time_slice + @semaphore.wait + + assert_equal "0123abcd", result + end + + def test_synchronize_many_threads + @semaphore = Semaphore.new(1) + + result = [] + 5.times do |i| + Thread.new do + @semaphore.wait + 2.times { |j| result << [i, j] } + @semaphore.signal + end + end + + give_up_my_time_slice + @semaphore.wait + + 5.times do |i| + 2.times do |j| + assert_equal i, result[2 * i + j][0] + assert_equal j, result[2 * i + j][1] + end + end + end + + def test_synchronize_ensures_signal + @semaphore = Semaphore.new(1) + threads = [] + run_count = 0 + threads << Thread.new do + @semaphore.synchronize { run_count += 1 } + end + threads << Thread.new do + @semaphore.synchronize { run_count += 1; raise "I'm throwing an error." } + end + threads << Thread.new do + @semaphore.synchronize { run_count += 1 } + end + + give_up_my_time_slice + @semaphore.wait + + assert !threads.any? { |thread| thread.alive? } + assert_equal 3, run_count + end + + private + + def give_up_my_time_slice + sleep(0) + end +end
\ No newline at end of file |