newrelic_rpm 3.7.0.177 → 3.7.1.180

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +28 -1
  3. data/lib/new_relic/agent.rb +1 -2
  4. data/lib/new_relic/agent/agent.rb +28 -10
  5. data/lib/new_relic/agent/agent_logger.rb +4 -3
  6. data/lib/new_relic/agent/audit_logger.rb +5 -8
  7. data/lib/new_relic/agent/configuration/default_source.rb +24 -0
  8. data/lib/new_relic/agent/cross_app_tracing.rb +21 -15
  9. data/lib/new_relic/agent/datastores/mongo.rb +25 -0
  10. data/lib/new_relic/agent/datastores/mongo/metric_generator.rb +25 -0
  11. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +189 -0
  12. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +39 -0
  13. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +52 -0
  14. data/lib/new_relic/agent/harvester.rb +55 -0
  15. data/lib/new_relic/agent/instrumentation/mongo.rb +139 -0
  16. data/lib/new_relic/agent/instrumentation/net.rb +6 -11
  17. data/lib/new_relic/agent/supported_versions.rb +9 -5
  18. data/lib/new_relic/agent/transaction_sampler.rb +4 -0
  19. data/lib/new_relic/version.rb +1 -1
  20. data/lib/tasks/versions.rake +1 -1
  21. data/test/agent_helper.rb +4 -0
  22. data/test/environments/norails/Gemfile +3 -0
  23. data/test/environments/rails40/Gemfile +5 -1
  24. data/test/flaky_proxy/Gemfile +3 -0
  25. data/test/flaky_proxy/README.md +82 -0
  26. data/test/flaky_proxy/lib/flaky_proxy.rb +22 -0
  27. data/test/flaky_proxy/lib/flaky_proxy/connection.rb +45 -0
  28. data/test/flaky_proxy/lib/flaky_proxy/http_message.rb +105 -0
  29. data/test/flaky_proxy/lib/flaky_proxy/proxy.rb +42 -0
  30. data/test/flaky_proxy/lib/flaky_proxy/rule.rb +75 -0
  31. data/test/flaky_proxy/lib/flaky_proxy/rule_set.rb +37 -0
  32. data/test/flaky_proxy/lib/flaky_proxy/server.rb +22 -0
  33. data/test/flaky_proxy/script/flaky_proxy +39 -0
  34. data/test/helpers/exceptions.rb +16 -0
  35. data/test/helpers/mongo_metric_builder.rb +29 -0
  36. data/test/multiverse/lib/multiverse/suite.rb +1 -0
  37. data/test/multiverse/suites/curb/curb_test.rb +0 -1
  38. data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +4 -3
  39. data/test/multiverse/suites/excon/excon_test.rb +0 -1
  40. data/test/multiverse/suites/httpclient/httpclient_test.rb +0 -1
  41. data/test/multiverse/suites/mongo/Envfile +66 -0
  42. data/test/multiverse/suites/mongo/config/newrelic.yml +19 -0
  43. data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +418 -0
  44. data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +36 -0
  45. data/test/multiverse/suites/net_http/net_http_test.rb +2 -4
  46. data/test/multiverse/suites/rails/Envfile +4 -4
  47. data/test/multiverse/suites/rails/config/newrelic.yml +1 -1
  48. data/test/multiverse/suites/rails/error_tracing_test.rb +7 -7
  49. data/test/multiverse/suites/sidekiq/Envfile +1 -1
  50. data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +0 -1
  51. data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +5 -3
  52. data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +5 -3
  53. data/test/multiverse/suites/typhoeus/typhoeus_test.rb +0 -1
  54. data/test/new_relic/agent/agent_logger_test.rb +9 -1
  55. data/test/new_relic/agent/agent_test.rb +66 -1
  56. data/test/new_relic/agent/agent_test_controller.rb +1 -2
  57. data/test/new_relic/agent/audit_logger_test.rb +12 -4
  58. data/test/new_relic/agent/configuration/orphan_configuration_test.rb +11 -2
  59. data/test/new_relic/agent/cpu_sampler_test.rb +1 -0
  60. data/test/new_relic/agent/cross_app_tracing_test.rb +60 -0
  61. data/test/new_relic/agent/datastores/mongo/metric_generator_test.rb +43 -0
  62. data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +301 -0
  63. data/test/new_relic/agent/datastores/mongo/obfuscator_test.rb +91 -0
  64. data/test/new_relic/agent/datastores/mongo/statement_formatter_test.rb +71 -0
  65. data/test/new_relic/agent/harvester_test.rb +85 -0
  66. data/test/new_relic/agent/transaction_sampler_test.rb +5 -0
  67. data/test/new_relic/agent/worker_loop_test.rb +3 -5
  68. data/test/new_relic/http_client_test_cases.rb +65 -81
  69. data/test/new_relic/noticed_error_test.rb +14 -16
  70. data/test/performance/lib/performance.rb +1 -0
  71. data/test/performance/lib/performance/console_reporter.rb +6 -2
  72. data/test/performance/lib/performance/instrumentor.rb +1 -15
  73. data/test/performance/lib/performance/platform.rb +35 -0
  74. data/test/performance/lib/performance/test_case.rb +16 -1
  75. data/test/performance/suites/marshalling.rb +73 -0
  76. metadata +48 -19
  77. metadata.gz.sig +1 -2
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
6
+ require 'new_relic/agent/harvester'
7
+
8
+ module NewRelic
9
+ module Agent
10
+ class HarvesterTest < Test::Unit::TestCase
11
+
12
+ attr_reader :harvester
13
+ def setup
14
+ @after_forker = stub_everything
15
+ @harvester = Harvester.new(nil, @after_forker)
16
+ end
17
+
18
+ def test_marks_started_in_process
19
+ pretend_started_in_another_process
20
+
21
+ with_config(:restart_thread_in_children => true) do
22
+ harvester.on_transaction
23
+ end
24
+
25
+ assert_false harvester.needs_restart?
26
+ end
27
+
28
+ def test_skips_out_early_if_already_started
29
+ harvester.mark_started
30
+ ::Mutex.any_instance.expects(:synchronize).never
31
+
32
+ with_config(:restart_thread_in_children => true) do
33
+ harvester.on_transaction
34
+ end
35
+ end
36
+
37
+ def test_doesnt_call_to_restart_by_default
38
+ pretend_started_in_another_process
39
+ @after_forker.expects(:after_fork).never
40
+
41
+ harvester.on_transaction
42
+ end
43
+
44
+ def test_doesnt_call_to_restart_if_explicitly_disabled
45
+ pretend_started_in_another_process
46
+ @after_forker.expects(:after_fork).never
47
+
48
+ with_config(:restart_thread_in_children => false) do
49
+ harvester.on_transaction
50
+ end
51
+ end
52
+
53
+ def test_calls_to_restart
54
+ pretend_started_in_another_process
55
+ @after_forker.expects(:after_fork).once
56
+
57
+ with_config(:restart_thread_in_children => true) do
58
+ harvester.on_transaction
59
+ end
60
+ end
61
+
62
+ def test_calls_to_restart_only_once
63
+ pretend_started_in_another_process
64
+ @after_forker.expects(:after_fork).once
65
+
66
+ with_config(:restart_thread_in_children => true) do
67
+ threads = []
68
+ 100.times do
69
+ threads << Thread.new do
70
+ harvester.on_transaction
71
+ end
72
+ end
73
+
74
+ threads.each do |thread|
75
+ thread.join
76
+ end
77
+ end
78
+ end
79
+
80
+ def pretend_started_in_another_process
81
+ harvester.mark_started(Process.pid - 1)
82
+ end
83
+ end
84
+ end
85
+ end
@@ -260,6 +260,11 @@ class NewRelic::Agent::TransactionSamplerTest < Test::Unit::TestCase
260
260
  @sampler.notice_nosql('a key', 1.0)
