newrelic_rpm 3.7.0.174.beta → 3.7.0.177

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +27 -4
  3. data/bin/nrdebug +10 -4
  4. data/lib/new_relic/agent.rb +33 -11
  5. data/lib/new_relic/agent/agent.rb +83 -120
  6. data/lib/new_relic/agent/agent_logger.rb +28 -16
  7. data/lib/new_relic/agent/audit_logger.rb +3 -4
  8. data/lib/new_relic/agent/autostart.rb +20 -8
  9. data/lib/new_relic/agent/commands/agent_command_router.rb +26 -17
  10. data/lib/new_relic/agent/commands/thread_profiler_session.rb +2 -2
  11. data/lib/new_relic/agent/configuration/default_source.rb +146 -59
  12. data/lib/new_relic/agent/configuration/manager.rb +3 -3
  13. data/lib/new_relic/agent/cross_app_monitor.rb +15 -40
  14. data/lib/new_relic/agent/cross_app_tracing.rb +20 -12
  15. data/lib/new_relic/agent/database.rb +24 -0
  16. data/lib/new_relic/agent/error_collector.rb +6 -2
  17. data/lib/new_relic/agent/instrumentation/merb/controller.rb +3 -1
  18. data/lib/new_relic/agent/javascript_instrumentor.rb +187 -0
  19. data/lib/new_relic/agent/new_relic_service.rb +30 -22
  20. data/lib/new_relic/agent/obfuscator.rb +48 -0
  21. data/lib/new_relic/agent/request_sampler.rb +5 -13
  22. data/lib/new_relic/agent/shim_agent.rb +1 -0
  23. data/lib/new_relic/agent/sql_sampler.rb +15 -5
  24. data/lib/new_relic/agent/stats_engine/metric_stats.rb +9 -4
  25. data/lib/new_relic/agent/transaction.rb +0 -1
  26. data/lib/new_relic/agent/transaction_sampler.rb +28 -16
  27. data/lib/new_relic/agent/transaction_state.rb +9 -0
  28. data/lib/new_relic/agent/transaction_timings.rb +5 -1
  29. data/lib/new_relic/agent/worker_loop.rb +0 -10
  30. data/lib/new_relic/cli/deployments.rb +1 -1
  31. data/lib/new_relic/control/instance_methods.rb +1 -1
  32. data/lib/new_relic/helper.rb +3 -1
  33. data/lib/new_relic/rack/browser_monitoring.rb +1 -2
  34. data/lib/new_relic/transaction_sample.rb +11 -13
  35. data/lib/newrelic_rpm.rb +1 -0
  36. data/test/agent_helper.rb +20 -5
  37. data/test/environments/lib/environments/runner.rb +1 -0
  38. data/test/helpers/file_searching.rb +28 -0
  39. data/test/multiverse/lib/multiverse/suite.rb +36 -19
  40. data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +49 -0
  41. data/test/multiverse/suites/agent_only/http_response_code_test.rb +2 -2
  42. data/test/multiverse/suites/agent_only/rum_instrumentation_test.rb +4 -2
  43. data/test/multiverse/suites/agent_only/service_timeout_test.rb +1 -1
  44. data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +7 -4
  45. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +2 -1
  46. data/test/multiverse/suites/rails/error_tracing_test.rb +34 -4
  47. data/test/multiverse/suites/rails/ignore_test.rb +1 -1
  48. data/test/multiverse/suites/rails/request_statistics_test.rb +1 -3
  49. data/test/multiverse/suites/sequel/sequel_instrumentation_test.rb +10 -7
  50. data/test/multiverse/suites/sinatra/ignoring_test.rb +1 -1
  51. data/test/new_relic/agent/agent/start_worker_thread_test.rb +1 -1
  52. data/test/new_relic/agent/agent_logger_test.rb +108 -114
  53. data/test/new_relic/agent/agent_test.rb +139 -21
  54. data/test/new_relic/agent/audit_logger_test.rb +22 -20
  55. data/test/new_relic/agent/autostart_test.rb +3 -2
  56. data/test/new_relic/agent/commands/agent_command_router_test.rb +51 -32
  57. data/test/new_relic/agent/configuration/default_source_test.rb +8 -2
  58. data/test/new_relic/agent/configuration/manager_test.rb +5 -1
  59. data/test/new_relic/agent/configuration/orphan_configuration_test.rb +57 -0
  60. data/test/new_relic/agent/cross_app_monitor_test.rb +10 -26
  61. data/test/new_relic/agent/database_test.rb +32 -0
  62. data/test/new_relic/agent/error_collector_test.rb +33 -16
  63. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +88 -71
  64. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
  65. data/test/new_relic/agent/javascript_instrumentor_test.rb +341 -0
  66. data/test/new_relic/agent/memcache_instrumentation_test.rb +91 -89
  67. data/test/new_relic/agent/method_tracer_test.rb +1 -1
  68. data/test/new_relic/agent/obfuscator_test.rb +77 -0
  69. data/test/new_relic/agent/pipe_channel_manager_test.rb +5 -5
  70. data/test/new_relic/agent/pipe_service_test.rb +1 -1
  71. data/test/new_relic/agent/request_sampler_test.rb +21 -11
  72. data/test/new_relic/agent/sql_sampler_test.rb +52 -8
  73. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +6 -6
  74. data/test/new_relic/agent/stats_engine_test.rb +18 -2
  75. data/test/new_relic/agent/transaction_sampler_test.rb +98 -53
  76. data/test/new_relic/agent/transaction_state_test.rb +44 -0
  77. data/test/new_relic/agent/transaction_test.rb +1 -1
  78. data/test/new_relic/agent/transaction_timings_test.rb +15 -5
  79. data/test/new_relic/agent/worker_loop_test.rb +0 -9
  80. data/test/new_relic/agent_test.rb +9 -21
  81. data/test/new_relic/data_container_tests.rb +72 -0
  82. data/test/new_relic/fake_collector.rb +69 -20
  83. data/test/new_relic/http_client_test_cases.rb +17 -2
  84. data/test/new_relic/license_test.rb +6 -15
  85. data/test/new_relic/multiverse_helpers.rb +2 -3
  86. data/test/new_relic/rack/browser_monitoring_test.rb +15 -37
  87. data/test/new_relic/transaction_sample_test.rb +92 -62
  88. data/test/performance/suites/rum_autoinsertion.rb +0 -3
  89. data/test/rum/x_ua_meta_tag_spaces_around_equals.result.html +10 -0
  90. data/test/rum/x_ua_meta_tag_spaces_around_equals.source.html +10 -0
  91. data/test/test_helper.rb +9 -5
  92. metadata +29 -11
  93. metadata.gz.sig +0 -0
  94. data/lib/new_relic/agent/beacon_configuration.rb +0 -37
  95. data/lib/new_relic/agent/browser_monitoring.rb +0 -257
  96. data/test/new_relic/agent/beacon_configuration_test.rb +0 -44
  97. data/test/new_relic/agent/browser_monitoring_test.rb +0 -474
