newrelic_rpm 3.6.0.83 → 3.6.1.85.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +27 -0
- data/Gemfile +2 -7
- data/README.md +1 -1
- data/lib/new_relic/agent/agent.rb +3 -2
- data/lib/new_relic/agent/autostart.rb +56 -0
- data/lib/new_relic/agent/browser_monitoring.rb +19 -14
- data/lib/new_relic/agent/configuration/defaults.rb +12 -2
- data/lib/new_relic/agent/configuration/environment_source.rb +4 -1
- data/lib/new_relic/agent/cross_app_monitor.rb +2 -1
- data/lib/new_relic/agent/cross_app_tracing.rb +19 -10
- data/lib/new_relic/agent/error_collector.rb +5 -4
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +204 -0
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +88 -0
- data/lib/new_relic/agent/instrumentation/active_record.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +84 -0
- data/lib/new_relic/agent/instrumentation/browser_monitoring_timings.rb +3 -2
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +104 -87
- data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +91 -0
- data/lib/new_relic/agent/instrumentation/memcache.rb +4 -4
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +4 -4
- data/lib/new_relic/agent/instrumentation/rack.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +20 -20
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +5 -5
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +3 -3
- data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +3 -25
- data/lib/new_relic/agent/instrumentation/rails4/action_view.rb +2 -115
- data/lib/new_relic/agent/instrumentation/rails4/active_record.rb +2 -82
- data/lib/new_relic/agent/instrumentation/rails4/errors.rb +3 -4
- data/lib/new_relic/agent/method_tracer.rb +93 -56
- data/lib/new_relic/agent/null_logger.rb +6 -0
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +9 -4
- data/lib/new_relic/agent/sql_sampler.rb +10 -6
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +19 -3
- data/lib/new_relic/agent/stats_engine/transactions.rb +53 -34
- data/lib/new_relic/agent/system_info.rb +54 -0
- data/lib/new_relic/agent/thread.rb +2 -2
- data/lib/new_relic/agent/transaction/pop.rb +52 -0
- data/lib/new_relic/agent/transaction.rb +388 -0
- data/lib/new_relic/agent/transaction_info.rb +5 -13
- data/lib/new_relic/agent/transaction_sample_builder.rb +13 -20
- data/lib/new_relic/agent/transaction_sampler.rb +13 -15
- data/lib/new_relic/agent/uri_util.rb +35 -0
- data/lib/new_relic/agent.rb +54 -11
- data/lib/new_relic/build.rb +2 -2
- data/lib/new_relic/control/frameworks/rails.rb +0 -1
- data/lib/new_relic/control/frameworks/rails3.rb +2 -0
- data/lib/new_relic/control/frameworks/rails4.rb +0 -4
- data/lib/new_relic/control/instance_methods.rb +5 -19
- data/lib/new_relic/control/server_methods.rb +2 -0
- data/lib/new_relic/environment_report.rb +4 -34
- data/lib/new_relic/latest_changes.rb +1 -1
- data/lib/new_relic/local_environment.rb +0 -6
- data/lib/new_relic/metric_spec.rb +2 -2
- data/lib/new_relic/rack/error_collector.rb +6 -4
- data/lib/new_relic/transaction_sample.rb +7 -1
- data/lib/new_relic/version.rb +1 -1
- data/lib/newrelic_rpm.rb +2 -2
- data/newrelic.yml +20 -20
- data/test/config/test_control.rb +2 -2
- data/test/multiverse/suites/agent_only/audit_log_test.rb +1 -1
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +0 -2
- data/test/multiverse/suites/agent_only/logging_test.rb +1 -1
- data/test/multiverse/suites/agent_only/marshaling_test.rb +5 -3
- data/test/multiverse/suites/agent_only/rename_rule_test.rb +2 -0
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +96 -0
- data/test/multiverse/suites/agent_only/testing_app.rb +1 -0
- data/test/multiverse/suites/rails/error_tracing_test.rb +17 -29
- data/test/multiverse/suites/rails/queue_time_test.rb +8 -2
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +6 -3
- data/test/multiverse/suites/resque/instrumentation_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_error_tracing_test.rb +8 -0
- data/test/new_relic/agent/agent/connect_test.rb +2 -1
- data/test/new_relic/agent/agent/start_test.rb +0 -10
- data/test/new_relic/agent/agent_logger_test.rb +15 -0
- data/test/new_relic/agent/agent_test_controller.rb +6 -2
- data/test/new_relic/agent/agent_test_controller_test.rb +20 -69
- data/test/new_relic/agent/autostart_test.rb +67 -0
- data/test/new_relic/agent/browser_monitoring_test.rb +60 -38
- data/test/new_relic/agent/configuration/environment_source_test.rb +19 -17
- data/test/new_relic/agent/cross_app_monitor_test.rb +8 -0
- data/test/new_relic/agent/error_collector/notice_error_test.rb +0 -5
- data/test/new_relic/agent/error_collector_test.rb +8 -9
- data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +228 -0
- data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +18 -34
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +5 -5
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +8 -9
- data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +24 -38
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +126 -178
- data/test/new_relic/agent/instrumentation/rack_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +135 -151
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +153 -81
- data/test/new_relic/agent/method_tracer_test.rb +42 -33
- data/test/new_relic/agent/mock_scope_listener.rb +4 -4
- data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -2
- data/test/new_relic/agent/rpm_agent_test.rb +86 -89
- data/test/new_relic/agent/sql_sampler_test.rb +18 -19
- data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +5 -8
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +20 -8
- data/test/new_relic/agent/stats_engine/samplers_test.rb +31 -14
- data/test/new_relic/agent/stats_engine_test.rb +53 -60
- data/test/new_relic/agent/thread_test.rb +7 -7
- data/test/new_relic/agent/transaction/pop_test.rb +96 -0
- data/test/new_relic/agent/transaction_info_test.rb +6 -17
- data/test/new_relic/agent/transaction_sample_builder_test.rb +10 -18
- data/test/new_relic/agent/transaction_sampler_test.rb +80 -75
- data/test/new_relic/agent/{instrumentation/metric_frame_test.rb → transaction_test.rb} +76 -42
- data/test/new_relic/agent/uri_util_test.rb +75 -0
- data/test/new_relic/agent_test.rb +115 -9
- data/test/test_helper.rb +138 -9
- data.tar.gz.sig +0 -0
- metadata +37 -74
- metadata.gz.sig +0 -0
- data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +0 -84
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +0 -353
- data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +0 -175
- data/test/test_contexts.rb +0 -34
@@ -3,158 +3,9 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper'))
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_contexts'))
|
7
6
|
|
8
7
|
class NewRelic::Agent::Instrumentation::TaskInstrumentationTest < Test::Unit::TestCase
|
9
8
|
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
10
|
-
extend TestContexts
|
11
|
-
attr_accessor :agent
|
12
|
-
|
13
|
-
with_running_agent do
|
14
|
-
|
15
|
-
should "run" do
|
16
|
-
run_task_inner 0
|
17
|
-
stat_names = %w[Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0
|
18
|
-
HttpDispatcher
|
19
|
-
Apdex Apdex/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0].sort
|
20
|
-
expected_but_missing = stat_names - @agent.stats_engine.metrics
|
21
|
-
assert_equal 0, expected_but_missing.size, @agent.stats_engine.metrics.map { |n|
|
22
|
-
stat = @agent.stats_engine.get_stats_no_scope(n)
|
23
|
-
"#{'%-26s' % n}: #{stat.call_count} calls"
|
24
|
-
}.join("\n ") + "\nmissing: #{expected_but_missing.inspect}"
|
25
|
-
assert_equal 0, @agent.stats_engine.get_stats_no_scope('Controller').call_count
|
26
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0').call_count
|
27
|
-
end
|
28
|
-
|
29
|
-
should "run_recursive" do
|
30
|
-
run_task_inner(3)
|
31
|
-
assert_equal 1, @agent.stats_engine.lookup_stats(
|
32
|
-
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0',
|
33
|
-
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1').call_count
|
34
|
-
assert_equal 1, @agent.stats_engine.lookup_stats(
|
35
|
-
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1',
|
36
|
-
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_2').call_count
|
37
|
-
assert_equal 1, @agent.stats_engine.lookup_stats(
|
38
|
-
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_2',
|
39
|
-
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_3').call_count
|
40
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0').call_count
|
41
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1').call_count
|
42
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_2').call_count
|
43
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_3').call_count
|
44
|
-
assert_equal 0, @agent.stats_engine.get_stats_no_scope('Controller').call_count
|
45
|
-
end
|
46
|
-
|
47
|
-
should "run_nested" do
|
48
|
-
run_task_outer(3)
|
49
|
-
@agent.stats_engine.metrics.sort.each do |n|
|
50
|
-
stat = @agent.stats_engine.get_stats_no_scope(n)
|
51
|
-
end
|
52
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/outer_task').call_count
|
53
|
-
assert_equal 2, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0').call_count
|
54
|
-
end
|
55
|
-
|
56
|
-
should "reentrancy" do
|
57
|
-
assert_equal 0, NewRelic::Agent::BusyCalculator.busy_count
|
58
|
-
run_task_inner(1)
|
59
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0').call_count
|
60
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1').call_count
|
61
|
-
compare_metrics %w[
|
62
|
-
Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0:Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1
|
63
|
-
Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0
|
64
|
-
Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1
|
65
|
-
], @agent.stats_engine.metrics.grep(/^Controller/)
|
66
|
-
end
|
67
|
-
|
68
|
-
should "transaction" do
|
69
|
-
assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
|
70
|
-
assert_nil @agent.transaction_sampler.last_sample
|
71
|
-
assert_equal @agent.transaction_sampler, @agent.stats_engine.instance_variable_get("@transaction_sampler")
|
72
|
-
run_task_outer(10)
|
73
|
-
assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
|
74
|
-
@agent.stats_engine.metrics.sort.each do |n|
|
75
|
-
stat = @agent.stats_engine.get_stats_no_scope(n)
|
76
|
-
end
|
77
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/outer_task').call_count
|
78
|
-
assert_equal 0, @agent.stats_engine.get_stats_no_scope('Controller').call_count
|
79
|
-
assert_equal 2, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0').call_count
|
80
|
-
assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
|
81
|
-
sample = @agent.transaction_sampler.last_sample
|
82
|
-
assert_not_nil sample
|
83
|
-
assert_not_nil sample.params[:custom_params][:cpu_time], "cpu time nil: \n#{sample}"
|
84
|
-
assert sample.params[:custom_params][:cpu_time] >= 0, "cpu time: #{sample.params[:cpu_time]},\n#{sample}"
|
85
|
-
assert_equal '10', sample.params[:request_params][:level]
|
86
|
-
end
|
87
|
-
|
88
|
-
should "abort" do
|
89
|
-
@acct = 'Redrocks'
|
90
|
-
perform_action_with_newrelic_trace(:name => 'hello', :force => true, :params => { :account => @acct}) do
|
91
|
-
self.class.inspect
|
92
|
-
NewRelic::Agent.abort_transaction!
|
93
|
-
end
|
94
|
-
# We record the controller metric still, but abort any transaction recording.
|
95
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/hello').call_count
|
96
|
-
assert_nil @agent.transaction_sampler.last_sample
|
97
|
-
end
|
98
|
-
should "block" do
|
99
|
-
assert_equal @agent, NewRelic::Agent.instance
|
100
|
-
@acct = 'Redrocks'
|
101
|
-
perform_action_with_newrelic_trace(:name => 'hello', :force => true, :params => { :account => @acct}) do
|
102
|
-
self.class.inspect
|
103
|
-
end
|
104
|
-
@agent.stats_engine.metrics.sort.each do |n|
|
105
|
-
stat = @agent.stats_engine.get_stats_no_scope(n)
|
106
|
-
end
|
107
|
-
assert_equal @agent, NewRelic::Agent.instance
|
108
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/hello').call_count
|
109
|
-
sample = @agent.transaction_sampler.last_sample
|
110
|
-
assert_not_nil sample
|
111
|
-
assert_equal 'Redrocks', sample.params[:request_params][:account]
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
should "error_handling" do
|
116
|
-
@agent.error_collector.ignore_error_filter
|
117
|
-
@agent.error_collector.harvest_errors([])
|
118
|
-
@agent.error_collector.expects(:notice_error).once
|
119
|
-
assert_equal @agent.error_collector, NewRelic::Agent.instance.error_collector
|
120
|
-
assert_raise RuntimeError do
|
121
|
-
run_task_exception
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
should "custom_params" do
|
126
|
-
@agent.error_collector.stubs(:enabled).returns(true)
|
127
|
-
@agent.error_collector.ignore_error_filter
|
128
|
-
@agent.error_collector.harvest_errors([])
|
129
|
-
assert_equal @agent.error_collector, NewRelic::Agent.instance.error_collector
|
130
|
-
assert_raise RuntimeError do
|
131
|
-
run_task_exception
|
132
|
-
end
|
133
|
-
errors = @agent.error_collector.harvest_errors([])
|
134
|
-
assert_equal 1, errors.size
|
135
|
-
error = errors.first
|
136
|
-
assert_equal "Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/run_task_exception", error.path
|
137
|
-
assert_not_nil error.params[:stack_trace]
|
138
|
-
assert_not_nil error.params[:custom_params]
|
139
|
-
end
|
140
|
-
|
141
|
-
should "instrument_bg" do
|
142
|
-
run_background_job
|
143
|
-
stat_names = %w[OtherTransaction/Background/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/run_background_job
|
144
|
-
OtherTransaction/Background/all
|
145
|
-
OtherTransaction/all].sort
|
146
|
-
|
147
|
-
expected_but_missing = stat_names - @agent.stats_engine.metrics
|
148
|
-
assert_equal 0, expected_but_missing.size, @agent.stats_engine.metrics.map { |n|
|
149
|
-
stat = @agent.stats_engine.get_stats_no_scope(n)
|
150
|
-
"#{'%-26s' % n}: #{stat.call_count} calls"
|
151
|
-
}.join("\n ") + "\nmissing: #{expected_but_missing.inspect}"
|
152
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('OtherTransaction/all').call_count
|
153
|
-
assert_equal 1, @agent.stats_engine.get_stats_no_scope('OtherTransaction/Background/all').call_count
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
private
|
158
9
|
|
159
10
|
def run_task_inner(n)
|
160
11
|
return if n == 0
|
@@ -181,6 +32,139 @@ class NewRelic::Agent::Instrumentation::TaskInstrumentationTest < Test::Unit::Te
|
|
181
32
|
add_transaction_tracer :run_task_exception
|
182
33
|
add_transaction_tracer :run_task_inner, :name => 'inner_task_#{args[0]}'
|
183
34
|
add_transaction_tracer :run_task_outer, :name => 'outer_task', :params => '{ :level => args[0] }'
|
184
|
-
|
185
|
-
|
35
|
+
add_transaction_tracer :run_background_job, :category => :task
|
36
|
+
|
37
|
+
def setup
|
38
|
+
@agent = NewRelic::Agent.instance
|
39
|
+
@agent.transaction_sampler.reset!
|
40
|
+
@agent.stats_engine.clear_stats
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Tests
|
45
|
+
#
|
46
|
+
|
47
|
+
def test_should_run
|
48
|
+
run_task_inner(0)
|
49
|
+
assert_metrics_recorded_exclusive([
|
50
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0',
|
51
|
+
'Apdex/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0',
|
52
|
+
'HttpDispatcher',
|
53
|
+
'Apdex'
|
54
|
+
])
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_should_handle_single_recursive_invocation
|
58
|
+
run_task_inner(1)
|
59
|
+
assert_metrics_recorded_exclusive(
|
60
|
+
[
|
61
|
+
[
|
62
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0',
|
63
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1'
|
64
|
+
],
|
65
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0',
|
66
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1'
|
67
|
+
],
|
68
|
+
:filter => /^Controller/
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_should_handle_recursive_task_invocations
|
73
|
+
run_task_inner(3)
|
74
|
+
assert_metrics_recorded_exclusive(
|
75
|
+
[
|
76
|
+
[
|
77
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0',
|
78
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1'
|
79
|
+
],
|
80
|
+
[
|
81
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1',
|
82
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_2'
|
83
|
+
],
|
84
|
+
[
|
85
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_2',
|
86
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_3'
|
87
|
+
],
|
88
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0',
|
89
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_1',
|
90
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_2',
|
91
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_3'
|
92
|
+
],
|
93
|
+
:filter => /^Controller/
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_should_handle_nested_task_invocations
|
98
|
+
run_task_outer(3)
|
99
|
+
assert_metrics_recorded({
|
100
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/outer_task' => { :call_count => 1 },
|
101
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0' => { :call_count => 2 }
|
102
|
+
})
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_transaction
|
106
|
+
run_task_outer(10)
|
107
|
+
|
108
|
+
assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
|
109
|
+
assert_metrics_recorded({
|
110
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/outer_task' => { :call_count => 1 },
|
111
|
+
'Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/inner_task_0' => { :call_count => 2 }
|
112
|
+
})
|
113
|
+
assert_metrics_not_recorded(['Controller'])
|
114
|
+
|
115
|
+
sample = @agent.transaction_sampler.last_sample
|
116
|
+
assert_not_nil(sample)
|
117
|
+
assert_not_nil(sample.params[:custom_params][:cpu_time], "cpu time nil: \n#{sample}")
|
118
|
+
assert((sample.params[:custom_params][:cpu_time] >= 0), "cpu time: #{sample.params[:cpu_time]},\n#{sample}")
|
119
|
+
assert_equal('10', sample.params[:request_params][:level])
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_abort_transaction
|
123
|
+
perform_action_with_newrelic_trace(:name => 'hello', :force => true) do
|
124
|
+
self.class.inspect
|
125
|
+
NewRelic::Agent.abort_transaction!
|
126
|
+
end
|
127
|
+
# We record the controller metric still, but abort any transaction recording.
|
128
|
+
assert_metrics_recorded(['Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/hello'])
|
129
|
+
assert_nil(@agent.transaction_sampler.last_sample)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_perform_action_with_newrelic_trace_saves_params
|
133
|
+
account = 'Redrocks'
|
134
|
+
perform_action_with_newrelic_trace(:name => 'hello', :force => true,
|
135
|
+
:params => { :account => account }) do
|
136
|
+
self.class.inspect
|
137
|
+
end
|
138
|
+
|
139
|
+
assert_metrics_recorded(['Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/hello'])
|
140
|
+
sample = @agent.transaction_sampler.last_sample
|
141
|
+
assert_not_nil(sample)
|
142
|
+
assert_equal(account, sample.params[:request_params][:account])
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_errors_are_noticed_and_not_swallowed
|
146
|
+
@agent.error_collector.expects(:notice_error).once
|
147
|
+
assert_raise(RuntimeError) { run_task_exception }
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_error_collector_captures_custom_params
|
151
|
+
@agent.error_collector.harvest_errors([])
|
152
|
+
run_task_exception rescue nil
|
153
|
+
errors = @agent.error_collector.harvest_errors([])
|
154
|
+
|
155
|
+
assert_equal(1, errors.size)
|
156
|
+
error = errors.first
|
157
|
+
assert_equal("Controller/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/run_task_exception", error.path)
|
158
|
+
assert_not_nil(error.params[:stack_trace])
|
159
|
+
assert_not_nil(error.params[:custom_params])
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_instrument_background_job
|
163
|
+
run_background_job
|
164
|
+
assert_metrics_recorded([
|
165
|
+
'OtherTransaction/Background/NewRelic::Agent::Instrumentation::TaskInstrumentationTest/run_background_job',
|
166
|
+
'OtherTransaction/Background/all',
|
167
|
+
'OtherTransaction/all'
|
168
|
+
])
|
169
|
+
end
|
186
170
|
end
|
@@ -7,6 +7,10 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
|
|
7
7
|
require 'new_relic/agent/method_tracer'
|
8
8
|
include NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScoped
|
9
9
|
|
10
|
+
def setup
|
11
|
+
NewRelic::Agent.agent.stats_engine.clear_stats
|
12
|
+
end
|
13
|
+
|
10
14
|
def test_trace_disabled_negative
|
11
15
|
self.expects(:traced?).returns(false)
|
12
16
|
options = {:force => false}
|
@@ -51,36 +55,117 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
|
|
51
55
|
assert_equal NewRelic::Agent.instance, agent_instance
|
52
56
|
end
|
53
57
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
def test_metric_recording_outside_transaction
|
59
|
+
trace_execution_scoped(['foo']) do
|
60
|
+
# meh
|
61
|
+
end
|
62
|
+
assert_metrics_recorded_exclusive(
|
63
|
+
'foo' => { :call_count => 1 }
|
64
|
+
)
|
65
|
+
end
|
58
66
|
|
59
|
-
|
67
|
+
def test_metric_recording_in_root_transaction
|
68
|
+
options = { :transaction => true }
|
69
|
+
self.stubs(:has_parent?).returns(false)
|
60
70
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
]
|
71
|
+
in_transaction('outer') do
|
72
|
+
trace_execution_scoped(['foo', 'bar'], options) do
|
73
|
+
# erm
|
74
|
+
end
|
75
|
+
end
|
67
76
|
|
68
|
-
|
77
|
+
expected_values = { :call_count => 1 }
|
78
|
+
assert_metrics_recorded_exclusive(
|
79
|
+
'foo' => expected_values,
|
80
|
+
'bar' => expected_values
|
81
|
+
)
|
69
82
|
end
|
70
83
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
84
|
+
def test_metric_recording_in_non_root_transaction
|
85
|
+
options = { :transaction => true }
|
86
|
+
self.stubs(:has_parent?).returns(true)
|
87
|
+
in_transaction('outer') do
|
88
|
+
in_transaction('inner') do
|
89
|
+
trace_execution_scoped(['inner', 'bar'], options) do
|
90
|
+
# erm
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
expected_values = { :call_count => 1 }
|
96
|
+
assert_metrics_recorded_exclusive(
|
97
|
+
'inner' => expected_values,
|
98
|
+
['inner', 'outer'] => expected_values,
|
99
|
+
'bar' => expected_values
|
100
|
+
)
|
101
|
+
end
|
75
102
|
|
76
|
-
|
103
|
+
def test_metric_recording_in_root_non_transaction
|
104
|
+
options = { :transaction => false }
|
105
|
+
self.stubs(:has_parent?).returns(false)
|
77
106
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
107
|
+
in_transaction('outer') do
|
108
|
+
trace_execution_scoped(['foo', 'bar'], options) do
|
109
|
+
# erm
|
110
|
+
end
|
111
|
+
end
|
82
112
|
|
83
|
-
|
113
|
+
expected_values = { :call_count => 1 }
|
114
|
+
assert_metrics_recorded_exclusive(
|
115
|
+
'foo' => expected_values,
|
116
|
+
['foo', 'outer'] => expected_values,
|
117
|
+
'bar' => expected_values
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_metric_recording_in_non_root_non_transaction
|
122
|
+
options = { :transaction => false }
|
123
|
+
self.stubs(:has_parent?).returns(false)
|
124
|
+
|
125
|
+
in_transaction('outer') do
|
126
|
+
trace_execution_scoped(['foo', 'bar'], options) do
|
127
|
+
# erm
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
expected_values = { :call_count => 1 }
|
132
|
+
assert_metrics_recorded_exclusive(
|
133
|
+
'foo' => expected_values,
|
134
|
+
['foo', 'outer'] => expected_values,
|
135
|
+
'bar' => expected_values
|
136
|
+
)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_metric_recording_without_metric_option
|
140
|
+
options = { :metric => false, :transaction => true }
|
141
|
+
self.stubs(:has_parent?).returns(false)
|
142
|
+
|
143
|
+
in_transaction('outer') do
|
144
|
+
trace_execution_scoped(['foo', 'bar'], options) do
|
145
|
+
# erm
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
expected_values = { :call_count => 1 }
|
150
|
+
assert_metrics_recorded_exclusive(
|
151
|
+
'bar' => expected_values
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_metric_recording_with_scoped_metric_only_option
|
156
|
+
options = { :transaction => false, :scoped_metric_only => true }
|
157
|
+
self.stubs(:has_parent?).returns(false)
|
158
|
+
|
159
|
+
in_transaction('outer') do
|
160
|
+
trace_execution_scoped(['foo', 'bar'], options) do
|
161
|
+
# erm
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
expected_values = { :call_count => 1 }
|
166
|
+
assert_metrics_recorded_exclusive(
|
167
|
+
['foo', 'outer'] => expected_values
|
168
|
+
)
|
84
169
|
end
|
85
170
|
|
86
171
|
def test_set_if_nil
|
@@ -116,7 +201,7 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
|
|
116
201
|
|
117
202
|
def test_log_errors_base
|
118
203
|
ran = false
|
119
|
-
log_errors("name"
|
204
|
+
log_errors("name") do
|
120
205
|
ran = true
|
121
206
|
end
|
122
207
|
assert ran, "should run the contents of the block"
|
@@ -124,7 +209,7 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
|
|
124
209
|
|
125
210
|
def test_log_errors_with_return
|
126
211
|
ran = false
|
127
|
-
return_val = log_errors('name'
|
212
|
+
return_val = log_errors('name') do
|
128
213
|
ran = true
|
129
214
|
'happy trees'
|
130
215
|
end
|
@@ -135,41 +220,56 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
|
|
135
220
|
|
136
221
|
def test_log_errors_with_error
|
137
222
|
expects_logging(:error,
|
138
|
-
includes("Caught exception in name.
|
223
|
+
includes("Caught exception in name."),
|
139
224
|
instance_of(RuntimeError))
|
140
225
|
|
141
|
-
log_errors("name"
|
226
|
+
log_errors("name") do
|
142
227
|
raise "should not propagate out of block"
|
143
228
|
end
|
144
229
|
end
|
145
230
|
|
146
231
|
def test_trace_execution_scoped_header
|
147
232
|
options = {:force => false, :deduct_call_time_from_parent => false}
|
148
|
-
self.expects(:log_errors).with('trace_execution_scoped header'
|
233
|
+
self.expects(:log_errors).with('trace_execution_scoped header').yields
|
149
234
|
self.expects(:push_flag!).with(false)
|
150
235
|
fakestats = mocked_object('stat_engine')
|
151
|
-
fakestats.expects(:push_scope).with(
|
152
|
-
trace_execution_scoped_header(
|
153
|
-
end
|
154
|
-
|
155
|
-
def
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
236
|
+
fakestats.expects(:push_scope).with(:method_tracer, 1.0, false)
|
237
|
+
trace_execution_scoped_header(options, 1.0)
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_trace_execution_scoped_calculates_exclusive_time
|
241
|
+
freeze_time
|
242
|
+
in_transaction('txn') do
|
243
|
+
trace_execution_scoped(['parent']) do
|
244
|
+
advance_time(10)
|
245
|
+
trace_execution_scoped(['child']) do
|
246
|
+
advance_time(10)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
assert_metrics_recorded_exclusive(
|
252
|
+
'parent' => { :call_count => 1, :total_call_time => 20, :total_exclusive_time => 10 },
|
253
|
+
['parent', 'txn'] => { :call_count => 1, :total_call_time => 20, :total_exclusive_time => 10 },
|
254
|
+
'child' => { :call_count => 1, :total_call_time => 10, :total_exclusive_time => 10 },
|
255
|
+
['child', 'txn'] => { :call_count => 1, :total_call_time => 10, :total_exclusive_time => 10 }
|
256
|
+
)
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_force_flag_enables_metric_recording_in_ignored_transaction
|
260
|
+
NewRelic::Agent.instance.push_trace_execution_flag(false)
|
261
|
+
in_transaction('txn') do
|
262
|
+
trace_execution_scoped(['foo'], :force => true) do
|
263
|
+
# whatever, man
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
assert_metrics_recorded_exclusive(
|
268
|
+
'foo' => { :call_count => 1 },
|
269
|
+
['foo', 'txn'] => { :call_count => 1 }
|
270
|
+
)
|
271
|
+
ensure
|
272
|
+
NewRelic::Agent.instance.pop_trace_execution_flag()
|
173
273
|
end
|
174
274
|
|
175
275
|
def test_trace_execution_scoped_disabled
|
@@ -186,47 +286,19 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
|
|
186
286
|
assert_equal 1172, value, 'should return contents of block'
|
187
287
|
end
|
188
288
|
|
189
|
-
def
|
190
|
-
|
191
|
-
opts_after_correction = {:metric => true, :deduct_call_time_from_parent => true}
|
192
|
-
specs = [
|
193
|
-
NewRelic::MetricSpec.new('metric'),
|
194
|
-
NewRelic::MetricSpec.new('array')
|
195
|
-
]
|
196
|
-
self.expects(:trace_disabled?).returns(false)
|
197
|
-
self.expects(:get_metric_specs).with('metric', ['array'], nil, opts_after_correction).returns(specs)
|
198
|
-
self.expects(:trace_execution_scoped_header).with('metric', opts_after_correction).returns(['start_time', 'expected_scope'])
|
199
|
-
self.expects(:trace_execution_scoped_footer).with('start_time', 'metric', specs, 'expected_scope', nil)
|
200
|
-
ran = false
|
201
|
-
value = trace_execution_scoped(['metric', 'array'], passed_in_opts) do
|
202
|
-
ran = true
|
289
|
+
def test_trace_execution_scope_runs_passed_block_and_returns_its_value
|
290
|
+
value = trace_execution_scoped(['metric', 'array'], {}) do
|
203
291
|
1172
|
204
292
|
end
|
205
|
-
|
206
|
-
assert ran, 'should run contents of the block'
|
207
293
|
assert_equal 1172, value, 'should return the contents of the block'
|
208
294
|
end
|
209
295
|
|
210
|
-
def
|
211
|
-
passed_in_opts = {}
|
212
|
-
opts_after_correction = {:metric => true, :deduct_call_time_from_parent => true}
|
213
|
-
specs = [
|
214
|
-
NewRelic::MetricSpec.new('metric'),
|
215
|
-
NewRelic::MetricSpec.new('array')
|
216
|
-
]
|
217
|
-
self.expects(:trace_disabled?).returns(false)
|
218
|
-
self.expects(:get_metric_specs).with('metric', ['array'], nil, opts_after_correction).returns(specs)
|
219
|
-
self.expects(:trace_execution_scoped_header).with('metric', opts_after_correction).returns(['start_time', 'expected_scope'])
|
220
|
-
self.expects(:trace_execution_scoped_footer).with('start_time', 'metric', specs, 'expected_scope', nil)
|
221
|
-
ran = false
|
296
|
+
def test_trace_execution_scoped_does_not_swallow_errors
|
222
297
|
assert_raises(RuntimeError) do
|
223
|
-
trace_execution_scoped(['metric', 'array'],
|
224
|
-
ran = true
|
298
|
+
trace_execution_scoped(['metric', 'array'], {}) do
|
225
299
|
raise 'raising a test error'
|
226
300
|
end
|
227
301
|
end
|
228
|
-
|
229
|
-
assert ran, 'should run contents of the block'
|
230
302
|
end
|
231
303
|
|
232
304
|
private
|