wd_newrelic_rpm 3.5.6 → 3.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/CHANGELOG +43 -3
  2. data/Gemfile +6 -2
  3. data/LICENSE +23 -0
  4. data/lib/new_relic/agent.rb +50 -3
  5. data/lib/new_relic/agent/agent.rb +40 -60
  6. data/lib/new_relic/agent/configuration/defaults.rb +9 -3
  7. data/lib/new_relic/agent/configuration/server_source.rb +4 -0
  8. data/lib/new_relic/agent/cross_app_monitor.rb +239 -0
  9. data/lib/new_relic/agent/cross_app_tracing.rb +281 -0
  10. data/lib/new_relic/agent/database.rb +28 -10
  11. data/lib/new_relic/agent/error_collector.rb +5 -0
  12. data/lib/new_relic/agent/event_listener.rb +4 -0
  13. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +58 -39
  14. data/lib/new_relic/agent/instrumentation/metric_frame.rb +16 -3
  15. data/lib/new_relic/agent/instrumentation/net.rb +13 -11
  16. data/lib/new_relic/agent/instrumentation/queue_time.rb +50 -192
  17. data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +145 -0
  18. data/lib/new_relic/agent/instrumentation/rails4/errors.rb +45 -0
  19. data/lib/new_relic/agent/instrumentation/resque.rb +10 -10
  20. data/lib/new_relic/agent/instrumentation/sinatra.rb +19 -9
  21. data/lib/new_relic/agent/new_relic_service.rb +63 -9
  22. data/lib/new_relic/agent/pipe_service.rb +8 -12
  23. data/lib/new_relic/agent/rules_engine.rb +72 -0
  24. data/lib/new_relic/agent/shim_agent.rb +0 -1
  25. data/lib/new_relic/agent/sql_sampler.rb +3 -2
  26. data/lib/new_relic/agent/stats.rb +149 -0
  27. data/lib/new_relic/agent/stats_engine.rb +9 -0
  28. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +1 -24
  29. data/lib/new_relic/agent/stats_engine/metric_stats.rb +84 -185
  30. data/lib/new_relic/agent/stats_engine/stats_hash.rb +58 -0
  31. data/lib/new_relic/agent/stats_engine/transactions.rb +10 -2
  32. data/lib/new_relic/agent/transaction_info.rb +31 -6
  33. data/lib/new_relic/agent/transaction_sample_builder.rb +19 -8
  34. data/lib/new_relic/agent/transaction_sampler.rb +17 -10
  35. data/lib/new_relic/helper.rb +32 -0
  36. data/lib/new_relic/local_environment.rb +24 -32
  37. data/lib/new_relic/okjson.rb +599 -0
  38. data/lib/new_relic/transaction_sample.rb +2 -1
  39. data/lib/new_relic/transaction_sample/segment.rb +2 -1
  40. data/lib/new_relic/version.rb +1 -1
  41. data/newrelic.yml +27 -41
  42. data/test/multiverse/suites/agent_only/Envfile +5 -1
  43. data/test/multiverse/suites/agent_only/audit_log_test.rb +2 -4
  44. data/test/multiverse/suites/agent_only/config/newrelic.yml +1 -2
  45. data/test/multiverse/suites/agent_only/{cross_process_test.rb → cross_application_tracing_test.rb} +3 -3
  46. data/test/multiverse/suites/agent_only/key_transactions_test.rb +66 -0
  47. data/test/multiverse/suites/agent_only/marshaling_test.rb +9 -22
  48. data/test/multiverse/suites/agent_only/rename_rule_test.rb +57 -0
  49. data/test/multiverse/suites/agent_only/start_up_test.rb +1 -1
  50. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +17 -6
  51. data/test/multiverse/suites/rails/error_tracing_test.rb +20 -8
  52. data/test/multiverse/suites/rails/queue_time_test.rb +2 -2
  53. data/test/multiverse/suites/resque/instrumentation_test.rb +4 -3
  54. data/test/multiverse/suites/sinatra/Envfile +2 -0
  55. data/test/multiverse/suites/sinatra/config/newrelic.yml +1 -0
  56. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +5 -5
  57. data/test/multiverse/suites/sinatra/sinatra_test.rb +77 -10
  58. data/test/new_relic/agent/agent/connect_test.rb +45 -1
  59. data/test/new_relic/agent/agent/start_worker_thread_test.rb +0 -3
  60. data/test/new_relic/agent/agent_test.rb +20 -40
  61. data/test/new_relic/agent/agent_test_controller_test.rb +27 -60
  62. data/test/new_relic/agent/busy_calculator_test.rb +1 -1
  63. data/test/new_relic/agent/configuration/server_source_test.rb +8 -3
  64. data/test/new_relic/agent/cross_app_monitor_test.rb +237 -0
  65. data/test/new_relic/agent/database_test.rb +60 -16
  66. data/test/new_relic/agent/error_collector_test.rb +28 -4
  67. data/test/new_relic/agent/event_listener_test.rb +23 -2
  68. data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +1 -1
  69. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +85 -12
  70. data/test/new_relic/agent/instrumentation/metric_frame_test.rb +95 -0
  71. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +436 -59
  72. data/test/new_relic/agent/instrumentation/queue_time_test.rb +58 -357
  73. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -5
  74. data/test/new_relic/agent/method_tracer_test.rb +4 -2
  75. data/test/new_relic/agent/new_relic_service_test.rb +108 -6
  76. data/test/new_relic/agent/pipe_channel_manager_test.rb +1 -1
  77. data/test/new_relic/agent/pipe_service_test.rb +9 -9
  78. data/test/new_relic/agent/rpm_agent_test.rb +0 -11
  79. data/test/new_relic/agent/rules_engine_test.rb +82 -0
  80. data/test/new_relic/agent/shim_agent_test.rb +0 -4
  81. data/test/new_relic/agent/sql_sampler_test.rb +7 -0
  82. data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +85 -0
  83. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +110 -23
  84. data/test/new_relic/agent/stats_engine_test.rb +1 -46
  85. data/test/new_relic/agent/stats_hash_test.rb +93 -0
  86. data/test/new_relic/agent/stats_test.rb +197 -0
  87. data/test/new_relic/agent/transaction_info_test.rb +63 -11
  88. data/test/new_relic/agent/transaction_sample_builder_test.rb +10 -3
  89. data/test/new_relic/agent/transaction_sampler_test.rb +92 -80
  90. data/test/new_relic/agent/worker_loop_test.rb +1 -1
  91. data/test/new_relic/agent_test.rb +35 -5
  92. data/test/new_relic/control_test.rb +1 -1
  93. data/test/new_relic/fake_collector.rb +87 -9
  94. data/test/new_relic/helper_test.rb +24 -0
  95. data/test/new_relic/metric_data_test.rb +11 -11
  96. data/test/new_relic/metric_spec_test.rb +1 -1
  97. data/test/script/ci.sh +1 -1
  98. data/test/test_contexts.rb +0 -1
  99. data/test/test_helper.rb +21 -3
  100. metadata +34 -41
  101. data/lib/new_relic/agent/cross_process_monitoring.rb +0 -187
  102. data/lib/new_relic/stats.rb +0 -337
  103. data/test/new_relic/agent/cross_process_monitoring_test.rb +0 -190
  104. data/test/new_relic/agent/stats_engine/metric_stats/harvest_test.rb +0 -133
  105. data/test/new_relic/fakes_sending_data.rb +0 -30
  106. data/test/new_relic/stats_test.rb +0 -421