261
261
  end
262
262
 
263
+ def test_notice_nosql_statement
264
+ @sampler.expects(:notice_extra_data).with('query data', 1.0, :statement)
265
+ @sampler.notice_nosql_statement('query data', 1.0)
266
+ end
267
+
263
268
  def test_harvest_when_disabled
264
269
  with_config(:'transaction_tracer.enabled' => false,
265
270
  :developer_mode => false) do
@@ -61,13 +61,11 @@ class NewRelic::Agent::WorkerLoopTest < Test::Unit::TestCase
61
61
  assert done
62
62
  end
63
63
 
64
- class Supernova < StandardError; end
65
-
66
64
  def test_task_error__exception
67
65
  expects_logging(:error, any_parameters)
68
66
  @worker_loop.run(0) do
69
67
  @worker_loop.stop
70
- raise Supernova, "oops"
68
+ raise NewRelic::TestHelper::Exception::TestError, "oops"
71
69
  end
72
70
  end
73
71
 
@@ -77,9 +75,9 @@ class NewRelic::Agent::WorkerLoopTest < Test::Unit::TestCase
77
75
  :propagate_errors => true
78
76
  )
79
77
 
80
- assert_raises Supernova do
78
+ assert_raises NewRelic::TestHelpers::Exceptions::TestError do
81
79
  @worker_loop.run(0) do
