async-container
async-container copied to clipboard
Specs fail against TruffleRuby
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.
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.
I'm going to migrate the entire test suite to sus anyway, so I'll fix it.
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?
Thank you!
Thanks for raising the issue!