newrelic_rpm 3.14.1.311 → 3.14.2.312

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +174 -11
  3. data/CHANGELOG +22 -0
  4. data/Rakefile +5 -0
  5. data/lib/new_relic/agent/agent.rb +22 -7
  6. data/lib/new_relic/agent/aws_info.rb +1 -1
  7. data/lib/new_relic/agent/custom_event_aggregator.rb +19 -44
  8. data/lib/new_relic/agent/error_event_aggregator.rb +11 -103
  9. data/lib/new_relic/agent/event_aggregator.rb +130 -0
  10. data/lib/new_relic/agent/event_buffer.rb +7 -0
  11. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +18 -2
  12. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +12 -4
  13. data/lib/new_relic/agent/new_relic_service.rb +6 -4
  14. data/lib/new_relic/agent/sampled_buffer.rb +9 -6
  15. data/lib/new_relic/agent/stats_engine/metric_stats.rb +1 -2
  16. data/lib/new_relic/agent/stats_engine/stats_hash.rb +2 -1
  17. data/lib/new_relic/agent/supported_versions.rb +1 -1
  18. data/lib/new_relic/agent/synthetics_event_aggregator.rb +52 -0
  19. data/lib/new_relic/agent/synthetics_event_buffer.rb +0 -2
  20. data/lib/new_relic/agent/transaction.rb +14 -7
  21. data/lib/new_relic/agent/transaction/request_attributes.rb +7 -2
  22. data/lib/new_relic/agent/transaction_error_primitive.rb +72 -0
  23. data/lib/new_relic/agent/transaction_event_aggregator.rb +33 -210
  24. data/lib/new_relic/agent/transaction_event_primitive.rb +106 -0
  25. data/lib/new_relic/agent/transaction_event_recorder.rb +48 -0
  26. data/lib/new_relic/agent/transaction_metrics.rb +9 -1
  27. data/lib/new_relic/agent/transction_event_recorder.rb +35 -0
  28. data/lib/new_relic/recipes/capistrano3.rb +1 -1
  29. data/lib/new_relic/version.rb +1 -1
  30. data/lib/tasks/versions.html.erb +13 -11
  31. data/lib/tasks/versions.postface.html +8 -0
  32. data/lib/tasks/versions.preface.html +3 -0
  33. data/lib/tasks/versions.rake +15 -5
  34. data/test/agent_helper.rb +1 -1
  35. data/test/environments/rails31/Gemfile +2 -0
  36. data/test/environments/rails32/Gemfile +2 -0
  37. data/test/environments/rails32/Rakefile +2 -1
  38. data/test/environments/rails32/config/database.yml +1 -6
  39. data/test/multiverse/suites/active_record/Envfile +1 -0
  40. data/test/multiverse/suites/agent_only/agent_attributes_test.rb +18 -0
  41. data/test/multiverse/suites/agent_only/custom_analytics_events_test.rb +21 -6
  42. data/test/multiverse/suites/agent_only/error_events_test.rb +14 -6
  43. data/test/multiverse/suites/agent_only/transaction_events_test.rb +31 -0
  44. data/test/multiverse/suites/agent_only/utilization_data_collection_test.rb +2 -0
  45. data/test/multiverse/suites/capistrano/Envfile +9 -3
  46. data/test/multiverse/suites/capistrano2/Envfile +4 -0
  47. data/test/multiverse/suites/config_file_loading/Envfile +1 -1
  48. data/test/multiverse/suites/curb/Envfile +1 -1
  49. data/test/multiverse/suites/datamapper/Envfile +3 -0
  50. data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +7 -3
  51. data/test/multiverse/suites/grape/grape_test.rb +2 -0
  52. data/test/multiverse/suites/padrino/Envfile +4 -3
  53. data/test/multiverse/suites/padrino/config/newrelic.yml +2 -0
  54. data/test/multiverse/suites/rack/config/newrelic.yml +18 -0
  55. data/test/multiverse/suites/rack/nested_non_rack_app_test.rb +1 -1
  56. data/test/multiverse/suites/rack/puma_rack_builder_test.rb +17 -14
  57. data/test/multiverse/suites/rack/rack_auto_instrumentation_test.rb +16 -13
  58. data/test/multiverse/suites/rack/rack_unsupported_version_test.rb +1 -1
  59. data/test/multiverse/suites/rails/Envfile +5 -0
  60. data/test/multiverse/suites/rails/parameter_capture_test.rb +9 -0
  61. data/test/multiverse/suites/rake/Envfile +2 -1
  62. data/test/multiverse/suites/redis/redis_instrumentation_test.rb +1 -1
  63. data/test/multiverse/suites/sidekiq/Envfile +18 -0
  64. data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +11 -10
  65. data/test/multiverse/suites/sidekiq/test_model.rb +12 -0
  66. data/test/multiverse/suites/sinatra/ignoring_test.rb +43 -25
  67. data/test/multiverse/suites/sinatra/nested_middleware_test.rb +10 -2
  68. data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +4 -0
  69. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +8 -2
  70. data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +4 -0
  71. data/test/multiverse/suites/sinatra/sinatra_parameter_capture_test.rb +2 -0
  72. data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +79 -10
  73. data/test/new_relic/agent/agent_test.rb +3 -3
  74. data/test/new_relic/agent/aws_info_test.rb +1 -2
  75. data/test/new_relic/agent/configuration/orphan_configuration_test.rb +2 -0
  76. data/test/new_relic/agent/custom_event_aggregator_test.rb +43 -4
  77. data/test/new_relic/agent/error_collector_test.rb +1 -1
  78. data/test/new_relic/agent/error_event_aggregator_test.rb +13 -81
  79. data/test/new_relic/agent/event_aggregator_test.rb +178 -0
  80. data/test/new_relic/agent/event_buffer_test_cases.rb +16 -0
  81. data/test/new_relic/agent/instrumentation/sinatra/transaction_namer_test.rb +7 -0
  82. data/test/new_relic/agent/new_relic_service_test.rb +7 -1
  83. data/test/new_relic/agent/pipe_channel_manager_test.rb +45 -3
  84. data/test/new_relic/agent/rpm_agent_test.rb +1 -0
  85. data/test/new_relic/agent/stats_engine/stats_hash_test.rb +2 -2
  86. data/test/new_relic/agent/synthetics_event_aggregator_test.rb +179 -0
  87. data/test/new_relic/agent/transaction/request_attributes_test.rb +8 -0
  88. data/test/new_relic/agent/transaction_error_primitive_test.rb +117 -0
  89. data/test/new_relic/agent/transaction_event_aggregator_test.rb +148 -374
  90. data/test/new_relic/agent/transaction_event_primitive_test.rb +195 -0
  91. data/test/new_relic/agent/transaction_event_recorder_test.rb +80 -0
  92. data/test/new_relic/agent/transaction_metrics_test.rb +7 -7
  93. data/test/new_relic/agent/transaction_test.rb +4 -4
  94. data/test/new_relic/agent/utilization_data_test.rb +7 -7
  95. data/test/new_relic/fake_collector.rb +10 -17
  96. data/test/new_relic/license_test.rb +2 -0
  97. data/test/new_relic/marshalling_test_cases.rb +1 -1
  98. data/test/nullverse/default_source_require_test.rb +21 -0
  99. data/test/nullverse/nullverse_helper.rb +10 -0
  100. data/test/performance/suites/active_record.rb +1 -1
  101. data/test/performance/suites/sql_obfuscation.rb +7 -6
  102. data/test/script/ci.sh +10 -165
  103. data/test/script/install_mongodb.sh +6 -0
  104. metadata +21 -6
  105. data/test/script/build_test_gem.sh +0 -57
  106. data/test/script/ci_agent-tests_runner.sh +0 -82
  107. data/test/script/ci_bench.sh +0 -52
  108. data/test/script/ci_multiverse_runner.sh +0 -63
