wd_newrelic_rpm 3.5.5 → 3.5.6

Sign up to get free protection for your applications and to get access to all the features.
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