diff options
author | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-20 20:18:52 +0000 |
---|---|---|
committer | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-20 20:18:52 +0000 |
commit | 1d15d5f08032acf1b7bceacbb450d617ff6e0931 (patch) | |
tree | a3785a79899302bc149e4a6e72f624ac27dc1f10 /spec/ruby/core/mutex | |
parent | 75bfc6440d595bf339007f4fb280fd4d743e89c1 (diff) |
Move spec/rubyspec to spec/ruby for consistency
* Other ruby implementations use the spec/ruby directory.
[Misc #13792] [ruby-core:82287]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/ruby/core/mutex')
-rw-r--r-- | spec/ruby/core/mutex/lock_spec.rb | 46 | ||||
-rw-r--r-- | spec/ruby/core/mutex/locked_spec.rb | 36 | ||||
-rw-r--r-- | spec/ruby/core/mutex/owned_spec.rb | 43 | ||||
-rw-r--r-- | spec/ruby/core/mutex/sleep_spec.rb | 74 | ||||
-rw-r--r-- | spec/ruby/core/mutex/synchronize_spec.rb | 27 | ||||
-rw-r--r-- | spec/ruby/core/mutex/try_lock_spec.rb | 32 | ||||
-rw-r--r-- | spec/ruby/core/mutex/unlock_spec.rb | 38 |
7 files changed, 296 insertions, 0 deletions
diff --git a/spec/ruby/core/mutex/lock_spec.rb b/spec/ruby/core/mutex/lock_spec.rb new file mode 100644 index 0000000000..98deabe056 --- /dev/null +++ b/spec/ruby/core/mutex/lock_spec.rb @@ -0,0 +1,46 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Mutex#lock" do + before :each do + ScratchPad.clear + end + + it "returns self" do + m = Mutex.new + m.lock.should == m + m.unlock + end + + it "waits if the lock is not available" do + m = Mutex.new + + m.lock + + th = Thread.new do + m.lock + ScratchPad.record :after_lock + end + + Thread.pass while th.status and th.status != "sleep" + + ScratchPad.recorded.should be_nil + m.unlock + th.join + ScratchPad.recorded.should == :after_lock + end + + # Unable to find a specific ticket but behavior change may be + # related to this ML thread. + it "raises a ThreadError when used recursively" do + m = Mutex.new + + th = Thread.new do + m.lock + m.lock + end + + lambda do + th.join + end.should raise_error(ThreadError) + end +end diff --git a/spec/ruby/core/mutex/locked_spec.rb b/spec/ruby/core/mutex/locked_spec.rb new file mode 100644 index 0000000000..7b92534be4 --- /dev/null +++ b/spec/ruby/core/mutex/locked_spec.rb @@ -0,0 +1,36 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Mutex#locked?" do + it "returns true if locked" do + m = Mutex.new + m.lock + m.locked?.should be_true + end + + it "returns false if unlocked" do + m = Mutex.new + m.locked?.should be_false + end + + it "returns the status of the lock" do + m1 = Mutex.new + m2 = Mutex.new + + m2.lock # hold th with only m1 locked + m1_locked = false + + th = Thread.new do + m1.lock + m1_locked = true + m2.lock + end + + Thread.pass until m1_locked + + m1.locked?.should be_true + m2.unlock # release th + th.join + # A Thread releases its locks upon termination + m1.locked?.should be_false + end +end diff --git a/spec/ruby/core/mutex/owned_spec.rb b/spec/ruby/core/mutex/owned_spec.rb new file mode 100644 index 0000000000..2e1c3f2481 --- /dev/null +++ b/spec/ruby/core/mutex/owned_spec.rb @@ -0,0 +1,43 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Mutex#owned?" do + describe "when unlocked" do + it "returns false" do + m = Mutex.new + m.owned?.should be_false + end + end + + describe "when locked by the current thread" do + it "returns true" do + m = Mutex.new + m.lock + m.owned?.should be_true + end + end + + describe "when locked by another thread" do + before :each do + @checked = false + end + + after :each do + @checked = true + @th.join + end + + it "returns false" do + m = Mutex.new + locked = false + + @th = Thread.new do + m.lock + locked = true + Thread.pass until @checked + end + + Thread.pass until locked + m.owned?.should be_false + end + end +end diff --git a/spec/ruby/core/mutex/sleep_spec.rb b/spec/ruby/core/mutex/sleep_spec.rb new file mode 100644 index 0000000000..a3fb86fba7 --- /dev/null +++ b/spec/ruby/core/mutex/sleep_spec.rb @@ -0,0 +1,74 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Mutex#sleep" do + describe "when not locked by the current thread" do + it "raises a ThreadError" do + m = Mutex.new + lambda { m.sleep }.should raise_error(ThreadError) + end + + it "raises an ArgumentError if passed a negative duration" do + m = Mutex.new + lambda { m.sleep(-0.1) }.should raise_error(ArgumentError) + lambda { m.sleep(-1) }.should raise_error(ArgumentError) + end + end + + it "raises an ArgumentError if passed a negative duration" do + m = Mutex.new + m.lock + lambda { m.sleep(-0.1) }.should raise_error(ArgumentError) + lambda { m.sleep(-1) }.should raise_error(ArgumentError) + end + + it "pauses execution for approximately the duration requested" do + m = Mutex.new + m.lock + duration = 0.1 + start = Time.now + m.sleep duration + (Time.now - start).should be_close(duration, 0.2) + end + + it "unlocks the mutex while sleeping" do + m = Mutex.new + locked = false + th = Thread.new { m.lock; locked = true; m.sleep } + Thread.pass until locked + Thread.pass while th.status and th.status != "sleep" + m.locked?.should be_false + th.run + th.join + end + + it "relocks the mutex when woken" do + m = Mutex.new + m.lock + m.sleep(0.01) + m.locked?.should be_true + end + + it "relocks the mutex when woken by an exception being raised" do + m = Mutex.new + locked = false + th = Thread.new do + m.lock + locked = true + begin + m.sleep + rescue Exception + m.locked? + end + end + Thread.pass until locked + Thread.pass while th.status and th.status != "sleep" + th.raise(Exception) + th.value.should be_true + end + + it "returns the rounded number of seconds asleep" do + m = Mutex.new + m.lock + m.sleep(0.01).should be_kind_of(Integer) + end +end diff --git a/spec/ruby/core/mutex/synchronize_spec.rb b/spec/ruby/core/mutex/synchronize_spec.rb new file mode 100644 index 0000000000..ec64aa60fa --- /dev/null +++ b/spec/ruby/core/mutex/synchronize_spec.rb @@ -0,0 +1,27 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Mutex#synchronize" do + it "wraps the lock/unlock pair in an ensure" do + m1 = Mutex.new + m2 = Mutex.new + m2.lock + synchronized = false + + th = Thread.new do + lambda do + m1.synchronize do + synchronized = true + m2.lock + raise Exception + end + end.should raise_error(Exception) + end + + Thread.pass until synchronized + + m1.locked?.should be_true + m2.unlock + th.join + m1.locked?.should be_false + end +end diff --git a/spec/ruby/core/mutex/try_lock_spec.rb b/spec/ruby/core/mutex/try_lock_spec.rb new file mode 100644 index 0000000000..3e875ff9ec --- /dev/null +++ b/spec/ruby/core/mutex/try_lock_spec.rb @@ -0,0 +1,32 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Mutex#try_lock" do + describe "when unlocked" do + it "returns true" do + m = Mutex.new + m.try_lock.should be_true + end + + it "locks the mutex" do + m = Mutex.new + m.try_lock + m.locked?.should be_true + end + end + + describe "when locked by the current thread" do + it "returns false" do + m = Mutex.new + m.lock + m.try_lock.should be_false + end + end + + describe "when locked by another thread" do + it "returns false" do + m = Mutex.new + m.lock + Thread.new { m.try_lock }.value.should be_false + end + end +end diff --git a/spec/ruby/core/mutex/unlock_spec.rb b/spec/ruby/core/mutex/unlock_spec.rb new file mode 100644 index 0000000000..4601fde634 --- /dev/null +++ b/spec/ruby/core/mutex/unlock_spec.rb @@ -0,0 +1,38 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Mutex#unlock" do + it "raises ThreadError unless Mutex is locked" do + mutex = Mutex.new + lambda { mutex.unlock }.should raise_error(ThreadError) + end + + it "raises ThreadError unless thread owns Mutex" do + mutex = Mutex.new + wait = Mutex.new + wait.lock + th = Thread.new do + mutex.lock + wait.lock + end + + # avoid race on mutex.lock + Thread.pass until mutex.locked? + Thread.pass while th.status and th.status != "sleep" + + lambda { mutex.unlock }.should raise_error(ThreadError) + + wait.unlock + th.join + end + + it "raises ThreadError if previously locking thread is gone" do + mutex = Mutex.new + th = Thread.new do + mutex.lock + end + + th.join + + lambda { mutex.unlock }.should raise_error(ThreadError) + end +end |