@@ -31,7 +31,7 @@ class IgnoredActionsTest < ActionDispatch::IntegrationTest
31
31
 
32
32
  def after_setup
33
33
  # Make sure we've got a blank slate for doing easier metric comparisons
34
- NewRelic::Agent.instance.reset_stats
34
+ NewRelic::Agent.instance.drop_buffered_data
35
35
  end
36
36
 
37
37
  def test_metric__ignore
@@ -97,9 +97,7 @@ class RequestStatsTest < ActionController::TestCase
97
97
 
98
98
  # fail once
99
99
  $collector.stub('analytic_event_data', {}, 503)
100
- assert_raises(NewRelic::Agent::ServerConnectionException) do
101
- NewRelic::Agent.agent.send(:harvest_and_send_analytic_event_data)
102
- end
100
+ NewRelic::Agent.agent.send(:harvest_and_send_analytic_event_data)
103
101
 
104
102
  # recover
105
103
  $collector.stub('analytic_event_data', {'return_value'=>nil}, 200)
@@ -200,8 +200,9 @@ class NewRelic::Agent::Instrumentation::SequelInstrumentationTest < MiniTest::Un
200
200
  end
201
201
 
202
202
  def test_slow_queries_get_an_explain_plan
203
- with_config( :'transaction_tracer.explain_threshold' => 0.0 ) do
204
- segment = last_segment_for(:record_sql => :raw) do
203
+ with_config( :'transaction_tracer.explain_threshold' => -0.01,
204
+ :'transaction_tracer.record_sql' => 'raw' ) do
205
+ segment = last_segment_for do
205
206
  Post[11]
206
207
  end
207
208
  assert_match %r{select \* from `posts` where `id` = 11}i, segment.params[:sql]
@@ -210,7 +211,11 @@ class NewRelic::Agent::Instrumentation::SequelInstrumentationTest < MiniTest::Un
210
211
  end
211
212
 
212
213
  def test_queries_can_get_explain_plan_with_obfuscated_sql
213
- with_config( :'transaction_tracer.explain_threshold' => 0.0 ) do
214
+ config = {
215
+ :'transaction_tracer.explain_threshold' => -0.01,
216
+ :'transaction_tracer.record_sql' => 'obfuscated'
217
+ }
218
+ with_config(config) do
214
219
  segment = last_segment_for(:record_sql => :obfuscated) do
