newrelic_rpm 3.7.3.204 → 3.8.0.218

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +73 -0
  3. data/README.md +1 -1
  4. data/Rakefile +1 -5
  5. data/lib/new_relic/agent.rb +1 -0
  6. data/lib/new_relic/agent/agent.rb +47 -18
  7. data/lib/new_relic/agent/agent_logger.rb +11 -1
  8. data/lib/new_relic/agent/configuration/default_source.rb +85 -1
  9. data/lib/new_relic/agent/configuration/manager.rb +5 -1
  10. data/lib/new_relic/agent/datastores/mongo.rb +8 -3
  11. data/lib/new_relic/agent/harvester.rb +5 -1
  12. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +1 -0
  13. data/lib/new_relic/agent/instrumentation/active_merchant.rb +7 -3
  14. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +13 -3
  15. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +7 -1
  16. data/lib/new_relic/agent/instrumentation/sidekiq.rb +3 -1
  17. data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -1
  18. data/lib/new_relic/agent/new_relic_service.rb +8 -0
  19. data/lib/new_relic/agent/request_sampler.rb +1 -1
  20. data/lib/new_relic/agent/sampler.rb +22 -2
  21. data/lib/new_relic/agent/sampler_collection.rb +13 -1
  22. data/lib/new_relic/agent/samplers/cpu_sampler.rb +3 -1
  23. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +2 -1
  24. data/lib/new_relic/agent/samplers/memory_sampler.rb +2 -1
  25. data/lib/new_relic/agent/samplers/object_sampler.rb +1 -3
  26. data/lib/new_relic/agent/samplers/vm_sampler.rb +126 -0
  27. data/lib/new_relic/agent/stats.rb +0 -15
  28. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +66 -75
  29. data/lib/new_relic/agent/stats_engine/stats_hash.rb +1 -1
  30. data/lib/new_relic/agent/supported_versions.rb +2 -2
  31. data/lib/new_relic/agent/transaction.rb +6 -3
  32. data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +17 -5
  33. data/lib/new_relic/agent/vm/mri_vm.rb +2 -1
  34. data/lib/new_relic/agent/vm/snapshot.rb +5 -1
  35. data/lib/new_relic/control/instance_methods.rb +8 -5
  36. data/lib/new_relic/control/instrumentation.rb +0 -9
  37. data/lib/new_relic/environment_report.rb +1 -1
  38. data/lib/new_relic/language_support.rb +4 -0
  39. data/lib/new_relic/local_environment.rb +39 -14
  40. data/lib/new_relic/noticed_error.rb +7 -4
  41. data/lib/new_relic/rack/browser_monitoring.rb +16 -3
  42. data/lib/new_relic/version.rb +2 -2
  43. data/newrelic_rpm.gemspec +1 -1
  44. data/test/agent_helper.rb +5 -3
  45. data/test/environments/lib/environments/runner.rb +8 -7
  46. data/test/environments/norails/Gemfile +1 -1
  47. data/test/environments/rails21/Gemfile +1 -0
  48. data/test/environments/rails22/Gemfile +1 -0
  49. data/test/environments/rails23/Gemfile +1 -0
  50. data/test/environments/rails30/Gemfile +4 -1
  51. data/test/environments/rails31/Gemfile +4 -1
  52. data/test/environments/rails32/Gemfile +3 -4
  53. data/test/environments/rails40/Gemfile +1 -1
  54. data/test/environments/rails41/Gemfile +1 -1
  55. data/test/flaky_proxy/lib/flaky_proxy/proxy.rb +1 -0
  56. data/test/multiverse/lib/multiverse/output_collector.rb +3 -1
  57. data/test/multiverse/lib/multiverse/runner.rb +2 -10
  58. data/test/multiverse/lib/multiverse/suite.rb +100 -30
  59. data/test/multiverse/suites/activemerchant/Envfile +16 -0
  60. data/test/multiverse/suites/activemerchant/activemerchant_test.rb +65 -0
  61. data/test/multiverse/suites/agent_only/custom_queue_time_test.rb +57 -0
  62. data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +1 -1
  63. data/test/multiverse/suites/mongo/Envfile +9 -1
  64. data/test/multiverse/suites/rails/Envfile +2 -2
  65. data/test/multiverse/suites/rails/app.rb +3 -0
  66. data/test/multiverse/suites/rails/bad_instrumentation_test.rb +0 -2
  67. data/test/multiverse/suites/rails/error_tracing_test.rb +1 -2
  68. data/test/multiverse/suites/rails/gc_instrumentation_test.rb +17 -8
  69. data/test/multiverse/suites/rails/ignore_test.rb +0 -2
  70. data/test/multiverse/suites/rails/mongrel_queue_depth_test.rb +0 -2
  71. data/test/multiverse/suites/rails/queue_time_test.rb +40 -11
  72. data/test/multiverse/suites/rails/request_statistics_test.rb +0 -3
  73. data/test/multiverse/suites/rails/view_instrumentation_test.rb +0 -2
  74. data/test/multiverse/suites/sidekiq/Envfile +7 -2
  75. data/test/multiverse/suites/sinatra/Envfile +1 -1
  76. data/test/multiverse/suites/sinatra/nested_middleware_test.rb +41 -0
  77. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +1 -1
  78. data/test/new_relic/agent/agent/connect_test.rb +32 -4
  79. data/test/new_relic/agent/agent/start_test.rb +9 -1
  80. data/test/new_relic/agent/agent_logger_test.rb +23 -2
  81. data/test/new_relic/agent/agent_test.rb +49 -7
  82. data/test/new_relic/agent/configuration/manager_test.rb +8 -0
  83. data/test/new_relic/agent/configuration/orphan_configuration_test.rb +7 -0
  84. data/test/new_relic/agent/cross_app_monitor_test.rb +5 -6
  85. data/test/new_relic/agent/harvester_test.rb +13 -8
  86. data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +28 -7
  87. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +32 -21
  88. data/test/new_relic/agent/new_relic_service_test.rb +14 -0
  89. data/test/new_relic/agent/request_sampler_test.rb +5 -3
  90. data/test/new_relic/agent/rpm_agent_test.rb +2 -3
  91. data/test/new_relic/agent/sampler_collection_test.rb +15 -5
  92. data/test/new_relic/agent/sampler_test.rb +43 -0
  93. data/test/new_relic/agent/{cpu_sampler_test.rb → samplers/cpu_sampler_test.rb} +1 -1
  94. data/test/new_relic/agent/samplers/vm_sampler_test.rb +349 -0
  95. data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +165 -44
  96. data/test/new_relic/agent/stats_hash_test.rb +1 -1
  97. data/test/new_relic/agent/transaction_test.rb +14 -0
  98. data/test/new_relic/agent/vm/monotonic_gc_profiler_test.rb +5 -5
  99. data/test/new_relic/agent/vm/mri_vm_test.rb +7 -0
  100. data/test/new_relic/agent/vm/snapshot_test.rb +5 -0
  101. data/test/new_relic/agent_test.rb +2 -2
  102. data/test/new_relic/control/instance_methods_test.rb +30 -0
  103. data/test/new_relic/control_test.rb +43 -21
  104. data/test/new_relic/dispatcher_test.rb +5 -0
  105. data/test/new_relic/local_environment_test.rb +3 -26
  106. data/test/new_relic/multiverse_helpers.rb +5 -0
  107. data/test/new_relic/noticed_error_test.rb +7 -0
  108. data/test/new_relic/rack/browser_monitoring_test.rb +13 -14
  109. data/test/test_helper.rb +2 -1
  110. metadata +56 -68
  111. metadata.gz.sig +1 -1
  112. data/lib/new_relic/agent/instrumentation/puma.rb +0 -25
  113. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +0 -26
  114. data/test/multiverse/script/run_one +0 -5
  115. data/test/rum/basic.result.html +0 -10
  116. data/test/rum/basic.source.html +0 -10
  117. data/test/rum/comments1.result.html +0 -24
  118. data/test/rum/comments1.source.html +0 -24
  119. data/test/rum/comments2.result.html +0 -24
  120. data/test/rum/comments2.source.html +0 -24
  121. data/test/rum/gt_in_quotes1.result.html +0 -27
  122. data/test/rum/gt_in_quotes1.source.html +0 -27
  123. data/test/rum/gt_in_quotes2.result.html +0 -24
  124. data/test/rum/gt_in_quotes2.source.html +0 -24
  125. data/test/rum/gt_in_quotes_mismatch.result.html +0 -24
  126. data/test/rum/gt_in_quotes_mismatch.source.html +0 -24
  127. data/test/rum/gt_in_single_quotes1.result.html +0 -25
  128. data/test/rum/gt_in_single_quotes1.source.html +0 -25
  129. data/test/rum/gt_in_single_quotes_mismatch.result.html +0 -25
  130. data/test/rum/gt_in_single_quotes_mismatch.source.html +0 -25
  131. data/test/rum/incomplete_non_meta_tags.result.html +0 -10
  132. data/test/rum/incomplete_non_meta_tags.source.html +0 -10
  133. data/test/rum/no_body.result.html +0 -21
  134. data/test/rum/no_body.source.html +0 -21
  135. data/test/rum/no_header.result.html +0 -7
  136. data/test/rum/no_header.source.html +0 -7
  137. data/test/rum/no_html_and_no_header.result.html +0 -3
  138. data/test/rum/no_html_and_no_header.source.html +0 -3
  139. data/test/rum/no_start_header.result.html +0 -9
  140. data/test/rum/no_start_header.source.html +0 -9
  141. data/test/rum/script1.result.html +0 -19
  142. data/test/rum/script1.source.html +0 -19
  143. data/test/rum/script2.result.html +0 -17
  144. data/test/rum/script2.source.html +0 -17
  145. data/test/rum/x_ua_meta_tag.result.html +0 -10
  146. data/test/rum/x_ua_meta_tag.source.html +0 -10
  147. data/test/rum/x_ua_meta_tag_multiline.result.html +0 -11
  148. data/test/rum/x_ua_meta_tag_multiline.source.html +0 -11
  149. data/test/rum/x_ua_meta_tag_spaces_around_equals.result.html +0 -10
  150. data/test/rum/x_ua_meta_tag_spaces_around_equals.source.html +0 -10
  151. data/test/rum/x_ua_meta_tag_with_others.result.html +0 -11
  152. data/test/rum/x_ua_meta_tag_with_others.source.html +0 -11
  153. data/test/rum/x_ua_meta_tag_with_spaces.result.html +0 -10
  154. data/test/rum/x_ua_meta_tag_with_spaces.source.html +0 -10
