newrelic_rpm 3.6.0.74.beta → 3.6.0.78

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.
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