wd_newrelic_rpm 3.5.5 → 3.5.6

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 (146) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG +60 -0
  3. data/Rakefile +14 -18
  4. data/gem-public_cert.pem +20 -0
  5. data/lib/new_relic/agent.rb +3 -0
  6. data/lib/new_relic/agent/agent.rb +86 -97
  7. data/lib/new_relic/agent/agent_logger.rb +9 -1
  8. data/lib/new_relic/agent/busy_calculator.rb +5 -0
  9. data/lib/new_relic/agent/configuration/defaults.rb +3 -3
  10. data/lib/new_relic/agent/configuration/manager.rb +12 -0
  11. data/lib/new_relic/agent/configuration/mask_defaults.rb +1 -0
  12. data/lib/new_relic/agent/configuration/yaml_source.rb +5 -1
  13. data/lib/new_relic/agent/cross_process_monitoring.rb +164 -20
  14. data/lib/new_relic/agent/error_collector.rb +13 -2
  15. data/lib/new_relic/agent/event_listener.rb +39 -0
  16. data/lib/new_relic/agent/instrumentation/browser_monitoring_timings.rb +18 -8
  17. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +1 -1
  18. data/lib/new_relic/agent/instrumentation/sinatra.rb +8 -1
  19. data/lib/new_relic/agent/new_relic_service.rb +90 -10
  20. data/lib/new_relic/agent/pipe_service.rb +9 -0
  21. data/lib/new_relic/agent/sql_sampler.rb +10 -3
  22. data/lib/new_relic/agent/stats_engine/transactions.rb +1 -0
  23. data/lib/new_relic/agent/thread_profiler.rb +20 -7
  24. data/lib/new_relic/agent/worker_loop.rb +2 -1
  25. data/lib/new_relic/coerce.rb +37 -0
  26. data/lib/new_relic/commands/deployments.rb +1 -1
  27. data/lib/new_relic/control/frameworks/rails.rb +29 -5
  28. data/lib/new_relic/control/frameworks/rails3.rb +2 -11
  29. data/lib/new_relic/control/instance_methods.rb +11 -7
  30. data/lib/new_relic/control/server_methods.rb +5 -37
  31. data/lib/new_relic/latest_changes.rb +31 -0
  32. data/lib/new_relic/local_environment.rb +1 -1
  33. data/lib/new_relic/metric_data.rb +13 -2
  34. data/lib/new_relic/noticed_error.rb +8 -1
  35. data/lib/new_relic/rack/agent_hooks.rb +20 -0
  36. data/lib/new_relic/rack/error_collector.rb +11 -1
  37. data/lib/new_relic/recipes.rb +32 -10
  38. data/lib/new_relic/transaction_sample.rb +12 -3
  39. data/lib/new_relic/transaction_sample/segment.rb +6 -3
  40. data/lib/new_relic/version.rb +10 -15
  41. data/newrelic.yml +12 -19
  42. data/newrelic_rpm.gemspec +22 -464
  43. data/test/multiverse/.gitignore +1 -0
  44. data/test/multiverse/lib/multiverse/environment.rb +1 -1
  45. data/test/multiverse/lib/multiverse/suite.rb +2 -0
  46. data/test/multiverse/suites/active_record/Envfile +3 -3
  47. data/test/multiverse/suites/active_record/ar_method_aliasing.rb +1 -1
  48. data/test/multiverse/suites/active_record/config/newrelic.yml +2 -2
  49. data/test/multiverse/suites/agent_only/Envfile +2 -1
  50. data/test/multiverse/suites/agent_only/config/newrelic.yml +3 -1
  51. data/test/multiverse/suites/agent_only/cross_process_test.rb +56 -0
  52. data/test/multiverse/suites/{logging → agent_only}/logging_test.rb +42 -22
  53. data/test/multiverse/suites/agent_only/no_dns_resolv.rb +17 -0
  54. data/test/multiverse/suites/{rum_auto_instrumentation/sanity_test.rb → agent_only/rum_instrumentation_test.rb} +25 -46
  55. data/test/multiverse/suites/agent_only/service_timeout_test.rb +6 -3
  56. data/test/multiverse/suites/agent_only/ssl_test.rb +22 -0
  57. data/test/multiverse/suites/{no_load → agent_only}/start_up_test.rb +9 -2
  58. data/test/multiverse/suites/agent_only/testing_app.rb +17 -0
  59. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +6 -5
  60. data/test/multiverse/suites/datamapper/config/newrelic.yml +1 -1
  61. data/test/multiverse/suites/{rails_3_queue_time → rails}/Envfile +3 -0
  62. data/test/multiverse/suites/rails/app.rb +49 -0
  63. data/test/multiverse/suites/{rails_3_views → rails}/app/views/foos/_foo.html.haml +0 -0
  64. data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/_a_partial.html.erb +0 -0
  65. data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/_mid_partial.html.erb +0 -0
  66. data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/_top_partial.html.erb +0 -0
  67. data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/deep_partial.html.erb +0 -0
  68. data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/haml_view.html.haml +0 -0
  69. data/test/multiverse/suites/{rails_3_views/app/views/test → rails/app/views/views}/index.html.erb +0 -0
  70. data/test/multiverse/suites/rails/config/newrelic.yml +32 -0
  71. data/test/multiverse/suites/{rails_3_error_tracing → rails}/error_tracing_test.rb +51 -88
  72. data/test/multiverse/suites/rails/gc_instrumentation_test.rb +79 -0
  73. data/test/multiverse/suites/{rails_3_queue_time → rails}/queue_time_test.rb +3 -23
  74. data/test/multiverse/suites/{rails_3_views → rails}/view_instrumentation_test.rb +21 -61
  75. data/test/multiverse/suites/resque/Envfile +7 -4
  76. data/test/multiverse/suites/resque/Rakefile +8 -0
  77. data/test/multiverse/suites/resque/config/newrelic.yml +1 -1
  78. data/test/multiverse/suites/resque/instrumentation_test.rb +118 -41
  79. data/test/multiverse/suites/resque/resque_setup.rb +15 -0
  80. data/test/multiverse/suites/sinatra/config/newrelic.yml +1 -2
  81. data/test/multiverse/suites/sinatra/sinatra_error_tracing_test.rb +38 -0
  82. data/test/multiverse/suites/sinatra/sinatra_test.rb +17 -0
  83. data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +1 -1
  84. data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +1 -1
  85. data/test/new_relic/agent/agent/connect_test.rb +24 -100
  86. data/test/new_relic/agent/agent/start_worker_thread_test.rb +3 -3
  87. data/test/new_relic/agent/agent_test.rb +126 -31
  88. data/test/new_relic/agent/browser_monitoring_test.rb +1 -1
  89. data/test/new_relic/agent/busy_calculator_test.rb +8 -0
  90. data/test/new_relic/agent/configuration/manager_test.rb +28 -0
  91. data/test/new_relic/agent/configuration/yaml_source_test.rb +12 -2
  92. data/test/new_relic/agent/cross_process_monitoring_test.rb +144 -31
  93. data/test/new_relic/agent/error_collector_test.rb +16 -0
  94. data/test/new_relic/agent/event_listener_test.rb +46 -0
  95. data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +57 -30
  96. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +1 -0
  97. data/test/new_relic/agent/new_relic_service_test.rb +95 -2
  98. data/test/new_relic/agent/pipe_channel_manager_test.rb +3 -3
  99. data/test/new_relic/agent/pipe_service_test.rb +21 -1
  100. data/test/new_relic/agent/rpm_agent_test.rb +1 -1
  101. data/test/new_relic/agent/sql_sampler_test.rb +20 -0
  102. data/test/new_relic/agent/thread_profiler_test.rb +53 -8
  103. data/test/new_relic/agent/worker_loop_test.rb +19 -16
  104. data/test/new_relic/agent_test.rb +1 -2
  105. data/test/new_relic/coerce_test.rb +65 -0
  106. data/test/new_relic/command/deployments_test.rb +1 -1
  107. data/test/new_relic/control_test.rb +23 -44
  108. data/test/new_relic/fake_collector.rb +34 -6
  109. data/test/new_relic/local_environment_test.rb +1 -1
  110. data/test/new_relic/metric_data_test.rb +29 -0
  111. data/test/new_relic/noticed_error_test.rb +8 -0
  112. data/test/new_relic/rack/agent_hooks_test.rb +30 -0
  113. data/test/new_relic/rack/error_collector_test.rb +16 -0
  114. data/test/new_relic/transaction_sample/segment_test.rb +7 -0
  115. data/test/new_relic/transaction_sample_test.rb +36 -8
  116. data/test/new_relic/version_number_test.rb +6 -30
  117. data/test/script/ci.sh +6 -5
  118. data/test/test_contexts.rb +2 -1
  119. data/test/test_helper.rb +23 -6
  120. data/ui/helpers/google_pie_chart.rb +1 -0
  121. metadata +68 -67
  122. data/newrelic_rpm.gemspec.erb +0 -54
  123. data/test/fixtures/gemspec_no_build.rb +0 -442
  124. data/test/fixtures/gemspec_with_build.rb +0 -442
  125. data/test/fixtures/gemspec_with_build_and_stage.rb +0 -442
  126. data/test/multiverse/suites/logging/Envfile +0 -4
  127. data/test/multiverse/suites/logging/config/newrelic.yml +0 -22
  128. data/test/multiverse/suites/monitor_mode_false/Envfile +0 -2
  129. data/test/multiverse/suites/monitor_mode_false/config/newrelic.yml +0 -25
  130. data/test/multiverse/suites/monitor_mode_false/no_dns_resolv.rb +0 -29
  131. data/test/multiverse/suites/no_load/Envfile +0 -2
  132. data/test/multiverse/suites/no_load/config/newrelic.yml +0 -22
  133. data/test/multiverse/suites/rails_3_error_tracing/Envfile +0 -15
  134. data/test/multiverse/suites/rails_3_error_tracing/config/newrelic.yml +0 -165
  135. data/test/multiverse/suites/rails_3_gc/Envfile +0 -8
  136. data/test/multiverse/suites/rails_3_gc/config/newrelic.yml +0 -167
  137. data/test/multiverse/suites/rails_3_gc/instrumentation_test.rb +0 -92
  138. data/test/multiverse/suites/rails_3_queue_time/config/newrelic.yml +0 -165
  139. data/test/multiverse/suites/rails_3_views/.gitignore +0 -3
  140. data/test/multiverse/suites/rails_3_views/Envfile +0 -16
  141. data/test/multiverse/suites/rails_3_views/config/newrelic.yml +0 -164
  142. data/test/multiverse/suites/resque/dump.rdb +0 -0
  143. data/test/multiverse/suites/rum_auto_instrumentation/Envfile +0 -4
  144. data/test/multiverse/suites/rum_auto_instrumentation/config/newrelic.yml +0 -24
  145. data/test/multiverse/suites/rum_auto_instrumentation/responses/worst_case_small.html +0 -5000
  146. data/test/new_relic/fake_service.rb +0 -53