215
220
  Post[11]
216
221
  end
@@ -262,10 +267,8 @@ class NewRelic::Agent::Instrumentation::SequelInstrumentationTest < MiniTest::Un
262
267
  yield
263
268
  end
264
269
 
265
- sample = transaction_samples.first.prepare_to_send!(
266
- :explain_sql=>options[:explain_sql] || -0.01, # Force to take explain, even if duration's reported as 0.0
267
- :record_sql=>options[:record_sql])
268
- segment = last_segment( sample )
270
+ sample = transaction_samples.first.prepare_to_send!
271
+ last_segment( sample )
269
272
  end
270
273
 
271
274
  def last_segment(txn_sample)
@@ -155,7 +155,7 @@ class SinatraIgnoreItAllTest < SinatraTestCase
155
155
 
156
156
  def test_ignores_everything
157
157
  # Avoid Supportability metrics from startup of agent for this check
158
- NewRelic::Agent.instance.reset_stats
158
+ NewRelic::Agent.drop_buffered_data
159
159
 
160
160
  get_and_assert_ok '/'
161
161
  assert_metrics_recorded_exclusive([])
@@ -38,7 +38,7 @@ class NewRelic::Agent::Agent::StartWorkerThreadTest < Test::Unit::TestCase
38
38
  # hooray for methods with no branches
39
39
  error = mock(:message => 'a message')
40
40
 
41
- self.expects(:reset_stats)
41
+ self.expects(:drop_buffered_data)
42
42
  self.expects(:sleep).with(30)
43
43
  @connected = true
44
44
 
@@ -25,24 +25,21 @@ class AgentLoggerTest < Test::Unit::TestCase
25
25
  LEVELS = [:fatal, :error, :warn, :info, :debug]
26
26
 
27
27
  def setup
28
- @config = {
29
- :log_file_path => "log/",
30
- :log_file_name => "testlog.log",
31
- :log_level => :info,
32
- }
28
+ NewRelic::Agent.config.apply_config(:log_file_path => "log/",
29
+ :log_file_name => "testlog.log",
30
+ :log_level => :info)
33
31
  end
34
32
 
35
-
36
33
  #
37
34
  # Tests
38
35
  #
39
36
 
40
37
  def test_initalizes_from_config
41
- logger = NewRelic::Agent::AgentLogger.new(@config)
38
+ logger = NewRelic::Agent::AgentLogger.new
42
39
 
43
40
  wrapped_logger = logger.instance_variable_get( :@log )
44
41
  logdev = wrapped_logger.instance_variable_get( :@logdev )
45
- expected_logpath = File.expand_path( @config[:log_file_path] + @config[:log_file_name] )
42
+ expected_logpath = File.expand_path( NewRelic::Agent.config[:log_file_path] + NewRelic::Agent.config[:log_file_name] )
46
43
 
47
44
  assert_kind_of( Logger, wrapped_logger )
48
45
  assert_kind_of( File, logdev.dev )
@@ -51,64 +48,62 @@ class AgentLoggerTest < Test::Unit::TestCase
51
48
 
52
49
  def test_initalizes_from_override
53
50
  override_logger = Logger.new( '/dev/null' )
54
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
51
+ logger = NewRelic::Agent::AgentLogger.new("", override_logger)
55
52
  assert_equal override_logger, logger.instance_variable_get(:@log)
56
53
  end
57
54
 
58
-
59
55
  def test_forwards_calls_to_logger
60
- logdev = ArrayLogDevice.new
61
- override_logger = Logger.new( logdev )
62
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
56
+ logger = create_basic_logger
63
57
 
64
58
  LEVELS.each do |level|
65
59
  logger.send(level, "Boo!")
66
60
  end
67
61
 
68
- assert_equal 4, logdev.array.length # No DEBUG
69
-
70
- assert_match( /FATAL/, logdev.array[0] )
71
- assert_match( /ERROR/, logdev.array[1] )
72
- assert_match( /WARN/, logdev.array[2] )
73
- assert_match( /INFO/, logdev.array[3] )
62
+ assert_logged(/FATAL/,
63
+ /ERROR/,
64
+ /WARN/,
65
+ /INFO/) # No DEBUG
74
66
  end
75
67
 
76
-
77
68
  def test_forwards_calls_to_logger_with_multiple_arguments
78
- logdev = ArrayLogDevice.new
79
- override_logger = Logger.new( logdev )
80
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
69
+ logger = create_basic_logger
81
70
 
82
71
  LEVELS.each do |level|
83
72
  logger.send(level, "What", "up?")
84
73
  end
85
74
 
