newrelic_rpm 3.6.0.74.beta → 3.6.0.78

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data.tar.gz.sig +1 -2
  2. data/CHANGELOG +18 -0
  3. data/Gemfile +3 -3
  4. data/Rakefile +8 -0
  5. data/lib/new_relic/agent/agent.rb +4 -9
  6. data/lib/new_relic/agent/agent_logger.rb +1 -2
  7. data/lib/new_relic/agent/audit_logger.rb +7 -3
  8. data/lib/new_relic/agent/busy_calculator.rb +3 -3
  9. data/lib/new_relic/agent/configuration/server_source.rb +23 -10
  10. data/lib/new_relic/agent/cross_app_monitor.rb +1 -0
  11. data/lib/new_relic/agent/database.rb +2 -0
  12. data/lib/new_relic/agent/error_collector.rb +1 -1
  13. data/lib/new_relic/agent/instrumentation/active_record.rb +14 -13
  14. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +72 -0
  15. data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +0 -76
  16. data/lib/new_relic/agent/instrumentation/rails4/action_view.rb +138 -0
  17. data/lib/new_relic/agent/instrumentation/rails4/active_record.rb +108 -0
  18. data/lib/new_relic/agent/null_logger.rb +15 -0
  19. data/lib/new_relic/agent/stats.rb +1 -0
  20. data/lib/new_relic/agent/stats_engine/transactions.rb +4 -4
  21. data/lib/new_relic/control/frameworks/rails.rb +0 -37
  22. data/lib/new_relic/control/frameworks/rails3.rb +0 -17
  23. data/lib/new_relic/control/instance_methods.rb +1 -2
  24. data/lib/new_relic/environment_report.rb +159 -0
  25. data/lib/new_relic/helper.rb +4 -0
  26. data/lib/new_relic/local_environment.rb +0 -161
  27. data/lib/newrelic_rpm.rb +1 -1
  28. data/test/multiverse/lib/multiverse/suite.rb +7 -0
  29. data/test/multiverse/suites/active_record/Envfile +0 -1
  30. data/test/multiverse/suites/agent_only/key_transactions_test.rb +22 -12
  31. data/test/multiverse/suites/rails/Envfile +8 -1
  32. data/test/multiverse/suites/rails/app.rb +7 -2
  33. data/test/multiverse/suites/rails/error_tracing_test.rb +28 -16
  34. data/test/multiverse/suites/rails/view_instrumentation_test.rb +8 -2
  35. data/test/new_relic/agent/agent/connect_test.rb +5 -8
  36. data/test/new_relic/agent/agent/start_test.rb +3 -1
  37. data/test/new_relic/agent/agent_logger_test.rb +8 -8
  38. data/test/new_relic/agent/agent_test.rb +0 -6
  39. data/test/new_relic/agent/agent_test_controller_test.rb +18 -14
  40. data/test/new_relic/agent/audit_logger_test.rb +12 -0
  41. data/test/new_relic/agent/configuration/server_source_test.rb +48 -0
  42. data/test/new_relic/agent/cross_app_monitor_test.rb +8 -0
  43. data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +254 -0
  44. data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +52 -0
  45. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +32 -51
  46. data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +132 -0
  47. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +20 -0
  48. data/test/new_relic/agent_test.rb +0 -8
  49. data/test/new_relic/control_test.rb +1 -2
  50. data/test/new_relic/dispatcher_test.rb +1 -5
  51. data/test/new_relic/environment_report_test.rb +89 -0
  52. data/test/new_relic/license_test.rb +1 -3
  53. data/test/new_relic/load_test.rb +5 -1
  54. data/test/new_relic/local_environment_test.rb +0 -27
  55. data/test/new_relic/rack/browser_monitoring_test.rb +1 -0
  56. data/test/script/ci.sh +19 -18
  57. data/test/test_helper.rb +15 -3
  58. metadata +42 -3
  59. metadata.gz.sig +0 -0
@@ -82,18 +82,15 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
82
82
  handle_license_error(error)
83
83
  end
84
84
 
