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,15 @@
1
+ require 'resque'
2
+ require 'newrelic_rpm'
3
+
4
+ redis_port = ENV["NEWRELIC_MULTIVERSE_REDIS_PORT"]
5
+ $redis = Redis.new(:port => redis_port)
6
+ Resque.redis = $redis
7
+
8
+ class JobForTesting
9
+ @queue = :resque_test
10
+
11
+ def self.perform(key, val, sleep_duration=0)
12
+ sleep sleep_duration
13
+ $redis.set(key, val)
14
+ end
15
+ end
@@ -12,7 +12,7 @@ development:
12
12
  app_name: test
13
13
  host: 127.0.0.1
14
14
  api_host: 127.0.0.1
15
- port: 30303
15
+ port: <%= 30_000 + ($$ % 10_000) %>
16
16
  transaction_tracer:
17
17
  record_sql: obfuscated
18
18
  enabled: true
@@ -20,5 +20,4 @@ development:
20
20
  transaction_threshold: 1.0
21
21
  capture_params: false
22
22
  log_level: debug
23
- #log_file_path: STDOUT
24
23
  disable_serialization: false
@@ -0,0 +1,38 @@
1
+ class SinatraErrorTracingTestApp < Sinatra::Base
2
+ configure do
3
+ set :show_exceptions, false
4
+ end
5
+
6
+ get '/will_boom' do
7
+ raise 'Boom!'
8
+ end
9
+
10
+ error do
11
+ 'We are sorry'
12
+ end
13
+ end
14
+
15
+ class SinatraErrorTracingTest < Test::Unit::TestCase
16
+ include Rack::Test::Methods
17
+ include ::NewRelic::Agent::Instrumentation::Sinatra
18
+
19
+ def app
20
+ SinatraErrorTracingTestApp
21
+ end
22
+
23
+ def setup
24
+ ::NewRelic::Agent.manual_start
25
+ @error_collector = ::NewRelic::Agent.instance.error_collector
26
+
27
+ assert(@error_collector.enabled?,
28
+ 'error collector should be enabled')
29
+ end
30
+
31
+ def test_traps_errors
32
+ get '/will_boom'
33
+ assert_equal 500, last_response.status
34
+ assert_equal 'We are sorry', last_response.body
35
+
36
+ assert_equal(1, @error_collector.errors.size)
37
+ end
38
+ end
@@ -8,6 +8,9 @@ class SinatraRouteTestApp < Sinatra::Base
8
8
  halt 404 unless boolean
9
9
  end
10
10
  end
11
+
12
+ # treat errors like production for testing purposes
13
+ set :show_exceptions, false
11
14
  end
12
15
 
13
16
  get '/user/login' do
@@ -18,6 +21,11 @@ class SinatraRouteTestApp < Sinatra::Base
18
21
  get '/user/:id', :my_condition => false do |id|
19
22
  "Welcome #{id}"
20
23
  end
24
+
25
+ get '/error' do
26
+ raise "Uh-oh"
27
+ end
28
+
21
29
  end
22
30
 
23
31
  class SinatraTest < Test::Unit::TestCase
@@ -32,6 +40,10 @@ class SinatraTest < Test::Unit::TestCase
32
40
  ::NewRelic::Agent.manual_start
33
41
  end
34
42
 
43
+ def teardown
44
+ ::NewRelic::Agent.agent.error_collector.harvest_errors([])
45
+ end
46
+
35
47
  # https://support.newrelic.com/tickets/24779
36
48
  def test_lower_priority_route_conditions_arent_applied_to_higher_priority_routes
37
49
  get '/user/login'
@@ -52,4 +64,9 @@ class SinatraTest < Test::Unit::TestCase
52
64
  assert metric_names.include?("WebFrontend/WebServer/all")
53
65
  assert ::NewRelic::Agent.agent.stats_engine.get_stats("WebFrontend/WebServer/all")
54
66
  end
