Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ jobs:
gemfile: gems/sqlite3-v2.gemfile
- ruby: 3.4
gemfile: gems/sqlite3-v2.gemfile
- ruby: 4.0
gemfile: gems/sqlite3-v2.gemfile
- ruby: 4.0
prepend: true
gemfile: gems/sqlite3-v2.gemfile
- ruby: 4.0
gemfile: gems/instruments-ruby4.gemfile
test_features: "instruments"
env:
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
SCOUT_TEST_FEATURES: ${{ matrix.test_features }}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Pending

- Ruby 4 support

# 6.0.2
- Fix `endpoint_sample_rate` and `job_sample_rate` to support float values

Expand Down
12 changes: 12 additions & 0 deletions gems/instruments-ruby4.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
eval_gemfile("../Gemfile")

gem 'minitest-mock'
gem 'ostruct'
gem "sqlite3", ">= 2.1"
gem 'httpclient'
gem 'http'
gem 'redis'
gem 'moped'
gem 'actionpack'
gem 'actionview'
gem 'httpx'
1 change: 1 addition & 0 deletions gems/sqlite3-v2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ eval_gemfile("../Gemfile")

gem "sqlite3", ">= 2.1"
gem 'minitest-mock'
gem 'ostruct'
14 changes: 12 additions & 2 deletions lib/scout_apm/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,19 +190,29 @@ def ruby_3?
@ruby_3 = defined?(RUBY_VERSION) && RUBY_VERSION.match(/^3/)
end

def ruby_4?
return @ruby_4 if defined?(@ruby_4)
@ruby_4 = defined?(RUBY_VERSION) && RUBY_VERSION.match(/^4/)
end

def ruby_2_or_above?
ruby_2? || ruby_3? || ruby_4?
end


def ruby_minor
return @ruby_minor if defined?(@ruby_minor)
@ruby_minor = defined?(RUBY_VERSION) && RUBY_VERSION.split(".")[1].to_i
end

# Returns true if this Ruby version supports Module#prepend.
def supports_module_prepend?
ruby_2? || ruby_3?
ruby_2_or_above?
end

# Returns true if this Ruby version makes positional and keyword arguments incompatible
def supports_kwarg_delegation?
ruby_3? || (ruby_2? && ruby_minor >= 7)
ruby_4? || ruby_3? || (ruby_2? && ruby_minor >= 7)
end

# Returns a string representation of the OS (ex: darwin, linux)
Expand Down
2 changes: 1 addition & 1 deletion lib/scout_apm/layer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def capture_backtrace!
# In Ruby 2.0+, we can pass the range directly to the caller to reduce the memory footprint.
def caller_array
# omits the first several callers which are in the ScoutAPM stack.
if ScoutApm::Agent.instance.context.environment.ruby_2? || ScoutApm::Agent.instance.context.environment.ruby_3?
if ScoutApm::Agent.instance.context.environment.ruby_2_or_above?
caller(3...BACKTRACE_CALLER_LIMIT)
else
caller[3...BACKTRACE_CALLER_LIMIT]
Expand Down
4 changes: 3 additions & 1 deletion scout_apm.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Gem::Specification.new do |s|

s.required_ruby_version = '>= 2.1'


s.add_development_dependency "minitest"
s.add_development_dependency "mocha"
s.add_development_dependency "pry"
Expand All @@ -34,10 +35,11 @@ Gem::Specification.new do |s|
# tests. Specific versions are pulled in using specific gemfiles, e.g.
# `gems/rails3.gemfile`.
s.add_development_dependency "activerecord"
s.add_development_dependency "sqlite3", "~> 1.4"
s.add_development_dependency "sqlite3"

s.add_development_dependency "rubocop"
s.add_development_dependency "guard"
s.add_development_dependency "guard-minitest"
s.add_development_dependency "m"

end
5 changes: 4 additions & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ def remove_rails_namespace
def fake_rails(version)
remove_rails_namespace if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")

Kernel.const_set("Rails", Module.new)
Kernel.const_set("Rails", Module.new {
# ActionView 8.1+ StructuredEventSubscriber calls Rails.try(:root)
def self.root; nil; end
})
Kernel.const_set("ActionController", Module.new)
r = Kernel.const_get("Rails")
r.const_set("VERSION", Module.new)
Expand Down
19 changes: 18 additions & 1 deletion test/unit/instruments/action_view_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,22 @@

if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")
require 'test_helper'
require 'action_view'

# Rails 8.1+ ActionView::StructuredEventSubscriber calls Rails.try(:root)
# https://github.com/rails/rails/blob/3ad79fcede4f9b620f03b9fd76507d9fb3c07e95/actionview/lib/action_view/structured_event_subscriber.rb#L67
# which raises NameError if Rails is not defined. Define a minimal stub.
# Maybe this can get fixed at some point.
unless defined?(Rails)
module Rails
def self.root
nil
end
end
end

require 'action_pack'
require 'action_controller'
require 'action_view'

FIXTURE_LOAD_PATH = File.expand_path("fixtures", __dir__)

Expand Down Expand Up @@ -62,6 +75,9 @@ class RenderTest < ActionController::TestCase

def setup
super
# Ensure Rails exists - other tests may have called clean_fake_rails
fake_rails(8)

@controller.logger = ActiveSupport::Logger.new(nil)
ActionView::Base.logger = ActiveSupport::Logger.new(nil)

Expand All @@ -75,6 +91,7 @@ def teardown
ActionView::Base.logger = nil

ActionController::Base.view_paths = @old_view_paths
clean_fake_rails
end

def test_partial_instrumentation
Expand Down