82
- raise Supernova
80
+ raise NewRelic::TestHelpers::Exceptions::TestError
83
81
  end
84
82
  end
85
83
  end
@@ -116,12 +116,7 @@ module HttpClientTestCases
116
116
  res = get_response
117
117
 
118
118
  assert_match %r/<head>/i, body(res)
119
- assert_metrics_recorded([
120
- "External/all",
121
- "External/localhost/#{client_name}/GET",
122
- "External/allOther",
123
- "External/localhost/all"
124
- ])
119
+ assert_externals_recorded_for("localhost", "GET")
125
120
  end
126
121
 
127
122
  # Although rare, some clients do explicitly set the "host" header on their
@@ -134,12 +129,7 @@ module HttpClientTestCases
134
129
  res = get_response(uri.to_s, 'Host' => 'test.local')
135
130
 
136
131
  assert_match %r/<head>/i, body(res)
137
- assert_metrics_recorded([
138
- "External/all",
139
- "External/test.local/#{client_name}/GET",
140
- "External/allOther",
141
- "External/test.local/all"
142
- ])
132
+ assert_externals_recorded_for("test.local", "GET")
143
133
  end
144
134
 
145
135
  def test_get_with_host_header_lowercase
@@ -148,12 +138,7 @@ module HttpClientTestCases
148
138
  res = get_response(uri.to_s, 'host' => 'test.local')
149
139
 
150
140
  assert_match %r/<head>/i, body(res)
151
- assert_metrics_recorded([
152
- "External/all",
153
- "External/test.local/#{client_name}/GET",
154
- "External/allOther",
155
- "External/test.local/all"
156
- ])
141
+ assert_externals_recorded_for("test.local", "GET")
157
142
  end
158
143
 
159
144
  # Only some HTTP clients support explicit connection reuse, so this test
@@ -168,12 +153,7 @@ module HttpClientTestCases
168
153
  end
169
154
 
170
155
  expected = { :call_count => n }
171
- assert_metrics_recorded(
172
- "External/all" => expected,
173
- "External/localhost/#{client_name}/GET" => expected,
174
- "External/allOther" => expected,
175
- "External/localhost/all" => expected
176
- )
156
+ assert_externals_recorded_for("localhost", "GET", :counts => expected)
177
157
  end
178
158
  end
179
159
 
@@ -185,11 +165,8 @@ module HttpClientTestCases
185
165
  end
186
166
 
187
167
  assert_match %r/<head>/i, body(res)