67
+
68
+ def test_shown_errors_get_caught
69
+ get '/error'
70
+ assert_equal 1, ::NewRelic::Agent.agent.error_collector.errors.size
71
+ end
55
72
  end
@@ -13,7 +13,7 @@ development:
13
13
  app_name: test
14
14
  host: 127.0.0.1
15
15
  api_host: 127.0.0.1
16
- port: 30303
16
+ port: <%= 30_000 + ($$ % 10_000) %>
17
17
  transaction_tracer:
18
18
  record_sql: obfuscated
19
19
  enabled: true
@@ -13,7 +13,7 @@ development:
13
13
  app_name: test
14
14
  host: 127.0.0.1
15
15
  api_host: 127.0.0.1
16
- port: 30303
16
+ port: <%= 30_000 + ($$ % 10_000) %>
17
17
  transaction_tracer:
18
18
  record_sql: obfuscated
19
19
  enabled: true
@@ -8,7 +8,7 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
8
8
  def setup
9
9
  @connected = nil
10
10
  @keep_retrying = nil
11
- @connect_attempts = 1
11
+ @connect_attempts = 0
12
12
  @connect_retry_period = 0
13
13
  @transaction_sampler = NewRelic::Agent::TransactionSampler.new
14
14
  @sql_sampler = NewRelic::Agent::SqlSampler.new
@@ -33,76 +33,35 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
33
33
  fake_control
34
34
  end
35
35
 
36
- def test_tried_to_connect?
37
- # base case, should default to false
38
- assert !tried_to_connect?({})
36
+ def test_should_connect_if_pending
37
+ @connect_state = :pending
38
+ assert(should_connect?, "should attempt to connect if pending")
39
39
  end
40
40
 
41
- def test_tried_to_connect_connected
42
- # is true if connected is true.
43
- @connected = true
44
- assert tried_to_connect?({})
41
+ def test_should_not_connect_if_disconnected
42
+ @connect_state = :disconnected
43
+ assert(!should_connect?, "should not attempt to connect if force disconnected")
45
44
  end
46
45
 
47
- def test_tried_to_connect_forced
48
- # is false if force_reconnect is true
49
- assert !tried_to_connect?({:force_reconnect => true})
50
- end
51
-
52
- def test_should_keep_retrying_base
53
- # default to true
54
- should_keep_retrying?({})
55
- assert @keep_retrying, "should keep retrying by default"
56
- end
57
-
58
- def test_should_keep_retrying_option_true
59
- # should be true if keep_retrying is true
60
- should_keep_retrying?({:keep_retrying => true})
61
- end
62
-
63
- def test_get_retry_period
64
- (1..6).each do |x|
65
- @connect_attempts = x
66
- assert_equal get_retry_period, x * 60, "should be #{x} minutes"
67
- end
68
- @connect_attempts = 100
69
- assert_equal get_retry_period, 600, "should max out at 10 minutes after 6 tries"
46
+ def test_should_connect_if_forced
47
+ @connect_state = :disconnected
48
+ assert(should_connect?(true), "should connect if forced")
49
+ @connect_state = :connected
50
+ assert(should_connect?(true), "should connect if forced")
70
51
  end
71
52
 
72
53
  def test_increment_retry_period
73
- @connect_retry_period = 0
74
- @connect_attempts = 1
75
- assert_equal 0, connect_retry_period
76
- increment_retry_period!
77
- assert_equal 60, connect_retry_period
78
- end
79
-
80
- def test_should_retry_true
81
- @keep_retrying = true
82
- @connect_attempts = 1
83
- self.expects(:increment_retry_period!).once
84
- assert should_retry?, "should retry in this circumstance"
85
- assert_equal 2, @connect_attempts, "should be on the second attempt"
86
- end
87
-
88
- def test_should_retry_false
89
- @keep_retrying = false
90
- self.expects(:disconnect).once
91
- assert !should_retry?
54
+ 10.times do |i|
55
+ assert_equal((i * 60), connect_retry_period)
56
+ note_connect_failure
57
+ end
58
+ assert_equal(600, connect_retry_period)
92
59
  end
