truffleruby
truffleruby copied to clipboard
TracePoint doesn't trigger the :class event within a `sus` test case
The console gem CI fails on TruffleRuby because in a :class event isn't triggered when a new class is declared in a test case.
The simplified example looks like so:
describe Console::Resolver do
it "tests TracePoint in sus" do
resolved = false
trace_point = TracePoint.new(:class) do |event|
resolved = true
end
trace_point.enable
class Foobar
end
puts "resolved -> true " + (resolved ? "[OK]" : "[FAIL]")
end
end
Expected result is:
resolved -> true [OK]
But actual is:
resolved -> true [FAIL]
If run this code as a plain Ruby script then result is expected:
resolved = false
trace_point = TracePoint.new(:class) do |event|
resolved = true
end
trace_point.enable
class Foobar
end
puts "resolved -> true " + (resolved ? "[OK]" : "[FAIL]")
The console gem CI job output:
🤔 Failed assertions:
describe Console::Resolver it triggers when class is defined test/console/resolver.rb:14
expect #<Console::Resolver:0x3238 @names={"Console::Resolver::Foobar"=>#<Proc:0x3258 test/console/resolver.rb:17>}, @trace_point=#<TracePoint:enabled>> to
be waiting?
expect #<Console::Resolver:0x3238 @names={"Console::Resolver::Foobar"=>#<Proc:0x3258 test/console/resolver.rb:17>}, @trace_point=#<TracePoint:enabled>> to not
be waiting?
✗ assertion passed /home/runner/work/console/console/vendor/bundle/truffleruby/3.1.3.23.0.0/gems/sus-0.20.3/lib/sus/assertions.rb:[18](https://github.com/socketry/console/actions/runs/5176976466/jobs/9326492884#step:4:19)3
expect false to
be == true
✗ assertion failed /home/runner/work/console/console/vendor/bundle/truffleruby/3.1.3.23.0.0/gems/sus-0.20.3/lib/sus/assertions.rb:183
https://github.com/socketry/console/actions/runs/5176976466/jobs/9326492884
FYI @ioquatix
From a quick look the sus gem doesn't use TracePoints itself: https://github.com/search?q=repo%3Aioquatix%2Fsus%20TracePoint&type=code
I'll try to investigate this when I have some time.
Related: https://github.com/oracle/truffleruby/issues/2371 Which might solve this, but we should understand why it doesn't work currently first.
sus does not use trace points, but console does to enable logging for classes.
It works like this:
# script.rb
class Foo
def do_something
Console.logger.debug(self, "Do something.")
end
end
Executed as so:
CONSOLE_DEBUG=Foo ruby ./script.rb
The mapping of class names to classes does not exist, so there is a "resolver" which attempts to resolve those strings to actual classes as they are loaded. This avoids using string comparisons of class names.
In any case, the 2nd example in the original report above is completely divorced from both console and sus.
If you think there is a better, more compatible way we could do this, I'd be totally fine to reimplement it.