@@ -0,0 +1,178 @@
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 File.expand_path(File.join(File.dirname(__FILE__),'..','data_container_tests'))
7
+ require 'new_relic/agent/event_aggregator'
8
+
9
+ module NewRelic
10
+ module Agent
11
+ class EventAggregatorTest < Minitest::Test
12
+ class TestAggregator < EventAggregator
13
+ named :TestAggregator
14
+ capacity_key :cap_key
15
+ enabled_key :enabled_key
16
+
17
+ attr_reader :buffer
18
+
19
+ def append item
20
+ @buffer.append item
21
+ notify_if_full
22
+ end
23
+ end
24
+
25
+ def setup
26
+ NewRelic::Agent.config.add_config_for_testing(
27
+ :cap_key => 100,
28
+ :enabled_key => true
29
+ )
30
+
31
+ @aggregator = TestAggregator.new
32
+ end
33
+
34
+ def create_container
35
+ @aggregator
36
+ end
37
+
38
+ def populate_container(container, n)
39
+ n.times { |i| container.append i }
40
+ end
41
+
42
+ include NewRelic::DataContainerTests
43
+
44
+ def test_it_has_a_name
45
+ assert_equal 'TestAggregator', TestAggregator.named
46
+ end
47
+
48
+ def test_enabled_relects_config_value
49
+ assert @aggregator.enabled?, "Expected enabled? to be true"
50
+
51
+ with_config :enabled_key => false do
52
+ refute @aggregator.enabled?, "Expected enabled? to be false"
53
+ end
54
+ end
55
+
56
+ def test_after_harvest_invoked_with_report
57
+ metadata = {:meta => true}
58
+ @aggregator.buffer.stubs(:metadata).returns(metadata)
59
+ @aggregator.expects(:after_harvest).with(metadata)
60
+ @aggregator.harvest!
61
+ end
62
+
63
+ def test_notifies_full
64
+ expects_logging :debug, includes("TestAggregator capacity of 5 reached")
65
+ with_config :cap_key => 5 do
66
+ 5.times { |i| @aggregator.append i}
67
+ end
68
+ end
69
+
70
+ def test_notifies_full_only_once
71
+ with_config :cap_key => 5 do
72
+ msg = "TestAggregator capacity of 5 reached"
73
+ # this will trigger a message to be logged
74
+ 5.times { |i| @aggregator.append i}
75
+
76
+ # we expect subsequent appends not to trigger logging
77
+ expects_logging :debug, Not(includes(msg))
78
+ 3.times {@aggregator.append 'no logs'}
79
+ end
80
+ end
81
+
82
+ def test_notifies_full_resets_after_harvest
83
+ msg = "TestAggregator capacity of 5 reached"
84
+
85
+ expects_logging :debug, includes(msg)
86
+ with_config :cap_key => 5 do
87
+ 5.times { |i| @aggregator.append i}
88
+ end
89
+
90
+ @aggregator.harvest!
91
+
92
+ expects_logging :debug, includes(msg)
93
+ with_config :cap_key => 5 do
94
+ 5.times { |i| @aggregator.append i}
95
+ end
96
+ end
97
+
98
+ def test_notifies_full_resets_after_buffer_reset
99
+ msg = "TestAggregator capacity of 5 reached"
100
+
101
+ expects_logging :debug, includes(msg)
102
+ with_config :cap_key => 5 do
103
+ 5.times { |i| @aggregator.append i}
104
+ end
105
+
106
+ @aggregator.reset!
107
+
108
+ expects_logging :debug, includes(msg)
109
+ with_config :cap_key => 5 do
110
+ 5.times { |i| @aggregator.append i}
111
+ end
112
+ end
113
+
114
+ def test_buffer_class_defaults_to_sampled_buffer
115
+ assert_kind_of NewRelic::Agent::SampledBuffer, @aggregator.buffer
116
+ end
117
+
118
+ def test_buffer_class_is_overridable
119
+ klass = Class.new(EventAggregator) do
120
+ named :TestAggregator2
121
+ capacity_key :cap_key
122
+ enabled_key :enabled_key
123
+ buffer_class NewRelic::Agent::SizedBuffer
124
+ attr_reader :buffer
125
+ end
126
+ instance = klass.new
127
+
128
+ assert_kind_of NewRelic::Agent::SizedBuffer, instance.buffer
129
+ end
130
+
131
+ def test_buffer_adjusts_count_by_default_on_merge
132
+ with_config :cap_key => 5 do
133
+ buffer = @aggregator.buffer
134
+
135
+ 4.times { |i| @aggregator.append i }
136
+ last_harvest = @aggregator.harvest!
137
+
138
+ assert_equal 4, buffer.seen_lifetime
139
+ assert_equal 4, buffer.captured_lifetime
140
+ assert_equal 4, last_harvest[0][:events_seen]
141
+
142
+ 4.times { |i| @aggregator.append i }
143
+ @aggregator.merge! last_harvest
144
+
145
+ reservoir_stats, samples = @aggregator.harvest!
146
+
147
+ assert_equal 5, samples.size
148
+ assert_equal 8, reservoir_stats[:events_seen]
149
+ assert_equal 8, buffer.seen_lifetime
150
+ assert_equal 5, buffer.captured_lifetime
151
+ end
152
+ end
153
+
154
+ def test_buffer_adds_to_original_count_on_merge_when_specified
155
+ with_config :cap_key => 5 do
156
+ buffer = @aggregator.buffer
157
+
158
+ 4.times { |i| @aggregator.append i }
159
+ last_harvest = @aggregator.harvest!
160
+
161
+ assert_equal 4, buffer.seen_lifetime
162
+ assert_equal 4, buffer.captured_lifetime
163
+ assert_equal 4, last_harvest[0][:events_seen]
164
+
165
+ 4.times { |i| @aggregator.append i }
166
+ @aggregator.merge! last_harvest, false
167
+
168
+ reservoir_stats, samples = @aggregator.harvest!
169
+
170
+ assert_equal 5, samples.size
171
+ assert_equal 8, reservoir_stats[:events_seen]
172
+ assert_equal 12, buffer.seen_lifetime
173
+ assert_equal 9, buffer.captured_lifetime
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -149,4 +149,20 @@ module NewRelic::Agent::EventBufferTestCases
149
149
  assert_equal(0.5, buffer.sample_rate)
