async-container icon indicating copy to clipboard operation
async-container copied to clipboard

Specs fail against TruffleRuby

Open andrykonchin opened this issue 3 years ago • 2 comments

Specs fail on CI against TruffleRuby (example) with the following error:

1) Async::Container::Forked behaves like Async::Container should be blocking
     Failure/Error:
       ::Process.fork do
       	Signal.trap(:INT) {raise Interrupt}
       	Signal.trap(:TERM) {raise Terminate}
       	
       	begin
       		yield Instance.for(process)
       	rescue Interrupt
       		# Graceful exit.
       	rescue Exception => error
       		Console.logger.error(self) {error}

     NotImplementedError:
       fork is not available
     Shared Example Group: Async::Container called from ./spec/async/container/forked_spec.rb:31
     # ./lib/async/container/process.rb:85:in `block in fork'
     # ./lib/async/container/process.rb:121:in `initialize'
     # ./lib/async/container/process.rb:[84](https://github.com/socketry/async-container/actions/runs/3212002629/jobs/5250556841#step:4:85):in `fork'
     # ./lib/async/container/forked.rb:39:in `start'
     # ./lib/async/container/generic.rb:166:in `block in spawn'
     # ./lib/async/container/generic.rb:164:in `resume'
     # ./lib/async/container/generic.rb:164:in `spawn'
     # ./spec/async/container/shared_examples.rb:54:in `block (2 levels) in <top (required)>'

Looks like the issue is cased by nesting of RSpec metadata key if.

TruffleRuby doesn't support fork so it makes sense not to run such specs at all. Actually they are disabled by RSpec metadata if: Async::Container.fork? so any spec but the failed one isn't run on CI.

The failed spec has its own metadata and overrides the if-condition that leads to running this particular test case.

# spec/async/container/forked_spec.rb

RSpec.describe Async::Container::Forked, if: Async::Container.fork? do
	it_behaves_like Async::Container
end
# spec/async/container/shared_examples.rb

RSpec.shared_examples_for Async::Container do
	it "should be blocking", if: Fiber.respond_to?(:blocking?) do
		# ...
	end
end

What is a proper way to fix the issue from your point of view? Nesting if metadata-keys doesn't work but replacing it with plain old Ruby if-expression looks ugly to me.

andrykonchin avatar Oct 11 '22 13:10 andrykonchin

In FFI specs I just used a plain Ruby if because I find RSpec's if: impossible to understand and never doing what I want.

eregon avatar Oct 12 '22 16:10 eregon

I'm going to migrate the entire test suite to sus anyway, so I'll fix it.

ioquatix avatar Oct 12 '22 19:10 ioquatix

Hello. The tests were migrated to sus recently. But it seems they still fail on TruffleRuby (CI build logs). The issue is caused by using top-level return:

https://github.com/socketry/async-container/blob/11bee9de5558d3b2e1a4e49c6e9791850a845358/test/async/container/forked.rb#L12

TruffleRuby doesn't support combination of top-level return and class_eval yet and it's a known issue. Is it OK to work around and skip the tests in some other way?

For instance with

if Async::Container.fork?
  describe Async::Container::Forked do
  end
end

or

describe Async::Container::Forked do
end if Async::Container.fork?

andrykonchin avatar Nov 07 '22 11:11 andrykonchin

Thank you!

andrykonchin avatar Nov 11 '22 10:11 andrykonchin

Thanks for raising the issue!

ioquatix avatar Nov 11 '22 21:11 ioquatix