93
60
 
94
61
  def test_disconnect
95
62
  assert disconnect
96
63
  end
97
64
 
98
- def test_attr_accessor_connect_retry_period
99
- assert_accessor(:connect_retry_period)
100
- end
101
-
102
- def test_attr_accessor_connect_attempts
103
- assert_accessor(:connect_attempts)
104
- end
105
-
106
65
  def test_log_error
107
66
  error = StandardError.new("message")
108
67
 
@@ -224,9 +183,8 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
224
183
 
225
184
  def test_connect_to_server_gets_config_from_collector
226
185
  NewRelic::Agent.manual_start
227
- service = NewRelic::FakeService.new
228
- NewRelic::Agent::Agent.instance.service = service
229
- service.mock['connect'] = {'agent_run_id' => 23, 'config' => 'a lot'}
186
+ NewRelic::Agent::Agent.instance.service = default_service(
187
+ :connect => {'agent_run_id' => 23, 'config' => 'a lot'})
230
188
 
231
189
  response = NewRelic::Agent.agent.connect_to_server
232
190
 
@@ -242,8 +200,6 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
242
200
  'collect_traces' => true,
243
201
  'collect_errors' => true,
244
202
  'sample_rate' => 10,
245
- 'cross_process_id' => '1#234',
246
- 'encoding_key' => 'a' * 30,
247
203
  'agent_config' => { 'transaction_tracer.record_sql' => 'raw' }
248
204
  }
249
205
  self.expects(:log_connection!).with(config)
@@ -253,26 +209,18 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
253
209
  with_config(:'transaction_tracer.enabled' => true) do
254
210
  finish_setup(config)
255
211
  assert_equal 'fishsticks', @service.agent_id
256
- assert_equal '1#234', @cross_process_id
257
- assert_equal 'a' * 30, @cross_process_encoding_key
258
- assert_equal [97] * 30, @cross_process_encoding_bytes
259
212
  assert_equal 'raw', NewRelic::Agent.config[:'transaction_tracer.record_sql']
260
213
  end
261
214
  end
262
215
 
263
- def test_get_bytes_with_nil
264
- assert_equal [], get_bytes(nil)
265
- end
266
216
 
267
217
  def test_logging_collector_messages
268
218
  NewRelic::Agent.manual_start
269
- service = NewRelic::FakeService.new
270
- NewRelic::Agent::Agent.instance.service = service
271
- service.mock['connect'] = {
272
- 'agent_run_id' => 23, 'config' => 'a lot',
273
- 'messages' => [{ 'message' => 'beep boop', 'level' => 'INFO' },
274
- { 'message' => 'ha cha cha', 'level' => 'WARN' }]
275
- }
219
+ NewRelic::Agent::Agent.instance.service = default_service(
220
+ :connect => {
221
+ 'messages' => [{ 'message' => 'beep boop', 'level' => 'INFO' },
222
+ { 'message' => 'ha cha cha', 'level' => 'WARN' }]
223
+ })
276
224
 
277
225
  expects_logging(:info, 'beep boop')
278
226
  expects_logging(:warn, 'ha cha cha')
@@ -287,22 +235,6 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
287
235
  assert_equal 'blah', @service.agent_id
288
236
  end
289
237
 
290
- # no idea why this test leaks in Rails 2.0
291
- # will be moved to a multiverse test eventually anyway
292
- if !Rails::VERSION::STRING =~ /2\.0.*/
293
- def test_set_apdex_t_from_server
294
- service = NewRelic::FakeService.new
295
- NewRelic::Agent::Agent.instance.service = service
296
- service.mock['connect'] = { 'apdex_t' => 0.5 }
297
- with_config(:sync_startup => true, :monitor_mode => true,
298
- :license_key => 'a' * 40) do
299
- NewRelic::Agent.manual_start
300
- assert_equal 0.5, NewRelic::Agent.config[:apdex_t]
301
- NewRelic::Agent.shutdown
302
- end
303
- end
304
- end
305
-
306
238
  private
