newrelic_rpm 3.9.7.266 → 3.9.8.273
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +44 -1
- data/lib/new_relic/agent.rb +31 -0
- data/lib/new_relic/agent/agent.rb +34 -5
- data/lib/new_relic/agent/configuration/default_source.rb +25 -1
- data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
- data/lib/new_relic/agent/cross_app_monitor.rb +1 -1
- data/lib/new_relic/agent/custom_event_aggregator.rb +2 -4
- data/lib/new_relic/agent/error_collector.rb +17 -12
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +9 -8
- data/lib/new_relic/agent/instrumentation/grape.rb +67 -0
- data/lib/new_relic/agent/new_relic_service.rb +93 -43
- data/lib/new_relic/agent/pipe_service.rb +4 -0
- data/lib/new_relic/agent/synthetics_event_buffer.rb +42 -0
- data/lib/new_relic/agent/system_info.rb +44 -18
- data/lib/new_relic/agent/transaction_event_aggregator.rb +9 -2
- data/lib/new_relic/agent/utilization_data.rb +77 -0
- data/lib/new_relic/agent/vm/mri_vm.rb +3 -3
- data/lib/new_relic/rack/agent_hooks.rb +15 -15
- data/lib/new_relic/recipes/capistrano3.rb +2 -2
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +0 -1
- data/test/agent_helper.rb +13 -3
- data/test/environments/lib/environments/runner.rb +3 -19
- data/test/environments/rails42/Gemfile +5 -1
- data/test/fixtures/cross_agent_tests/README.md +1 -1
- data/test/fixtures/cross_agent_tests/cat_map.json +154 -88
- data/test/fixtures/cross_agent_tests/docker_container_id/cases.json +30 -6
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.1.2-lxc-driver.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.1.2-native-driver-fs.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.1.2-native-driver-systemd.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/heroku.txt +1 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/ubuntu-14.04-lxc-container.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/{lxc-containers-without-docker.txt → ubuntu-14.04-no-container.txt} +0 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/ubuntu-14.10-no-container.txt +10 -0
- data/test/multiverse/lib/multiverse/runner.rb +1 -0
- data/test/multiverse/lib/multiverse/suite.rb +6 -2
- data/test/multiverse/suites/active_record/.gitignore +1 -0
- data/test/multiverse/suites/active_record/Envfile +25 -7
- data/test/multiverse/suites/active_record/Rakefile +9 -0
- data/test/{new_relic/agent/instrumentation → multiverse/suites/active_record}/active_record_test.rb +82 -88
- data/test/multiverse/suites/active_record/app/models/models.rb +27 -0
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +5 -46
- data/test/multiverse/suites/active_record/before_suite.rb +23 -0
- data/test/multiverse/suites/active_record/config/database.rb +79 -0
- data/test/multiverse/suites/active_record/config/database.yml +19 -0
- data/test/multiverse/suites/active_record/db/migrate/20141105131800_create_users_and_aliases.rb +21 -0
- data/test/multiverse/suites/active_record/db/migrate/20141106082200_create_orders_and_shipments.rb +25 -0
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +4 -1
- data/test/multiverse/suites/agent_only/custom_analytics_events_test.rb +53 -0
- data/test/multiverse/suites/agent_only/keepalive_test.rb +3 -7
- data/test/multiverse/suites/agent_only/utilization_data_collection_test.rb +170 -0
- data/test/multiverse/suites/grape/Envfile +15 -0
- data/test/multiverse/suites/grape/config/newrelic.yml +18 -0
- data/test/multiverse/suites/grape/grape_test.rb +60 -0
- data/test/multiverse/suites/grape/grape_test_api.rb +43 -0
- data/test/multiverse/suites/grape/unsupported_version_test.rb +31 -0
- data/test/multiverse/suites/json/Envfile +3 -1
- data/test/multiverse/suites/rack/rack_env_mutation_test.rb +54 -0
- data/test/multiverse/suites/rails/Envfile +1 -1
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +2 -1
- data/test/multiverse/suites/resque/resque_marshalling_test.rb +54 -0
- data/test/multiverse/suites/typhoeus/Envfile +4 -4
- data/test/new_relic/agent/agent_test.rb +37 -0
- data/test/new_relic/agent/configuration/default_source_test.rb +14 -0
- data/test/new_relic/agent/custom_event_aggregator_test.rb +3 -3
- data/test/new_relic/agent/error_collector/notice_error_test.rb +4 -4
- data/test/new_relic/agent/error_collector_test.rb +27 -4
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +23 -0
- data/test/new_relic/agent/new_relic_service_test.rb +208 -103
- data/test/new_relic/agent/pipe_service_test.rb +7 -0
- data/test/new_relic/agent/synthetics_event_buffer_test.rb +54 -0
- data/test/new_relic/agent/synthetics_monitor_test.rb +0 -3
- data/test/new_relic/agent/system_info_test.rb +6 -6
- data/test/new_relic/agent/transaction_event_aggregator_test.rb +43 -2
- data/test/new_relic/agent/utilization_data_test.rb +18 -0
- data/test/new_relic/collection_helper_test.rb +0 -1
- data/test/new_relic/data_container_tests.rb +11 -7
- data/test/new_relic/fake_collector.rb +23 -0
- data/test/new_relic/fake_instance_metadata_service.rb +45 -0
- data/test/new_relic/license_test.rb +2 -0
- data/test/new_relic/marshalling_test_cases.rb +89 -4
- data/test/new_relic/transaction_sample_test.rb +1 -0
- data/test/test_helper.rb +1 -0
- metadata +33 -6
- metadata.gz.sig +1 -2
- data/test/active_record_fixtures.rb +0 -79
- data/test/new_relic/rack/all_test.rb +0 -14
@@ -238,7 +238,7 @@ class NewRelic::Agent::ErrorCollectorTest < Minitest::Test
|
|
238
238
|
|
239
239
|
def test_increment_error_count_record_summary_and_txn_metric
|
240
240
|
in_web_transaction('Controller/class/method') do
|
241
|
-
@error_collector.increment_error_count!(StandardError.new('Boo'))
|
241
|
+
@error_collector.increment_error_count!(NewRelic::Agent::TransactionState.tl_get, StandardError.new('Boo'))
|
242
242
|
end
|
243
243
|
|
244
244
|
assert_metrics_recorded(['Errors/all',
|
@@ -248,7 +248,7 @@ class NewRelic::Agent::ErrorCollectorTest < Minitest::Test
|
|
248
248
|
|
249
249
|
def test_increment_error_count_record_summary_and_txn_metric
|
250
250
|
in_background_transaction('OtherTransaction/AnotherFramework/Job/perform') do
|
251
|
-
@error_collector.increment_error_count!(StandardError.new('Boo'))
|
251
|
+
@error_collector.increment_error_count!(NewRelic::Agent::TransactionState.tl_get, StandardError.new('Boo'))
|
252
252
|
end
|
253
253
|
|
254
254
|
assert_metrics_recorded(['Errors/all',
|
@@ -257,14 +257,15 @@ class NewRelic::Agent::ErrorCollectorTest < Minitest::Test
|
|
257
257
|
end
|
258
258
|
|
259
259
|
def test_icrement_error_count_summary_outside_transaction
|
260
|
-
@error_collector.increment_error_count!(StandardError.new('Boo'))
|
260
|
+
@error_collector.increment_error_count!(NewRelic::Agent::TransactionState.tl_get, StandardError.new('Boo'))
|
261
261
|
|
262
262
|
assert_metrics_recorded(['Errors/all'])
|
263
263
|
assert_metrics_not_recorded(['Errors/allWeb', 'Errors/allOther'])
|
264
264
|
end
|
265
265
|
|
266
266
|
def test_doesnt_increment_error_count_on_transaction_if_nameless
|
267
|
-
@error_collector.increment_error_count!(
|
267
|
+
@error_collector.increment_error_count!(NewRelic::Agent::TransactionState.tl_get,
|
268
|
+
StandardError.new('Boo'),
|
268
269
|
:metric => '(unknown)')
|
269
270
|
|
270
271
|
assert_metrics_not_recorded(['Errors/(unknown)'])
|
@@ -395,6 +396,28 @@ class NewRelic::Agent::ErrorCollectorTest < Minitest::Test
|
|
395
396
|
assert_metrics_recorded_exclusive(['Errors/all'])
|
396
397
|
end
|
397
398
|
|
399
|
+
def test_doesnt_double_count_same_exception
|
400
|
+
in_transaction do
|
401
|
+
error = StandardError.new('wat')
|
402
|
+
@error_collector.notice_error(error)
|
403
|
+
@error_collector.notice_error(error)
|
404
|
+
end
|
405
|
+
|
406
|
+
assert_metrics_recorded('Errors/all' => { :call_count => 1 })
|
407
|
+
assert_equal 1, @error_collector.errors.length
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_doesnt_count_seen_exceptions
|
411
|
+
in_transaction do
|
412
|
+
error = StandardError.new('wat')
|
413
|
+
@error_collector.tag_as_seen(NewRelic::Agent::TransactionState.tl_get, error)
|
414
|
+
@error_collector.notice_error(error)
|
415
|
+
end
|
416
|
+
|
417
|
+
assert_metrics_not_recorded(['Errors/all'])
|
418
|
+
assert_empty @error_collector.errors
|
419
|
+
end
|
420
|
+
|
398
421
|
private
|
399
422
|
|
400
423
|
def expects_error_count_increase(increase)
|
@@ -39,6 +39,29 @@ module NewRelic::Agent::Instrumentation
|
|
39
39
|
add_transaction_tracer :bar
|
40
40
|
end
|
41
41
|
|
42
|
+
class TestNonBlockObject
|
43
|
+
attr_reader :called
|
44
|
+
|
45
|
+
def perform_action_without_newrelic_trace(*args)
|
46
|
+
@called = true
|
47
|
+
end
|
48
|
+
|
49
|
+
include ControllerInstrumentation
|
50
|
+
|
51
|
+
alias_method :perform_action, :perform_action_with_newrelic_trace
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_non_block_form
|
55
|
+
state = NewRelic::Agent::TransactionState.tl_get
|
56
|
+
state.push_traced(false)
|
57
|
+
|
58
|
+
object = TestNonBlockObject.new
|
59
|
+
object.perform_action
|
60
|
+
assert object.called
|
61
|
+
ensure
|
62
|
+
state.pop_traced if state
|
63
|
+
end
|
64
|
+
|
42
65
|
def setup
|
43
66
|
NewRelic::Agent.drop_buffered_data
|
44
67
|
@object = TestObject.new
|
@@ -6,29 +6,33 @@ require 'cgi'
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
|
7
7
|
require 'new_relic/agent/commands/thread_profiler_session'
|
8
8
|
|
9
|
-
|
10
|
-
# set of mocks.
|
11
|
-
class NewRelicServiceKeepAliveTest < Minitest::Test
|
9
|
+
class NewRelicServiceTest < Minitest::Test
|
12
10
|
def setup
|
13
11
|
@server = NewRelic::Control::Server.new('somewhere.example.com',
|
14
12
|
30303, '10.10.10.10')
|
15
13
|
@service = NewRelic::Agent::NewRelicService.new('license-key', @server)
|
14
|
+
|
15
|
+
@http_handle = create_http_handle
|
16
|
+
@http_handle.respond_to(:get_redirect_host, 'localhost')
|
17
|
+
connect_response = {
|
18
|
+
'config' => 'some config directives',
|
19
|
+
'agent_run_id' => 1
|
20
|
+
}
|
21
|
+
@http_handle.respond_to(:connect, connect_response)
|
22
|
+
|
23
|
+
@service.stubs(:create_http_connection).returns(@http_handle)
|
16
24
|
end
|
17
25
|
|
18
|
-
def
|
19
|
-
|
20
|
-
stub('http_handle', defaults.merge(overrides))
|
26
|
+
def create_http_handle(name='connection')
|
27
|
+
HTTPHandle.new(name)
|
21
28
|
end
|
22
29
|
|
23
30
|
def test_session_handles_timeouts_opening_connection_gracefully
|
24
|
-
|
25
|
-
conn.stubs(:start).raises(Timeout::Error)
|
26
|
-
conn.stubs(:finish).raises(RuntimeError)
|
27
|
-
@service.stubs(:create_http_connection).returns(conn)
|
31
|
+
@http_handle.stubs(:start).raises(Timeout::Error)
|
28
32
|
|
29
33
|
block_ran = false
|
30
34
|
|
31
|
-
assert_raises(
|
35
|
+
assert_raises(::NewRelic::Agent::ServerConnectionException) do
|
32
36
|
@service.session do
|
33
37
|
block_ran = true
|
34
38
|
end
|
@@ -38,14 +42,10 @@ class NewRelicServiceKeepAliveTest < Minitest::Test
|
|
38
42
|
end
|
39
43
|
|
40
44
|
def test_session_block_reuses_http_handle_with_aggressive_keepalive_off
|
41
|
-
handle1 =
|
42
|
-
handle2 =
|
45
|
+
handle1 = create_http_handle
|
46
|
+
handle2 = create_http_handle
|
43
47
|
@service.stubs(:create_http_connection).returns(handle1, handle2)
|
44
48
|
|
45
|
-
handle1.expects(:start).once
|
46
|
-
handle1.expects(:finish).once
|
47
|
-
handle2.expects(:start).never
|
48
|
-
|
49
49
|
block_ran = false
|
50
50
|
with_config(:aggressive_keepalive => false) do
|
51
51
|
@service.session do
|
@@ -58,44 +58,46 @@ class NewRelicServiceKeepAliveTest < Minitest::Test
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
assert(block_ran)
|
61
|
+
|
62
|
+
assert_equal([:start, :finish], handle1.calls)
|
63
|
+
assert_equal([], handle2.calls)
|
61
64
|
end
|
62
65
|
|
63
66
|
def test_multiple_http_handles_are_used_outside_session_block
|
64
|
-
handle1 =
|
65
|
-
handle2 =
|
67
|
+
handle1 = create_http_handle
|
68
|
+
handle2 = create_http_handle
|
66
69
|
@service.stubs(:create_http_connection).returns(handle1, handle2)
|
67
70
|
assert_equal(@service.http_connection.object_id, handle1.object_id)
|
68
71
|
assert_equal(@service.http_connection.object_id, handle2.object_id)
|
69
72
|
end
|
70
73
|
|
74
|
+
# Calling start on a Net::HTTP instance results in connection keep-alive
|
75
|
+
# being used, which means that the connection won't be automatically closed
|
76
|
+
# once a request is issued. For calls to the service outside of a session
|
77
|
+
# block (/get_redirect_host and /connect, namely), we actually want the
|
78
|
+
# connection to only be used for a single request.
|
79
|
+
def test_connections_not_explicitly_started_outside_session_block
|
80
|
+
@http_handle.respond_to(:foo, ['blah'])
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@service.stubs(:create_http_connection).returns(handle1)
|
82
|
+
@service.send(:invoke_remote, :foo, ['payload'])
|
83
|
+
|
84
|
+
assert_equal([:request], @http_handle.calls)
|
85
|
+
end
|
77
86
|
|
87
|
+
def test_session_starts_and_finishes_http_session_with_aggressive_keepalive_off
|
78
88
|
block_ran = false
|
79
89
|
|
80
90
|
with_config(:aggressive_keepalive => false) do
|
81
91
|
@service.session do
|
82
92
|
block_ran = true
|
83
|
-
# mocks expect #start and #finish to be called. This is how Net::HTTP
|
84
|
-
# implements keep alive
|
85
93
|
end
|
86
94
|
end
|
95
|
+
|
87
96
|
assert(block_ran)
|
97
|
+
assert_equal([:start, :finish], @http_handle.calls)
|
88
98
|
end
|
89
99
|
|
90
100
|
def test_session_does_not_close_connection_if_aggressive_keepalive_on
|
91
|
-
defaults = { :address => '10.10.10.10', :port => 30303, :started? => true }
|
92
|
-
handle = stub('http_handle', defaults)
|
93
|
-
|
94
|
-
handle.expects(:start).once
|
95
|
-
handle.expects(:finish).never
|
96
|
-
|
97
|
-
@service.stubs(:create_http_connection).returns(handle)
|
98
|
-
|
99
101
|
calls_to_block = 0
|
100
102
|
|
101
103
|
with_config(:aggressive_keepalive => true) do
|
@@ -105,51 +107,96 @@ class NewRelicServiceKeepAliveTest < Minitest::Test
|
|
105
107
|
end
|
106
108
|
|
107
109
|
assert_equal(2, calls_to_block)
|
110
|
+
assert_equal([:start], @http_handle.calls)
|
108
111
|
end
|
109
|
-
end
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
113
|
+
def test_requests_after_connection_failure_in_session_still_use_connection_caching
|
114
|
+
conn0 = create_http_handle('first connection')
|
115
|
+
conn1 = create_http_handle('second connection')
|
116
|
+
conn2 = create_http_handle('third connection')
|
117
|
+
@service.stubs(:create_http_connection).returns(conn0, conn1, conn2)
|
118
|
+
|
119
|
+
rsp_payload = ['ok']
|
120
|
+
|
121
|
+
conn0.respond_to(:foo, EOFError.new)
|
122
|
+
conn1.respond_to(:foo, rsp_payload)
|
123
|
+
conn1.respond_to(:bar, rsp_payload)
|
124
|
+
conn1.respond_to(:baz, rsp_payload)
|
125
|
+
|
126
|
+
@service.session do
|
127
|
+
@service.send(:invoke_remote, :foo, ['payload'])
|
128
|
+
@service.send(:invoke_remote, :bar, ['payload'])
|
129
|
+
@service.send(:invoke_remote, :baz, ['payload'])
|
119
130
|
end
|
120
|
-
|
131
|
+
|
132
|
+
assert_equal([:start, :request, :finish], conn0.calls)
|
133
|
+
assert_equal([:start, :request, :request, :request], conn1.calls)
|
134
|
+
assert_equal([], conn2.calls)
|
121
135
|
end
|
122
136
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
137
|
+
def test_repeated_connection_failures
|
138
|
+
conn0 = create_http_handle('first connection')
|
139
|
+
conn1 = create_http_handle('second connection')
|
140
|
+
conn2 = create_http_handle('third connection')
|
141
|
+
@service.stubs(:create_http_connection).returns(conn0, conn1, conn2)
|
142
|
+
|
143
|
+
rsp_payload = ['ok']
|
144
|
+
|
145
|
+
conn0.respond_to(:foo, EOFError.new)
|
146
|
+
conn1.respond_to(:foo, EOFError.new)
|
147
|
+
conn2.respond_to(:bar, rsp_payload)
|
148
|
+
conn2.respond_to(:baz, rsp_payload)
|
149
|
+
|
150
|
+
@service.session do
|
151
|
+
assert_raises(::NewRelic::Agent::ServerConnectionException) do
|
152
|
+
@service.send(:invoke_remote, :foo, ['payload'])
|
153
|
+
end
|
154
|
+
@service.send(:invoke_remote, :bar, ['payload'])
|
155
|
+
@service.send(:invoke_remote, :baz, ['payload'])
|
128
156
|
end
|
157
|
+
|
158
|
+
assert_equal([:start, :request, :finish], conn0.calls)
|
159
|
+
assert_equal([:start, :request, :finish], conn1.calls)
|
160
|
+
assert_equal([:start, :request, :request], conn2.calls)
|
129
161
|
end
|
130
|
-
protected :extend_with_mock
|
131
162
|
|
132
|
-
def
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
@http_handle = HTTPHandle.new
|
137
|
-
@service.stubs(:create_http_connection).returns(@http_handle)
|
163
|
+
def test_repeated_connection_failures_on_reconnect
|
164
|
+
conn0 = create_http_handle('first connection')
|
165
|
+
conn1 = create_http_handle('second connection')
|
166
|
+
conn2 = create_http_handle('third connection')
|
138
167
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
@http_handle.respond_to(:connect, connect_response)
|
168
|
+
conn0.respond_to(:foo, EOFError.new)
|
169
|
+
conn1.expects(:start).once.raises(EOFError.new)
|
170
|
+
conn2.expects(:start).never
|
171
|
+
|
172
|
+
@service.stubs(:create_http_connection).returns(conn0, conn1, conn2)
|
145
173
|
|
146
|
-
|
147
|
-
|
148
|
-
|
174
|
+
assert_raises(::NewRelic::Agent::ServerConnectionException) do
|
175
|
+
@service.session do
|
176
|
+
@service.send(:invoke_remote, :foo, ['payload'])
|
149
177
|
end
|
150
178
|
end
|
151
179
|
end
|
152
180
|
|
181
|
+
def test_repeated_connection_failures_outside_session
|
182
|
+
conn0 = create_http_handle('first connection')
|
183
|
+
conn1 = create_http_handle('second connection')
|
184
|
+
conn2 = create_http_handle('third connection')
|
185
|
+
|
186
|
+
conn0.respond_to(:foo, EOFError.new)
|
187
|
+
conn1.respond_to(:foo, EOFError.new)
|
188
|
+
|
189
|
+
@service.stubs(:create_http_connection).returns(conn0, conn1, conn2)
|
190
|
+
|
191
|
+
assert_raises(::NewRelic::Agent::ServerConnectionException) do
|
192
|
+
@service.send(:invoke_remote, :foo, ['payload'])
|
193
|
+
end
|
194
|
+
|
195
|
+
assert_equal([:request], conn0.calls)
|
196
|
+
assert_equal([:request], conn1.calls)
|
197
|
+
assert_equal([], conn2.calls)
|
198
|
+
end
|
199
|
+
|
153
200
|
def test_cert_file_path
|
154
201
|
assert @service.cert_file_path
|
155
202
|
assert_equal File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'cert', 'cacert.pem')), @service.cert_file_path
|
@@ -584,7 +631,7 @@ class NewRelicServiceTest < Minitest::Test
|
|
584
631
|
prepared = marshaller.prepare(dummy, :encoder => identity_encoder)
|
585
632
|
assert_equal(dummy, prepared)
|
586
633
|
|
587
|
-
prepared = marshaller.prepare(dummy, :encoder =>
|
634
|
+
prepared = marshaller.prepare(dummy, :encoder => ReverseEncoder)
|
588
635
|
decoded = prepared.map { |x| x.reverse }
|
589
636
|
assert_equal(dummy, decoded)
|
590
637
|
end
|
@@ -596,7 +643,7 @@ class NewRelicServiceTest < Minitest::Test
|
|
596
643
|
end
|
597
644
|
dummy = [[inner_array]]
|
598
645
|
marshaller = NewRelic::Agent::NewRelicService::Marshaller.new
|
599
|
-
prepared = marshaller.prepare(dummy, :encoder =>
|
646
|
+
prepared = marshaller.prepare(dummy, :encoder => ReverseEncoder)
|
600
647
|
assert_equal([[['dcba']]], prepared)
|
601
648
|
end
|
602
649
|
|
@@ -826,14 +873,82 @@ class NewRelicServiceTest < Minitest::Test
|
|
826
873
|
end
|
827
874
|
end
|
828
875
|
|
876
|
+
module ReverseEncoder
|
877
|
+
def self.encode(data)
|
878
|
+
data.reverse
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
882
|
+
# This class acts as a stand-in for instances of Net::HTTP, which represent
|
883
|
+
# HTTP connections.
|
884
|
+
#
|
885
|
+
# It can record the start / finish / request calls made to it, and exposes
|
886
|
+
# that call sequence via the #calls accessor.
|
887
|
+
#
|
888
|
+
# It can also be configured to generate dummy responses for calls to request,
|
889
|
+
# via the #respond_to method.
|
829
890
|
class HTTPHandle
|
830
|
-
|
891
|
+
# This module gets included into the Net::HTTPResponse subclasses that we
|
892
|
+
# create below. We do this because the code in NewRelicService switches
|
893
|
+
# behavior based on the type of response that is returned, and we want to be
|
894
|
+
# able to create dummy responses for testing easily.
|
895
|
+
module HTTPResponseMock
|
896
|
+
attr_accessor :code, :body, :message, :headers
|
897
|
+
|
898
|
+
def initialize(body, code=200, message='OK')
|
899
|
+
@code = code
|
900
|
+
@body = body
|
901
|
+
@message = message
|
902
|
+
@headers = {}
|
903
|
+
end
|
904
|
+
|
905
|
+
def [](key)
|
906
|
+
@headers[key]
|
907
|
+
end
|
908
|
+
end
|
831
909
|
|
832
|
-
|
910
|
+
HTTPSuccess = Class.new(Net::HTTPSuccess) { include HTTPResponseMock }
|
911
|
+
HTTPUnauthorized = Class.new(Net::HTTPUnauthorized) { include HTTPResponseMock }
|
912
|
+
HTTPNotFound = Class.new(Net::HTTPNotFound) { include HTTPResponseMock }
|
913
|
+
HTTPRequestEntityTooLarge = Class.new(Net::HTTPRequestEntityTooLarge) { include HTTPResponseMock }
|
914
|
+
HTTPUnsupportedMediaType = Class.new(Net::HTTPUnsupportedMediaType) { include HTTPResponseMock }
|
915
|
+
|
916
|
+
attr_accessor :read_timeout
|
917
|
+
attr_reader :calls, :last_request
|
918
|
+
|
919
|
+
def initialize(name)
|
920
|
+
@name = name
|
921
|
+
@started = false
|
833
922
|
reset
|
834
923
|
end
|
835
924
|
|
836
|
-
def
|
925
|
+
def start
|
926
|
+
@calls << :start
|
927
|
+
@started = true
|
928
|
+
end
|
929
|
+
|
930
|
+
def finish
|
931
|
+
@calls << :finish
|
932
|
+
@started = false
|
933
|
+
end
|
934
|
+
|
935
|
+
def inspect
|
936
|
+
"<HTTPHandle: #{@name}>"
|
937
|
+
end
|
938
|
+
|
939
|
+
def started?
|
940
|
+
@started
|
941
|
+
end
|
942
|
+
|
943
|
+
def address
|
944
|
+
'whereever.com'
|
945
|
+
end
|
946
|
+
|
947
|
+
def port
|
948
|
+
8080
|
949
|
+
end
|
950
|
+
|
951
|
+
def create_response_mock(payload, opts={})
|
837
952
|
if NewRelic::Agent::NewRelicService::JsonMarshaller.is_supported?
|
838
953
|
format = :json
|
839
954
|
else
|
@@ -858,39 +973,44 @@ class NewRelicServiceTest < Minitest::Test
|
|
858
973
|
end
|
859
974
|
|
860
975
|
if opts[:format] == :json
|
861
|
-
|
862
|
-
request.path.include?(method.to_s)
|
863
|
-
end
|
976
|
+
klass.new(JSON.dump('return_value' => payload), opts[:code], {})
|
864
977
|
else
|
865
|
-
|
866
|
-
request.path.include?(method.to_s)
|
867
|
-
end
|
978
|
+
klass.new(Marshal.dump('return_value' => payload), opts[:code], {})
|
868
979
|
end
|
869
980
|
end
|
870
981
|
|
871
|
-
def
|
872
|
-
|
982
|
+
def respond_to(method, payload, opts={})
|
983
|
+
case payload
|
984
|
+
when Exception then rsp = payload
|
985
|
+
else rsp = create_response_mock(payload, opts)
|
986
|
+
end
|
987
|
+
|
988
|
+
@route_table[method.to_s] = rsp
|
873
989
|
end
|
874
990
|
|
875
991
|
def request(*args)
|
876
|
-
@
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
992
|
+
@calls << :request
|
993
|
+
|
994
|
+
request = args.first
|
995
|
+
@last_request = request
|
996
|
+
|
997
|
+
route = @route_table.keys.find { |r| request.path.include?(r) }
|
998
|
+
|
999
|
+
if route
|
1000
|
+
response = @route_table[route]
|
1001
|
+
raise response if response.kind_of?(Exception)
|
1002
|
+
response
|
1003
|
+
else
|
1004
|
+
HTTPNotFound.new('not found', 404)
|
881
1005
|
end
|
882
|
-
HTTPNotFound.new('not found', 404)
|
883
1006
|
end
|
884
1007
|
|
885
1008
|
def reset
|
1009
|
+
@calls = []
|
886
1010
|
@route_table = {}
|
887
1011
|
@last_request = nil
|
888
1012
|
end
|
889
1013
|
|
890
|
-
def last_request
|
891
|
-
@last_request
|
892
|
-
end
|
893
|
-
|
894
1014
|
def last_request_payload
|
895
1015
|
return nil unless @last_request && @last_request.body
|
896
1016
|
|
@@ -908,19 +1028,4 @@ class NewRelicServiceTest < Minitest::Test
|
|
908
1028
|
end
|
909
1029
|
end
|
910
1030
|
end
|
911
|
-
|
912
|
-
module HTTPResponseMock
|
913
|
-
attr_accessor :code, :body, :message, :headers
|
914
|
-
|
915
|
-
def initialize(body, code=200, message='OK')
|
916
|
-
@code = code
|
917
|
-
@body = body
|
918
|
-
@message = message
|
919
|
-
@headers = {}
|
920
|
-
end
|
921
|
-
|
922
|
-
def [](key)
|
923
|
-
@headers[key]
|
924
|
-
end
|
925
|
-
end
|
926
1031
|
end
|