Closed agrare closed 2 months ago
cc @kbrock
@kbrock @jrafanie I figured out a simple reproducer for (part of) this:
SPEC_OPTS="--seed 3896" be rspec spec/models/mixins/supports_feature_mixin_spec.rb spec/models/blacklisted_event_spec.rb
irb # not rails console
class A ; end # => nil
class B < A ; end #=> nil
Object.send(:remove_const, :B) #=> B
B # uninitialized constant B (NameError)
A.subclasses.first # => B
A.subclasses.reject! { |x| x.name == "B" }
A.subclasses.first # => B
This was introduced to ruby 3.1, and the changes were incorporated in the rails 7.0 DependencyTracker.
So depending upon the version of ruby running, DependencyTracker#subclasses
can simply point to Class#subclasses
.
Only 1 spec is causing this issue: supports_feature_mixin_spec.rb:318
I'm looking through the ruby code to see if there is a way to call the internal rb_class_remove_from_super_subclasses
of note, rspec has https://github.com/rspec/rspec-mocks/issues/1568 which states the same problem. When I find a solution, I'll share with them.
DescendantsTracker documents it, but doesn't really say if and when it will be used https://api.rubyonrails.org/classes/ActiveSupport/DescendantsTracker.html
This module provides an internal implementation to track descendants which is faster than iterating through ObjectSpace.
However Ruby 3.1 provide a fast native +Class#subclasses+ method, so if you know your code won’t be executed on older rubies, including ActiveSupport::DescendantsTracker does not provide any benefit.
Well, descendants_tracker.rb is pretty clear:
module ActiveSupport
# This module provides an internal implementation to track descendants
# which is faster than iterating through ObjectSpace.
module DescendantsTracker
if RubyFeatures::CLASS_SUBCLASSES # RUBY_VERSION >= "3.1"
# [...]
class << self
#[...]
def subclasses(klass)
klass.subclasses
end
def descendants(klass) # think this is deprecated
klass.descendants
end
end
end
end
end
I was getting sporadic results when calling 3.times { GC.start }
.
Sometimes subclasses
returns the class and other times does not.
Adding in a sleep(1) ; GC.start
sometimes fixed this, other times it did not.
I converted over to manually adding and removing the objects and even running these tests from pure ruby with no rails or miq patches in place. Got the same results.
So my current solution is to change the temporary ExtManagementSystem
defined returned so it doesn't break the other tests.
There appear to be some sporadic test failures between supports_feature_mixin_spec and a number of other specs which test
ExtManagementSystem
classes.All of these failures reference
ProviderA::ExtManagementSystem:Class
and I only seeProviderA
inspec/models/mixins/supports_feature_mixin_spec.rb
[ref]