86
- assert_equal 8, logdev.array.length # No DEBUG, two per level
75
+ assert_logged(/FATAL/, /FATAL/,
76
+ /ERROR/, /ERROR/,
77
+ /WARN/, /WARN/,
78
+ /INFO/, /INFO/) # No DEBUG
79
+ end
80
+
81
+ def test_forwards_calls_to_logger_once
82
+ logger = create_basic_logger
87
83
 
88
- assert_match( /FATAL/, logdev.array[0] )
89
- assert_match( /FATAL/, logdev.array[1] )
90
- assert_match( /ERROR/, logdev.array[2] )
91
- assert_match( /ERROR/, logdev.array[3] )
92
- assert_match( /WARN/, logdev.array[4] )
93
- assert_match( /WARN/, logdev.array[5] )
94
- assert_match( /INFO/, logdev.array[6] )
95
- assert_match( /INFO/, logdev.array[7] )
84
+ LEVELS.each do |level|
85
+ logger.send(:log_once, level, :special_key, "Special!")
86
+ end
87
+
88
+ assert_logged(/Special/)
96
89
  end
97
90
 
98
91
  def test_wont_log_if_agent_not_enabled
99
- @config[:agent_enabled] = false
100
- logger = NewRelic::Agent::AgentLogger.new(@config)
101
- assert_nothing_raised do
102
- logger.warn('hi there')
103
- end
92
+ with_config(:agent_enabled => false) do
93
+ logger = NewRelic::Agent::AgentLogger.new
94
+ assert_nothing_raised do
95
+ logger.warn('hi there')
96
+ end
104
97
 
105
- assert_kind_of NewRelic::Agent::NullLogger, logger.instance_variable_get( :@log )
98
+ assert_kind_of NewRelic::Agent::NullLogger, logger.instance_variable_get( :@log )
99
+ end
106
100
  end
107
101
 
108
102
  def test_does_not_touch_dev_null
109
103
  Logger.expects(:new).with('/dev/null').never
110
- @config[:agent_enabled] = false
111
- logger = NewRelic::Agent::AgentLogger.new(@config)
104
+ with_config(:agent_enabled => false) do
105
+ logger = NewRelic::Agent::AgentLogger.new
106
+ end
112
107
  end
113
108
 
114
109
  def test_maps_log_levels
@@ -123,38 +118,39 @@ class AgentLoggerTest < Test::Unit::TestCase
123
118
  end
124
119
 
125
120
  def test_sets_log_level
126
- @config[:log_level] = :debug
127
-
128
- override_logger = Logger.new( $stderr )
129
- override_logger.level = Logger::FATAL
121
+ with_config(:log_level => :debug) do
122
+ override_logger = Logger.new( $stderr )
123
+ override_logger.level = Logger::FATAL
130
124
 
131
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
125
+ logger = NewRelic::Agent::AgentLogger.new("", override_logger)
132
126
 
133
- assert_equal Logger::DEBUG, override_logger.level
127
+ assert_equal Logger::DEBUG, override_logger.level
128
+ end
134
129
  end
135
130
 
136
131
  def test_log_to_stdout_and_warns_if_failed_on_create
137
- Dir.stubs(:mkdir).returns(nil)
138
- config = @config.merge( :log_file_path => '/someplace/non/existant' )
132
+ Dir.stubs(:mkdir).returns(nil)
139
133
 
140
- logger = with_squelched_stdout do
141
- NewRelic::Agent::AgentLogger.new(config)
142
- end
134
+ with_config(:log_file_path => '/someplace/nonexistent') do
135
+ logger = with_squelched_stdout do
136
+ NewRelic::Agent::AgentLogger.new
137
+ end
143
138
 
144
- wrapped_logger = logger.instance_variable_get(:@log)
145
- logdev = wrapped_logger.instance_variable_get(:@logdev)
139
+ wrapped_logger = logger.instance_variable_get(:@log)
140
+ logdev = wrapped_logger.instance_variable_get(:@logdev)
146
141
 
147
- assert_equal $stdout, logdev.dev
142
+ assert_equal $stdout, logdev.dev
143
+ end
148
144
  end
149
145
 
150
146
  def test_log_to_stdout_based_on_config
151
- @config[:log_file_path] = "STDOUT"
147
+ with_config(:log_file_path => 'STDOUT') do
148
+ logger = NewRelic::Agent::AgentLogger.new
149
+ wrapped_logger = logger.instance_variable_get(:@log)
150
+ logdev = wrapped_logger.instance_variable_get(:@logdev)
152
151
 
153
- logger = NewRelic::Agent::AgentLogger.new(@config)
154
- wrapped_logger = logger.instance_variable_get(:@log)
155
- logdev = wrapped_logger.instance_variable_get(:@logdev)
156
-
157
- assert_equal $stdout, logdev.dev
152
+ assert_equal $stdout, logdev.dev
153
+ end
158
154
  end