85
- def test_environment_for_connect_positive
86
- fake_env = stub('local_env', :discovered_dispatcher => nil)
87
- fake_env.expects(:snapshot).returns("snapshot")
88
- NewRelic::Control.instance.expects(:local_env).at_least_once.returns(fake_env)
89
- with_config(:send_environment_info => true) do
90
- assert_equal 'snapshot', environment_for_connect
91
- end
85
+ def test_connect_settings_have_environment_report
86
+ assert NewRelic::Agent.agent.connect_settings[:environment].detect{ |(k, v)|
87
+ k == 'Gems'
88
+ }, "expected connect_settings to include gems from environment"
92
89
  end
93
90
 
94
91
  def test_environment_for_connect_negative
95
92
  with_config(:send_environment_info => false) do
96
- assert_equal [], environment_for_connect
93
+ assert_equal [], NewRelic::Agent.agent.connect_settings[:environment]
97
94
  end
98
95
  end
99
96
 
@@ -18,7 +18,9 @@ class NewRelic::Agent::Agent::StartTest < Test::Unit::TestCase
18
18
  end
19
19
 
20
20
  def test_already_started_positive
21
- ::Logger.any_instance.expects(:error).with("Agent Started Already!")
21
+ dummy_logger = mock
22
+ dummy_logger.expects(:error).with("Agent Started Already!")
23
+ NewRelic::Agent.stubs(:logger).returns(dummy_logger)
22
24
  self.expects(:started?).returns(true)
23
25
  assert already_started?, "should have already started"
24
26
  end
@@ -4,6 +4,7 @@
4
4
 
5
5
  require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
6
6
  require 'new_relic/agent/agent_logger'
7
+ require 'new_relic/agent/null_logger'
7
8
 
8
9
  class AgentLoggerTest < Test::Unit::TestCase
9
10
  def setup
@@ -67,18 +68,17 @@ class AgentLoggerTest < Test::Unit::TestCase
67
68
  end
68
69
 
69
70
  def test_wont_log_if_agent_not_enabled
70
- ::Logger.stubs(:new).with("/dev/null").returns(stub(:level=)).at_least_once
71
-
71
+ null_logger = NewRelic::Agent::NullLogger.new
72
+ NewRelic::Agent::NullLogger.expects(:new).returns(null_logger)
72
73
  @config[:agent_enabled] = false
73
74
  logger = NewRelic::Agent::AgentLogger.new(@config)
75
+ assert_nothing_raised do
76
+ logger.warn('hi there')
77
+ end
74
78
  end
75
79
 
76
- def test_logs_to_nul_if_dev_null_not_there
77
- File.stubs(:exists?).with("/dev/null").returns(false)
78
- File.stubs(:exists?).with("NUL").returns(true)
79
-
80
- ::Logger.stubs(:new).with("NUL").returns(stub(:level=)).once
81
-
80
+ def test_does_not_touch_dev_null
81
+ Logger.expects(:new).with('/dev/null').never
82
82
  @config[:agent_enabled] = false
83
83
  logger = NewRelic::Agent::AgentLogger.new(@config)
84
84
  end
@@ -69,12 +69,6 @@ module NewRelic
69
69
  @agent.instance_eval { transmit_data }
70
70
  end
71
71
 
72
- def test_transmit_data_should_not_close_db_connections_if_forked
73
- NewRelic::Agent::Database.expects(:close_connections).never
74
- @agent.after_fork
75
- @agent.instance_eval { transmit_data }
76
- end
77
-
78
72
  def test_harvest_transaction_traces
79
73
  assert_equal([], @agent.send(:harvest_transaction_traces), 'should return transaction traces')
80
74
  end
@@ -1,9 +1,9 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
-
5
4
  require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
6
5
  require 'action_controller/test_case'
6
+
7
7
  class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
8
8
  require 'action_controller/base'
9
9
  require 'new_relic/agent/agent_test_controller'
@@ -12,7 +12,7 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
12
12
 
13
13
  attr_accessor :agent, :engine
14
14
 
15
- def test_initialization
15
+ def suite_initialization
16
16
  # Suggested by cee-dub for merb tests. I'm actually amazed if our tests work with merb.
17
17
  if defined?(Merb::Router)
18
18
  Merb::Router.prepare do |r|
@@ -25,19 +25,19 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
25
25
  end
