|
15 | 15 | let(:metric_values) { {"cpu-time" => 123, "cpu-samples" => 456, "wall-time" => 789} } |
16 | 16 | let(:labels) { {"label_a" => "value_a", "label_b" => "value_b", "state" => "unknown"}.to_a } |
17 | 17 |
|
18 | | - let(:raw_reference_stack) { stacks.fetch(:reference) } |
19 | | - let(:reference_stack) { convert_reference_stack(raw_reference_stack) } |
20 | | - let(:gathered_stack) { stacks.fetch(:gathered) } |
| 18 | + let(:raw_reference_stack) { stacks.fetch(:reference).freeze } |
| 19 | + let(:reference_stack) { convert_reference_stack(raw_reference_stack).freeze } |
| 20 | + let(:gathered_stack) { stacks.fetch(:gathered).freeze } |
21 | 21 | let(:native_filenames_enabled) { false } |
22 | 22 |
|
23 | 23 | def sample(thread, recorder_instance, metric_values_hash, labels_array, **options) |
@@ -220,7 +220,35 @@ def call_sleep |
220 | 220 |
|
221 | 221 | # I opted to join these two expects to avoid running the `load` above more than once |
222 | 222 | it "matches the Ruby backtrace API AND has a sleeping frame at the top of the stack" do |
223 | | - expect(gathered_stack).to eq reference_stack |
| 223 | + if RUBY_VERSION.start_with?("4.") |
| 224 | + # In Ruby 4, due to https://bugs.ruby-lang.org/issues/20968 while internally Integer#times has the path |
| 225 | + # `<internal:numeric>` (and this is what the profiler observes), Ruby actually hides this and "blames" it |
| 226 | + # on the last ruby file/line that was on the stack. |
| 227 | + # |
| 228 | + # @ivoanjo: At this point I'm not sure we want to match that behavior as we don't match it either when |
| 229 | + # using the "native filenames" feature. So for now we adjust the assertions to account for that |
| 230 | + unmatched_indexes = |
| 231 | + reference_stack.each_with_index.select { |frame, index| frame.base_label == "times" }.map(&:last) |
| 232 | + expect(unmatched_indexes).to_not be_empty |
| 233 | + |
| 234 | + gathered_stack_without_unmatched = gathered_stack.dup |
| 235 | + reference_stack_without_unmatched = reference_stack.dup |
| 236 | + |
| 237 | + # Check the expected frames are different -- and remove them from the match |
| 238 | + unmatched_indexes.sort.reverse_each do |index| |
| 239 | + expect(gathered_stack[index].path).to eq "<internal:numeric>" |
| 240 | + expect(reference_stack[index].path).to end_with "/interesting_backtrace_helper.rb" |
| 241 | + |
| 242 | + gathered_stack_without_unmatched.delete_at(index) |
| 243 | + reference_stack_without_unmatched.delete_at(index) |
| 244 | + end |
| 245 | + |
| 246 | + # ...match the rest of the frames |
| 247 | + expect(gathered_stack_without_unmatched).to eq reference_stack_without_unmatched |
| 248 | + else |
| 249 | + expect(gathered_stack).to eq reference_stack |
| 250 | + end |
| 251 | + |
224 | 252 | expect(reference_stack.first.base_label).to eq "sleep" |
225 | 253 | end |
226 | 254 | end |
|
0 commit comments