@@ -0,0 +1,17 @@
1
+ class TestingApp
2
+
3
+ attr_accessor :response, :headers
4
+
5
+ def initialize
6
+ reset_headers
7
+ end
8
+
9
+ def reset_headers
10
+ @headers = {'Content-Type' => 'text/html'}
11
+ end
12
+
13
+ def call(env)
14
+ [200, headers, [response]]
15
+ end
16
+
17
+ end
@@ -4,17 +4,18 @@
4
4
  if RUBY_VERSION >= '1.9'
5
5
  class ThreadProfilingTest < Test::Unit::TestCase
6
6
  def setup
7
- NewRelic::Agent.manual_start(:'thread_profiler.enabled' => true)
8
-
9
- @agent = NewRelic::Agent.instance
10
- @thread_profiler = @agent.thread_profiler
11
-
12
7
  $collector ||= NewRelic::FakeCollector.new
13
8
  $collector.reset
14
9
  $collector.mock['connect'] = [200, {'return_value' => {"agent_run_id" => 666 }}]
15
10
  $collector.mock['get_agent_commands'] = [200, {'return_value' => START_COMMAND}]
16
11
  $collector.mock['agent_command_results'] = [200, {'return_value' => []}]
17
12
  $collector.run
13
+
14
+ NewRelic::Agent::Agent.instance_variable_set(:@instance, nil)
15
+ NewRelic::Agent.manual_start(:'thread_profiler.enabled' => true)
16
+
17
+ @agent = NewRelic::Agent.instance
18
+ @thread_profiler = @agent.thread_profiler
18
19
  end