@@ -1,190 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
-
3
- module NewRelic::Agent
4
- class CrossProcessMonitorTest < Test::Unit::TestCase
5
- AGENT_CROSS_PROCESS_ID = "qwerty"
6
- REQUEST_CROSS_PROCESS_ID = "42#1234"
7
-
8
- ENCODING_KEY_NOOP = "\0"
9
- TRUSTED_ACCOUNT_IDS = [42,13]
10
-
11
- CROSS_PROCESS_ID_POSITION = 0
12
- TRANSACTION_NAME_POSITION = 1
13
- QUEUE_TIME_POSITION = 2
14
- APP_TIME_POSITION = 3
15
- CONTENT_LENGTH_POSITION = 4
16
-
17
- def setup
18
- @response = {}
19
-
20
- @monitor = NewRelic::Agent::CrossProcessMonitor.new()
21
- @monitor.finish_setup(
22
- :cross_process_id => AGENT_CROSS_PROCESS_ID,
23
- :encoding_key => ENCODING_KEY_NOOP,
24
- :trusted_account_ids => TRUSTED_ACCOUNT_IDS)
25
- end
26
-
27
- def when_request_runs(request=for_id(REQUEST_CROSS_PROCESS_ID))
28
- @monitor.save_client_cross_process_id(request)
29
- @monitor.set_transaction_custom_parameters
30
- @monitor.insert_response_header(request, @response)
31
- end
32
-
33
- def when_request_has_error(request=for_id(REQUEST_CROSS_PROCESS_ID))
34
- options = {}
35
- @monitor.save_client_cross_process_id(request)
36
- @monitor.set_error_custom_parameters(options)
37
- @monitor.insert_response_header(request, @response)
38
-
39
- options
40
- end
41
-
42
- def test_adds_response_header
43
- with_default_timings
44
-
45
- when_request_runs
46
-
47
- assert_equal ["qwerty", "transaction", 1000, 2000, -1], unpacked_response
48
- end
49
-
50
- def test_strips_bad_characters_in_transaction_name
51
- NewRelic::Agent::BrowserMonitoring.stubs(:timings).returns(stub(
52
- :transaction_name => "\"'goo",
53
- :queue_time_in_seconds => 1000,
54
- :app_time_in_seconds => 2000))
55
-
56
- when_request_runs
57
-
58
- assert_equal "goo", unpacked_response[TRANSACTION_NAME_POSITION]
59
- end
60
-
61
- def test_doesnt_write_response_header_if_id_blank
62
- with_default_timings
63
-
64
- when_request_runs(for_id(''))
65
- assert_nil response_app_data
66
- end
67
-
68
- def test_doesnt_write_response_header_if_untrusted_id
69
- with_default_timings
70
-
71
- when_request_runs(for_id("4#1234"))
72
- assert_nil response_app_data
73
- end
74
-
75
- def test_doesnt_write_response_header_if_improperly_formatted_id
76
- with_default_timings
77
-
78
- when_request_runs(for_id("42"))
79
- assert_nil response_app_data
80
- end
81
-
82
- def test_doesnt_add_header_if_no_id_in_request
83
- when_request_runs({})
84
- assert_nil response_app_data
85
- end
86
-
87
- def test_doesnt_add_header_if_no_id_on_agent
88
- @monitor.finish_setup(
89
- :cross_process_id => nil,
90
- :encoding_key => ENCODING_KEY_NOOP,
91
- :trusted_account_ids => TRUSTED_ACCOUNT_IDS)
92
-
93
- when_request_runs
94
- assert_nil response_app_data
95
- end
96
-
97
- def test_doesnt_add_header_if_config_disabled
98
- with_config(:'cross_process.enabled' => false) do
99
- when_request_runs
100
- assert_nil response_app_data
101
- end
102
- end
103
-
104
- def test_includes_content_length
105
- with_default_timings
106
-
107
- when_request_runs(for_id(REQUEST_CROSS_PROCESS_ID).merge("Content-Length" => 3000))
108
- assert_equal 3000, unpacked_response[CONTENT_LENGTH_POSITION]
109
- end
110
-
111
- def test_finds_content_length_from_headers
112
- %w{Content-Length HTTP_CONTENT_LENGTH CONTENT_LENGTH cOnTeNt-LeNgTh}.each do |key|
113
- request = { key => 42 }
114
-
115
- assert_equal(42, @monitor.content_length_from_request(request), \
116
- "Failed to find header on key #{key}")
117
- end
118
- end
119
-
120
- def test_writes_custom_parameters
121
- with_default_timings
122
-
123
- NewRelic::Agent.expects(:add_custom_parameters).once
124
-
125
- when_request_runs
126
- end
127
-
128
- def test_error_writes_custom_parameters
129
- with_default_timings
130
-
131
- options = when_request_has_error
132
-
133
- assert_equal REQUEST_CROSS_PROCESS_ID, options[:client_cross_process_id]
134
- end
135
-
136
- def test_error_doesnt_write_custom_parameters_if_no_id
137
- with_default_timings
138
-
139
- options = when_request_has_error(for_id(''))
140
-
141
- assert_equal false, options.key?(:client_cross_process_id)
142
- end
143
-
144
- def test_writes_metric
145
- with_default_timings
146
-
147
- metric = mock()
148
- metric.expects(:record_data_point).with(2000)
149
- NewRelic::Agent.instance.stats_engine.stubs(:get_stats_no_scope).returns(metric)
150
-
151
- when_request_runs
152
- end
153
-
154
- def test_doesnt_write_metric_if_id_blank
155
- with_default_timings
156
- NewRelic::Agent.instance.stats_engine.expects(:get_stats_no_scope).never
157
-
158
- when_request_runs(for_id(''))
159
- end
160
-
161
- def test_decoding_blank
162
- assert_equal "", @monitor.decode_with_key("")
163
- end
164
-
165
- def test_get_bytes_with_nil
166
- assert_equal [], @monitor.send(:get_bytes, nil)
167
- end
168
-
169
- def with_default_timings
170
- NewRelic::Agent::BrowserMonitoring.stubs(:timings).returns(stub(
171
- :transaction_name => "transaction",
172
- :queue_time_in_seconds => 1000,
173
- :app_time_in_seconds => 2000))
174
- end
175
-
176
- def for_id(id)
177
- encoded_id = id == "" ? "" : Base64.encode64(id)
178
- { 'X-NewRelic-ID' => encoded_id }
179
- end
180
-
181
- def response_app_data
182
- @response['X-NewRelic-App-Data']
183
- end
184
-
185
- def unpacked_response
186
- # Assumes array is valid JSON and Ruby, which is currently is
187
- eval(Base64.decode64(response_app_data))
188
- end
189
- end
190
- end
@@ -1,133 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','..','test_helper'))
2
- require 'new_relic/agent/stats_engine/metric_stats'
3
-
4
- class NewRelic::Agent::StatsEngine::MetricStats::HarvestTest < Test::Unit::TestCase
5
- include NewRelic::Agent::StatsEngine::MetricStats::Harvest
6
-
7
- attr_accessor :stats_hash
8
- def test_merge_stats_with_nil_stats
9
- self.stats_hash = NewRelic::Agent::StatsEngine::MetricStats::SynchronizedHash.new
10
- assert_equal({}, merge_stats({}, {}))
11
- end
12
-
13
-
14
- def test_get_stats_hash_from_hash
15
- assert_equal({}, get_stats_hash_from({}))
16
- end
17
-
18
- def test_get_stats_hash_from_engine
19
- assert_equal({}, get_stats_hash_from(NewRelic::Agent::StatsEngine.new))
20
- end
21
-
22
- def test_coerce_to_metric_spec_metric_spec
23
- assert_equal NewRelic::MetricSpec.new, coerce_to_metric_spec(NewRelic::MetricSpec.new)
24
- end
25
-
26
- def test_coerce_to_metric_spec_string
27
- assert_equal NewRelic::MetricSpec.new('foo'), coerce_to_metric_spec('foo')
28
- end
29
-
30
- def test_clone_and_reset_stats_nil
31
- spec = NewRelic::MetricSpec.new('foo', 'bar')
32
- stats = nil
33
- begin
34
- clone_and_reset_stats(spec, stats)
35
- rescue RuntimeError => e
36
- assert_equal("Nil stats for foo (bar)", e.message)
37
- end
38
- end
39
-
40
- def test_clone_and_reset_stats_present
41
- # spec is only used for debug output
42
- spec = nil
43
- stats = mock('stats')
44
- stats_clone = mock('stats_clone')
45
- stats.expects(:clone).returns(stats_clone)
46
- stats.expects(:reset)
47
- # should return a clone
48
- assert_equal stats_clone, clone_and_reset_stats(spec, stats)
49
- end
50
-
51
- def test_merge_old_data_present
52
- metric_spec = mock('metric_spec')
53
- stats = mock('stats obj')
54
- stats.expects(:merge!).with('some stats')
55
- old_data = mock('old data')
56
- old_data.expects(:stats).returns('some stats')
57
- old_data_hash = {metric_spec => old_data}
58
- merge_old_data!(metric_spec, stats, old_data_hash)
59
- end
60
-
61
- def test_merge_old_data_nil
62
- metric_spec = mock('metric_spec')
63
- stats = mock('stats') # doesn't matter
64
- old_data_hash = {metric_spec => nil}
65
- merge_old_data!(metric_spec, stats, old_data_hash)
66
- end
67
-
68
- def test_add_data_to_send_unless_empty_when_is_empty
69
- stats = mock('stats')
70
- stats.expects(:is_reset?).returns(true)
71
- assert_equal nil, add_data_to_send_unless_empty(nil, stats, nil, nil)
72
- end
73
-
74
- def test_add_data_to_send_unless_empty_main
75
- data = mock('data hash')
76
- stats = mock('stats')
77
- stats.expects(:is_reset?).returns(false)
78
- metric_spec = mock('spec')
79
-
80
- NewRelic::MetricData.expects(:new).with(metric_spec, stats, nil).returns('metric data')
81
- data.expects(:[]=).with(metric_spec, 'metric data')
82
- add_data_to_send_unless_empty(data, stats, metric_spec, nil)
83
- end
84
-
85
- def test_add_data_to_send_unless_empty_with_id
86
- data = mock('data hash')
87
- stats = mock('stats')
88
- stats.expects(:is_reset?).returns(false)
89
- metric_spec = mock('spec')
90
- id = mock('id')
91
-
92
- NewRelic::MetricData.expects(:new).with(nil, stats, id).returns('metric data')
93
- data.expects(:[]=).with(metric_spec, 'metric data')
94
- assert_equal 'metric data', add_data_to_send_unless_empty(data, stats, metric_spec, id)
95
- end
96
-
97
- def test_merge_data_basic
98
- mock_stats_hash = mock('stats hash')
99
- self.stats_hash = mock_stats_hash
100
- merge_data({})
101
- end
102
-
103
- def test_merge_data_new_and_old_data
104
- stats = NewRelic::MethodTraceStats.new
105
- stats.record_data_point(1.0)
106
- new_stats = NewRelic::MethodTraceStats.new
107
- new_stats.record_data_point(2.0)
108
- self.expects(:lookup_stats).with('Custom/test/method', '').returns(new_stats)
109
- assert_equal(2.0, new_stats.total_call_time)
110
-
111
- metric_spec = NewRelic::MetricSpec.new('Custom/test/method')
112
- mock_stats_hash = mock('stats_hash')
113
- self.stats_hash = mock_stats_hash
114
- merge_data({metric_spec => NewRelic::MetricData.new(metric_spec, stats, nil)})
115
- assert_equal(3.0, new_stats.total_call_time)
116
- end
117
-
118
- def test_merge_data_old_data
119
- stats = NewRelic::MethodTraceStats.new
120
- stats.record_data_point(1.0)
121
- self.expects(:lookup_stats).returns(nil)
122
-
123
- metric_spec = NewRelic::MetricSpec.new('Custom/test/method')
124
- mock_stats_hash = mock('stats_hash')
125
- mock_stats_hash.expects(:[]=).with(metric_spec, stats)
126
- self.stats_hash = mock_stats_hash
127
- merge_data({metric_spec => NewRelic::MetricData.new(metric_spec, stats, nil)})
128
- end
129
-
130
- end
131
-
132
-
133
-
@@ -1,30 +0,0 @@
1
- module NewRelic
2
- module FakesSendingData
3
- def calls_for(method)
4
- @agent_data. \
5
- select { |d| d.action == method }. \
6
- map { |d| d.body }
7
- end
8
-
9
- # Unpeel the inner layers of encoding applied by the JSON marshaller.
10
- # I'm sorry.
11
- def unpack_inner_blobs(req)
12
- body = req.body
13
- if req.format == :json
14
- case req.action
15
- when 'profile_data' then
16
- body[0][4] = unpack(body[0][4])
17
- when 'sql_trace_data' then
18
- body[0][0][9] = unpack(body[0][0][9])
19
- when 'transaction_sample_data' then
20
- body[4] = unpack(body[4])
21
- end
22
- end
23
- body
24
- end
25
-
26
- def unpack(blob)
27
- JSON.load(Zlib::Inflate.inflate(Base64.decode64(blob)))
28
- end
29
- end
30
- end
@@ -1,421 +0,0 @@
1
- ENV['SKIP_RAILS'] = 'true'
2
- require File.expand_path(File.join(File.dirname(__FILE__),'..', 'test_helper'))
3
- ##require "new_relic/stats"
4
-
5
- module NewRelic; class TestObjectForStats
6
- include Stats
7
- attr_accessor :total_call_time
8
- attr_accessor :total_exclusive_time
9
- attr_accessor :begin_time
10
- attr_accessor :end_time
11
- attr_accessor :call_count
12
- end; end
13
-
14
-
15
- class NewRelic::StatsTest < Test::Unit::TestCase
16
-
17
- def test_checked_calculation_standard
18
- obj = NewRelic::TestObjectForStats.new
19
-
20
- assert_equal(1.0, obj.checked_calculation(1, 1))
21
-
22
- end
23
-
24
- def test_checked_calculation_with_zero
25
- obj = NewRelic::TestObjectForStats.new
26
- assert_equal(0.0, obj.checked_calculation(1, 0))
27
- end
28
-
29
- def test_checked_calculation_should_return_floats
30
- obj = NewRelic::TestObjectForStats.new
31
- assert_equal(0.5, obj.checked_calculation(1, 2))
32
- end
33
-
34
- def test_sum_attributes
35
- first = NewRelic::TestObjectForStats.new
36
- second = mock('other object')
37
- first.expects(:call_count).returns(6)
38
- second.expects(:call_count).returns(8)
39
- first.expects(:update_totals).with(second)
40
- first.expects(:stack_min_max_from).with(second)
41
- first.expects(:update_boundaries).with(second)
42
- first.expects(:call_count=).with(8)
43
- first.sum_attributes(second)
44
- end
45
-
46
- def mock_plusequals(first, second, method, first_value, second_value)
47
- first.expects(method).returns(first_value)
48
- second.expects(method).returns(second_value)
49
- first.expects("#{method}=".to_sym).with(first_value + second_value)
50
- end
51
-
52
- def test_stack_min_max_from
53
- first = NewRelic::TestObjectForStats.new
54
- second = mock('other object')
55
- mock_plusequals(first, second, :min_call_time, 1.5, 0.5)
56
- mock_plusequals(first, second, :max_call_time, 1.0, 3.0)
57
-
58
- first.stack_min_max_from(second)
59
- end
60
-
61
- def test_update_boundaries
62
- first = NewRelic::TestObjectForStats.new
63
- second = mock('other object')
64
-
65
- first.expects(:should_replace_begin_time?).with(second).returns(true)
66
- first.expects(:should_replace_end_time?).with(second).returns(true)
67
- first.expects(:begin_time=).with('other_begin_time')
68
- first.expects(:end_time=).with('other_end_time')
69
-
70
- second.expects(:begin_time).returns('other_begin_time')
71
- second.expects(:end_time).returns('other_end_time')
72
- first.update_boundaries(second)
73
- end
74
-
75
- def test_should_replace_end_time
76
- first = NewRelic::TestObjectForStats.new
77
- second = mock('other object')
78
-
79
- first.expects(:end_time).returns(Time.at(1))
80
- second.expects(:end_time).returns(Time.at(2))
81
- assert first.should_replace_end_time?(second), 'should replace end time when the other stat is larger'
82
- end
83
-
84
- def test_should_replace_begin_time_base
85
- first = NewRelic::TestObjectForStats.new
86
- second = mock('other object')
87
-
88
- first.expects(:begin_time).returns(Time.at(2))
89
- second.expects(:begin_time).returns(Time.at(1))
90
-
91
- assert first.should_replace_begin_time?(second), 'should replace the begin time when it is larger'
92
- end
93
-
94
- def test_should_replace_begin_time_empty
95
- first = NewRelic::TestObjectForStats.new
96
- second = mock('other object')
97
-
98
- first.expects(:begin_time).returns(Time.at(0))
99
- second.expects(:begin_time).returns(Time.at(2))
100
-
101
- first.expects(:begin_time).returns(Time.at(0))
102
-
103
- assert first.should_replace_begin_time?(second), "should replace the begin time if self.call_count == 0"
104
- end
105
-
106
- def test_update_totals
107
- first = NewRelic::TestObjectForStats.new
108
- second = mock('other object')
109
-
110
- [:total_call_time, :total_exclusive_time, :sum_of_squares].each do |method|
111
- mock_plusequals(first, second, method, 2.0, 3.0)
112
- end
113
-
114
- first.update_totals(second)
115
- end
116
-
117
- def test_min_time_less
118
- first = NewRelic::TestObjectForStats.new
119
- second = mock('other object')
120
-
121
- second.expects(:min_call_time).returns(1.0)
122
- first.expects(:min_call_time).returns(2.0)
123
- second.expects(:call_count).returns(1)
124
-
125
- first.min_time_less?(second)
126
- end
127
-
128
- def test_expand_min_max_to
129
- first = NewRelic::TestObjectForStats.new
130
- second = mock('other object')
131
-
132
- first.expects(:min_time_less?).with(second).returns(true)
133
- first.expects(:max_call_time).returns(3.0)
134
-
135
- second.expects(:min_call_time).returns(1.0)
136
- second.expects(:max_call_time).returns(4.0).twice
137
-
138
- first.expects(:min_call_time=).with(1.0)
139
- first.expects(:max_call_time=).with(4.0)
140
-
141
- first.expand_min_max_to(second)
142
- end
143
-
144
-
145
-
146
- def test_simple
147
- stats = NewRelic::MethodTraceStats.new
148
- validate stats, 0, 0, 0, 0
149
-
150
- assert_equal stats.call_count,0
151
- stats.trace_call 10
152
- stats.trace_call 20
153
- stats.trace_call 30
154
-
155
- validate stats, 3, (10+20+30), 10, 30
156
- end
157
-
158
- def test_to_s
159
- s1 = NewRelic::MethodTraceStats.new
160
- s1.trace_call 10
161
- assert_equal("[01/01/70 12:00AM UTC, 0.000s; 1 calls 10s]", s1.to_s)
162
- end
163
-
164
- def test_time_str
165
- s1 = NewRelic::MethodTraceStats.new
166
- assert_equal(s1.time_str(10), "10 ms")
167
- assert_equal(s1.time_str(4999), "4999 ms")
168
- assert_equal(s1.time_str(5000), "5.00 s")
169
- assert_equal(s1.time_str(5010), "5.01 s")
170
- assert_equal(s1.time_str(9999), "10.00 s")
171
- assert_equal(s1.time_str(10000), "10.0 s")
172
- assert_equal(s1.time_str(20000), "20.0 s")
173
- end
174
-
175
- def test_multiply_by
176
- s1 = NewRelic::MethodTraceStats.new
177
- s1.trace_call 10
178
- assert_equal("[01/01/70 12:00AM UTC, 0.000s; 10 calls 10s]", s1.multiply_by(10).to_s)
179
- end
180
-
181
- def test_get_apdex
182
- s1 = NewRelic::MethodTraceStats.new
183
- s1.trace_call 10
184
- assert_equal(s1.get_apdex, [1, 10, 10])
185
- end
186
-
187
- def test_apdex_score
188
- s1 = NewRelic::MethodTraceStats.new
189
- s1.trace_call 10
190
- assert_in_delta(s1.apdex_score, 0.285714285714286, 0.0000001)
191
- end
192
-
193
- def test_as_percentage
194
- s1 = NewRelic::MethodTraceStats.new
195
- s1.trace_call 10
196
- assert_equal(s1.as_percentage, 1000.0)
197
- end
198
-
199
- def test_calls_per_minute
200
-
201
- s1 = NewRelic::TestObjectForStats.new
202
- s1.call_count = 1
203
- s1.begin_time = Time.at(0)
204
- s1.end_time = Time.at(30)
205
- assert_equal(s1.calls_per_minute, 2)
206
- end
207
-
208
- def test_total_call_time_per_minute
209
- s1 = NewRelic::TestObjectForStats.new
210
- s1.begin_time = Time.at(0)
211
- s1.end_time = Time.at(0)
212
- assert_equal(0, s1.total_call_time_per_minute)
213
- s1.begin_time = Time.at(0)
214
- s1.end_time = Time.at(30)
215
- s1.total_call_time = 10
216
- assert_equal(20, s1.total_call_time_per_minute)
217
- end
218
-
219
- def test_time_percentage
220
- s1 = NewRelic::TestObjectForStats.new
221
- s1.begin_time = Time.at(0)
222
- s1.end_time = Time.at(0)
223
- assert_equal(0, s1.time_percentage)
224
- s1.total_call_time = 10
225
- s1.begin_time = Time.at(0)
226
- s1.end_time = Time.at(30)
227
- assert_equal((1.0 / 3.0), s1.time_percentage)
228
- s1.total_call_time = 20
229
- assert_equal((2.0 / 3.0), s1.time_percentage)
230
- end
231
-
232
- def test_exclusive_time_percentage
233
- s1 = NewRelic::TestObjectForStats.new
234
- s1.begin_time = Time.at(0)
235
- s1.end_time = Time.at(0)
236
- assert_equal(0, s1.exclusive_time_percentage)
237
- s1.total_exclusive_time = 10
238
- s1.begin_time = Time.at(0)
239
- s1.end_time = Time.at(30)
240
- assert_equal((1.0 / 3.0), s1.exclusive_time_percentage)
241
- s1.total_exclusive_time = 20
242
- assert_equal((2.0 / 3.0), s1.exclusive_time_percentage)
243
- end
244
-
245
- def test_sum_merge
246
- s1 = NewRelic::MethodTraceStats.new
247
- s2 = NewRelic::MethodTraceStats.new
248
- s1.trace_call 10
249
- s2.trace_call 20
250
- s2.freeze
251
-
252
- validate s1, 1, 10, 10, 10
253
- validate s2, 1, 20, 20, 20
254
- s1.sum_merge! s2
255
- validate s1, 1, (10+20), 10 + 20, 20 + 10
256
- validate s2, 1, 20, 20, 20
257
- end
258
-
259
- def test_sum_merge_with_exclusive
260
- s1 = NewRelic::MethodTraceStats.new
261
- s2 = NewRelic::MethodTraceStats.new
262
-
263
- s1.trace_call 10, 5
264
- s2.trace_call 20, 10
265
- s2.freeze
266
-
267
- validate s1, 1, 10, 10, 10, 5
268
- validate s2, 1, 20, 20, 20, 10
269
- s1.sum_merge! s2
270
- validate s1, 1, (10+20), 10 + 20, 20 + 10, (10+5)
271
- end
272
-
273
- def test_merge
274
- s1 = NewRelic::MethodTraceStats.new
275
- s2 = NewRelic::MethodTraceStats.new
276
-
277
- s1.trace_call 10
278
- s2.trace_call 20
279
- s2.freeze
280
-
281
- validate s2, 1, 20, 20, 20
282
- s3 = s1.merge s2
283
- validate s3, 2, (10+20), 10, 20
284
- validate s1, 1, 10, 10, 10
285
- validate s2, 1, 20, 20, 20
286
-
287
- s1.merge! s2
288
- validate s1, 2, (10+20), 10, 20
289
- validate s2, 1, 20, 20, 20
290
- end
291
-
292
- def test_merge_with_exclusive
293
- s1 = NewRelic::MethodTraceStats.new
294
-
295
- s2 = NewRelic::MethodTraceStats.new
296
-
297
- s1.trace_call 10, 5
298
- s2.trace_call 20, 10
299
- s2.freeze
300
-
301
- validate s2, 1, 20, 20, 20, 10
302
- s3 = s1.merge s2
303
- validate s3, 2, (10+20), 10, 20, (10+5)
304
- validate s1, 1, 10, 10, 10, 5
305
- validate s2, 1, 20, 20, 20, 10
306
-
307
- s1.merge! s2
308
- validate s1, 2, (10+20), 10, 20, (5+10)
309
- validate s2, 1, 20, 20, 20, 10
310
- end
311
-
312
- def test_merge_array
313
- s1 = NewRelic::MethodTraceStats.new
314
- merges = []
315
- merges << (NewRelic::MethodTraceStats.new.trace_call 1)
316
- merges << (NewRelic::MethodTraceStats.new.trace_call 1)
317
- merges << (NewRelic::MethodTraceStats.new.trace_call 1)
318
-
319
- s1.merge! merges
320
- validate s1, 3, 3, 1, 1
321
- end
322
-
323
- def test_freeze
324
- s1 = NewRelic::MethodTraceStats.new
325
-
326
- s1.trace_call 10
327
- s1.freeze
328
-
329
- begin
330
- # the following should throw an exception because s1 is frozen
331
- s1.trace_call 20
332
- assert false
333
- rescue StandardError
334
- assert s1.frozen?
335
- validate s1, 1, 10, 10, 10
336
- end
337
- end
338
-
339
- def test_std_dev
340
- s = NewRelic::MethodTraceStats.new
341
- s.trace_call 1
342
- assert s.standard_deviation == 0
343
-
344
- s = NewRelic::MethodTraceStats.new
345
- s.trace_call 10
346
- s.trace_call 10
347
- s.sum_of_squares = nil
348
- assert s.standard_deviation == 0
349
-
350
- s = NewRelic::MethodTraceStats.new
351
- s.trace_call 0.001
352
- s.trace_call 0.001
353
- assert s.standard_deviation == 0
354
-
355
-
356
- s = NewRelic::MethodTraceStats.new
357
- s.trace_call 10
358
- s.trace_call 10
359
- s.trace_call 10
360
- s.trace_call 10
361
- s.trace_call 10
362
- s.trace_call 10
363
- assert s.standard_deviation == 0
364
-
365
- s = NewRelic::MethodTraceStats.new
366
- s.trace_call 4
367
- s.trace_call 7
368
- s.trace_call 13
369
- s.trace_call 16
370
- s.trace_call 8
371
- s.trace_call 4
372
- assert_equal(s.sum_of_squares, 4**2 + 7**2 + 13**2 + 16**2 + 8**2 + 4**2)
373
-
374
- s.trace_call 9
375
- s.trace_call 3
376
- s.trace_call 1000
377
- s.trace_call 4
378
-
379
- # calculated stdev (population, not sample) from a spreadsheet.
380
- assert_in_delta(s.standard_deviation, 297.76, 0.01)
381
- end
382
-
383
- def test_std_dev_merge
384
- s1 = NewRelic::MethodTraceStats.new
385
- s1.trace_call 4
386
- s1.trace_call 7
387
-
388
- s2 = NewRelic::MethodTraceStats.new
389
- s2.trace_call 13
390
- s2.trace_call 16
391
-
392
- s3 = s1.merge(s2)
393
-
394
- assert_equal(s1.sum_of_squares, 4*4 + 7*7)
395
- assert_in_delta(s1.standard_deviation, 1.5, 0.01)
396
-
397
- assert_in_delta(s2.standard_deviation, 1.5, 0.01)
398
- assert_equal(s3.sum_of_squares, 4*4 + 7*7 + 13*13 + 16*16, "check sum of squares")
399
- assert_in_delta(s3.standard_deviation, 4.743, 0.01)
400
- end
401
-
402
- if RUBY_VERSION >= '1.9'
403
- def test_to_json_enforces_float_values
404
- s1 = NewRelic::MethodTraceStats.new
405
- s1.trace_call 3.to_r
406
- s1.trace_call 7.to_r
407
-
408
- assert_equal 3.0, JSON.load(s1.to_json)['min_call_time']
409
- end
410
- end
411
-
412
- private
413
- def validate (stats, count, total, min, max, exclusive = nil)
414
- assert_equal stats.call_count, count
415
- assert_equal stats.total_call_time, total
416
- assert_equal stats.average_call_time, (count > 0 ? total / count : 0)
417
- assert_equal stats.min_call_time, min
418
- assert_equal stats.max_call_time, max
419
- assert_equal stats.total_exclusive_time, exclusive if exclusive
420
- end
421
- end