307
239
 
308
240
  def mocked_control
@@ -316,12 +248,4 @@ class NewRelic::Agent::Agent::ConnectTest < Test::Unit::TestCase
316
248
  self.stubs(:error_collector).returns(fake_collector)
317
249
  fake_collector
318
250
  end
319
-
320
- def assert_accessor(sym)
321
- var_name = "@#{sym}"
322
- instance_variable_set(var_name, 1)
323
- assert (self.send(sym) == 1)
324
- self.send(sym.to_s + '=', 10)
325
- assert (instance_variable_get(var_name) == 10)
326
- end
327
251
  end
@@ -6,7 +6,7 @@ class NewRelic::Agent::Agent::StartWorkerThreadTest < Test::Unit::TestCase
6
6
  def test_deferred_work_connects
7
7
  self.expects(:catch_errors).yields
8
8
  self.expects(:connect).with('connection_options')
9
- @connected = true
9
+ self.stubs(:connected?).returns(true)
10
10
  self.expects(:log_worker_loop_start)
11
11
  self.expects(:create_and_run_worker_loop)
12
12
  deferred_work!('connection_options')
@@ -15,7 +15,7 @@ class NewRelic::Agent::Agent::StartWorkerThreadTest < Test::Unit::TestCase
15
15
  def test_deferred_work_connect_failed
16
16
  self.expects(:catch_errors).yields
17
17
  self.expects(:connect).with('connection_options')
18
- @connected = false
18
+ self.stubs(:connected?).returns(false)
19
19
  deferred_work!('connection_options')
20
20
  end
21
21
 
@@ -43,7 +43,7 @@ class NewRelic::Agent::Agent::StartWorkerThreadTest < Test::Unit::TestCase
43
43
  handle_force_restart(error)
44
44
 
45
45
  assert_equal({}, @metric_ids)
46
- assert @connected.nil?
46
+ assert_equal(:pending, @connect_state)
47
47
  end
48
48
 
49
49
  def test_handle_force_disconnect
@@ -4,22 +4,59 @@ require 'new_relic/agent/thread_profiler'
4
4
  module NewRelic
5
5
  module Agent
6
6
  class AgentTest < Test::Unit::TestCase
7
+
7
8
  def setup
8
9
  super
9
10
  @agent = NewRelic::Agent::Agent.new
10
- @agent.service = NewRelic::FakeService.new
11
+ @agent.service = default_service
11
12
  end
12
13
 
14
+ #
15
+ # Helpers
16
+ #
17
+
18
+ def with_profile(opts)
19
+ profile = NewRelic::Agent::ThreadProfile.new(-1, 0, 0, true)
20
+ profile.aggregate(["chunky.rb:42:in `bacon'"], profile.traces[:other])
21
+ profile.instance_variable_set(:@finished, opts[:finished])
22
+
23
+ @agent.thread_profiler.instance_variable_set(:@profile, profile)
24
+ profile
25
+ end
26
+
27
+ #
28
+ # Tests
29
+ #
30
+
13
31
  def test_after_fork_reporting_to_channel
32
+ @agent.stubs(:connected?).returns(true)
14
33
  @agent.after_fork(:report_to_channel => 123)
15
34
  assert(@agent.service.kind_of?(NewRelic::Agent::PipeService),
16
35
  'Agent should use PipeService when directed to report to pipe channel')
36
+ NewRelic::Agent::PipeService.any_instance.expects(:shutdown).never
17
37
  assert_equal 123, @agent.service.channel_id
18
38
  end
19
39
 