19
20
 
20
21
  def teardown
@@ -11,7 +11,7 @@ development:
11
11
  app_name: test
12
12
  host: 127.0.0.1
13
13
  api_host: 127.0.0.1
14
- port: 30303
14
+ port: <%= 30_000 + ($$ % 10_000) %>
15
15
  transaction_tracer:
16
16
  record_sql: obfuscated
17
17
  enabled: true
@@ -4,12 +4,15 @@ end
4
4
 
5
5
  gemfile <<-RB
6
6
  gem 'rails', '~>3.2.0'
7
+ gem 'haml'
7
8
  RB
8
9
 
9
10
  gemfile <<-RB
10
11
  gem 'rails', '~>3.1.0'
12
+ gem 'haml'
11
13
  RB
12
14
 
13
15
  gemfile <<-RB
14
16
  gem 'rails', '~>3.0.0'
17
+ gem 'haml'
15
18
  RB
@@ -0,0 +1,49 @@
1
+ require 'action_controller/railtie'
2
+
3
+ # We define our single Rails application here, one time, upon the first inclusion
4
+ # Tests should feel free to define their own Controllers locally, but if they
5
+ # need anything special at the Application level, put it here
6
+ if !defined?(MyApp)
7
+
8
+ ENV['NEW_RELIC_DISPATCHER'] = 'test'
9
+
10
+ class MyApp < Rails::Application
11
+ # We need a secret token for session, cookies, etc.
12
+ config.active_support.deprecation = :log
13
+ config.secret_token = "49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"
14
+ end
15
+ MyApp.initialize!
16
+
17
+ MyApp.routes.draw do
18
+ get('/bad_route' => 'Test#controller_error',
19
+ :constraints => lambda do |_|
20
+ raise ActionController::RoutingError.new('this is an uncaught routing error')
21
+ end)
22
+ match '/:controller(/:action(/:id))'
23
+ end
24
+
25
+ class ApplicationController < ActionController::Base; end
26
+
27
+ # a basic active model compliant model we can render
28
+ class Foo
29
+ extend ActiveModel::Naming
30
+ def to_model
31
+ self
32
+ end
33
+
34
+ def valid?() true end
35
+ def new_record?() true end
36
+ def destroyed?() true end
37
+
38
+ def raise_error
39
+ raise 'this is an uncaught model error'
40
+ end
41
+
42
+ def errors
43
+ obj = Object.new
44
+ def obj.[](key) [] end
45
+ def obj.full_messages() [] end
46
+ obj
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,32 @@
1
+ common: &default_settings
2
+ license_key: 'bd0e1d52adade840f7ca727d29a86249e89a6f1c'
3
+ host: 127.0.0.1
4
+ port: <%= 30_000 + ($$ % 10_000) %>
5
+ app_name: Rails 3 view test ap
6
+ enabled: true
7
+ log_level: debug
8
+ ssl: false
9
+ apdex_t: 1.0
10
+ capture_params: true
11
+ transaction_tracer:
12
+ enabled: true
13
+ transaction_threshold: apdex_f
14
+ record_sql: obfuscated
15
+ stack_trace_threshold: 0.500
16
+ error_collector:
17
+ enabled: true
18
+ capture_source: true
19
+ ignore_errors: IgnoredError
20
+
21
+ development:
22
+ <<: *default_settings
23
+ developer: true
24
+
25
+ test:
26
+ <<: *default_settings
27
+
28
+ production:
29
+ <<: *default_settings
30
+
31
+ staging:
32
+ <<: *default_settings
@@ -1,58 +1,9 @@
1
1
  # https://newrelic.atlassian.net/browse/RUBY-747
