scout_apm 5.3.3 → 5.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +30 -0
- data/.github/workflows/test.yml +18 -16
- data/CHANGELOG.markdown +51 -1
- data/README.markdown +5 -1
- data/gems/instruments.gemfile +2 -0
- data/gems/rails7.gemfile +4 -0
- data/gems/sidekiq7.gemfile +3 -0
- data/gems/sidekiq8.gemfile +4 -0
- data/gems/sqlite3-v2.gemfile +3 -0
- data/lib/scout_apm/agent.rb +1 -1
- data/lib/scout_apm/agent_context.rb +4 -0
- data/lib/scout_apm/app_server_load.rb +1 -1
- data/lib/scout_apm/auto_instrument/layer.rb +1 -0
- data/lib/scout_apm/auto_instrument/rails.rb +21 -0
- data/lib/scout_apm/background_job_integrations/good_job.rb +49 -0
- data/lib/scout_apm/background_job_integrations/resque.rb +13 -27
- data/lib/scout_apm/background_job_integrations/sidekiq.rb +22 -2
- data/lib/scout_apm/background_job_integrations/solid_queue.rb +47 -0
- data/lib/scout_apm/config.rb +69 -34
- data/lib/scout_apm/environment.rb +2 -0
- data/lib/scout_apm/error_service/sidekiq.rb +1 -1
- data/lib/scout_apm/git_revision.rb +7 -1
- data/lib/scout_apm/instruments/action_view.rb +62 -3
- data/lib/scout_apm/instruments/active_record.rb +1 -1
- data/lib/scout_apm/instruments/grape.rb +1 -1
- data/lib/scout_apm/instruments/mongoid.rb +7 -35
- data/lib/scout_apm/instruments/net_http.rb +1 -1
- data/lib/scout_apm/instruments/resque.rb +31 -2
- data/lib/scout_apm/layer_converters/external_service_converter.rb +1 -1
- data/lib/scout_apm/layer_converters/request_queue_time_converter.rb +7 -0
- data/lib/scout_apm/sampling.rb +104 -0
- data/lib/scout_apm/slow_request_policy.rb +1 -1
- data/lib/scout_apm/tracked_request.rb +7 -1
- data/lib/scout_apm/utils/installed_gems.rb +2 -1
- data/lib/scout_apm/version.rb +1 -1
- data/lib/scout_apm.rb +3 -0
- data/scout_apm.gemspec +2 -2
- data/test/test_helper.rb +61 -0
- data/test/unit/auto_instrument/hash_shorthand_controller-instrumented.rb +41 -0
- data/test/unit/auto_instrument/hash_shorthand_controller.rb +41 -0
- data/test/unit/auto_instrument_test.rb +7 -1
- data/test/unit/background_job_integrations/sidekiq_test.rb +13 -3
- data/test/unit/config_test.rb +20 -0
- data/test/unit/environment_test.rb +0 -28
- data/test/unit/git_revision_test.rb +65 -3
- data/test/unit/instruments/action_view_test.rb +102 -0
- data/test/unit/instruments/active_record_test.rb +30 -0
- data/test/unit/instruments/fixtures/test/_test_partial.html.erb +3 -0
- data/test/unit/instruments/fixtures/test/_test_partial_collection.html.erb +3 -0
- data/test/unit/instruments/fixtures/test_view.html.erb +10 -0
- data/test/unit/sampling_test.rb +215 -0
- metadata +22 -10
@@ -4,7 +4,7 @@ require 'scout_apm/auto_instrument'
|
|
4
4
|
|
5
5
|
class AutoInstrumentTest < Minitest::Test
|
6
6
|
ROOT = File.expand_path("../../", __dir__)
|
7
|
-
|
7
|
+
|
8
8
|
def source_path(name)
|
9
9
|
File.expand_path("auto_instrument/#{name}.rb", __dir__)
|
10
10
|
end
|
@@ -38,6 +38,12 @@ class AutoInstrumentTest < Minitest::Test
|
|
38
38
|
normalize_backtrace(::ScoutApm::AutoInstrument::Rails.rewrite(source_path("controller")))
|
39
39
|
end
|
40
40
|
|
41
|
+
def test_controller_rewrite_hash_shorthand
|
42
|
+
skip if RUBY_VERSION < "3.1"
|
43
|
+
assert_equal instrumented_source("hash_shorthand_controller"),
|
44
|
+
normalize_backtrace(::ScoutApm::AutoInstrument::Rails.rewrite(source_path("hash_shorthand_controller")))
|
45
|
+
end
|
46
|
+
|
41
47
|
def test_rescue_from_rewrite
|
42
48
|
# update_instrumented_source("rescue_from")
|
43
49
|
|
@@ -18,7 +18,9 @@ class SidekiqTest < Minitest::Test
|
|
18
18
|
def test_starts_on_startup
|
19
19
|
::ScoutApm::Agent.any_instance.expects(:start)
|
20
20
|
SidekiqIntegration.new.install
|
21
|
-
Sidekiq.
|
21
|
+
::Sidekiq.configure_server do |config|
|
22
|
+
config[:lifecycle_events][:startup].map(&:call)
|
23
|
+
end
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -100,13 +102,21 @@ class SidekiqTest < Minitest::Test
|
|
100
102
|
########################################
|
101
103
|
def test_latency_from_created_at
|
102
104
|
# Created at time 80, but now it is 200. Latency was 120
|
103
|
-
msg =
|
105
|
+
msg = if SidekiqMiddleware.sidekiq_version_8?
|
106
|
+
{ 'created_at' => 80000 } # milliseconds for Sidekiq 8+
|
107
|
+
else
|
108
|
+
{ 'created_at' => 80 }
|
109
|
+
end
|
104
110
|
assert_equal 120, SidekiqMiddleware.new.latency(msg, 200)
|
105
111
|
end
|
106
112
|
|
107
113
|
def test_latency_from_enqueued_at
|
108
114
|
# Created at time 80, but now it is 200. Latency was 120
|
109
|
-
msg =
|
115
|
+
msg = if SidekiqMiddleware.sidekiq_version_8?
|
116
|
+
{ 'enqueued_at' => 80000 } # milliseconds for Sidekiq 8+
|
117
|
+
else
|
118
|
+
{ 'enqueued_at' => 80 }
|
119
|
+
end
|
110
120
|
assert_equal 120, SidekiqMiddleware.new.latency(msg, 200)
|
111
121
|
end
|
112
122
|
|
data/test/unit/config_test.rb
CHANGED
@@ -72,6 +72,26 @@ class ConfigTest < Minitest::Test
|
|
72
72
|
assert_equal ["a"], coercion.coerce(["a"])
|
73
73
|
end
|
74
74
|
|
75
|
+
def test_integer_coercion
|
76
|
+
coercion = ScoutApm::Config::IntegerCoercion.new
|
77
|
+
assert_equal 1, coercion.coerce("1")
|
78
|
+
assert_equal 1, coercion.coerce(1)
|
79
|
+
assert_equal 0, coercion.coerce("0")
|
80
|
+
assert_equal 0, coercion.coerce(0)
|
81
|
+
assert_equal 0, coercion.coerce("")
|
82
|
+
assert_equal 0, coercion.coerce(nil)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_nullable_integer_coercion
|
86
|
+
coercion = ScoutApm::Config::NullableIntegerCoercion.new
|
87
|
+
assert_equal 1, coercion.coerce("1")
|
88
|
+
assert_equal 1, coercion.coerce(1)
|
89
|
+
assert_equal 0, coercion.coerce("0")
|
90
|
+
assert_equal 0, coercion.coerce(0)
|
91
|
+
assert_equal 0, coercion.coerce("")
|
92
|
+
assert_nil coercion.coerce(nil)
|
93
|
+
end
|
94
|
+
|
75
95
|
def test_any_keys_found
|
76
96
|
ENV.stubs(:has_key?).returns(nil)
|
77
97
|
|
@@ -29,32 +29,4 @@ class EnvironmentTest < Minitest::Test
|
|
29
29
|
def test_framework_ruby
|
30
30
|
assert_equal :ruby, ScoutApm::Environment.send(:new).framework
|
31
31
|
end
|
32
|
-
|
33
|
-
############################################################
|
34
|
-
|
35
|
-
def fake_rails(version)
|
36
|
-
Kernel.const_set("Rails", Module.new)
|
37
|
-
Kernel.const_set("ActionController", Module.new)
|
38
|
-
r = Kernel.const_get("Rails")
|
39
|
-
r.const_set("VERSION", Module.new)
|
40
|
-
v = r.const_get("VERSION")
|
41
|
-
v.const_set("MAJOR", version)
|
42
|
-
|
43
|
-
assert_equal version, Rails::VERSION::MAJOR
|
44
|
-
end
|
45
|
-
|
46
|
-
def clean_fake_rails
|
47
|
-
Kernel.send(:remove_const, "Rails") if defined?(Kernel::Rails)
|
48
|
-
Kernel.send(:remove_const, "ActionController") if defined?(Kernel::ActionController)
|
49
|
-
end
|
50
|
-
|
51
|
-
def fake_sinatra
|
52
|
-
Kernel.const_set("Sinatra", Module.new)
|
53
|
-
s = Kernel.const_get("Sinatra")
|
54
|
-
s.const_set("Base", Module.new)
|
55
|
-
end
|
56
|
-
|
57
|
-
def clean_fake_sinatra
|
58
|
-
Kernel.const_unset("Sinatra") if defined?(Kernel::Sinatra)
|
59
|
-
end
|
60
32
|
end
|
@@ -3,13 +3,75 @@ require 'test_helper'
|
|
3
3
|
require 'scout_apm/git_revision'
|
4
4
|
|
5
5
|
class GitRevisionTest < Minitest::Test
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def setup
|
7
|
+
@env = ENV.to_h
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
ENV.replace(@env)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_sha_detected_once
|
15
|
+
ENV['HEROKU_SLUG_COMMIT'] = 'initial_slug'
|
16
|
+
revision = ScoutApm::GitRevision.new(ScoutApm::AgentContext.new)
|
17
|
+
assert_equal 'initial_slug', revision.sha
|
18
|
+
|
19
|
+
ENV['HEROKU_SLUG_COMMIT'] = 'new_slug'
|
20
|
+
assert_equal 'initial_slug', revision.sha
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_sha_from_config
|
24
|
+
config = make_fake_config('revision_sha' => 'config_sha')
|
25
|
+
context = ScoutApm::AgentContext.new().tap { |c| c.config = config }
|
26
|
+
revision = ScoutApm::GitRevision.new(context)
|
27
|
+
|
28
|
+
assert_equal 'config_sha', revision.sha
|
29
|
+
end
|
9
30
|
|
10
31
|
def test_sha_from_heroku
|
11
32
|
ENV['HEROKU_SLUG_COMMIT'] = 'heroku_slug'
|
12
33
|
revision = ScoutApm::GitRevision.new(ScoutApm::AgentContext.new)
|
13
34
|
assert_equal 'heroku_slug', revision.sha
|
14
35
|
end
|
36
|
+
|
37
|
+
def test_sha_from_capistrano
|
38
|
+
Dir.mktmpdir do |dir|
|
39
|
+
context = context_with_file_in_root(File.join(dir, 'REVISION'), 'capistrano_sha')
|
40
|
+
revision = ScoutApm::GitRevision.new(context)
|
41
|
+
assert_equal 'capistrano_sha', revision.sha
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_sha_from_kamal
|
46
|
+
ENV['KAMAL_VERSION'] = 'kamal_sha'
|
47
|
+
revision = ScoutApm::GitRevision.new(ScoutApm::AgentContext.new)
|
48
|
+
assert_equal 'kamal_sha', revision.sha
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def test_sha_from_mina
|
53
|
+
Dir.mktmpdir do |dir|
|
54
|
+
context = context_with_file_in_root(File.join(dir, '.mina_git_revision'), 'mina_sha')
|
55
|
+
revision = ScoutApm::GitRevision.new(context)
|
56
|
+
assert_equal 'mina_sha', revision.sha
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_sha_from_git
|
61
|
+
short_sha = `git rev-parse --short HEAD`.strip
|
62
|
+
skip 'git not installed or not in a git repository' if short_sha.empty?
|
63
|
+
|
64
|
+
revision = ScoutApm::GitRevision.new(ScoutApm::AgentContext.new)
|
65
|
+
assert_equal short_sha, revision.sha
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def context_with_file_in_root(file_name, contents)
|
71
|
+
config = make_fake_config({})
|
72
|
+
env = make_fake_environment(root: File.dirname(file_name))
|
73
|
+
File.write(file_name, contents)
|
74
|
+
|
75
|
+
ScoutApm::AgentContext.new().tap { |c| c.config = config; c.environment = env }
|
76
|
+
end
|
15
77
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# Most of this was taken from Rails:
|
2
|
+
# https://github.com/rails/rails/blob/v7.1.3/actionview/test/actionpack/controller/render_test.rb
|
3
|
+
# https://github.com/rails/rails/blob/v7.1.3/actionview/test/abstract_unit.rb
|
4
|
+
|
5
|
+
if (ENV["SCOUT_TEST_FEATURES"] || "").include?("instruments")
|
6
|
+
require 'test_helper'
|
7
|
+
require 'action_view'
|
8
|
+
require 'action_pack'
|
9
|
+
require 'action_controller'
|
10
|
+
|
11
|
+
FIXTURE_LOAD_PATH = File.expand_path("fixtures", __dir__)
|
12
|
+
|
13
|
+
include ActionView::Context
|
14
|
+
include ActionView::Helpers::TagHelper
|
15
|
+
include ActionView::Helpers::TextHelper
|
16
|
+
|
17
|
+
module ActionController
|
18
|
+
|
19
|
+
class Base
|
20
|
+
self.view_paths = FIXTURE_LOAD_PATH
|
21
|
+
|
22
|
+
def self.test_routes(&block)
|
23
|
+
routes = ActionDispatch::Routing::RouteSet.new
|
24
|
+
routes.draw(&block)
|
25
|
+
include routes.url_helpers
|
26
|
+
routes
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class TestCase
|
31
|
+
include ActionDispatch::TestProcess
|
32
|
+
|
33
|
+
def self.with_routes(&block)
|
34
|
+
routes = ActionDispatch::Routing::RouteSet.new
|
35
|
+
routes.draw(&block)
|
36
|
+
include Module.new {
|
37
|
+
define_method(:setup) do
|
38
|
+
super()
|
39
|
+
@routes = routes
|
40
|
+
@controller.singleton_class.include @routes.url_helpers if @controller
|
41
|
+
end
|
42
|
+
}
|
43
|
+
routes
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class TestController < ActionController::Base
|
49
|
+
|
50
|
+
def render_test_view
|
51
|
+
render template: "test_view"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class RenderTest < ActionController::TestCase
|
56
|
+
|
57
|
+
tests TestController
|
58
|
+
|
59
|
+
with_routes do
|
60
|
+
get :render_test_view, to: "test#render_test_view"
|
61
|
+
end
|
62
|
+
|
63
|
+
def setup
|
64
|
+
super
|
65
|
+
@controller.logger = ActiveSupport::Logger.new(nil)
|
66
|
+
ActionView::Base.logger = ActiveSupport::Logger.new(nil)
|
67
|
+
|
68
|
+
@request.host = "www.scoutapm.com"
|
69
|
+
|
70
|
+
@old_view_paths = ActionController::Base.view_paths
|
71
|
+
ActionController::Base.view_paths = FIXTURE_LOAD_PATH
|
72
|
+
end
|
73
|
+
|
74
|
+
def teardown
|
75
|
+
ActionView::Base.logger = nil
|
76
|
+
|
77
|
+
ActionController::Base.view_paths = @old_view_paths
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_partial_instrumentation
|
81
|
+
recorder = FakeRecorder.new
|
82
|
+
agent_context.recorder = recorder
|
83
|
+
|
84
|
+
instrument = ScoutApm::Instruments::ActionView.new(agent_context)
|
85
|
+
instrument.install(prepend: true)
|
86
|
+
|
87
|
+
get :render_test_view
|
88
|
+
assert_response :success
|
89
|
+
|
90
|
+
root_layer = recorder.requests.first.root_layer
|
91
|
+
children = root_layer.children.to_a
|
92
|
+
assert_equal 2, children.size
|
93
|
+
|
94
|
+
partial_layer = children[0]
|
95
|
+
collection_layer = children[1]
|
96
|
+
|
97
|
+
assert_equal "test_view/Rendering", root_layer.name
|
98
|
+
assert_equal "test/_test_partial/Rendering", partial_layer.name
|
99
|
+
assert_equal "test/_test_partial_collection/Rendering", collection_layer.name
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -24,6 +24,36 @@ class ActiveRecordTest < Minitest::Test
|
|
24
24
|
class User < ActiveRecord::Base
|
25
25
|
end
|
26
26
|
|
27
|
+
class DumbRailsConfig
|
28
|
+
def self.after_initialize; end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_old_rails_initialization
|
32
|
+
recorder = FakeRecorder.new
|
33
|
+
agent_context.recorder = recorder
|
34
|
+
old_rails_version = (1..2).to_a.sample
|
35
|
+
fake_rails(old_rails_version)
|
36
|
+
|
37
|
+
::Rails.expects(:configuration).never
|
38
|
+
|
39
|
+
instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
|
40
|
+
instrument.install(prepend: false)
|
41
|
+
clean_fake_rails
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_modern_rails_initialization
|
45
|
+
recorder = FakeRecorder.new
|
46
|
+
agent_context.recorder = recorder
|
47
|
+
modern_rails_version = (3..7).to_a.sample
|
48
|
+
fake_rails(modern_rails_version)
|
49
|
+
|
50
|
+
::Rails.expects(:configuration).returns(DumbRailsConfig).once
|
51
|
+
|
52
|
+
instrument = ScoutApm::Instruments::ActiveRecord.new(agent_context)
|
53
|
+
instrument.install(prepend: false)
|
54
|
+
clean_fake_rails
|
55
|
+
end
|
56
|
+
|
27
57
|
def test_instrumentation
|
28
58
|
recorder = FakeRecorder.new
|
29
59
|
agent_context.recorder = recorder
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'scout_apm/sampling'
|
4
|
+
|
5
|
+
class SamplingTest < Minitest::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@global_sample_config = FakeConfigOverlay.new(
|
9
|
+
{
|
10
|
+
'sample_rate' => 80,
|
11
|
+
}
|
12
|
+
)
|
13
|
+
|
14
|
+
@individual_config = FakeConfigOverlay.new(
|
15
|
+
{
|
16
|
+
'sample_endpoints' => ['/foo/bar:100', '/foo:50', '/bar/zap:80'],
|
17
|
+
'ignore_endpoints' => ['/baz'],
|
18
|
+
'sample_jobs' => ['joba:50'],
|
19
|
+
'ignore_jobs' => 'jobb,jobc',
|
20
|
+
}
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_individual_sample_to_hash
|
25
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
26
|
+
assert_equal({'/foo/bar' => 100, '/foo' => 50, '/bar/zap' => 80}, sampling.individual_sample_to_hash(@individual_config.value('sample_endpoints')))
|
27
|
+
|
28
|
+
sampling = ScoutApm::Sampling.new(@global_sample_config)
|
29
|
+
assert_nil sampling.individual_sample_to_hash(@global_sample_config.value('sample_endpoints'))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_uri_ignore
|
33
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
34
|
+
assert_equal true, sampling.ignore_uri?('/baz/bap')
|
35
|
+
assert_equal false, sampling.ignore_uri?('/foo/far')
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_uri_sample
|
39
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
40
|
+
rate = sampling.web_sample_rate('/foo/far')
|
41
|
+
assert_equal 50, rate
|
42
|
+
|
43
|
+
rate = sampling.web_sample_rate('/bar')
|
44
|
+
assert_nil rate
|
45
|
+
|
46
|
+
rate = sampling.web_sample_rate('/baz/bap')
|
47
|
+
assert_nil rate
|
48
|
+
|
49
|
+
rate = sampling.web_sample_rate('/foo/bar/baz')
|
50
|
+
assert_equal 100, rate
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_job_ignore
|
54
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
55
|
+
assert_equal true, sampling.ignore_job?('jobb')
|
56
|
+
assert_equal false, sampling.ignore_job?('joba')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_job_sample
|
60
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
61
|
+
assert_equal 50, sampling.job_sample_rate('joba')
|
62
|
+
assert_nil sampling.job_sample_rate('jobb')
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_sample
|
66
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
67
|
+
sampling.stub(:rand, 0.01) do
|
68
|
+
assert_equal(false, sampling.sample?(50))
|
69
|
+
end
|
70
|
+
sampling.stub(:rand, 0.99) do
|
71
|
+
assert_equal(true, sampling.sample?(50))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_old_ignore
|
76
|
+
config = FakeConfigOverlay.new({'ignore' => ['/foo', '/bar']})
|
77
|
+
sampling = ScoutApm::Sampling.new(config)
|
78
|
+
assert_equal true, sampling.ignore_uri?('/foo')
|
79
|
+
assert_equal true, sampling.ignore_uri?('/bar/bap')
|
80
|
+
assert_equal false, sampling.ignore_uri?('/baz')
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_web_request_individual_sampling
|
84
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
85
|
+
|
86
|
+
# should be ignored
|
87
|
+
transaction = FakeTrackedRequest.new_web_request('/baz/bap')
|
88
|
+
assert_equal true, sampling.drop_request?(transaction)
|
89
|
+
|
90
|
+
# should be kept
|
91
|
+
transaction = FakeTrackedRequest.new_web_request('/faz/bap')
|
92
|
+
assert_equal false, sampling.drop_request?(transaction)
|
93
|
+
|
94
|
+
transaction = FakeTrackedRequest.new_web_request('/foo/far')
|
95
|
+
sampling.stub(:rand, 0.01) do
|
96
|
+
assert_equal false, sampling.drop_request?(transaction)
|
97
|
+
end
|
98
|
+
|
99
|
+
# passes individual sample but caught by global rate
|
100
|
+
sampling.stub(:rand, 0.99) do
|
101
|
+
assert_equal true, sampling.drop_request?(transaction)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_web_reqeust_general_sampling
|
106
|
+
config = FakeConfigOverlay.new(@individual_config.values.merge({'endpoint_sample_rate' => 80}))
|
107
|
+
sampling = ScoutApm::Sampling.new(config)
|
108
|
+
|
109
|
+
transaction = FakeTrackedRequest.new_web_request('/foo/far')
|
110
|
+
transaction2 = FakeTrackedRequest.new_web_request('/ooo/oar')
|
111
|
+
# /foo/far sampled at 50 specifically, /ooo/oar caught by general endpoint rate of 80
|
112
|
+
sampling.stub(:rand, 0.01) do
|
113
|
+
assert_equal false, sampling.drop_request?(transaction)
|
114
|
+
assert_equal false, sampling.drop_request?(transaction2)
|
115
|
+
end
|
116
|
+
|
117
|
+
sampling.stub(:rand, 0.70) do
|
118
|
+
assert_equal true, sampling.drop_request?(transaction)
|
119
|
+
assert_equal false, sampling.drop_request?(transaction2)
|
120
|
+
end
|
121
|
+
|
122
|
+
sampling.stub(:rand, 0.99) do
|
123
|
+
assert_equal true, sampling.drop_request?(transaction)
|
124
|
+
assert_equal true, sampling.drop_request?(transaction2)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_web_request_with_global_sampling
|
129
|
+
config = FakeConfigOverlay.new(@individual_config.values.merge({'sample_rate' => 20}))
|
130
|
+
sampling = ScoutApm::Sampling.new(config)
|
131
|
+
|
132
|
+
# caught by individual rate
|
133
|
+
transaction = FakeTrackedRequest.new_web_request('/foo/far')
|
134
|
+
sampling.stub(:rand, 0.01) do
|
135
|
+
assert_equal false, sampling.drop_request?(transaction)
|
136
|
+
end
|
137
|
+
|
138
|
+
# passes individual rate (50) but caught by global rate (20)
|
139
|
+
sampling.stub(:rand, 0.30) do
|
140
|
+
assert_equal false, sampling.drop_request?(transaction)
|
141
|
+
end
|
142
|
+
|
143
|
+
# passes individual rate
|
144
|
+
sampling.stub(:rand, 0.99) do
|
145
|
+
assert_equal true, sampling.drop_request?(transaction)
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_job_request_individual_sampling
|
151
|
+
sampling = ScoutApm::Sampling.new(@individual_config)
|
152
|
+
|
153
|
+
# should be ignored
|
154
|
+
transaction = FakeTrackedRequest.new_job_request('jobb')
|
155
|
+
assert_equal true, sampling.drop_request?(transaction)
|
156
|
+
|
157
|
+
# should be kept
|
158
|
+
transaction = FakeTrackedRequest.new_job_request('jobz')
|
159
|
+
assert_equal false, sampling.drop_request?(transaction)
|
160
|
+
|
161
|
+
# should be sampled if rand > 50
|
162
|
+
transaction = FakeTrackedRequest.new_job_request('joba')
|
163
|
+
sampling.stub(:rand, 0.01) do
|
164
|
+
assert_equal false, sampling.drop_request?(transaction)
|
165
|
+
end
|
166
|
+
|
167
|
+
sampling.stub(:rand, 0.99) do
|
168
|
+
assert_equal true, sampling.drop_request?(transaction)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_job_general_sampling
|
173
|
+
config = FakeConfigOverlay.new(@individual_config.values.merge({'job_sample_rate' => 80}))
|
174
|
+
sampling = ScoutApm::Sampling.new(config)
|
175
|
+
|
176
|
+
transaction = FakeTrackedRequest.new_job_request('joba')
|
177
|
+
transaction2 = FakeTrackedRequest.new_job_request('jobz')
|
178
|
+
# joba sampled at 50 specifically, jobz caught by general job rate of 80
|
179
|
+
sampling.stub(:rand, 0.01) do
|
180
|
+
assert_equal false, sampling.drop_request?(transaction)
|
181
|
+
assert_equal false, sampling.drop_request?(transaction2)
|
182
|
+
end
|
183
|
+
|
184
|
+
sampling.stub(:rand, 0.70) do
|
185
|
+
assert_equal true, sampling.drop_request?(transaction)
|
186
|
+
assert_equal false, sampling.drop_request?(transaction2)
|
187
|
+
end
|
188
|
+
|
189
|
+
sampling.stub(:rand, 0.99) do
|
190
|
+
assert_equal true, sampling.drop_request?(transaction)
|
191
|
+
assert_equal true, sampling.drop_request?(transaction2)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_job_request_global_sampling
|
196
|
+
config = FakeConfigOverlay.new(@individual_config.values.merge({'sample_rate' => 20}))
|
197
|
+
sampling = ScoutApm::Sampling.new(config)
|
198
|
+
|
199
|
+
# caught by individual rate
|
200
|
+
transaction = FakeTrackedRequest.new_job_request('joba')
|
201
|
+
sampling.stub(:rand, 0.01) do
|
202
|
+
assert_equal false, sampling.drop_request?(transaction)
|
203
|
+
end
|
204
|
+
|
205
|
+
# passes individual rate (50) but caught by global rate (20)
|
206
|
+
sampling.stub(:rand, 0.30) do
|
207
|
+
assert_equal false, sampling.drop_request?(transaction)
|
208
|
+
end
|
209
|
+
|
210
|
+
# passes individual rate
|
211
|
+
sampling.stub(:rand, 0.99) do
|
212
|
+
assert_equal true, sampling.drop_request?(transaction)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|