@@ -47,15 +47,14 @@ class NewRelic::Agent::RpmAgentTest < Minitest::Test
47
47
  assert (not @agent.started?)
48
48
  @agent.start
49
49
  assert !@agent.started?
50
+
50
51
  # this installs the real agent:
51
- NewRelic::Agent.manual_start
52
+ NewRelic::Agent.manual_start :monitor_mode => true, :license_key => ('x' * 40)
52
53
  @agent = NewRelic::Agent.instance
53
54
  assert @agent != NewRelic::Agent::ShimAgent.instance
54
55
  assert @agent.started?
55
56
  @agent.shutdown
56
57
  assert !@agent.started?
57
- @agent.start
58
- assert @agent.started?
59
58
  NewRelic::Agent.shutdown
60
59
  end
61
60
  end
@@ -6,15 +6,18 @@ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper
6
6
 
7
7
  class SamplerCollectionTest < Minitest::Test
8
8
 
9
- class DummySampler
10
- attr_reader :id
11
- def self.supported_on_this_platform?; true; end
9
+ class DummySampler < NewRelic::Agent::Sampler
10
+ named :dummy
11
+ def poll; end
12
+ end
13
+
14
+ class DummySampler2 < NewRelic::Agent::Sampler
15
+ named :dummy2
12
16
  def poll; end