2
2
 
3
- ENV['NEW_RELIC_DISPATCHER'] = 'test'
4
-
5
- require 'action_controller/railtie'
6
- require 'rails/test_unit/railtie'
7
3
  require 'rails/test_help'
8
- require 'test/unit'
9
- require 'new_relic/rack/error_collector'
10
- require 'fake_service'
11
-
12
-
13
- # BEGIN RAILS APP
14
-
15
- class MyApp < Rails::Application
16
- # We need a secret token for session, cookies, etc.
17
- config.active_support.deprecation = :log
18
- config.secret_token = "49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"
19
- end
20
- MyApp.initialize!
21
-
22
- MyApp.routes.draw do
23
- get('/bad_route' => 'Test#controller_error',
24
- :constraints => lambda do |_|
25
- raise ActionController::RoutingError.new('this is an uncaught routing error')
26
- end)
27
- match '/:controller(/:action(/:id))'
28
- end
29
-
30
- class ApplicationController < ActionController::Base; end
31
-
32
- # a basic active model compliant model we can render
33
- class Foo
34
- extend ActiveModel::Naming
35
- def to_model
36
- self
37
- end
4
+ require 'fake_collector'
38
5
 
39
- def valid?() true end
40
- def new_record?() true end
41
- def destroyed?() true end
42
-
43
- def raise_error
44
- raise 'this is an uncaught model error'
45
- end
46
-
47
- def errors
48
- obj = Object.new
49
- def obj.[](key) [] end
50
- def obj.full_messages() [] end
51
- obj
52
- end
53
- end
54
-
55
- class TestController < ApplicationController
6
+ class ErrorController < ApplicationController
56
7
  include Rails.application.routes.url_helpers