159
155
 
160
156
  def test_startup_purges_memory_logger
@@ -162,22 +158,16 @@ class AgentLoggerTest < Test::Unit::TestCase
162
158
  ::NewRelic::Agent::StartupLogger.instance.send(level, "boo!")
163
159
  end
164
160
 
165
- logdev = ArrayLogDevice.new
166
- override_logger = Logger.new( logdev )
167
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
161
+ logger = create_basic_logger
168
162
 
169
- assert_equal 4, logdev.array.length # No DEBUG
170
-
171
- assert_match( /FATAL/, logdev.array[0] )
172
- assert_match( /ERROR/, logdev.array[1] )
173
- assert_match( /WARN/, logdev.array[2] )
174
- assert_match( /INFO/, logdev.array[3] )
163
+ assert_logged(/FATAL/,
164
+ /ERROR/,
165
+ /WARN/,
166
+ /INFO/) # No DEBUG
175
167
  end
176
168
 
177
169
  def test_passing_exceptions_only_logs_the_message_at_levels_higher_than_debug
178
- logdev = ArrayLogDevice.new
179
- override_logger = Logger.new( logdev )
180
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
170
+ logger = create_basic_logger
181
171
 
182
172
  begin
183
173
  raise "Something bad happened"
@@ -185,80 +175,66 @@ class AgentLoggerTest < Test::Unit::TestCase
185
175
  logger.error( err )
186
176
  end
187
177
 
188
- assert_equal 1, logdev.array.length
189
- assert_match( /ERROR : RuntimeError: Something bad happened/i, logdev.array[0] )
178
+ assert_logged(/ERROR : RuntimeError: Something bad happened/i)
190
179
  end
191
180
 
192
181
  def test_passing_exceptions_logs_the_backtrace_at_debug_level
193
- config = @config.merge(:log_level => :debug)
182
+ with_config(:log_level => :debug) do
183
+ logger = create_basic_logger
194
184
 
195
- logdev = ArrayLogDevice.new
196
- override_logger = Logger.new( logdev )
197
- logger = NewRelic::Agent::AgentLogger.new(config, "", override_logger)
185
+ begin
186
+ raise "Something bad happened"
187
+ rescue => err
188
+ logger.error( err )
189
+ end
198
190
 
199
- begin
200
- raise "Something bad happened"
201
- rescue => err
202
- logger.error( err )
191
+ assert_logged(/ERROR : RuntimeError: Something bad happened/i,
192
+ /DEBUG : Debugging backtrace:\n.*test_passing_exceptions/i)
203
193
  end
204
-
205
- assert_equal 2, logdev.array.length
206
- assert_match( /ERROR : RuntimeError: Something bad happened/i, logdev.array[0] )
207
- assert_match( /DEBUG : Debugging backtrace:\n.*test_passing_exceptions/i,
208
- logdev.array[1] )
209
194
  end
210
195
 
211
196
  def test_format_message_allows_nil_backtrace
212
- config = @config.merge(:log_level => :debug)
213
-
214
- logdev = ArrayLogDevice.new
215
- override_logger = Logger.new( logdev )
216
- logger = NewRelic::Agent::AgentLogger.new(config, "", override_logger)
197
+ with_config(:log_level => :debug) do
198
+ logger = create_basic_logger
217
199
 
218
- e = Exception.new("Look Ma, no backtrace!")
219
- assert_nil(e.backtrace)
220
- logger.error(e)
200
+ e = Exception.new("Look Ma, no backtrace!")
201
+ assert_nil(e.backtrace)
202
+ logger.error(e)
221
203
 
222
- assert_equal 2, logdev.array.length
223
- assert_match( /ERROR : Exception: Look Ma, no backtrace!/i, logdev.array[0] )
224
- assert_match( /DEBUG : No backtrace available./, logdev.array[1])
204
+ assert_logged(/ERROR : Exception: Look Ma, no backtrace!/i,
205
+ /DEBUG : No backtrace available./)
206
+ end
225
207
  end
226
208
 
227
209
  def test_log_exception_logs_backtrace_at_same_level_as_message_by_default
228
- logdev = ArrayLogDevice.new
229
- override_logger = Logger.new(logdev)
230
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
210
+ logger = create_basic_logger
231
211
 
232
212
  e = Exception.new("howdy")
233
213
  e.set_backtrace(["wiggle", "wobble", "topple"])
234
214
 
235
215
  logger.log_exception(:info, e)
236
216
 