150
150
  end
151
151
 
152
+ def test_metadata
153
+ buffer = buffer_class.new(5)
154
+ 7.times { buffer << 'x' }
155
+
156
+ expected = {
157
+ :capacity => 5,
158
+ :seen => 7,
159
+ :captured => 5
160
+ }
161
+
162
+ metadata = buffer.metadata
163
+ metadata.delete :captured_lifetime
164
+ metadata.delete :seen_lifetime
165
+
166
+ assert_equal expected, metadata
167
+ end
152
168
  end
@@ -28,6 +28,13 @@ module NewRelic
28
28
  assert_equal "GET path/:id", result
29
29
  end
30
30
 
31
+ def test_transaction_name_for_root_route
32
+ env = { "newrelic.last_route" => /\A\/\z/}
33
+ request = stub(:request_method => "GET")
34
+ result = TransactionNamer.transaction_name_for_route(env, request)
35
+ assert_equal "GET /", result
36
+ end
37
+
31
38
  def test_transaction_name_for_route_without_routes
32
39
  assert_nil TransactionNamer.transaction_name_for_route({}, nil)
33
40
  end
@@ -363,10 +363,16 @@ class NewRelicServiceTest < Minitest::Test
363
363
 
364
364
  def test_analytic_event_data
365
365
  @http_handle.respond_to(:analytic_event_data, 'some analytic events')