57
8
  newrelic_ignore :only => :ignored_action
58
9
 
@@ -85,36 +36,37 @@ class TestController < ApplicationController
85
36
  render :text => "Shoulda noticed an error"
86
37
  end
87
38
  end
88
- # END RAILS APP
89
39
 
90
40
  class IgnoredError < StandardError; end
91
41
  class ServerIgnoredError < StandardError; end
92
42
 
93
- class TestControllerTest < ActionDispatch::IntegrationTest
43
+ class ErrorsWithoutSSCTest < ActionDispatch::IntegrationTest
94
44
  def setup
95
- NewRelic::Agent::Agent.instance_variable_set(:@instance, NewRelic::Agent::Agent.new)
45
+ $collector ||= NewRelic::FakeCollector.new
46
+ $collector.reset
47
+ setup_collector
48
+ $collector.run
49
+
50
+ NewRelic::Agent.reset_config
51
+ NewRelic::Agent.instance_variable_set(:@agent, nil)
52
+ NewRelic::Agent::Agent.instance_variable_set(:@instance, nil)
53
+ NewRelic::Agent.manual_start
96
54
 
97
- @service = NewRelic::FakeService.new
98
- NewRelic::Agent::Agent.instance.service = @service
55
+ reset_error_collector
56
+ end
99
57
 
100
- NewRelic::Agent.manual_start
58
+ # Let base class override this without moving where we start the agent
59
+ def setup_collector
60
+ $collector.mock['connect'] = [200, {'return_value' => {"agent_run_id" => 666 }}]
101
61
  end
102
62
 
103
63
  def teardown
104
64
  NewRelic::Agent::Agent.instance.shutdown if NewRelic::Agent::Agent.instance
105
- end
106
- end
107
-
108
- class ErrorsWithoutSSCTest < TestControllerTest
109
- def setup
110
- super
111
- reset_error_collector
65
+ NewRelic::Agent::Agent.instance_variable_set(:@instance, nil)
112
66
  end
113
67
 
114
68
  def reset_error_collector
115
- @error_collector = NewRelic::Agent.instance.error_collector
116
- NewRelic::Agent.instance.error_collector \
117
- .instance_variable_set(:@ignore_filter, nil)
69
+ @error_collector = NewRelic::Agent::Agent.instance.error_collector
118
70
 