237
- assert_match(/INFO : Exception: howdy/i, logdev.array[0])
238
- assert_match(/INFO : Debugging backtrace:\n.*wiggle\s+wobble\s+topple/,
239
- logdev.array[1])
217
+ assert_logged(/INFO : Exception: howdy/i,
218
+ /INFO : Debugging backtrace:\n.*wiggle\s+wobble\s+topple/)
240
219
  end
241
220
 
242
221
  def test_log_exception_logs_backtrace_at_explicitly_specified_level
243
- logdev = ArrayLogDevice.new
244
- override_logger = Logger.new(logdev)
245
- logger = NewRelic::Agent::AgentLogger.new(@config, "", override_logger)
222
+ logger = create_basic_logger
246
223
 
247
224
  e = Exception.new("howdy")
248
225
  e.set_backtrace(["wiggle", "wobble", "topple"])
249
226
 
250
227
  logger.log_exception(:warn, e, :info)
251
228
 
252
- assert_match(/WARN : Exception: howdy/i, logdev.array[0])
253
- assert_match(/INFO : Debugging backtrace:\n.*wiggle\s+wobble\s+topple/,
254
- logdev.array[1])
229
+ assert_logged(/WARN : Exception: howdy/i,
230
+ /INFO : Debugging backtrace:\n.*wiggle\s+wobble\s+topple/)
255
231
  end
256
232
 
257
233
  def test_logs_to_stdout_if_fails_on_file
258
234
  Logger::LogDevice.any_instance.stubs(:open).raises(Errno::EACCES)
259
235
 
260
236
  logger = with_squelched_stdout do
261
- NewRelic::Agent::AgentLogger.new(@config, "")
237
+ NewRelic::Agent::AgentLogger.new
262
238
  end
263
239
 
264
240
  wrapped_logger = logger.instance_variable_get(:@log)
@@ -272,9 +248,11 @@ class AgentLoggerTest < Test::Unit::TestCase
272
248
  def debug; end
273
249
  end
274
250
 
275
- logger = NewRelic::Agent::AgentLogger.new(@config.merge(:agent_enabled => false))
276
- assert_nothing_raised do
277
- logger.debug('hi!')
251
+ logger = NewRelic::Agent::AgentLogger.new
252
+ with_config(:agent_enabled => false) do
253
+ assert_nothing_raised do
254
+ logger.debug('hi!')
255
+ end
278
256
  end
279
257
  ensure
280
258
  Kernel.module_eval do
@@ -288,6 +266,16 @@ class AgentLoggerTest < Test::Unit::TestCase
288
266
  # Helpers
289
267
  #
290
268
 
269
+ def logged_lines
270
+ @logdev.array
271
+ end
272
+
273
+ def create_basic_logger
274
+ @logdev = ArrayLogDevice.new
275
+ override_logger = Logger.new(@logdev)
276
+ NewRelic::Agent::AgentLogger.new("", override_logger)
277
+ end
278
+
291
279
  def with_squelched_stdout
292
280
  orig = $stdout.dup
293
281
  $stdout.reopen( '/dev/null' )
@@ -296,4 +284,10 @@ class AgentLoggerTest < Test::Unit::TestCase
296
284
  $stdout.reopen( orig )
297
285
  end
298
286
 
287
+ def assert_logged(*args)
288
+ assert_equal(args.length, logged_lines.length)
289
+ logged_lines.each_with_index do |line, index|
290
+ assert_match(args[index], line)
291
+ end
292
+ end
299
293
  end
@@ -78,6 +78,7 @@ module NewRelic
78
78
 
79
79
  def test_transmit_data_should_transmit
80
80
  @agent.service.expects(:metric_data).at_least_once
81
+ @agent.stats_engine.record_metrics(['foo'], 12)
81
82
  @agent.instance_eval { transmit_data }
82
83
  end
83
84
 
@@ -100,10 +101,8 @@ module NewRelic
100
101
  :transaction_name => nil,
101
102
  :force_persist => true,
102
103
  :truncate => 4000)
103
- trace.expects(:prepare_to_send!).with(:record_sql => :raw,
104
- :explain_sql => 2)
105
104
 
106
- @agent.transaction_sampler.stubs(:harvest).returns([trace])
105
+ @agent.transaction_sampler.stubs(:harvest!).returns([trace])
107
106
  @agent.send :harvest_and_send_transaction_traces
108
107
  end
109
108
  end
@@ -111,10 +110,7 @@ module NewRelic
111
110
  def test_harvest_and_send_transaction_traces_merges_back_on_failure
112
111
  traces = [mock('tt1'), mock('tt2')]
113
112
 