13
17
  end
14
- class DummySampler2 < DummySampler; end
15
18
 
16
19
  def setup
17
- @events = NewRelic::Agent::EventListener.new
20
+ @events = NewRelic::Agent::EventListener.new
18
21
  @collection = NewRelic::Agent::SamplerCollection.new(@events)
19
22
  end
20
23
 
@@ -43,6 +46,13 @@ class SamplerCollectionTest < Minitest::Test
43
46
  assert_equal(0, @collection.to_a.size)
44
47
  end
45
48
 
49
+ def test_add_sampler_omits_disabled_samplers
50
+ with_config(:disable_dummy_sampler => true) do
51
+ @collection.add_sampler(DummySampler)
52
+ assert_equal(0, @collection.to_a.size)
53
+ end
54
+ end
55
+
46
56
  def test_add_sampler_swallows_exceptions_during_sampler_creation
47
57
  DummySampler.stubs(:new).raises(StandardError)
48
58
  @collection.add_sampler(DummySampler)
@@ -6,6 +6,16 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_hel
6
6
  class NewRelic::Agent::SamplerTest < Minitest::Test
7
7
  require 'new_relic/agent/sampler'
8
8
 
9
+ class UnnamedSampler < NewRelic::Agent::Sampler
10
+ def poll; end
11
+ end
12
+
13
+ class DummySampler < NewRelic::Agent::Sampler
14
+ named :dummy
15
+
16
+ def poll; end
17
+ end
18
+
9
19
  def test_inherited_should_append_subclasses_to_sampler_classes