26
26
  else
27
27
  Rails.application.routes.draw do
28
- match '/:controller/:action.:format'
29
- match '/:controller/:action'
28
+ get '/:controller/:action.:format'
29
+ get '/:controller/:action'
30
30
  end
31
31
  end
32
32
 
33
- if defined?(Rails) && Rails.respond_to?(:application) && Rails.application.respond_to?(:routes)
33
+ if defined?(Rails) && Rails.respond_to?(:application) &&
34
+ Rails.application.respond_to?(:routes)
34
35
  @routes = Rails.application.routes
35
36
  end
36
37
 
37
38
  Thread.current[:newrelic_ignore_controller] = nil
38
39
  NewRelic::Agent.manual_start
39
40
  @agent = NewRelic::Agent.instance
40
- # @agent.instrument_app
41
41
  agent.transaction_sampler.harvest
42
42
  NewRelic::Agent::AgentTestController.class_eval do
43
43
  newrelic_ignore :only => [:action_to_ignore, :entry_action, :base_action]
@@ -51,10 +51,10 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
51
51
  if NewRelic::Control.instance.rails_version <= '2.1.0'
52
52
  def initialize name
53
53
  super name
54
- test_initialization
54
+ suite_initialization
55
55
  end
56
56
  else
57
- alias_method :setup, :test_initialization
57
+ alias_method :setup, :suite_initialization
58
58
  end
59
59
 
60
60
  def teardown
@@ -67,8 +67,11 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
67
67
  def test_mongrel_queue
68
68
  NewRelic::Agent::AgentTestController.clear_headers
69
69
  engine.clear_stats
70
- NewRelic::Control.instance.local_env.stubs(:mongrel).returns( stub('mongrel', :workers => stub('workers', :list => stub('list', :length => '10'))))
71
-
70
+ NewRelic::Control.instance.local_env.stubs(:mongrel) \
71
+ .returns(stub('mongrel',
72
+ :workers => stub('workers',
73
+ :list => stub('list',
74
+ :length => '10'))))
72
75
  get :index
73
76
  assert_equal 1, stats('HttpDispatcher').call_count
74
77
  assert_equal 1, engine.get_stats_no_scope('Mongrel/Queue Length').call_count
@@ -119,6 +122,7 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
119
122
  assert_equal 'foofah', @response.body
120
123
  compare_metrics %w[Controller/new_relic/agent/agent_test/action_inline], engine.metrics.grep(/^Controller/)
121
124
  end
125
+
122
126
  def test_metric__ignore
123
127
  engine.clear_stats
124
128
  compare_metrics [], engine.metrics
@@ -209,6 +213,7 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
209
213
  end
210
214
  assert_nil Thread.current[:newrelic_ignore_controller]
211
215
  end
216
+
212
217
  def test_metric__ignore_apdex
213
218
  engine = @agent.stats_engine
214
219
  path = 'new_relic/agent/agent_test/action_to_ignore_apdex'
@@ -221,8 +226,8 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
221
226
  end
222
227
  end
223
228
  assert_nil Thread.current[:newrelic_ignore_controller]
224
-
225
229
  end
230
+
226
231
  def test_metric__dispatched
227
232
  engine = @agent.stats_engine
228
233
  get :entry_action
@@ -234,6 +239,7 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
234
239
  assert_nil engine.lookup_stats('Controller/NewRelic::Agent::AgentTestController_controller/internal_action')
235
240
  assert_not_nil engine.lookup_stats('Controller/NewRelic::Agent::AgentTestController/internal_traced_action')
236
241
  end
242
+
237
243
  def test_action_instrumentation
238
244
  get :index, :foo => 'bar'
239
245
  assert_match /bar/, @response.body
@@ -259,9 +265,7 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
259
265
  assert_equal 5, s.first.params.size
260
266
  end
261
267
 
262
-
263
268
  def test_busy_calculation_correctly_calculates_based_acccumlator
264
-
265
269
  # woah it's 1970
266
270
  now = Time.at 0
267
271
 
@@ -332,6 +336,7 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
332
336
  assert(queue_time_stat.total_call_time < 10, "Queue time should be under 10 seconds (sanity check)")