119
71
  # sanity checks
120
72
  assert(@error_collector.enabled?,
@@ -132,25 +84,35 @@ class ErrorsWithoutSSCTest < TestControllerTest
132
84
  end
133
85
 
134
86
  def test_should_capture_error_raised_in_view
135
- get '/test/view_error'
87
+ get '/error/view_error'
136
88
  assert_error_reported_once('this is an uncaught view error')
137
89
  end
138
90
 
139
91
  def test_should_capture_error_raised_in_controller
140
- get '/test/controller_error'
92
+ get '/error/controller_error'
141
93
  assert_error_reported_once('this is an uncaught controller error')
142
94
  end
143
95
 
144
96
  def test_should_capture_error_raised_in_model
145
- get '/test/model_error'
97
+ get '/error/model_error'
146
98
  assert_error_reported_once('this is an uncaught model error')
147
99
  end
148
100
 
149
101
  def test_should_capture_noticed_error_in_controller
150
- get '/test/noticed_error'
102
+ get '/error/noticed_error'
151
103
  assert_error_reported_once('this error should be noticed')
152
104
  end
153
105
 
106
+ # Important choice of controllor_error, since this goes through both the
107
+ # metric_frame and the rack error collector, so risks multiple counting!
108
+ def test_should_capture_multiple_errors
109
+ 40.times do
110
+ get '/error/controller_error'
111
+ end
112
+
113
+ assert_errors_reported('this is an uncaught controller error', 20, 40)
114
+ end
115
+
154
116
  def test_should_capture_manually_noticed_error
155
117
  NewRelic::Agent.notice_error(RuntimeError.new('this is a noticed error'))
156
118
  assert_error_reported_once('this is a noticed error')
@@ -170,13 +132,13 @@ class ErrorsWithoutSSCTest < TestControllerTest
170
132
  end
171
133
 
172
134
  def test_should_not_notice_errors_from_ignored_action
173
- get '/test/ignored_action'
135
+ get '/error/ignored_action'
174
136
  assert(@error_collector.errors.empty?,
175
137
  'Noticed an error that should have been ignored')
176
138
  end
177
139
 
178
140
  def test_should_not_notice_ignored_error_classes
179
- get '/test/ignored_error'
141
+ get '/error/ignored_error'
180
142
  assert(@error_collector.errors.empty?,
181
143
  'Noticed an error that should have been ignored')
182
144
  end
@@ -192,35 +154,36 @@ class ErrorsWithoutSSCTest < TestControllerTest
192
154
  end
193
155
 
194
156
  def test_should_notice_server_ignored_error_if_no_server_side_config
195
- get '/test/server_ignored_error'
157
+ get '/error/server_ignored_error'
196
158
  assert_error_reported_once('this is a server ignored error')
197
159
  end
198
160
 
199
- protected
161
+ protected
162
+
163
+ def assert_errors_reported(message, queued_count, total_count=queued_count)
164
+ error_count = NewRelic::Agent::Agent.instance.stats_engine.get_stats("Errors/all")
165
+ assert_equal total_count, error_count.call_count
166
+
167
+ assert_equal(queued_count,
168
+ @error_collector.errors.select{|error| error.message == message}.size,
169
+ "Wrong number of errors with message '#{message} found'")
170
+ end
200
171
 
201
172
  def assert_error_reported_once(message)
202
- assert_equal(message,
203
- @error_collector.errors[0].message,
204
- 'This error type was not detected')
205
- assert_equal(1, @error_collector.errors.size,
206
- 'Too many of this error type was detected')
173
+ assert_errors_reported(message, 1)
207
174
  end
208
175
  end
209
176
 
210
177
  class ErrorsWithSSCTest < ErrorsWithoutSSCTest
211
- def setup
212
- super
213
- @service.mock['connect'] = {
178
+ def setup_collector
179
+ $collector.mock['connect'] = [200, {'return_value' => {
214
180
  "listen_to_server_config" => true,
215
181
  "agent_run_id" => 1,
216
182
  "error_collector.ignore_errors" => 'IgnoredError,ServerIgnoredError',
217
183
  "error_collector.enabled" => true,
218
184
  "error_collector.capture_source" => true,
219
185
  "collect_errors" => true
220
- }
221
-
222
- # Force us to apply the mocked connect values to our configuration
223
- NewRelic::Agent.instance.query_server_for_configuration
186
+ }}]
224
187
  end
225
188
 
226
189
  def test_should_notice_server_ignored_error_if_no_server_side_config
@@ -228,7 +191,7 @@ class ErrorsWithSSCTest < ErrorsWithoutSSCTest
228
191
  end
229
192
 
230
193
  def test_should_ignore_server_ignored_errors
231
- get '/test/server_ignored_error'
194
+ get '/error/server_ignored_error'
232
195
  assert(@error_collector.errors.empty?,
233
196
  'Noticed an error that should have been ignored')
234
197
  end
@@ -0,0 +1,79 @@
1
+ require './app'
2
+
3
+ # GC instrumentation only works with REE or 1.9.x
4
+ if (defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /Enterprise/) ||
5
+ RUBY_VERSION >= '1.9.2'
6
+
7
+ class GcController < ApplicationController
8
+ include Rails.application.routes.url_helpers
9
+ def gc_action
10
+ long_string = "01234567" * 100_000
11
+ long_string = nil
12
+ another_long_string = "01234567" * 100_000
13
+
14
+ GC.start
15
+
16
+ render :text => 'ha'
17
+ end
18
+ end
19
+
20
+ class GCRailsInstrumentationTest < ActionController::TestCase
21
+ tests GcController
22
+ def setup
23
+ enable_gc_stats
24
+
25
+ @controller = GcController.new
26
+ NewRelic::Agent.instance.stats_engine.reset_stats
27
+ NewRelic::Agent.instance.transaction_sampler.instance_variable_set(:@samples, [])
28
+ NewRelic::Agent.manual_start
29
+ end
30
+
31
+ def teardown
32
+ NewRelic::Agent.shutdown
33
+ end
34
+
35
+ def test_records_accurate_time_for_gc_activity
36
+ start = Time.now
37
+ get :gc_action
38
+ elapsed = Time.now.to_f - start.to_f
39
+
40
+ assert_in_range(elapsed, get_call_time('GC/cumulative'))
41
+ assert_in_range(elapsed, get_call_time('GC/cumulative', 'Controller/gc/gc_action'))
42
+ end
43
+
44
+ def test_records_transaction_param_for_gc_activity
45
+ start = Time.now.to_f
46
+ get :gc_action
47
+ elapsed = Time.now.to_f - start
48
+
49
+ trace = NewRelic::Agent.instance.transaction_sampler.last_sample
50
+ assert_in_range(elapsed, trace.params[:custom_params][:gc_time])
51
+ end
52
+
53
+ def assert_in_range(duration, gc_time)
54
+ assert gc_time > 0.0, "GC Time wasn't recorded!"
55
+
56
+ # This is a guess for a reasonable threshold here.
57
+ # Since these are timing based, we can revise or ditch as evidence ditacts
58
+ # One CI failure we saw at least had duration=0.314 and gc_time=0.088
59
+ ratio = gc_time / duration
60
+ assert(ratio > 0.1 && ratio < 1.0,
61
+ "Problem with GC/duration ratio. #{gc_time}/#{duration} = #{ratio} not between 0.1 and 1.0")
62
+ end
63
+
64
+ def get_call_time(name, scope=nil)
65
+ NewRelic::Agent.agent.stats_engine.
66
+ get_stats(name, true, false, scope).
67
+ total_call_time
68
+ end
69
+
70
+ def enable_gc_stats
71
+ if RUBY_DESCRIPTION =~ /Enterprise/
72
+ GC.enable_stats
73
+ elsif RUBY_VERSION >= '1.9.2'
74
+ GC::Profiler.enable
75
+ end
76
+ end
77
+ end
78
+
79
+ end