10
20
  test_class = Class.new(NewRelic::Agent::Sampler)
11
21
  sampler_classes = NewRelic::Agent::Sampler.instance_eval { @sampler_classes }
@@ -20,4 +30,37 @@ class NewRelic::Agent::SamplerTest < Minitest::Test
20
30
  assert(sampler_classes.include?(NewRelic::Agent::Samplers::CpuSampler), 'Sampler classes should include the CPU sampler')
21
31
  end
22
32
 
33
+ def test_enabled_should_return_true_if_name_unknown
34
+ assert UnnamedSampler.enabled?
35
+ end
36
+
37
+ def test_initialize_should_accept_id_argument
38
+ UnnamedSampler.new(:larry)
39
+ end
40
+
41
+ def test_initialize_should_work_without_id_argument
42
+ UnnamedSampler.new
43
+ end
44
+
45
+ def test_initialize_should_set_id_from_passed_id
46
+ sampler = DummySampler.new(:larry)
47
+ assert_equal(:larry, sampler.id)
48
+ end
49
+
50
+ def test_initialize_should_set_id_from_name_if_no_passed_id
51
+ sampler = DummySampler.new
52
+ assert_equal(:dummy, sampler.id)
53
+ end
54
+
55
+ def test_enabled_should_return_false_if_disabled_via_config_setting
56
+ with_config(:disable_dummy_sampler => true) do
57
+ refute DummySampler.enabled?
58
+ end
59
+ end
60
+
61
+ def test_enabled_should_return_true_if_enabled_via_config_setting
62
+ with_config(:disable_dummy_sampler => false) do
63
+ assert DummySampler.enabled?
64
+ end
65
+ end
23
66
  end
@@ -3,7 +3,7 @@
3
3
  # This file is distributed under New Relic's license terms.
4
4
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
5
5
 
6
- require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
6
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','test_helper'))
7
7
  require 'new_relic/agent/samplers/cpu_sampler'
8
8
 
9
9
  class NewRelic::Agent::Samplers::CpuSamplerTest < Minitest::Test