333
337
 
334
338
  end
339
+
335
340
  def test_queue_headers_heroku
336
341
  # make this test deterministic
337
342
  Time.stubs(:now => Time.at(1360973845))
@@ -382,4 +387,3 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
382
387
  end
383
388
 
384
389
  end if defined? Rails
385
-
@@ -4,6 +4,7 @@
4
4
 
5
5
  require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
6
6
  require 'new_relic/agent/audit_logger'
7
+ require 'new_relic/agent/null_logger'
7
8
 
8
9
  class AuditLoggerTest < Test::Unit::TestCase
9
10
  def setup
@@ -66,6 +67,17 @@ class AuditLoggerTest < Test::Unit::TestCase
66
67
  assert_nil(logger.ensure_log_path)
67
68
  end
68
69
 
70
+ def test_setup_logger_creates_null_logger_when_ensure_path_fails
71
+ null_logger = NewRelic::Agent::NullLogger.new
72
+ NewRelic::Agent::NullLogger.expects(:new).returns(null_logger)
73
+ logger = NewRelic::Agent::AuditLogger.new(@config)
74
+ logger.stubs(:ensure_log_path).returns(nil)
75
+ assert_nothing_raised do
76
+ logger.setup_logger
77
+ logger.log_request(@uri, 'whatever', @marshaller)
78
+ end
79
+ end
80
+
69
81
  def test_log_request_captures_system_call_errors
70
82
  logger = NewRelic::Agent::AuditLogger.new(@config)
71
83
  dummy_sink = StringIO.new
@@ -50,5 +50,53 @@ module NewRelic::Agent::Configuration
50
50
  def test_should_not_dot_the_web_transactions_apdex_hash
51
51
  assert_equal 1.5, @source[:web_transactions_apdex]['Controller/some/txn']
52
52
  end
53
+
54
+ def test_should_disable_gated_features_when_server_says_to
55
+ rsp = {
56
+ 'collect_errors' => false,
57
+ 'collect_traces' => false
58
+ }
59
+ existing_config = {
60
+ :'error_collector.enabled' => true,
61
+ :'slow_sql.enabled' => true,
62
+ :'transaction_tracer.enabled' => true
63
+ }
64
+ @source = ServerSource.new(rsp, existing_config)
65
+ assert !@source[:'error_collector.enabled']
66
+ assert !@source[:'slow_sql.enabled']
67
+ assert !@source[:'transaction_tracer.enabled']
68
+ end
69
+
70
+ def test_should_enable_gated_features_when_server_says_to
71
+ rsp = {
72
+ 'collect_errors' => true,
73
+ 'collect_traces' => true
74
+ }
75
+ existing_config = {
76
+ :'error_collector.enabled' => true,
77
+ :'slow_sql.enabled' => true,
78
+ :'transaction_tracer.enabled' => true
79
+ }
80
+ @source = ServerSource.new(rsp, existing_config)
81
+ assert @source[:'error_collector.enabled']
82
+ assert @source[:'slow_sql.enabled']
83
+ assert @source[:'transaction_tracer.enabled']
84
+ end
85
+
86
+ def test_should_allow_manual_disable_of_gated_features
87
+ rsp = {
88
+ 'collect_errors' => true,
89
+ 'collect_traces' => true
90
+ }
91
+ existing_config = {
92
+ :'error_collector.enabled' => false,
93
+ :'slow_sql.enabled' => false,
94
+ :'transaction_tracer.enabled' => false
95
+ }
96
+ @source = ServerSource.new(rsp, existing_config)
97
+ assert !@source[:'error_collector.enabled']
98
+ assert !@source[:'slow_sql.enabled']
99
+ assert !@source[:'transaction_tracer.enabled']
100
+ end
53
101
  end
54
102
  end
@@ -190,6 +190,14 @@ module NewRelic::Agent
190
190
  NewRelic::Agent::CrossAppMonitor::EncodingFunctions.encode_with_key( nil, 'querty' )
191
191
  end
192
192
 