40
+ def test_after_fork_should_close_pipe_if_parent_not_connected
41
+ pipe = mock
42
+ pipe.expects(:write).with('EOF')
43
+ pipe.expects(:close)
44
+ dummy_channels = { 123 => pipe }
45
+ NewRelic::Agent::PipeChannelManager.stubs(:channels).returns(dummy_channels)
46
+
47
+ @agent.stubs(:connected?).returns(false)
48
+ @agent.after_fork(:report_to_channel => 123)
49
+ assert(@agent.disconnected?)
50
+ end
51
+
20
52
  def test_transmit_data_should_transmit
53
+ @agent.service.expects(:metric_data).at_least_once
54
+ @agent.instance_eval { transmit_data }
55
+ end
56
+
57
+ def test_transmit_data_should_use_one_http_handle_per_harvest
58
+ @agent.service.expects(:session).once
21
59
  @agent.instance_eval { transmit_data }
22
- assert @agent.service.agent_data.any?
23
60
  end
24
61
 
25
62
  def test_transmit_data_should_close_explain_db_connections
@@ -57,43 +94,26 @@ module NewRelic
57
94
 
58
95
  def test_graceful_shutdown_ends_thread_profiling
59
96
  @agent.thread_profiler.expects(:stop).once
60
- @agent.instance_variable_set(:@connected, true)
61
-
97
+ @agent.stubs(:connected?).returns(true)
62
98
  @agent.send(:graceful_disconnect)
63
99
  end
64
100
 
65
101
  def test_harvest_and_send_thread_profile
66
102
  profile = with_profile(:finished => true)
103
+ @agent.service.expects(:profile_data).with(any_parameters)
67
104
  @agent.send(:harvest_and_send_thread_profile, false)
68
-
69
- assert_equal([profile],
70
- @agent.service.agent_data \
71
- .find{|data| data.action == :profile_data}.params)
72
105
  end
73
106
 
74
107
  def test_harvest_and_send_thread_profile_when_not_finished
75
108
  with_profile(:finished => false)
109
+ @agent.service.expects(:profile_data).never
76
110
  @agent.send(:harvest_and_send_thread_profile, false)
77
-
78
- assert_nil @agent.service.agent_data.find{|data| data.action == :profile_data}
79
111
  end
80
112
 
81
113
  def test_harvest_and_send_thread_profile_when_not_finished_but_disconnecting
82
114
  profile = with_profile(:finished => false)
115
+ @agent.service.expects(:profile_data).with(any_parameters)
83
116
  @agent.send(:harvest_and_send_thread_profile, true)
84
-
85
- assert_equal([profile],
86
- @agent.service.agent_data \
87
- .find{|data| data.action == :profile_data}.params)
88
- end
89
-
90
- def with_profile(opts)
91
- profile = NewRelic::Agent::ThreadProfile.new(-1, 0, 0, true)
92
- profile.aggregate(["chunky.rb:42:in `bacon'"], profile.traces[:other])
93
- profile.instance_variable_set(:@finished, opts[:finished])
94
-
95
- @agent.thread_profiler.instance_variable_set(:@profile, profile)
96
- profile
97
117
  end
98
118
 
99
119
  def test_harvest_timeslice_data
@@ -126,8 +146,8 @@ module NewRelic
126
146
  end
127
147
 
128
148
  def test_check_for_agent_commands
149
+ @agent.service.expects(:get_agent_commands).returns([]).once
129
150
  @agent.send :check_for_agent_commands
130
- assert_equal(1, @agent.service.calls_for(:get_agent_commands).size)
131
151
  end
132
152
 
133
153
  def test_merge_data_from_empty
@@ -186,18 +206,26 @@ module NewRelic
186
206
  assert_equal(1, @agent.unsent_timeslice_data, "should have the key from above")
187
207
  end
188
208
 
189
- def test_merge_data_from_all_three_empty
190
- unsent_timeslice_data = mock('unsent timeslice data')
191
- unsent_errors = mock('unsent errors')
209
+ def test_merge_data_traces
192
210
  unsent_traces = mock('unsent traces')
193
211
  @agent.instance_eval {
194
- @unsent_errors = unsent_errors
195
- @unsent_timeslice_data = unsent_timeslice_data
196
212
  @traces = unsent_traces
197
213
  }