366
- response = @service.analytic_event_data([])
366
+ response = @service.analytic_event_data([{}, []])
367
367
  assert_equal 'some analytic events', response
368
368
  end
369
369
 
370
+ def error_event_data
371
+ @http_handle.respond_to(:error_event_data, 'some error events')
372
+ response = @service.error_event_data([{}, []])
373
+ assert_equal 'some error events', response
374
+ end
375
+
370
376
  # Although thread profiling is only available in some circumstances, the
371
377
  # service communication doesn't care about that at all
372
378
  def test_profile_data
@@ -5,6 +5,7 @@
5
5
  require 'timeout'
6
6
  require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
7
7
  require 'new_relic/agent/pipe_channel_manager'
8
+ require 'new_relic/agent/transaction_event_primitive'
8
9
 
9
10
  class NewRelic::Agent::PipeChannelManagerTest < Minitest::Test
10
11
  include TransactionSampleTestHelper
@@ -103,13 +104,14 @@ class NewRelic::Agent::PipeChannelManagerTest < Minitest::Test
103
104
  end
104
105
 
105
106
  def test_listener_merges_analytics_events
106
- transaction_event_aggregator = NewRelic::Agent.agent.instance_variable_get(:@transaction_event_aggregator)
107
+ transaction_event_aggregator = NewRelic::Agent.agent.transaction_event_aggregator
108
+ reset_lifetime_counts! transaction_event_aggregator
107
109
 