168
+ assert_externals_recorded_for("localhost", "GET")
188
169
  assert_metrics_recorded([
189
- "External/all",
190
- "External/allOther",
191
- "External/localhost/all",
192
- "External/localhost/#{client_name}/GET",
193
170
  ["External/localhost/#{client_name}/GET", "OtherTransaction/Background/#{self.class.name}/task"],
194
171
  "OtherTransaction/Background/#{self.class.name}/task",
195
172
  "OtherTransaction/Background/all",
@@ -205,11 +182,8 @@ module HttpClientTestCases
205
182
  end
206
183
 
207
184
  assert_match %r/<head>/i, body(res)
185
+ assert_externals_recorded_for("localhost", "GET", :transaction_type => "Web")
208
186
  assert_metrics_recorded([
209
- "External/all",
210
- "External/localhost/#{client_name}/GET",
211
- "External/allWeb",
212
- "External/localhost/all",
213
187
  "Controller/#{self.class.name}/task"
214
188
  ])
215
189
 
@@ -240,46 +214,22 @@ module HttpClientTestCases
240
214
 
241
215
  def test_head
242
216
  res = head_response
243
-
244
- assert_metrics_recorded([
245
- "External/all",
246
- "External/localhost/#{client_name}/HEAD",
247
- "External/allOther",
248
- "External/localhost/all"
249
- ])
217
+ assert_externals_recorded_for("localhost", "HEAD")
250
218
  end
251
219
 
252
220
  def test_post
253
221
  post_response
254
-
255
- assert_metrics_recorded([
256
- "External/all",
257
- "External/localhost/#{client_name}/POST",
258
- "External/allOther",
259
- "External/localhost/all"
260
- ])
222
+ assert_externals_recorded_for("localhost", "POST")
261
223
  end
262
224
 
263
225
  def test_put
264
226
  put_response
265
-
266
- assert_metrics_recorded([
267
- "External/all",
268
- "External/localhost/#{client_name}/PUT",
269
- "External/allOther",
270
- "External/localhost/all"
271
- ])
227
+ assert_externals_recorded_for("localhost", "PUT")
272
228
  end
273
229
 
274
230
  def test_delete
275
231
  delete_response
276
-
277
- assert_metrics_recorded([
278
- "External/all",
279
- "External/localhost/#{client_name}/DELETE",
280
- "External/allOther",
281
- "External/localhost/all"
282
- ])
232
+ assert_externals_recorded_for("localhost", "DELETE")
283
233
  end
284
234
 
285
235
  # When an http call is made, the agent should add a request header named
@@ -329,13 +279,8 @@ module HttpClientTestCases
329
279
  end
330
280
  end
331
281
 
332
- assert_metrics_recorded([
333
- "External/all",
334
- "External/allOther",
335
- "External/localhost/all",
336
- "External/localhost/#{client_name}/GET",
337
- ["External/localhost/#{client_name}/GET", "test"]
338
- ])
282
+ assert_externals_recorded_for("localhost", "GET")
283
+ assert_metrics_recorded([["External/localhost/#{client_name}/GET", "test"]])
339
284
  end
340
285
 
341
286
  def test_instrumentation_with_crossapp_disabled_records_normal_metrics_even_if_header_is_present
@@ -346,13 +291,8 @@ module HttpClientTestCases
346
291
  get_response
347
292
  end
348
293
 
349
- assert_metrics_recorded([
350
- "External/all",
351
- "External/allOther",
352
- "External/localhost/all",
353
- "External/localhost/#{client_name}/GET",
354
- ["External/localhost/#{client_name}/GET", "test"]
355
- ])
294
+ assert_externals_recorded_for("localhost", "GET")
295
+ assert_metrics_recorded([["External/localhost/#{client_name}/GET", "test"]])
356
296
  end
357
297
 
358
298
  def test_instrumentation_with_crossapp_enabled_records_crossapp_metrics_if_header_present
@@ -413,13 +353,8 @@ module HttpClientTestCases
413
353
  end
414
354
  end
415
355
 
416
- assert_metrics_recorded([
417
- "External/all",
418
- "External/allOther",
419
- "External/localhost/#{client_name}/GET",
420
- "External/localhost/all",
421
- ["External/localhost/#{client_name}/GET", "test"]
422
- ])
356
+ assert_externals_recorded_for("localhost", "GET")
357
+ assert_metrics_recorded([["External/localhost/#{client_name}/GET", "test"]])
423
358
  end
424
359
 
425
360
  def test_doesnt_affect_the_request_if_an_exception_is_raised_while_setting_up_tracing
@@ -475,6 +410,34 @@ module HttpClientTestCases
475
410
  end
476
411
  end
477
412
 
413
+ # https://newrelic.atlassian.net/browse/RUBY-1244
414
+ def test_failure_in_our_start_code_still_records_externals
415
+ # Fake a failure in our start-up code...
416
+ NewRelic.stubs(:json_dump).raises("Boom!")
417
+
418
+ with_config(:"cross_application_tracer.enabled" => true) do
419
+ get_response
420
+ end
421
+
422
+ assert_externals_recorded_for("localhost", "GET")
423
+ end
424
+
425
+ # https://newrelic.atlassian.net/browse/RUBY-1244
426
+ def test_failure_to_add_tt_node_doesnt_append_params_to_wrong_segment
427
+ # Fake a failure in our start-up code...
428
+ NewRelic.stubs(:json_dump).raises("Boom!")
429
+
430
+ in_transaction do
431
+ with_config(:"cross_application_tracer.enabled" => true) do
432
+ get_response
433
+
434
+ last_segment = find_last_transaction_segment()
435
+ refute last_segment.params.key?(:uri)
436
+ end
437
+ end
438
+ end
439
+
440
+
478
441
  def test_still_records_tt_node_when_request_fails
479
442
  # This test does not work on older versions of Typhoeus, because the
480
443
  # on_complete callback is not reliably invoked. That said, it's a corner
@@ -509,4 +472,25 @@ module HttpClientTestCases
509
472
  return obfuscator.obfuscate( args.to_json ) + "\n"
510
473
  end
511
474
 
475
+ def assert_externals_recorded_for(host, meth, opts={})
476
+ txn_type = opts.fetch(:transaction_type, "Other")
477
+ counts = opts.fetch(:counts, nil)
478
+
479
+ if counts.nil?
480
+ assert_metrics_recorded([
481
+ "External/all",
482
+ "External/all#{txn_type}",
483
+ "External/#{host}/#{client_name}/#{meth}",
484
+ "External/#{host}/all"
485
+ ])
486
+ else
487
+ assert_metrics_recorded(
488
+ "External/all" => counts,
489
+ "External/all#{txn_type}" => counts,
490
+ "External/#{host}/#{client_name}/#{meth}" => counts,
491
+ "External/#{host}/all" => counts
492
+ )
493
+ end
494
+ end
495
+
512
496
  end
@@ -4,11 +4,9 @@
4
4
 
5
5
  require File.expand_path(File.join(File.dirname(__FILE__),'..','test_helper'))
6
6
 
7
- class NoticedErrorTestException < StandardError; end
8
- class ParentException < Exception; end
9
- class ChildException < ParentException; end
10
-
11
7
  class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
8
+ include NewRelic::TestHelpers::Exceptions
9
+
12
10
  def setup
13
11
  @path = 'foo/bar/baz'
14
12
  @params = { 'key' => 'val' }
@@ -16,10 +14,10 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
16
14
  end
17
15
 
18
16
  def test_to_collector_array
19
- e = NoticedErrorTestException.new('test exception')
17
+ e = TestError.new('test exception')
20
18
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
21
19
  expected = [
22
- (@time.to_f * 1000).round, @path, 'test exception', 'NoticedErrorTestException', @params
20
+ (@time.to_f * 1000).round, @path, 'test exception', 'NewRelic::TestHelpers::Exceptions::TestError', @params
23
21
  ]
24
22
  assert_equal expected, error.to_collector_array
25
23
  end
@@ -40,7 +38,7 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
40
38
 
41
39
  def test_strips_message_from_exceptions_in_high_security_mode
42
40
  with_config(:high_security => true) do
43
- e = NoticedErrorTestException.new('test exception')
41
+ e = TestError.new('test exception')
44
42
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
45
43
 
46
44
  assert_equal NewRelic::NoticedError::STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE, error.message
@@ -48,8 +46,8 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
48
46
  end
49
47
 
50
48
  def test_permits_messages_from_whitelisted_exceptions_in_high_security_mode
51
- with_config(:'strip_exception_messages.whitelist' => 'NoticedErrorTestException') do
52
- e = NoticedErrorTestException.new('whitelisted test exception')
49
+ with_config(:'strip_exception_messages.whitelist' => 'NewRelic::TestHelpers::Exceptions::TestError') do
50
+ e = TestError.new('whitelisted test exception')
53
51
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
54
52
 
55
53
  assert_equal 'whitelisted test exception', error.message
@@ -58,7 +56,7 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
58
56
 
59
57
  def test_whitelisted_returns_nil_with_an_empty_whitelist
60
58
  with_config(:'strip_exception_messages.whitelist' => '') do
61
- e = NoticedErrorTestException.new('whitelisted test exception')
59
+ e = TestError.new('whitelisted test exception')
62
60
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
63
61
 
64
62
  assert_falsy error.whitelisted?
@@ -67,7 +65,7 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
67
65
 
68
66
  def test_whitelisted_returns_nil_when_error_is_not_in_whitelist
69
67
  with_config(:'strip_exception_messages.whitelist' => 'YourErrorIsInAnotherCastle') do
70
- e = NoticedErrorTestException.new('whitelisted test exception')
68
+ e = TestError.new('whitelisted test exception')
71
69
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
72
70
 
73
71
  assert_falsy error.whitelisted?
@@ -75,8 +73,8 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
75
73
  end
76
74
 
77
75
  def test_whitelisted_is_true_when_error_is_in_whitelist
78
- with_config(:'strip_exception_messages.whitelist' => 'OtherException,NoticedErrorTestException') do
79
- test_exception_class = NoticedErrorTestException
76
+ with_config(:'strip_exception_messages.whitelist' => 'OtherException,NewRelic::TestHelpers::Exceptions::TestError') do
77
+ test_exception_class = TestError
80
78
  e = test_exception_class.new('whitelisted test exception')
81
79
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
82
80
 
@@ -85,8 +83,8 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
85
83
  end
86
84
 
87
85
  def test_whitelisted_ignores_nonexistent_exception_types_in_whitelist
88
- with_config(:'strip_exception_messages.whitelist' => 'NonExistent::Exception,NoticedErrorTestException') do
89
- test_exception_class = NoticedErrorTestException
86
+ with_config(:'strip_exception_messages.whitelist' => 'NonExistent::Exception,NewRelic::TestHelpers::Exceptions::TestError') do
87
+ test_exception_class = TestError
90
88
  e = test_exception_class.new('whitelisted test exception')
91
89
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
92
90
 
@@ -95,7 +93,7 @@ class NewRelic::Agent::NoticedErrorTest < Test::Unit::TestCase
95
93
  end
96
94
 
97
95
  def test_whitelisted_is_true_when_an_exceptions_ancestor_is_whitelisted
98
- with_config(:'strip_exception_messages.whitelist' => 'ParentException') do
96
+ with_config(:'strip_exception_messages.whitelist' => 'NewRelic::TestHelpers::Exceptions::ParentException') do
99
97
  e = ChildException.new('whitelisted test exception')
100
98
  error = NewRelic::NoticedError.new(@path, @params, e, @time)
101
99