198
214
  unsent_traces.expects(:+).with([1,2,3])
199
- unsent_errors.expects(:+).with([4,5,6])
200
- @agent.merge_data_from([{}, [1,2,3], [4,5,6]])
215
+ @agent.merge_data_from([{}, [1,2,3], []])
216
+ end
217
+
218
+ def test_merge_data_from_abides_by_error_queue_limit
219
+ errors = []
220
+ 40.times { |i| errors << Exception.new("boo #{i}") }
221
+
222
+ @agent.merge_data_from([{}, [], errors])
223
+
224
+ assert_equal 20, @agent.error_collector.errors.length
225
+
226
+ # This method should NOT increment error counts, since that has already
227
+ # been counted in the child
228
+ assert_equal 0, NewRelic::Agent.get_stats("Errors/all").call_count
201
229
  end
202
230
 
203
231
  def test_fill_metric_id_cache_from_collect_response
@@ -221,6 +249,73 @@ module NewRelic
221
249
  assert_equal 10, @agent.metric_ids[MetricSpec.new('WebFrontend/QueueTime')]
222
250
  assert_equal 1017, @agent.metric_ids[MetricSpec.new('ActiveRecord/Blog/find')]
223
251
  end
252
+
253
+ def test_connect_retries_on_timeout
254
+ service = @agent.service
255
+ def service.connect(opts={})
256
+ unless @tried
257
+ @tried = true
258
+ raise Timeout::Error
259
+ end
260
+ nil
261
+ end
262
+ @agent.stubs(:connect_retry_period).returns(0)
263
+ @agent.send(:connect)
264
+ assert(@agent.connected?)
265
+ end
266
+
267
+ def test_connect_does_not_retry_if_keep_retrying_false
268
+ @agent.service.expects(:connect).once.raises(Timeout::Error)
269
+ @agent.send(:connect, :keep_retrying => false)
270
+ assert(@agent.disconnected?)
271
+ end
272
+
273
+ def test_connect_does_not_retry_on_license_error
274
+ @agent.service.expects(:connect).raises(NewRelic::Agent::LicenseException)
275
+ @agent.send(:connect)
276
+ assert(@agent.disconnected?)
277
+ end
278
+
279
+ def test_connect_does_not_reconnect_by_default
280
+ @agent.stubs(:connected?).returns(true)
281
+ @agent.service.expects(:connect).never
282
+ @agent.send(:connect)
283
+ end
284
+
285
+ def test_connect_does_not_reconnect_if_disconnected
286
+ @agent.stubs(:disconnected?).returns(true)
287
+ @agent.service.expects(:connect).never
288
+ @agent.send(:connect)
289
+ end
290
+
291
+ def test_connect_does_reconnect_if_forced
292
+ @agent.stubs(:connected?).returns(true)
293
+ @agent.service.expects(:connect)
294
+ @agent.send(:connect, :force_reconnect => true)
295
+ end
296
+
297
+ def test_defer_start_if_resque_dispatcher_and_channel_manager_isnt_started
298
+ NewRelic::Agent::PipeChannelManager.listener.expects(:started?).returns(false)
299
+
300
+ # :send_data_on_exit setting to avoid setting an at_exit
301
+ with_config( :send_data_on_exit => false, :dispatcher => :resque ) do
302
+ @agent.start
303
+ end
304
+
305
+ assert !@agent.started?
306
+ end
307
+
308
+ def test_doesnt_defer_start_if_resque_dispatcher_and_channel_manager_started
309
+ NewRelic::Agent::PipeChannelManager.listener.expects(:started?).returns(true)
310
+
311
+ # :send_data_on_exit setting to avoid setting an at_exit
312
+ with_config( :send_data_on_exit => false, :dispatcher => :resque ) do
313
+ @agent.start
314
+ end
315
+
316
+ assert @agent.started?
317
+ end
318
+
224
319
  end
225
320
  end
226
321
  end