summaryrefslogtreecommitdiff
path: root/trunk/test/ruby/test_fiber.rb
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/test/ruby/test_fiber.rb')
-rw-r--r--trunk/test/ruby/test_fiber.rb164
1 files changed, 164 insertions, 0 deletions
diff --git a/trunk/test/ruby/test_fiber.rb b/trunk/test/ruby/test_fiber.rb
new file mode 100644
index 0000000000..fc9a49919a
--- /dev/null
+++ b/trunk/test/ruby/test_fiber.rb
@@ -0,0 +1,164 @@
+require 'test/unit'
+require 'fiber'
+require 'continuation'
+
+class TestFiber < Test::Unit::TestCase
+ def test_normal
+ f = Fiber.current
+ assert_equal(:ok2,
+ Fiber.new{|e|
+ assert_equal(:ok1, e)
+ Fiber.yield :ok2
+ }.resume(:ok1)
+ )
+ assert_equal([:a, :b], Fiber.new{|a, b| [a, b]}.resume(:a, :b))
+ end
+
+ def test_term
+ assert_equal(:ok, Fiber.new{:ok}.resume)
+ assert_equal([:a, :b, :c, :d, :e],
+ Fiber.new{
+ Fiber.new{
+ Fiber.new{
+ Fiber.new{
+ [:a]
+ }.resume + [:b]
+ }.resume + [:c]
+ }.resume + [:d]
+ }.resume + [:e])
+ end
+
+ def test_many_fibers
+ max = 10000
+ assert_equal(max, max.times{
+ Fiber.new{}
+ })
+ assert_equal(max,
+ max.times{|i|
+ Fiber.new{
+ }.resume
+ }
+ )
+ end
+
+ def test_many_fibers_with_threads
+ max = 1000
+ @cnt = 0
+ (1..100).map{|ti|
+ Thread.new{
+ max.times{|i|
+ Fiber.new{
+ @cnt += 1
+ }.resume
+ }
+ }
+ }.each{|t|
+ t.join
+ }
+ assert_equal(:ok, :ok)
+ end
+
+ def test_error
+ assert_raise(ArgumentError){
+ Fiber.new # Fiber without block
+ }
+ assert_raise(FiberError){
+ f = Fiber.new{}
+ Thread.new{f.resume}.join # Fiber yielding across thread
+ }
+ assert_raise(FiberError){
+ f = Fiber.new{}
+ f.resume
+ f.resume
+ }
+ assert_raise(RuntimeError){
+ f = Fiber.new{
+ @c = callcc{|c| @c = c}
+ }.resume
+ @c.call # cross fiber callcc
+ }
+ assert_raise(RuntimeError){
+ Fiber.new{
+ raise
+ }.resume
+ }
+ assert_raise(FiberError){
+ Fiber.yield
+ }
+ assert_raise(FiberError){
+ fib = Fiber.new{
+ fib.resume
+ }
+ fib.resume
+ }
+ assert_raise(FiberError){
+ fib = Fiber.new{
+ Fiber.new{
+ fib.resume
+ }.resume
+ }
+ fib.resume
+ }
+ end
+
+ def test_return
+ assert_raise(LocalJumpError){
+ Fiber.new do
+ return
+ end.resume
+ }
+ end
+
+ def test_throw
+ assert_raise(ArgumentError){
+ Fiber.new do
+ throw :a
+ end.resume
+ }
+ end
+
+ def test_transfer
+ ary = []
+ f2 = nil
+ f1 = Fiber.new{
+ ary << f2.transfer(:foo)
+ :ok
+ }
+ f2 = Fiber.new{
+ ary << f1.transfer(:baz)
+ :ng
+ }
+ assert_equal(:ok, f1.transfer)
+ assert_equal([:baz], ary)
+ end
+
+ def test_tls
+ #
+ def tvar(var, val)
+ old = Thread.current[var]
+ begin
+ Thread.current[var] = val
+ yield
+ ensure
+ Thread.current[var] = old
+ end
+ end
+
+ fb = Fiber.new {
+ assert_equal(nil, Thread.current[:v]); tvar(:v, :x) {
+ assert_equal(:x, Thread.current[:v]); Fiber.yield
+ assert_equal(:x, Thread.current[:v]); }
+ assert_equal(nil, Thread.current[:v]); Fiber.yield
+ raise # unreachable
+ }
+
+ assert_equal(nil, Thread.current[:v]); tvar(:v,1) {
+ assert_equal(1, Thread.current[:v]); tvar(:v,3) {
+ assert_equal(3, Thread.current[:v]); fb.resume
+ assert_equal(3, Thread.current[:v]); }
+ assert_equal(1, Thread.current[:v]); }
+ assert_equal(nil, Thread.current[:v]); fb.resume
+ assert_equal(nil, Thread.current[:v]);
+ end
+end
+