108
110
  start_listener_with_pipe(699)
109
111
  NewRelic::Agent.agent.stubs(:connected?).returns(true)
110
112
  run_child(699) do
111
113
  NewRelic::Agent.after_fork(:report_to_channel => 699)
112
- transaction_event_aggregator.on_transaction_finished({
114
+ transaction_event_aggregator.append NewRelic::Agent::TransactionEventPrimitive.create({
113
115
  :start_timestamp => Time.now,
114
116
  :name => 'whatever',
115
117
  :duration => 10,
@@ -118,7 +120,35 @@ class NewRelic::Agent::PipeChannelManagerTest < Minitest::Test
118
120
  NewRelic::Agent.agent.send(:transmit_event_data)
119
121
  end
120
122
 
121
- assert_equal(1, transaction_event_aggregator.samples.size)
123
+ _, samples = transaction_event_aggregator.harvest!
124
+
125
+ assert_equal(1, samples.size)
126
+ assert_lifetime_counts(transaction_event_aggregator, 1)
127
+ end
128
+
129
+ def test_listener_merges_error_events
130
+ error_event_aggregator = NewRelic::Agent.agent.error_collector.error_event_aggregator
131
+ reset_lifetime_counts! error_event_aggregator
132
+
133
+ sampler = NewRelic::Agent.agent.error_collector
134
+ sampler.notice_error(Exception.new("message"), :uri => '/myurl/',
135
+ :metric => 'path', :referer => 'test_referer',
136
+ :request_params => {:x => 'y'})
137
+
138
+ start_listener_with_pipe(668)
139
+
140
+ run_child(668) do
141
+ NewRelic::Agent.after_fork
142
+ new_sampler = NewRelic::Agent::ErrorCollector.new
143
+ new_sampler.notice_error(Exception.new("new message"), :uri => '/myurl/',
144
+ :metric => 'path', :referer => 'test_referer',
145
+ :request_params => {:x => 'y'})
146
+ service = NewRelic::Agent::PipeService.new(668)
147
+ service.error_event_data(new_sampler.error_event_aggregator.harvest!)
148
+ end
149
+ _, errors = error_event_aggregator.harvest!
150
+ assert_equal(2, errors.size)
151
+ assert_lifetime_counts(error_event_aggregator, 2)
122
152
  end
123
153
 
124
154
  def test_listener_merges_sql_traces
@@ -276,4 +306,16 @@ class NewRelic::Agent::PipeChannelManagerTest < Minitest::Test
276
306
  sleep 0.01
277
307
  end
278
308
  end
309
+
310
+ def assert_lifetime_counts container, value
311
+ buffer = container.instance_variable_get :@buffer
312
+ assert_equal value, buffer.captured_lifetime
313
+ assert_equal value, buffer.seen_lifetime
314
+ end
315
+
316
+ def reset_lifetime_counts! container
317
+ buffer = container.instance_variable_get :@buffer
318
+ buffer.instance_variable_set :@captured_lifetime, 0
319
+ buffer.instance_variable_set :@seen_lifetime, 0
320
+ end
279
321
  end
@@ -13,6 +13,7 @@ class NewRelic::Agent::RpmAgentTest < Minitest::Test
13
13
 
14
14
  def teardown
15
15
  NewRelic::Agent.instance.shutdown
16
+ NewRelic::Agent.drop_buffered_data
16
17
  end
17
18
 
18
19
  def test_public_apis
@@ -136,14 +136,14 @@ class NewRelic::Agent::StatsHashTest < Minitest::Test
136
136
  txn_metrics = NewRelic::Agent::TransactionMetrics.new
137
137
  txn_metrics.record_unscoped(specs[0].name, 1)
138
138
  txn_metrics.record_unscoped(specs[1].name, 2)
139
- txn_metrics.record_scoped(specs[3].name, 3)
139
+ txn_metrics.record_scoped_and_unscoped(specs[3].name, 3)
140
140
 
141
141
  hash.merge_transaction_metrics!(txn_metrics, 'a_scope')
142
142
 
143
143
  assert_equal(4, hash.to_h.keys.size)
144
144
  assert_equal(2, hash[specs[0]].call_count)
145
145
  assert_equal(2, hash[specs[1]].call_count)
146
- assert_equal(1, hash[specs[2]].call_count)
146
+ assert_equal(2, hash[specs[2]].call_count)
147
147
  assert_equal(1, hash[specs[3]].call_count)
148
148
  end
149
149
 
@@ -0,0 +1,179 @@
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 File.expand_path(File.join(File.dirname(__FILE__),'..','data_container_tests'))
7
+ require 'new_relic/agent/synthetics_event_aggregator'
8
+ require 'new_relic/agent/transaction_event_primitive'
9
+
10
+ module NewRelic
11
+ module Agent
12
+ class SyntheticsEventAggregatorTest < Minitest::Test
13
+ def setup
14
+ freeze_time
15
+ @synthetics_event_aggregator = SyntheticsEventAggregator.new
16
+ end
17
+
18
+ def teardown
19
+ @synthetics_event_aggregator.reset!
20
+ end
21
+
22
+ def create_container
23
+ @synthetics_event_aggregator
24
+ end
25
+
26
+ def populate_container(sampler, n)
27
+ n.times do |i|
28
+ generate_request
29
+ end
30
+ end
31
+
32
+ include NewRelic::DataContainerTests
33
+
34
+ def test_synthetics_aggregation_limits
35
+ with_config :'synthetics.events_limit' => 10 do
36
+ 20.times do
37
+ generate_request
38
+ end
39
+
40
+ assert_equal 10, last_synthetics_events.size
41
+ end
42
+ end
43
+
44
+ def test_synthetics_events_kept_by_timestamp
45
+ with_config :'synthetics.events_limit' => 10 do
46
+ 11.times do |i|
47
+ _, rejected = generate_request('whatever', :timestamp => i)
48
+ if i < 10
49
+ assert_nil rejected, "Expected event to be accepted"
50
+ else
51
+ refute_nil rejected, "Expected event to be rejected"
52
+ assert_equal 10.0, rejected.first["timestamp"]
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def test_sythetics_events_rejected_when_buffer_is_full_of_newer_events
59
+ with_config :'synthetics.events_limit' => 10 do
60
+ 11.times do |i|
61
+ generate_request 'whatever', :timestamp => i + 10.0
62
+ end
63
+
64
+ generate_request 'whatever', :timestamp => 1
65
+ samples = last_synthetics_events
66
+ assert_equal 10, samples.size
67
+ timestamps = samples.map do |(main, _)|
68
+ main["timestamp"]
69
+ end.sort
70
+
71
+ assert_equal ([1] + (10..18).to_a), timestamps
72
+ end
73
+ end
74
+
75
+ def test_does_not_drop_samples_when_used_from_multiple_threads
76
+ with_config :'synthetics.events_limit' => 100 * 100 do
77
+ threads = []
78
+ 25.times do
79
+ threads << Thread.new do
80
+ 100.times{ generate_request }
81
+ end
82
+ end
83
+ threads.each { |t| t.join }
84
+
85
+ assert_equal(25 * 100, last_synthetics_events.size)
86
+ end
87
+ end
88
+
89
+ def test_events_not_recorded_when_disabled
90
+ with_config :'analytics_events.enabled' => false do
91
+ generate_request
92
+ errors = last_synthetics_events
93
+ assert_empty errors
94
+ end
95
+ end
96
+
97
+ def test_includes_custom_attributes
98
+ attrs = {"user" => "Wes Mantooth", "channel" => 9}
99
+
100
+ attributes.merge_custom_attributes attrs
101
+
102
+ generate_request
103
+
104
+ _, custom_attrs, _ = last_synthetics_event
105
+
106
+ assert_equal attrs, custom_attrs
107
+ end
108
+
109
+ def test_does_not_record_supportability_metric_when_no_events_dropped
110
+ with_config :'synthetics.events_limit' => 20 do
111
+ 20.times do
112
+ generate_request
113
+ end
114
+
115
+ @synthetics_event_aggregator.harvest!
116
+
117
+ metric = 'Supportability/TransactionEventAggregator/synthetics_events_dropped'
118
+ assert_metrics_not_recorded(metric)
119
+ end
120
+ end
121
+
122
+ def test_synthetics_event_dropped_records_supportability_metrics
123
+ with_config :'synthetics.events_limit' => 10 do
124
+ 20.times do
125
+ generate_request
126
+ end
127
+
128
+ @synthetics_event_aggregator.harvest!
129
+
130
+ metric = 'Supportability/SyntheticsEventAggregator/synthetics_events_dropped'
131
+ assert_metrics_recorded(metric => { :call_count => 10 })
132
+ end
133
+ end
134
+
135
+ def test_includes_agent_attributes
136
+ attributes.add_agent_attribute :'request.headers.referer', "http://blog.site/home", AttributeFilter::DST_TRANSACTION_EVENTS
137
+ attributes.add_agent_attribute :httpResponseCode, "200", AttributeFilter::DST_TRANSACTION_EVENTS
138
+
139
+ generate_request
140
+
141
+ _, _, agent_attrs = last_synthetics_event
142
+
143
+ expected = {:"request.headers.referer" => "http://blog.site/home", :httpResponseCode => "200"}
144
+ assert_equal expected, agent_attrs
145
+ end
146
+
147
+ def last_synthetics_events
148
+ @synthetics_event_aggregator.harvest![1]
149
+ end
150
+
151
+ def last_synthetics_event
152
+ last_synthetics_events.first
153
+ end
154
+
155
+ def generate_request name='whatever', options={}
156
+ payload = {
157
+ :name => "Controller/blogs/index",
158
+ :type => :controller,
159
+ :start_timestamp => options[:timestamp] || Time.now.to_f,
160
+ :duration => 0.1,
161
+ :synthetics_resource_id => 100,
162
+ :attributes => attributes,
163
+ :error => false
164
+ }.merge(options)
165
+
166
+ @synthetics_event_aggregator.append_or_reject TransactionEventPrimitive.create(payload)
167
+ end
168
+
169
+ def attributes
170
+ if @attributes.nil?
171
+ filter = NewRelic::Agent::AttributeFilter.new(NewRelic::Agent.config)
172
+ @attributes = NewRelic::Agent::Transaction::Attributes.new(filter)
173
+ end
174
+
175
+ @attributes
176
+ end
177
+ end
178
+ end
179
+ end