193
+ def test_encoding_functions_can_roundtrip_utf8_text
194
+ str = 'Анастасі́я Олексі́ївна Каме́нських'
195
+ encoded = NewRelic::Agent::CrossAppMonitor::EncodingFunctions.obfuscate_with_key( 'potap', str )
196
+ decoded = NewRelic::Agent::CrossAppMonitor::EncodingFunctions.decode_with_key( 'potap', encoded )
197
+ decoded.force_encoding( 'utf-8' ) if decoded.respond_to?( :force_encoding )
198
+ assert_equal str, decoded
199
+ end
200
+
193
201
  #
194
202
  # Helpers
195
203
  #
@@ -0,0 +1,254 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','test_helper'))
5
+ require 'new_relic/agent/instrumentation/rails4/action_view'
6
+
7
+ class NewRelic::Agent::Instrumentation::ActionViewSubscriberTest < Test::Unit::TestCase
8
+ def setup
9
+ @subscriber = NewRelic::Agent::Instrumentation::ActionViewSubscriber.new
10
+ @stats_engine = NewRelic::Agent.instance.stats_engine
11
+ end
12
+
13
+ def teardown
14
+ NewRelic::Agent.instance.stats_engine.clear_stats
15
+ end
16
+
17
+ def test_records_metrics_for_simple_template
18
+ params = { :identifier => '/root/app/views/model/index.html.erb' }
19
+ t0 = Time.now
20
+ Time.stubs(:now).returns(t0, t0, t0 + 2, t0 + 2)
21
+
22
+ @subscriber.start('render_template.action_view', :id, params)
23
+ @subscriber.start('!render_template.action_view', :id,
24
+ :virtual_path => 'model/index')
25
+ @subscriber.finish('!render_template.action_view', :id,
26
+ :virtual_path => 'model/index')
27
+ @subscriber.finish('render_template.action_view', :id, params)
28
+
29
+ metric = @stats_engine.lookup_stats('View/model/index.html.erb/Rendering')
30
+ assert_equal(1, metric.call_count)
31
+ assert_equal(2.0, metric.total_call_time)
32
+ end
33
+
34
+ def test_records_metrics_for_simple_file
35
+ params = { :identifier => '/root/something.txt' }
36
+ t0 = Time.now
37
+ Time.stubs(:now).returns(t0, t0, t0 + 2, t0 + 2)
38
+
39
+ @subscriber.start('render_template.action_view', :id, params)
40
+ @subscriber.start('!render_template.action_view', :id,
41
+ :virtual_path => nil)
42
+ @subscriber.finish('!render_template.action_view', :id,
43
+ :virtual_path => nil)
44
+ @subscriber.finish('render_template.action_view', :id, params)
45
+
46
+ metric = @stats_engine.lookup_stats('View/file/Rendering')
47
+ assert_equal(1, metric.call_count)
48
+ assert_equal(2.0, metric.total_call_time)
49
+ end
50
+
51
+ def test_records_metrics_for_simple_inline
52
+ params = { :identifier => 'inline template' }
53
+ t0 = Time.now
54
+ Time.stubs(:now).returns(t0, t0, t0 + 2, t0 + 2)
55
+
56
+ @subscriber.start('render_template.action_view', :id, params)
57
+ @subscriber.start('!render_template.action_view', :id,
58
+ :virtual_path => nil)
59
+ @subscriber.finish('!render_template.action_view', :id,
60
+ :virtual_path => nil)
61
+ @subscriber.finish('render_template.action_view', :id, params)
62
+
63
+ metric = @stats_engine.lookup_stats('View/inline template/Rendering')
64
+ assert_equal(1, metric.call_count)
65
+ assert_equal(2.0, metric.total_call_time)
66
+ end
67
+
68
+ def test_records_metrics_for_simple_text
69
+ params = { :identifier => 'text template' }
70
+ t0 = Time.now
71
+ Time.stubs(:now).returns(t0, t0 + 2)
72
+
73
+ @subscriber.start('render_template.action_view', :id, params)
74
+ @subscriber.finish('render_template.action_view', :id, params)
75
+
76
+ metric = @stats_engine.lookup_stats('View/text template/Rendering')
77
+ assert_equal(1, metric.call_count)
78
+ assert_equal(2.0, metric.total_call_time)
79
+ end
80
+
81
+ def test_records_metrics_for_simple_partial
82
+ params = { :identifier => '/root/app/views/model/_form.html.erb' }
83
+ t0 = Time.now
84
+ Time.stubs(:now).returns(t0, t0, t0 + 2, t0 + 2)
85
+
86
+ @subscriber.start('render_partial.action_view', :id, params)
87
+ @subscriber.start('!render_template.action_view', :id,
88
+ :virtual_path => 'model/_form')
89
+ @subscriber.finish('!render_template.action_view', :id,
90
+ :virtual_path => 'model/_form')
91
+ @subscriber.finish('render_partial.action_view', :id, params)
92
+
93
+ metric = @stats_engine.lookup_stats('View/model/_form.html.erb/Partial')
94
+ assert_equal(1, metric.call_count)
95
+ assert_equal(2.0, metric.total_call_time)
96
+ end
97
+
98
+ def test_records_metrics_for_simple_collection
99
+ params = { :identifier => '/root/app/views/model/_user.html.erb' }
100
+ t0 = Time.now
101
+ Time.stubs(:now).returns(t0, t0, t0 + 2, t0 + 2)
102
+
103
+ @subscriber.start('render_collection.action_view', :id, params)
104
+ @subscriber.start('!render_template.action_view', :id,
105
+ :virtual_path => 'model/_user')
106
+ @subscriber.finish('!render_template.action_view', :id,
107
+ :virtual_path => 'model/_user')
108
+ @subscriber.finish('render_collection.action_view', :id, params)
109
+
110
+ metric = @stats_engine.lookup_stats('View/model/_user.html.erb/Partial')
111
+ assert_equal(1, metric.call_count)
112
+ assert_equal(2.0, metric.total_call_time)
113
+ end
114
+
115
+ def test_records_metrics_for_layout
116
+ t0 = Time.now
117
+ Time.stubs(:now).returns(t0, t0 + 2)
118
+
119
+ @subscriber.start('!render_template.action_view', :id,
120
+ :virtual_path => 'layouts/application')
121
+ @subscriber.finish('!render_template.action_view', :id,
122
+ :virtual_path => 'layouts/application')
123
+
124
+ metric = @stats_engine.lookup_stats('View/layouts/application/Rendering')
125
+ assert_equal(1, metric.call_count)
126
+ assert_equal(2.0, metric.total_call_time)
127
+ end
128
+
129
+ def test_records_scoped_metric
130
+ params = { :identifier => '/root/app/views/model/index.html.erb' }
131
+ t0 = Time.now
132
+ Time.stubs(:now).returns(t0, t0, t0 + 2, t0 + 2)
133
+ @stats_engine.start_transaction('test_txn')
134
+
135
+ @subscriber.start('render_template.action_view', :id, params)
136
+ @subscriber.start('!render_template.action_view', :id,
137
+ :virtual_path => 'model/index')
138
+ @subscriber.finish('!render_template.action_view', :id,
139
+ :virtual_path => 'model/index')
140
+ @subscriber.finish('render_template.action_view', :id, params)
141
+
142
+ metric = @stats_engine.lookup_stats('View/model/index.html.erb/Rendering',
143
+ 'test_txn')
144
+ assert_equal(1, metric.call_count)
145
+ assert_equal(2.0, metric.total_call_time)
146
+
147
+ end
148
+
149
+ def test_records_nothing_if_tracing_disabled
150
+ params = { :identifier => '/root/app/views/model/_user.html.erb' }
151
+
152
+ NewRelic::Agent.disable_all_tracing do
153
+ @subscriber.start('render_collection.action_view', :id, params)
154
+ @subscriber.finish('render_collection.action_view', :id, params)
155
+ end
156
+
157
+ metric = @stats_engine.lookup_stats('View/model/_user.html.erb/Partial')
158
+ assert_nil metric
159
+ end
160
+
161
+ def test_creates_txn_segment_for_simple_render
162
+ params = { :identifier => '/root/app/views/model/index.html.erb' }
163
+
164
+ sampler = in_transaction do
165
+ @subscriber.start('render_template.action_view', :id, params)
166
+ @subscriber.start('!render_template.action_view', :id,
167
+ :virtual_path => 'model/index')
168
+ @subscriber.finish('!render_template.action_view', :id,
169
+ :virtual_path => 'model/index')
170
+ @subscriber.finish('render_template.action_view', :id, params)
171
+ end
172
+
173
+ last_segment = nil
174
+ sampler.last_sample.root_segment.each_segment{|s| last_segment = s }
175
+ NewRelic::Agent.shutdown
176
+
177
+ assert_equal('View/model/index.html.erb/Rendering',
178
+ last_segment.metric_name)
179
+ end
180
+
181
+ def test_creates_nested_partial_segment_within_render_segment
182
+ sampler = in_transaction do
183
+ @subscriber.start('render_template.action_view', :id,
184
+ :identifier => 'model/index.html.erb')
185
+ @subscriber.start('!render_template.action_view', :id,
186
+ :virtual_path => 'model/index')
187
+ @subscriber.start('render_partial.action_view', :id,
188
+ :identifier => '/root/app/views/model/_list.html.erb')
189
+ @subscriber.start('!render_template.action_view', :id,
190
+ :virtual_path => 'model/_list')
191
+ @subscriber.finish('!render_template.action_view', :id,
192
+ :virtual_path => 'model/_list')
193
+ @subscriber.finish('render_partial.action_view', :id,
194
+ :identifier => '/root/app/views/model/_list.html.erb')
195
+ @subscriber.finish('!render_template.action_view', :id,
196
+ :virtual_path => 'model/index')
197
+ @subscriber.finish('render_template.action_view', :id,
198
+ :identifier => 'model/index.html.erb')
199
+ end
200
+
201
+ template_segment = sampler.last_sample.root_segment.called_segments[0].called_segments[0]
202
+ partial_segment = template_segment.called_segments[0]
203
+
204
+ assert_equal('View/model/index.html.erb/Rendering',
205
+ template_segment.metric_name)
206
+ assert_equal('View/model/_list.html.erb/Partial',
207
+ partial_segment.metric_name)
208
+ end
209
+
210
+ def test_creates_nodes_for_each_in_a_collection_event
211
+ sampler = in_transaction do
212
+ @subscriber.start('render_collection.action_view', :id,
213
+ :identifier => '/root/app/views/model/_list.html.erb',
214
+ :count => 3)
215
+ @subscriber.start('!render_template.action_view', :id,
216
+ :virtual_path => 'model/_list')
217
+ @subscriber.finish('!render_template.action_view', :id,
218
+ :virtual_path => 'model/_list')
219
+ @subscriber.start('!render_template.action_view', :id,
220
+ :virtual_path => 'model/_list')
221
+ @subscriber.finish('!render_template.action_view', :id,
222
+ :virtual_path => 'model/_list')
223
+ @subscriber.start('!render_template.action_view', :id,
224
+ :virtual_path => 'model/_list')
225
+ @subscriber.finish('!render_template.action_view', :id,
226
+ :virtual_path => 'model/_list')
227
+ @subscriber.finish('render_collection.action_view', :id,
228
+ :identifier => '/root/app/views/model/_list.html.erb',
229
+ :count => 3)
230
+ end
231
+
232
+ template_segment = sampler.last_sample.root_segment.called_segments[0]
233
+ partial_segments = template_segment.called_segments
234
+
235
+ assert_equal 3, partial_segments.size
236
+ assert_equal('View/model/_list.html.erb/Partial',
237
+ partial_segments[0].metric_name)
238
+ end
239
+
240
+ def in_transaction
241
+ NewRelic::Agent.manual_start
242
+ NewRelic::Agent.instance.stats_engine.start_transaction('test')
243
+ sampler = NewRelic::Agent.instance.transaction_sampler
244
+ sampler.notice_first_scope_push(Time.now.to_f)
245
+ sampler.notice_transaction('/path', '/path', {})
246
+ sampler.notice_push_scope('Controller/sandwiches/index')
247
+ yield
248
+ sampler.notice_pop_scope('Controller/sandwiches/index')
249
+ sampler.notice_scope_empty
250
+ sampler
251
+ ensure
252
+ NewRelic::Agent.shutdown
253
+ end
254
+ end if ::Rails::VERSION::MAJOR.to_i >= 4