114
- # make prepare_to_send just return self
115
- traces.each { |tt| tt.expects(:prepare_to_send!).returns(tt) }
116
-
117
- @agent.transaction_sampler.expects(:harvest).returns(traces)
113
+ @agent.transaction_sampler.expects(:harvest!).returns(traces)
118
114
  @agent.service.stubs(:transaction_sample_data).raises("wat")
119
115
  @agent.transaction_sampler.expects(:merge!).with(traces)
120
116
 
@@ -126,7 +122,7 @@ module NewRelic
126
122
  def test_harvest_and_send_errors_merges_back_on_failure
127
123
  errors = [mock('e0'), mock('e1')]
128
124
 
129
- @agent.error_collector.expects(:harvest_errors).returns(errors)
125
+ @agent.error_collector.expects(:harvest!).returns(errors)
130
126
  @agent.service.stubs(:error_data).raises('wat')
131
127
  @agent.error_collector.expects(:merge!).with(errors)
132
128
 
@@ -135,11 +131,6 @@ module NewRelic
135
131
  end
136
132
  end
137
133
 
138
- def test_harvest_timeslice_data
139
- assert_equal({}, @agent.send(:harvest_timeslice_data),
140
- 'should return timeslice data')
141
- end
142
-
143
134
  # This test asserts nothing about correctness of logging data from multiple
144
135
  # threads, since the get_stats + record_data_point combo is not designed
145
136
  # to be thread-safe, but it does ensure that writes to the stats hash
@@ -161,7 +152,7 @@ module NewRelic
161
152
  threads << t
162
153
  end
163
154
 
164
- 100.times { @agent.send(:harvest_timeslice_data) }
155
+ 100.times { @agent.send(:harvest_and_send_timeslice_data) }
165
156
  threads.each { |t| t.join }
166
157
  end
167
158
  end
@@ -171,9 +162,16 @@ module NewRelic
171
162
  @agent.send :check_for_and_handle_agent_commands
172
163
  end
173
164
 
165
+ def test_check_for_and_handle_agent_commands_with_error
166
+ @agent.service.expects(:get_agent_commands).raises('bad news')
167
+ assert_nothing_raised do
168
+ @agent.send :check_for_and_handle_agent_commands
169
+ end
170
+ end
171
+
174
172
  def test_harvest_and_send_for_agent_commands
175
173
  @agent.service.expects(:profile_data).with(any_parameters)
176
- @agent.agent_command_router.stubs(:harvest_data_to_send).returns({:profile_data => Object.new})
174
+ @agent.agent_command_router.stubs(:harvest!).returns({:profile_data => [Object.new]})
177
175
  @agent.send :harvest_and_send_for_agent_commands
178
176
  end
179
177
 
@@ -211,21 +209,19 @@ module NewRelic
211
209
  request_sampler = @agent.instance_variable_get(:@request_sampler)
212
210
  samples = [mock('some analytics event')]
213
211
 
214
- request_sampler.expects(:harvest).returns(samples)
212
+ request_sampler.expects(:harvest!).returns(samples)
215
213
  request_sampler.expects(:merge!).with(samples)
216
214
 
217
215
  # simulate a failure in transmitting analytics events
218
216
  service.stubs(:analytic_event_data).raises(StandardError.new)
219
217
 
220
- assert_raises(StandardError) do
221
- @agent.send(:harvest_and_send_analytic_event_data)
222
- end
218
+ @agent.send(:harvest_and_send_analytic_event_data)
223
219
  end
224
220
 
225
221
  def test_harvest_and_send_timeslice_data_merges_back_on_failure
226
- timeslices = mock('timeslices')
222
+ timeslices = [1,2,3]
227
223
 
228
- @agent.stats_engine.expects(:harvest).returns(timeslices)
224
+ @agent.stats_engine.expects(:harvest!).returns(timeslices)
229
225
  @agent.service.stubs(:metric_data).raises('wat')
230
226
  @agent.stats_engine.expects(:merge!).with(timeslices)
231
227
 
@@ -353,6 +349,128 @@ module NewRelic
353
349
  assert done
354
350
  end
355
351
 
