diff options
Diffstat (limited to 'test/ruby/test_fiber.rb')
| -rw-r--r-- | test/ruby/test_fiber.rb | 87 |
1 files changed, 73 insertions, 14 deletions
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb index 67fef33b85..6976bd9742 100644 --- a/test/ruby/test_fiber.rb +++ b/test/ruby/test_fiber.rb @@ -34,7 +34,6 @@ class TestFiber < Test::Unit::TestCase end def test_many_fibers - skip 'This is unstable on GitHub Actions --jit-wait. TODO: debug it' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? max = 1000 assert_equal(max, max.times{ Fiber.new{} @@ -50,7 +49,7 @@ class TestFiber < Test::Unit::TestCase end def test_many_fibers_with_threads - assert_normal_exit <<-SRC, timeout: (/solaris/i =~ RUBY_PLATFORM ? 300 : 60) + assert_normal_exit <<-SRC, timeout: 60 max = 1000 @cnt = 0 (1..100).map{|ti| @@ -82,12 +81,14 @@ class TestFiber < Test::Unit::TestCase f.resume f.resume } - assert_raise(RuntimeError){ - Fiber.new{ - @c = callcc{|c| @c = c} - }.resume - @c.call # cross fiber callcc - } + if respond_to?(:callcc) + assert_raise(RuntimeError){ + Fiber.new{ + @c = callcc{|c| @c = c} + }.resume + @c.call # cross fiber callcc + } + end assert_raise(RuntimeError){ Fiber.new{ raise @@ -250,6 +251,18 @@ class TestFiber < Test::Unit::TestCase assert_equal(nil, Thread.current[:v]); end + def test_fiber_variables + assert_equal "bar", Fiber.new {Fiber[:foo] = "bar"; Fiber[:foo]}.resume + + key = :"#{self.class.name}#.#{self.object_id}" + Fiber[key] = 42 + assert_equal 42, Fiber[key] + + key = Object.new + def key.to_str; "foo"; end + assert_equal "Bar", Fiber.new {Fiber[key] = "Bar"; Fiber[key]}.resume + end + def test_alive fib = Fiber.new{Fiber.yield} assert_equal(true, fib.alive?) @@ -381,7 +394,7 @@ class TestFiber < Test::Unit::TestCase def test_fork_from_fiber - skip 'fork not supported' unless Process.respond_to?(:fork) + omit 'fork not supported' unless Process.respond_to?(:fork) pid = nil bug5700 = '[ruby-core:41456]' assert_nothing_raised(bug5700) do @@ -396,7 +409,7 @@ class TestFiber < Test::Unit::TestCase Fiber.new {}.transfer Fiber.new { Fiber.yield } end - exit!(0) + exit!(true) end }.transfer _, status = Process.waitpid2(xpid) @@ -405,8 +418,13 @@ class TestFiber < Test::Unit::TestCase end.resume end pid, status = Process.waitpid2(pid) - assert_equal(0, status.exitstatus, bug5700) - assert_equal(false, status.signaled?, bug5700) + assert_not_predicate(status, :signaled?, bug5700) + assert_predicate(status, :success?, bug5700) + + pid = Fiber.new {fork}.resume + pid, status = Process.waitpid2(pid) + assert_not_predicate(status, :signaled?) + assert_predicate(status, :success?) end def test_exit_in_fiber @@ -417,7 +435,7 @@ class TestFiber < Test::Unit::TestCase end def test_fatal_in_fiber - assert_in_out_err(["-r-test-/fatal/rb_fatal", "-e", <<-EOS], "", [], /ok/) + assert_in_out_err(["-r-test-/fatal", "-e", <<-EOS], "", [], /ok/) Fiber.new{ Bug.rb_fatal "ok" }.resume @@ -480,7 +498,7 @@ class TestFiber < Test::Unit::TestCase end def test_machine_stack_gc - assert_normal_exit <<-RUBY, '[Bug #14561]', timeout: 10 + assert_normal_exit <<-RUBY, '[Bug #14561]', timeout: 60 enum = Enumerator.new { |y| y << 1 } thread = Thread.new { enum.peek } thread.join @@ -488,4 +506,45 @@ class TestFiber < Test::Unit::TestCase GC.start RUBY end + + def test_fiber_pool_stack_acquire_failure + environment = { + "RUBY_SHARED_FIBER_POOL_MINIMUM_COUNT" => "0", + "RUBY_SHARED_FIBER_POOL_MAXIMUM_COUNT" => "128" + } + + # This program requires, effectively, at most one fiber stack, since the fiber immediately becomes unreachable. + assert_separately([environment], <<~RUBY, timeout: 30) + GC.disable + count_before = GC.count + + # Create more fibers than the pool can handle (but they become immediately unreachable): + assert_nothing_raised do + 256.times do + Fiber.new{Fiber.yield}.resume + end + end + + # Major GC should have happened at least once: + assert_operator(GC.count, :>, count_before) + RUBY + end + + def test_fiber_pool_stack_acquire_failure_at_maximum_count + environment = { + "RUBY_SHARED_FIBER_POOL_MAXIMUM_COUNT" => "128" + } + + assert_separately([environment], <<~RUBY, timeout: 30) + GC.disable + fibers = [] + assert_raise(FiberError) do + loop do + Fiber.new{fibers << Fiber.current; Fiber.yield}.resume + raise "expected FiberError before this" if fibers.size > 128 + end + end + assert_operator fibers.size, :>=, 128 + RUBY + end end |