@@ -0,0 +1,349 @@
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/samplers/vm_sampler'
7
+ require 'new_relic/agent/vm/snapshot'
8
+
9
+ module NewRelic
10
+ module Agent
11
+ module Samplers
12
+ class VMSamplerTest < Minitest::Test
13
+ def setup
14
+ stub_snapshot(
15
+ :taken_at => 0,
16
+ :gc_runs => 0,
17
+ :gc_total_time => 0,
18
+ :total_allocated_object => 0,
19
+ :major_gc_count => 0,
20
+ :minor_gc_count => 0,
21
+ :heap_live => 0,
22
+ :heap_free => 0,
23
+ :method_cache_invalidations => 0,
24
+ :constant_cache_invalidations => 0
25
+ )
26
+ @sampler = VMSampler.new
27
+ @sampler.setup_events(NewRelic::Agent.instance.events)
28
+ NewRelic::Agent.drop_buffered_data
29
+ end
30
+
31
+ def test_supported_on_this_platform?
32
+ assert VMSampler.supported_on_this_platform?
33
+ end
34
+
35
+ def test_enabled_should_return_false_if_disabled_via_config_setting
36
+ with_config(:disable_vm_sampler => true) do
37
+ refute VMSampler.enabled?
38
+ end
39
+ end
40
+
41
+ def test_records_transaction_count
42
+ generate_transactions(10)
43
+ assert_equal(10, @sampler.transaction_count)
44
+ end
45
+
46
+ def test_reset_transaction_count
47
+ generate_transactions(10)
48
+
49
+ old_count = @sampler.reset_transaction_count
50
+ assert_equal(10, old_count)
51
+ assert_equal(0, @sampler.transaction_count)
52
+ end
53
+
54
+ def test_poll_records_thread_count
55
+ stub_snapshot(:thread_count => 2)
56
+
57
+ @sampler.poll
58
+ assert_metrics_recorded(
59
+ 'RubyVM/Threads/all' => {
60
+ :call_count => 2,
61
+ :sum_of_squares => 1
62
+ }
63
+ )
64
+ end
65
+
66
+ def test_poll_records_gc_runs_metric
67
+ stub_snapshot(:gc_runs => 10, :gc_total_time => 100, :taken_at => 200)
68
+ generate_transactions(50)
69
+ @sampler.poll
70
+
71
+ assert_metrics_recorded(
72
+ 'RubyVM/GC/runs' => {
73
+ :call_count => 50, # number of transactions
74
+ :total_call_time => 10, # number of GC runs
75
+ :total_exclusive_time => 100, # total GC time
76
+ :sum_of_squares => 200 # total wall clock time
77
+ }
78
+ )
79
+ end
80
+
81
+ def test_poll_records_total_allocated_object
82
+ stub_snapshot(:total_allocated_object => 25)
83
+ generate_transactions(50)
84
+ @sampler.poll
85
+
86
+ assert_metrics_recorded(
87
+ 'RubyVM/GC/total_allocated_object' => {
88
+ :call_count => 50, # number of transactions
89
+ :total_call_time => 25 # number of allocated objects
90
+ }
91
+ )
92
+ end
93
+
94
+ def test_poll_records_major_minor_gc_counts
95
+ stub_snapshot(:major_gc_count => 10, :minor_gc_count => 20)
96
+ generate_transactions(50)
97
+ @sampler.poll
98
+
99
+ assert_metrics_recorded(
100
+ 'RubyVM/GC/major_gc_count' => {
101
+ :call_count => 50, # number of transactions
102
+ :total_call_time => 10 # number of major GC runs
103
+ },
104
+ 'RubyVM/GC/minor_gc_count' => {
105
+ :call_count => 50, # number of transactions
106
+ :total_call_time => 20 # number of minor GC runs
107
+ }
108
+ )
109
+ end
110
+
111
+ def test_poll_records_heap_usage_metrics
112
+ stub_snapshot(:heap_live => 100, :heap_free => 25)
113
+ @sampler.poll
114
+
115
+ assert_metrics_recorded(
116
+ 'RubyVM/GC/heap_live' => {
117
+ :call_count => 100,
118
+ :sum_of_squares => 1
119
+ },
120
+ 'RubyVM/GC/heap_free' => {
121
+ :call_count => 25,
122
+ :sum_of_squares => 1
123
+ }
124
+ )
125
+ end
126
+
127
+ def test_poll_records_vm_cache_invalidations
128
+ stub_snapshot(
129
+ :method_cache_invalidations => 100,
130
+ :constant_cache_invalidations => 200
131
+ )
132
+ generate_transactions(50)
133
+ @sampler.poll
134
+
135
+ assert_metrics_recorded(
136
+ 'RubyVM/CacheInvalidations/method' => {
137
+ :call_count => 50, # number of transactions
138
+ :total_call_time => 100 # number of method cache invalidations
139
+ },
140
+ 'RubyVM/CacheInvalidations/constant' => {
141
+ :call_count => 50, # number of transactions
142
+ :total_call_time => 200 # number of constant cache invalidations
143
+ }
144
+ )
145
+ end
146
+
147
+ def test_poll_gracefully_handles_missing_fields
148
+ stub_snapshot({}) # snapshot will be empty
149
+ @sampler.poll
150
+
151
+ assert_metrics_not_recorded([
152
+ 'RubyVM/GC/runs',
153
+ 'RubyVM/GC/total_allocated_object',
154
+ 'RubyVM/GC/major_gc_count',
155
+ 'RubyVM/GC/minor_gc_count',
156
+ 'RubyVM/GC/heap_live',
157
+ 'RubyVM/GC/heap_free',
158
+ 'RubyVM/CacheInvalidations/method',
159
+ 'RubyVM/CacheInvalidations/constant'
160
+ ])
161
+ end
162
+
163
+ def test_poll_handles_missing_gc_time_but_present_gc_count
164
+ # We were able to determine the number of GC runs, but not the total
165
+ # GC time. This will be the case if GC::Profiler is not available.
166
+ stub_snapshot(:gc_runs => 10, :taken_at => 60)
167
+ generate_transactions(50)
168
+ @sampler.poll
169
+
170
+ assert_metrics_recorded(
171
+ 'RubyVM/GC/runs' => {
172
+ :call_count => 50, # number of transactions
173
+ :total_call_time => 10, # number of GC runs
174
+ :total_exclusive_time => 0, # total GC time
175
+ :sum_of_squares => 60 # total wall clock time
176
+ }
177
+ )
178
+ end
179
+
180
+ def test_poll_records_deltas_not_cumulative_values
181
+ stub_snapshot(
182
+ :gc_runs => 10,
183
+ :gc_total_time => 10,
184
+ :total_allocated_object => 10,
185
+ :major_gc_count => 10,
186
+ :minor_gc_count => 10,
187
+ :method_cache_invalidations => 10,
188
+ :constant_cache_invalidations => 10
189
+ )
190
+ @sampler.poll
191
+
192
+ expected = {
193
+ 'RubyVM/GC/runs' => {
194
+ :total_call_time => 10,
195
+ :total_exclusive_time => 10
196
+ },
197
+ 'RubyVM/GC/total_allocated_object' => {
198
+ :total_call_time => 10
199
+ },
200
+ 'RubyVM/GC/major_gc_count' => {
201
+ :total_call_time => 10
202
+ },
203
+ 'RubyVM/GC/minor_gc_count' => {
204
+ :total_call_time => 10
205
+ },
206
+ 'RubyVM/CacheInvalidations/method' => {
207
+ :total_call_time => 10
208
+ },
209
+ 'RubyVM/CacheInvalidations/constant' => {
210
+ :total_call_time => 10
211
+ }
212
+ }
213
+
214
+ assert_metrics_recorded(expected)
215
+
216
+ NewRelic::Agent.drop_buffered_data
217
+
218
+ stub_snapshot(
219
+ :gc_runs => 20,
220
+ :gc_total_time => 20,
221
+ :total_allocated_object => 20,
222
+ :major_gc_count => 20,
223
+ :minor_gc_count => 20,
224
+ :method_cache_invalidations => 20,
225
+ :constant_cache_invalidations => 20
226
+ )
227
+ @sampler.poll
228
+
229
+ assert_metrics_recorded(expected)
230
+ end
231
+
232
+ # This test simulates multiple poll cycles without a metric reset
233
+ # between them. This can happen, for example, when the agent fails to
234
+ # post metric data to the collector.
235
+ def test_poll_aggregates_multiple_polls
236
+ stub_snapshot(
237
+ :gc_runs => 10,
238
+ :gc_total_time => 10,
239
+ :total_allocated_object => 10,
240
+ :major_gc_count => 10,
241
+ :minor_gc_count => 10,
242
+ :method_cache_invalidations => 10,
243
+ :constant_cache_invalidations => 10,
244
+ :taken_at => 10
245
+ )
246
+ generate_transactions(10)
247
+ @sampler.poll
248
+
249
+ stub_snapshot(
250
+ :gc_runs => 20,
251
+ :gc_total_time => 20,
252
+ :total_allocated_object => 20,
253
+ :major_gc_count => 20,
254
+ :minor_gc_count => 20,
255
+ :method_cache_invalidations => 20,
256
+ :constant_cache_invalidations => 20,
257
+ :taken_at => 20
258
+ )
259
+ generate_transactions(10)
260
+ @sampler.poll
261
+
262
+ assert_metrics_recorded(
263
+ 'RubyVM/GC/runs' => {
264
+ :call_count => 20,
265
+ :total_call_time => 20,
266
+ :total_exclusive_time => 20,
267
+ :sum_of_squares => 20
268
+ },
269
+ 'RubyVM/GC/total_allocated_object' => {
270
+ :call_count => 20,
271
+ :total_call_time => 20
272
+ },
273
+ 'RubyVM/GC/major_gc_count' => {
274
+ :call_count => 20,
275
+ :total_call_time => 20
276
+ },
277
+ 'RubyVM/GC/minor_gc_count' => {
278
+ :call_count => 20,
279
+ :total_call_time => 20
280
+ },
281
+ 'RubyVM/CacheInvalidations/method' => {
282
+ :call_count => 20,
283
+ :total_call_time => 20
284
+ },
285
+ 'RubyVM/CacheInvalidations/constant' => {
286
+ :call_count => 20,
287
+ :total_call_time => 20
288
+ }
289
+ )
290
+ end
291
+
292
+ def test_poll_records_wall_clock_time_for_gc_runs_metric
293
+ stub_snapshot(:gc_runs => 10, :gc_total_time => 10, :taken_at => 60)
294
+ @sampler.poll
295
+
296
+ assert_metrics_recorded(
297
+ 'RubyVM/GC/runs' => {
298
+ :total_exclusive_time => 10, # total GC time
299
+ :sum_of_squares => 60 # total wall clock time
300
+ }
301
+ )
302
+
303
+ stub_snapshot(:gc_runs => 10, :gc_total_time => 15, :taken_at => 120)
304
+ @sampler.poll
305
+
306
+ assert_metrics_recorded(
307
+ 'RubyVM/GC/runs' => {
308
+ :total_exclusive_time => 15, # total GC time
309
+ :sum_of_squares => 120 # total wall clock time
310
+ }
311
+ )
312
+ end
313
+
314
+ def test_poll_records_one_in_gc_runs_max_if_gc_time_available
315
+ stub_snapshot(:gc_runs => 10, :gc_total_time => 10)
316
+ @sampler.poll
317
+
318
+ assert_metrics_recorded(
319
+ 'RubyVM/GC/runs' => { :max_call_time => 1 }
320
+ )
321
+ end
322
+
323
+ def test_poll_records_zero_in_gc_runs_max_if_gc_time_not_available
324
+ stub_snapshot(:gc_runs => 10)
325
+ @sampler.poll
326
+
327
+ assert_metrics_recorded(
328
+ 'RubyVM/GC/runs' => { :max_call_time => 0 }
329
+ )
330
+ end
331
+
332
+ def generate_transactions(n)
333
+ n.times do
334
+ in_transaction('txn') { }
335
+ end
336
+ end
337
+
338
+ def stub_snapshot(values)
339
+ fakeshot = NewRelic::Agent::VM::Snapshot.new
340
+ values.each do |key, value|
341
+ fakeshot.send("#{key}=", value)
342
+ end
343
+ NewRelic::Agent::VM.stubs(:snapshot).returns(fakeshot)
344
+ fakeshot
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end