352
+ def test_harvest_from_container
353
+ container = mock
354
+ harvested_items = ['foo', 'bar', 'baz']
355
+ container.expects(:harvest!).returns(harvested_items)
356
+ items = @agent.send(:harvest_from_container, container, 'digglewumpus')
357
+ assert_equal(harvested_items, items)
358
+ end
359
+
360
+ def test_harvest_from_container_with_error
361
+ container = mock
362
+ container.stubs(:harvest!).raises('an error')
363
+ container.expects(:reset!)
364
+ @agent.send(:harvest_from_container, container, 'digglewumpus')
365
+ end
366
+
367
+ def send_data_from_container
368
+ service = @agent.service
369
+ items = [1, 2, 3]
370
+ service.expects(:dummy_endpoint).with(items)
371
+ @agent.send(:send_data_from_container, stub, 'dummy_endpoint', items)
372
+ end
373
+
374
+ def send_data_from_container_with_unrecoverable_server_error
375
+ service = @agent.service
376
+ container = mock('data container')
377
+ container.expects(:merge!).never
378
+ items = [1, 2, 3]
379
+ service.expects(:dummy_endpoint).raises(UnrecoverableServerException)
380
+ @agent.send(:send_data_from_container, container, 'dummy_endpoint', items)
381
+ end
382
+
383
+ def send_data_from_container_with_other_error
384
+ service = @agent.service
385
+ items = [1, 2, 3]
386
+ container = mock('data container')
387
+ container.expects(:merge!).with(items)
388
+ service.expects(:dummy_endpoint).raises('other errors')
389
+ @agent.send(:send_data_from_container, container, 'dummy_endpoint', items)
390
+ end
391
+
392
+ def harvest_and_send_from_container
393
+ container = mock('data container')
394
+ items = [1, 2, 3]
395
+ container.expects(:harvest!).returns(items)
396
+ service = @agent.service
397
+ service.expects(:dummy_endpoint).with(items)
398
+ @agent.send(:harvest_and_send_from_container, container, 'dummy_endpoint')
399
+ end
400
+
401
+ def harvest_and_send_from_container_does_not_harvest_if_nothing_to_send
402
+ container = mock('data container')
403
+ items = []
404
+ container.expects(:harvest!).returns(items)
405
+ service = @agent.service
406
+ service.expects(:dummy_endpoint).never
407
+ @agent.send(:harvest_and_send_from_container, container, 'dummy_endpoint')
408
+ end
409
+
410
+ def harvest_and_send_from_container_resets_on_harvest_failure
411
+ container = mock('data container')
412
+ container.stubs(:harvest!).raises('an error')
413
+ container.expects(:reset!)
414
+ @agent.service.expects(:dummy_endpoint).never
415
+ @agent.send(:harvest_and_send_from_container, container, 'dummy_endpoint')
416
+ end
417
+
418
+ def harvest_and_send_from_container_does_not_merge_on_unrecoverable_failure
419
+ container = mock('data container')
420
+ container.stubs(:harvest!).returns([1,2,3])
421
+ @agent.service.expects(:dummy_endpoint).with([1,2,3]).raises(UnrecoverableServerException)
422
+ container.expects(:merge!).never
423
+ @agent.send(:harvest_and_send_from_container, container, 'dummy_endpoint')
424
+ end
425
+
426
+ def harvest_and_send_from_container_merges_on_other_failure
427
+ container = mock('data container')
428
+ container.stubs(:harvest!).returns([1,2,3])
429
+ @agent.service.expects(:dummy_endpoint).with([1,2,3]).raises('other error')
430
+ container.expects(:merge!).with([1,2,3])
431
+ @agent.send(:harvest_and_send_from_container, container, 'dummy_endpoint')
432
+ end
433
+
434
+ def test_harvest_and_send_from_container_does_not_swallow_forced_errors
435
+ container = mock('data container')
436
+ container.stubs(:harvest!).returns([1])
437
+
438
+ error_classes = [
439
+ NewRelic::Agent::ForceRestartException,
440
+ NewRelic::Agent::ForceDisconnectException
441
+ ]
442
+
443
+ error_classes.each do |cls|
444
+ @agent.service.expects(:dummy_endpoint).with([1]).raises(cls.new)
445
+ assert_raise(cls) do
446
+ @agent.send(:harvest_and_send_from_container, container, 'dummy_endpoint')
447
+ end
448
+ end
449
+ end
450
+
451
+ def test_check_for_and_handle_agent_commands_does_not_swallow_forced_errors
452
+ error_classes = [
453
+ NewRelic::Agent::ForceRestartException,
454
+ NewRelic::Agent::ForceDisconnectException
455
+ ]
456
+
457
+ error_classes.each do |cls|
458
+ @agent.service.expects(:get_agent_commands).raises(cls.new)
459
+ assert_raise(cls) do
460
+ @agent.send(:check_for_and_handle_agent_commands)
461
+ end
462
+ end
463
+ end
464
+
465
+ def test_graceful_disconnect_should_emit_before_disconnect_event
466
+ before_shutdown_call_count = 0
467
+ @agent.events.subscribe(:before_shutdown) do
468
+ before_shutdown_call_count += 1
469
+ end
470
+ @agent.stubs(:connected?).returns(true)
471
+ @agent.send(:graceful_disconnect)
472
+ assert_equal(1, before_shutdown_call_count)
473
+ end
356
474
  end
357
475
 
358
476