newrelic_rpm 3.17.2.327 → 3.18.0.329
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +32 -10
- data/CHANGELOG.md +43 -3
- data/Rakefile +0 -21
- data/lib/new_relic/agent/cross_app_tracing.rb +34 -269
- data/lib/new_relic/agent/http_clients/curb_wrappers.rb +10 -2
- data/lib/new_relic/agent/http_clients/excon_wrappers.rb +18 -9
- data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +12 -6
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +13 -6
- data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +13 -6
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +14 -3
- data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +10 -15
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -7
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +4 -19
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +0 -1
- data/lib/new_relic/agent/instrumentation/curb.rb +9 -7
- data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +4 -0
- data/lib/new_relic/agent/instrumentation/excon/connection.rb +15 -5
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +17 -12
- data/lib/new_relic/agent/instrumentation/http.rb +12 -5
- data/lib/new_relic/agent/instrumentation/httpclient.rb +13 -4
- data/lib/new_relic/agent/instrumentation/net.rb +13 -2
- data/lib/new_relic/agent/instrumentation/rails5/action_controller.rb +2 -10
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +8 -3
- data/lib/new_relic/agent/method_tracer_helpers.rb +3 -1
- data/lib/new_relic/agent/parameter_filtering.rb +1 -1
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +0 -18
- data/lib/new_relic/agent/supported_versions.rb +1 -0
- data/lib/new_relic/agent/transaction/abstract_segment.rb +7 -9
- data/lib/new_relic/agent/transaction/external_request_segment.rb +139 -0
- data/lib/new_relic/agent/transaction/segment.rb +1 -1
- data/lib/new_relic/agent/transaction/tracing.rb +10 -1
- data/lib/new_relic/recipes/capistrano3.rb +3 -1
- data/lib/new_relic/version.rb +2 -2
- data/lib/tasks/multiverse.rb +27 -7
- data/test/environments/rails42/Gemfile +1 -0
- data/test/multiverse/lib/multiverse.rb +32 -0
- data/test/multiverse/lib/multiverse/runner.rb +2 -2
- data/test/multiverse/lib/multiverse/suite.rb +43 -22
- data/test/multiverse/suites/active_record/Envfile +3 -1
- data/test/multiverse/suites/activemerchant/Envfile +5 -1
- data/test/multiverse/suites/agent_only/Envfile +1 -0
- data/test/multiverse/suites/capistrano/deployment_test.rb +6 -9
- data/test/multiverse/suites/capistrano2/deployment_test.rb +6 -6
- data/test/multiverse/suites/curb/curb_test.rb +2 -3
- data/test/multiverse/suites/datamapper/Envfile +4 -0
- data/test/multiverse/suites/datamapper/datamapper_test.rb +106 -36
- data/test/multiverse/suites/delayed_job/Envfile +3 -3
- data/test/multiverse/suites/excon/excon_test.rb +1 -1
- data/test/multiverse/suites/grape/grape_test.rb +1 -1
- data/test/multiverse/suites/grape/grape_test_api.rb +1 -1
- data/test/multiverse/suites/grape/grape_versioning_test.rb +1 -1
- data/test/multiverse/suites/grape/grape_versioning_test_api.rb +1 -1
- data/test/multiverse/suites/grape/unsupported_version_test.rb +1 -1
- data/test/multiverse/suites/httpclient/Envfile +2 -0
- data/test/multiverse/suites/httpclient/httpclient_test.rb +1 -1
- data/test/multiverse/suites/httprb/Envfile +2 -0
- data/test/multiverse/suites/httprb/httprb_test.rb +1 -1
- data/test/multiverse/suites/json/Envfile +7 -2
- data/test/multiverse/suites/memcached/Envfile +2 -0
- data/test/multiverse/suites/mongo/Envfile +2 -0
- data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +95 -33
- data/test/multiverse/suites/mongo/mongo2_instrumentation_test.rb +62 -23
- data/test/multiverse/suites/net_http/Envfile +2 -0
- data/test/multiverse/suites/net_http/net_http_test.rb +7 -3
- data/test/multiverse/suites/padrino/Envfile +2 -0
- data/test/multiverse/suites/rack/Envfile +2 -0
- data/test/multiverse/suites/rack/url_map_test.rb +4 -0
- data/test/multiverse/suites/rails/Envfile +34 -29
- data/test/multiverse/suites/rake/Envfile +11 -6
- data/test/multiverse/suites/redis/Envfile +2 -0
- data/test/multiverse/suites/redis/redis_instrumentation_test.rb +31 -12
- data/test/multiverse/suites/sidekiq/Envfile +6 -2
- data/test/multiverse/suites/sinatra/Envfile +2 -0
- data/test/multiverse/suites/typhoeus/Envfile +31 -27
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +4 -3
- data/test/multiverse/suites/yajl/Envfile +4 -2
- data/test/new_relic/agent/datastores_test.rb +0 -10
- data/test/new_relic/agent/instrumentation/action_cable_subscriber_test.rb +2 -2
- data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +64 -65
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +11 -9
- data/test/new_relic/agent/instrumentation/instance_identification_test.rb +9 -8
- data/test/new_relic/agent/instrumentation/mongodb_command_subscriber_test.rb +7 -11
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +4 -0
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +0 -9
- data/test/new_relic/agent/method_tracer_test.rb +24 -8
- data/test/new_relic/agent/parameter_filtering_test.rb +2 -2
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +1 -0
- data/test/new_relic/agent/transaction/abstract_segment_test.rb +25 -16
- data/test/new_relic/agent/transaction/datastore_segment_test.rb +55 -38
- data/test/new_relic/agent/transaction/external_request_segment_test.rb +330 -0
- data/test/new_relic/agent/transaction/segment_test.rb +28 -4
- data/test/new_relic/agent/transaction/tracing_test.rb +60 -22
- data/test/new_relic/agent_test.rb +2 -1
- data/test/new_relic/collection_helper_test.rb +1 -0
- data/test/new_relic/dispatcher_test.rb +1 -0
- data/test/new_relic/fake_external_server.rb +1 -1
- data/test/new_relic/filtering_test_app.rb +1 -1
- data/test/new_relic/http_client_test_cases.rb +38 -20
- data/test/new_relic/rack/error_collector_test.rb +1 -0
- data/test/performance/suites/external_segment.rb +82 -0
- data/test/script/before_install/update_bundler.sh +12 -0
- data/test/script/external_server.rb +31 -0
- metadata +8 -5
- data/test/multiverse/lib/multiverse/environment.rb +0 -19
- data/test/new_relic/agent/cross_app_tracing_test.rb +0 -71
- data/test/script/before_install/jruby_bundler.sh +0 -22
@@ -30,7 +30,7 @@ class NewRelic::Agent::Instrumentation::MongodbCommandSubscriberTest < Minitest:
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_records_metrics_for_simple_find
|
33
|
-
simulate_query
|
33
|
+
in_transaction { simulate_query }
|
34
34
|
|
35
35
|
metric_name = 'Datastore/statement/MongoDB/users/find'
|
36
36
|
assert_metrics_recorded(
|
@@ -65,31 +65,29 @@ class NewRelic::Agent::Instrumentation::MongodbCommandSubscriberTest < Minitest:
|
|
65
65
|
|
66
66
|
def test_should_not_raise_due_to_an_exception_during_instrumentation_callback
|
67
67
|
@subscriber.stubs(:metrics).raises(StandardError)
|
68
|
-
simulate_query
|
68
|
+
in_transaction { simulate_query }
|
69
69
|
end
|
70
70
|
|
71
71
|
def test_records_instance_metrics_for_tcp_connection
|
72
|
-
simulate_query
|
72
|
+
in_transaction { simulate_query }
|
73
73
|
assert_metrics_recorded('Datastore/instance/MongoDB/nerd-server/27017')
|
74
74
|
end
|
75
75
|
|
76
76
|
def test_records_instance_metrics_for_unix_domain_socket
|
77
77
|
address = stub('address', :host => "/tmp/mongodb-27017.sock", :port => nil)
|
78
78
|
@started_event.stubs(:address).returns(address)
|
79
|
-
simulate_query
|
79
|
+
in_transaction { simulate_query }
|
80
80
|
assert_metrics_recorded('Datastore/instance/MongoDB/nerd-server//tmp/mongodb-27017.sock')
|
81
81
|
end
|
82
82
|
|
83
83
|
def test_records_unknown_unknown_metric_when_error_gathering_instance_data
|
84
84
|
@started_event.stubs(:address).returns(nil)
|
85
|
-
simulate_query
|
85
|
+
in_transaction { simulate_query }
|
86
86
|
assert_metrics_recorded('Datastore/instance/MongoDB/unknown/unknown')
|
87
87
|
end
|
88
88
|
|
89
89
|
def test_records_tt_segment_parameters_for_datastore_instance
|
90
|
-
in_transaction
|
91
|
-
simulate_query
|
92
|
-
end
|
90
|
+
in_transaction { simulate_query }
|
93
91
|
|
94
92
|
tt = last_transaction_trace
|
95
93
|
|
@@ -103,12 +101,10 @@ class NewRelic::Agent::Instrumentation::MongodbCommandSubscriberTest < Minitest:
|
|
103
101
|
def test_does_not_record_unknown_unknown_metric_when_data_empty
|
104
102
|
address = stub('address', :host => "", :port => "")
|
105
103
|
@started_event.stubs(:address).returns(address)
|
106
|
-
simulate_query
|
104
|
+
in_transaction { simulate_query }
|
107
105
|
assert_metrics_not_recorded('Datastore/instance/MongoDB/unknown/unknown')
|
108
106
|
end
|
109
107
|
|
110
|
-
|
111
|
-
|
112
108
|
def simulate_query
|
113
109
|
@subscriber.started(@started_event)
|
114
110
|
advance_time @succeeded_event.duration
|
@@ -23,6 +23,10 @@ class NewRelic::Agent::Instrumentation::NetInstrumentationTest < Minitest::Test
|
|
23
23
|
NewRelic::Agent.instance.stats_engine.clear_stats
|
24
24
|
end
|
25
25
|
|
26
|
+
def teardown
|
27
|
+
NewRelic::Agent.shutdown
|
28
|
+
end
|
29
|
+
|
26
30
|
def test_scope_stack_integrity_maintained_on_request_failure
|
27
31
|
@socket.stubs(:write).raises('fake network error')
|
28
32
|
with_config(:"cross_application_tracer.enabled" => true) do
|
@@ -11,15 +11,6 @@ class NewRelic::Agent::MethodTracer::TraceExecutionScopedTest < Minitest::Test
|
|
11
11
|
NewRelic::Agent.agent.stats_engine.clear_stats
|
12
12
|
end
|
13
13
|
|
14
|
-
def test_metric_recording_outside_transaction
|
15
|
-
trace_execution_scoped(['foo']) do
|
16
|
-
# meh
|
17
|
-
end
|
18
|
-
assert_metrics_recorded_exclusive(
|
19
|
-
'foo' => { :call_count => 1 }
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
14
|
def test_metric_recording_in_non_nested_transaction
|
24
15
|
in_transaction('outer') do
|
25
16
|
trace_execution_scoped(['foo', 'bar']) do
|
@@ -95,6 +95,7 @@ class NewRelic::Agent::MethodTracerTest < Minitest::Test
|
|
95
95
|
end
|
96
96
|
|
97
97
|
@metric_name = nil
|
98
|
+
NewRelic::Agent.shutdown
|
98
99
|
super
|
99
100
|
end
|
100
101
|
|
@@ -112,8 +113,11 @@ class NewRelic::Agent::MethodTracerTest < Minitest::Test
|
|
112
113
|
|
113
114
|
def test_trace_execution_scoped_records_metric_data
|
114
115
|
metric = "hello"
|
115
|
-
|
116
|
-
|
116
|
+
|
117
|
+
in_transaction do
|
118
|
+
self.class.trace_execution_scoped(metric) do
|
119
|
+
advance_time 0.05
|
120
|
+
end
|
117
121
|
end
|
118
122
|
|
119
123
|
stats = @stats_engine.get_stats(metric)
|
@@ -177,14 +181,18 @@ class NewRelic::Agent::MethodTracerTest < Minitest::Test
|
|
177
181
|
def test_add_method_tracer__default
|
178
182
|
self.class.add_method_tracer :simple_method
|
179
183
|
|
180
|
-
|
184
|
+
in_transaction do
|
185
|
+
simple_method
|
186
|
+
end
|
181
187
|
|
182
188
|
stats = @stats_engine.get_stats("Custom/#{self.class.name}/simple_method")
|
183
189
|
assert stats.call_count == 1
|
184
190
|
end
|
185
191
|
|
186
192
|
def test_add_class_method_tracer
|
187
|
-
|
193
|
+
in_transaction do
|
194
|
+
MyClass.class_method
|
195
|
+
end
|
188
196
|
stats = @stats_engine.get_stats("Custom/MyClass/Class/class_method")
|
189
197
|
assert stats.call_count == 1
|
190
198
|
end
|
@@ -196,7 +204,10 @@ class NewRelic::Agent::MethodTracerTest < Minitest::Test
|
|
196
204
|
add_method_tracer :instance_method
|
197
205
|
end
|
198
206
|
|
199
|
-
|
207
|
+
in_transaction do
|
208
|
+
cls.new.instance_method
|
209
|
+
end
|
210
|
+
|
200
211
|
stats = @stats_engine.get_stats("Custom/AnonymousClass/instance_method")
|
201
212
|
assert stats.call_count == 1
|
202
213
|
end
|
@@ -206,7 +217,9 @@ class NewRelic::Agent::MethodTracerTest < Minitest::Test
|
|
206
217
|
self.class.add_method_tracer :simple_method
|
207
218
|
self.class.add_method_tracer :simple_method
|
208
219
|
|
209
|
-
|
220
|
+
in_transaction do
|
221
|
+
simple_method
|
222
|
+
end
|
210
223
|
|
211
224
|
stats = @stats_engine.get_stats("Custom/#{self.class.name}/simple_method")
|
212
225
|
assert stats.call_count == 1
|
@@ -247,8 +260,11 @@ class NewRelic::Agent::MethodTracerTest < Minitest::Test
|
|
247
260
|
NewRelic::Agent.instance.stubs(:transaction_sampler).returns(@old_sampler)
|
248
261
|
|
249
262
|
mock = Insider.new(@stats_engine)
|
250
|
-
|
251
|
-
|
263
|
+
|
264
|
+
in_transaction do
|
265
|
+
mock.catcher(0)
|
266
|
+
mock.catcher(5)
|
267
|
+
end
|
252
268
|
|
253
269
|
stats = @stats_engine.get_stats("catcher")
|
254
270
|
assert_equal 2, stats.call_count
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# This file is distributed under New Relic
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
|
@@ -36,4 +36,4 @@ module NewRelic
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
-
end
|
39
|
+
end
|
@@ -45,18 +45,21 @@ module NewRelic
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_segment_records_metrics
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
in_transaction do |txn|
|
49
|
+
segment = BasicSegment.new "Custom/basic/segment"
|
50
|
+
txn.add_segment segment
|
51
|
+
segment.start
|
52
|
+
advance_time 1.0
|
53
|
+
segment.finish
|
54
|
+
end
|
52
55
|
|
53
56
|
assert_metrics_recorded ["Custom/basic/segment", "Basic/all"]
|
54
57
|
end
|
55
58
|
|
56
59
|
def test_segment_records_metrics_in_local_cache_if_part_of_transaction
|
57
60
|
segment = BasicSegment.new "Custom/basic/segment"
|
58
|
-
|
59
|
-
|
61
|
+
in_transaction "test_transaction" do |txn|
|
62
|
+
txn.add_segment segment
|
60
63
|
segment.start
|
61
64
|
advance_time 1.0
|
62
65
|
segment.finish
|
@@ -72,21 +75,27 @@ module NewRelic
|
|
72
75
|
# segments we would like to create a TT node for the segment, but not record
|
73
76
|
# metrics
|
74
77
|
def test_segments_will_not_record_metrics_when_turned_off
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
in_transaction do |txn|
|
79
|
+
segment = BasicSegment.new "Custom/basic/segment"
|
80
|
+
txn.add_segment segment
|
81
|
+
segment.record_metrics = false
|
82
|
+
segment.start
|
83
|
+
advance_time 1.0
|
84
|
+
segment.finish
|
85
|
+
end
|
80
86
|
|
81
87
|
refute_metrics_recorded ["Custom/basic/segment", "Basic/all"]
|
82
88
|
end
|
83
89
|
|
84
90
|
def test_segment_complete_callback_executes_when_segment_finished
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
91
|
+
in_transaction do |txn|
|
92
|
+
segment = BasicSegment.new "Custom/basic/segment"
|
93
|
+
txn.add_segment segment
|
94
|
+
segment.expects(:segment_complete)
|
95
|
+
segment.start
|
96
|
+
advance_time 1.0
|
97
|
+
segment.finish
|
98
|
+
end
|
90
99
|
end
|
91
100
|
end
|
92
101
|
end
|
@@ -28,14 +28,31 @@ module NewRelic
|
|
28
28
|
assert_equal "Datastore/operation/SQLite/select", segment.name
|
29
29
|
end
|
30
30
|
|
31
|
-
def test_segment_records_expected_metrics
|
32
|
-
Transaction.stubs(:recording_web_transaction?).returns(true)
|
33
31
|
|
32
|
+
def test_segment_does_not_record_metrics_outside_of_txn
|
34
33
|
segment = DatastoreSegment.new "SQLite", "insert", "Blog"
|
35
34
|
segment.start
|
36
35
|
advance_time 1
|
37
36
|
segment.finish
|
38
37
|
|
38
|
+
refute_metrics_recorded [
|
39
|
+
"Datastore/statement/SQLite/Blog/insert",
|
40
|
+
"Datastore/operation/SQLite/insert",
|
41
|
+
"Datastore/SQLite/allWeb",
|
42
|
+
"Datastore/SQLite/all",
|
43
|
+
"Datastore/allWeb",
|
44
|
+
"Datastore/all"
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_segment_records_expected_metrics
|
49
|
+
in_web_transaction "text_txn" do
|
50
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment "SQLite", "insert", "Blog"
|
51
|
+
segment.start
|
52
|
+
advance_time 1
|
53
|
+
segment.finish
|
54
|
+
end
|
55
|
+
|
39
56
|
assert_metrics_recorded [
|
40
57
|
"Datastore/statement/SQLite/Blog/insert",
|
41
58
|
"Datastore/operation/SQLite/insert",
|
@@ -47,12 +64,12 @@ module NewRelic
|
|
47
64
|
end
|
48
65
|
|
49
66
|
def test_segment_records_expected_metrics_without_collection
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
67
|
+
in_web_transaction "text_txn" do
|
68
|
+
segment = Transaction.start_datastore_segment "SQLite", "select"
|
69
|
+
segment.start
|
70
|
+
advance_time 1
|
71
|
+
segment.finish
|
72
|
+
end
|
56
73
|
|
57
74
|
assert_metrics_recorded [
|
58
75
|
"Datastore/operation/SQLite/select",
|
@@ -64,12 +81,12 @@ module NewRelic
|
|
64
81
|
end
|
65
82
|
|
66
83
|
def test_segment_records_expected_metrics_with_instance_identifier
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
84
|
+
in_web_transaction "text_txn" do
|
85
|
+
segment = Transaction.start_datastore_segment "SQLite", "select", nil, "jonan-01", "1337807"
|
86
|
+
segment.start
|
87
|
+
advance_time 1
|
88
|
+
segment.finish
|
89
|
+
end
|
73
90
|
|
74
91
|
assert_metrics_recorded [
|
75
92
|
"Datastore/instance/SQLite/jonan-01/1337807",
|
@@ -82,12 +99,12 @@ module NewRelic
|
|
82
99
|
end
|
83
100
|
|
84
101
|
def test_segment_records_expected_metrics_with_instance_identifier_host_only
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
102
|
+
in_web_transaction "text_txn" do
|
103
|
+
segment = Transaction.start_datastore_segment "SQLite", "select", nil, "jonan-01"
|
104
|
+
segment.start
|
105
|
+
advance_time 1
|
106
|
+
segment.finish
|
107
|
+
end
|
91
108
|
|
92
109
|
assert_metrics_recorded [
|
93
110
|
"Datastore/instance/SQLite/jonan-01/unknown",
|
@@ -100,12 +117,12 @@ module NewRelic
|
|
100
117
|
end
|
101
118
|
|
102
119
|
def test_segment_records_expected_metrics_with_instance_identifier_port_only
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
120
|
+
in_web_transaction "text_txn" do
|
121
|
+
segment = Transaction.start_datastore_segment "SQLite", "select", nil, nil, 1337807
|
122
|
+
segment.start
|
123
|
+
advance_time 1
|
124
|
+
segment.finish
|
125
|
+
end
|
109
126
|
|
110
127
|
assert_metrics_recorded [
|
111
128
|
"Datastore/instance/SQLite/unknown/1337807",
|
@@ -118,24 +135,24 @@ module NewRelic
|
|
118
135
|
end
|
119
136
|
|
120
137
|
def test_segment_does_not_record_expected_metrics_with_empty_data
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
138
|
+
in_web_transaction "text_txn" do
|
139
|
+
segment = Transaction.start_datastore_segment "SQLite", "select", nil
|
140
|
+
segment.start
|
141
|
+
advance_time 1
|
142
|
+
segment.finish
|
143
|
+
end
|
127
144
|
|
128
145
|
assert_metrics_not_recorded "Datastore/instance/SQLite/unknown/unknown"
|
129
146
|
end
|
130
147
|
|
131
148
|
def test_segment_does_not_record_instance_id_metrics_when_disabled
|
132
149
|
with_config(:'datastore_tracer.instance_reporting.enabled' => false) do
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
150
|
+
in_web_transaction "text_txn" do
|
151
|
+
segment = Transaction.start_datastore_segment "SQLite", "select", nil, "jonan-01", "1337807"
|
152
|
+
segment.start
|
153
|
+
advance_time 1
|
154
|
+
segment.finish
|
155
|
+
end
|
139
156
|
|
140
157
|
assert_metrics_not_recorded "Datastore/instance/SQLite/jonan-01/1337807"
|
141
158
|
end
|
@@ -0,0 +1,330 @@
|
|
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
|
+
|
7
|
+
require 'new_relic/agent/transaction'
|
8
|
+
require 'new_relic/agent/transaction/external_request_segment'
|
9
|
+
|
10
|
+
module NewRelic
|
11
|
+
module Agent
|
12
|
+
class Transaction
|
13
|
+
class ExternalRequestSegmentTest < Minitest::Test
|
14
|
+
class RequestWrapper
|
15
|
+
attr_reader :headers
|
16
|
+
|
17
|
+
def initialize headers = {}
|
18
|
+
@headers = headers
|
19
|
+
end
|
20
|
+
|
21
|
+
def [] key
|
22
|
+
@headers[key]
|
23
|
+
end
|
24
|
+
|
25
|
+
def []= key, value
|
26
|
+
@headers[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def host_from_header
|
30
|
+
self['host']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
TRANSACTION_GUID = 'BEC1BC64675138B9'
|
35
|
+
|
36
|
+
def setup
|
37
|
+
@obfuscator = NewRelic::Agent::Obfuscator.new "jotorotoes"
|
38
|
+
CrossAppTracing.stubs(:obfuscator).returns(@obfuscator)
|
39
|
+
CrossAppTracing.stubs(:valid_encoding_key?).returns(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
def teardown
|
43
|
+
NewRelic::Agent.drop_buffered_data
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_generates_expected_name
|
47
|
+
segment = ExternalRequestSegment.new "Typhoeus", "http://remotehost.com/blogs/index", "GET"
|
48
|
+
assert_equal "External/remotehost.com/Typhoeus/GET", segment.name
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_segment_does_not_record_metrics_outside_of_txn
|
52
|
+
segment = ExternalRequestSegment.new "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
53
|
+
segment.finish
|
54
|
+
|
55
|
+
refute_metrics_recorded [
|
56
|
+
"External/remotehost.com/Net::HTTP/GET",
|
57
|
+
"External/all",
|
58
|
+
"External/remotehost.com/all",
|
59
|
+
"External/allWeb",
|
60
|
+
["External/remotehost.com/Net::HTTP/GET", "test"]
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_segment_records_expected_metrics_for_non_cat_txn
|
65
|
+
in_transaction "test", :category => :controller do
|
66
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
67
|
+
segment.finish
|
68
|
+
end
|
69
|
+
|
70
|
+
expected_metrics = [
|
71
|
+
"External/remotehost.com/Net::HTTP/GET",
|
72
|
+
"External/all",
|
73
|
+
"External/remotehost.com/all",
|
74
|
+
"External/allWeb",
|
75
|
+
["External/remotehost.com/Net::HTTP/GET", "test"]
|
76
|
+
]
|
77
|
+
|
78
|
+
assert_metrics_recorded expected_metrics
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_segment_records_noncat_metrics_when_cat_disabled
|
82
|
+
request = RequestWrapper.new
|
83
|
+
response = {
|
84
|
+
'X-NewRelic-App-Data' => make_app_data_payload("1#1884", "txn-name", 2, 8, 0, TRANSACTION_GUID)
|
85
|
+
}
|
86
|
+
|
87
|
+
with_config(cat_config.merge({:"cross_application_tracer.enabled" => false})) do
|
88
|
+
in_transaction "test", :category => :controller do
|
89
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
90
|
+
segment.add_request_headers request
|
91
|
+
segment.read_response_headers response
|
92
|
+
segment.finish
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
expected_metrics = [
|
97
|
+
"External/remotehost.com/Net::HTTP/GET",
|
98
|
+
"External/all",
|
99
|
+
"External/remotehost.com/all",
|
100
|
+
"External/allWeb",
|
101
|
+
["External/remotehost.com/Net::HTTP/GET", "test"]
|
102
|
+
]
|
103
|
+
|
104
|
+
assert_metrics_recorded expected_metrics
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_segment_records_noncat_metrics_without_valid_cross_process_id
|
108
|
+
request = RequestWrapper.new
|
109
|
+
response = {
|
110
|
+
'X-NewRelic-App-Data' => make_app_data_payload("1#1884", "txn-name", 2, 8, 0, TRANSACTION_GUID)
|
111
|
+
}
|
112
|
+
|
113
|
+
with_config(cat_config.merge({:cross_process_id => ''})) do
|
114
|
+
in_transaction "test", :category => :controller do
|
115
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
116
|
+
segment.add_request_headers request
|
117
|
+
segment.read_response_headers response
|
118
|
+
segment.finish
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
expected_metrics = [
|
123
|
+
"External/remotehost.com/Net::HTTP/GET",
|
124
|
+
"External/all",
|
125
|
+
"External/remotehost.com/all",
|
126
|
+
"External/allWeb",
|
127
|
+
["External/remotehost.com/Net::HTTP/GET", "test"]
|
128
|
+
]
|
129
|
+
|
130
|
+
assert_metrics_recorded expected_metrics
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_segment_records_noncat_metrics_without_valid_encoding_key
|
134
|
+
CrossAppTracing.unstub(:valid_encoding_key?)
|
135
|
+
request = RequestWrapper.new
|
136
|
+
response = {
|
137
|
+
'X-NewRelic-App-Data' => make_app_data_payload("1#1884", "txn-name", 2, 8, 0, TRANSACTION_GUID)
|
138
|
+
}
|
139
|
+
|
140
|
+
with_config(cat_config.merge({:encoding_key => ''})) do
|
141
|
+
in_transaction "test", :category => :controller do
|
142
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
143
|
+
segment.add_request_headers request
|
144
|
+
segment.read_response_headers response
|
145
|
+
segment.finish
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
expected_metrics = [
|
150
|
+
"External/remotehost.com/Net::HTTP/GET",
|
151
|
+
"External/all",
|
152
|
+
"External/remotehost.com/all",
|
153
|
+
"External/allWeb",
|
154
|
+
["External/remotehost.com/Net::HTTP/GET", "test"]
|
155
|
+
]
|
156
|
+
|
157
|
+
assert_metrics_recorded expected_metrics
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_segment_records_expected_metrics_for_cat_transaction
|
161
|
+
response = {
|
162
|
+
'X-NewRelic-App-Data' => make_app_data_payload("1#1884", "txn-name", 2, 8, 0, TRANSACTION_GUID)
|
163
|
+
}
|
164
|
+
|
165
|
+
with_config cat_config do
|
166
|
+
in_transaction "test", :category => :controller do |txn|
|
167
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://newrelic.com/blogs/index", "GET"
|
168
|
+
segment.read_response_headers response
|
169
|
+
segment.finish
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
expected_metrics = [
|
174
|
+
"ExternalTransaction/newrelic.com/1#1884/txn-name",
|
175
|
+
"ExternalApp/newrelic.com/1#1884/all",
|
176
|
+
"External/all",
|
177
|
+
"External/newrelic.com/all",
|
178
|
+
"External/allWeb",
|
179
|
+
["ExternalTransaction/newrelic.com/1#1884/txn-name", "test"]
|
180
|
+
]
|
181
|
+
|
182
|
+
assert_metrics_recorded expected_metrics
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_segment_writes_outbound_request_headers
|
186
|
+
request = RequestWrapper.new
|
187
|
+
with_config cat_config do
|
188
|
+
in_transaction :category => :controller do
|
189
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
190
|
+
segment.add_request_headers request
|
191
|
+
segment.finish
|
192
|
+
end
|
193
|
+
end
|
194
|
+
assert request.headers.key?("X-NewRelic-ID"), "Expected to find X-NewRelic-ID header"
|
195
|
+
assert request.headers.key?("X-NewRelic-Transaction"), "Expected to find X-NewRelic-Transaction header"
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_segment_writes_synthetics_header_for_synthetics_txn
|
199
|
+
request = RequestWrapper.new
|
200
|
+
with_config cat_config do
|
201
|
+
in_transaction :category => :controller do |txn|
|
202
|
+
txn.raw_synthetics_header = json_dump_and_encode [1, 42, 100, 200, 300]
|
203
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
204
|
+
segment.add_request_headers request
|
205
|
+
segment.finish
|
206
|
+
end
|
207
|
+
end
|
208
|
+
assert request.headers.key?("X-NewRelic-Synthetics"), "Expected to find X-NewRelic-Synthetics header"
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_add_request_headers_renames_segment_based_on_host_header
|
212
|
+
request = RequestWrapper.new({"host" => "anotherhost.local"})
|
213
|
+
with_config cat_config do
|
214
|
+
in_transaction :category => :controller do
|
215
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
216
|
+
assert_equal "External/remotehost.com/Net::HTTP/GET", segment.name
|
217
|
+
segment.add_request_headers request
|
218
|
+
assert_equal "External/anotherhost.local/Net::HTTP/GET", segment.name
|
219
|
+
segment.finish
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_read_response_headers_decodes_valid_appdata
|
225
|
+
response = {
|
226
|
+
'X-NewRelic-App-Data' => make_app_data_payload("1#1884", "txn-name", 2, 8, 0, TRANSACTION_GUID)
|
227
|
+
}
|
228
|
+
|
229
|
+
with_config cat_config do
|
230
|
+
in_transaction :category => :controller do |txn|
|
231
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
232
|
+
segment.read_response_headers response
|
233
|
+
segment.finish
|
234
|
+
|
235
|
+
assert segment.cross_app_request?
|
236
|
+
assert_equal "1#1884", segment.cross_process_id
|
237
|
+
assert_equal "txn-name", segment.cross_process_transaction_name
|
238
|
+
assert_equal "BEC1BC64675138B9", segment.transaction_guid
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_read_response_headers_ignores_invalid_appdata
|
244
|
+
response = {
|
245
|
+
'X-NewRelic-App-Data' => "this#is#not#valid#appdata"
|
246
|
+
}
|
247
|
+
|
248
|
+
with_config cat_config do
|
249
|
+
in_transaction :category => :controller do |txn|
|
250
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
251
|
+
segment.read_response_headers response
|
252
|
+
segment.finish
|
253
|
+
|
254
|
+
refute segment.cross_app_request?
|
255
|
+
assert_nil segment.cross_process_id
|
256
|
+
assert_nil segment.cross_process_transaction_name
|
257
|
+
assert_nil segment.transaction_guid
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_read_response_headers_ignores_invalid_cross_app_id
|
263
|
+
response = {
|
264
|
+
'X-NewRelic-App-Data' => make_app_data_payload("not_an_ID", "txn-name", 2, 8, 0, TRANSACTION_GUID)
|
265
|
+
}
|
266
|
+
|
267
|
+
with_config cat_config do
|
268
|
+
in_transaction :category => :controller do |txn|
|
269
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://remotehost.com/blogs/index", "GET"
|
270
|
+
segment.read_response_headers response
|
271
|
+
segment.finish
|
272
|
+
|
273
|
+
refute segment.cross_app_request?
|
274
|
+
assert_nil segment.cross_process_id
|
275
|
+
assert_nil segment.cross_process_transaction_name
|
276
|
+
assert_nil segment.transaction_guid
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_uri_recorded_as_tt_attribute
|
282
|
+
segment = nil
|
283
|
+
uri = "http://newrelic.com/blogs/index"
|
284
|
+
|
285
|
+
in_transaction :category => :controller do
|
286
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", uri, "GET"
|
287
|
+
segment.finish
|
288
|
+
end
|
289
|
+
|
290
|
+
sample = NewRelic::Agent.agent.transaction_sampler.last_sample
|
291
|
+
node = find_node_with_name(sample, segment.name)
|
292
|
+
|
293
|
+
assert_equal uri, node.params[:uri]
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_guid_recorded_as_tt_attribute_for_cat_txn
|
297
|
+
segment = nil
|
298
|
+
|
299
|
+
response = {
|
300
|
+
'X-NewRelic-App-Data' => make_app_data_payload("1#1884", "txn-name", 2, 8, 0, TRANSACTION_GUID)
|
301
|
+
}
|
302
|
+
|
303
|
+
with_config cat_config do
|
304
|
+
in_transaction :category => :controller do
|
305
|
+
segment = Transaction.start_external_request_segment "Net::HTTP", "http://newrelic.com/blogs/index", "GET"
|
306
|
+
segment.read_response_headers response
|
307
|
+
segment.finish
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
sample = NewRelic::Agent.agent.transaction_sampler.last_sample
|
312
|
+
node = find_node_with_name(sample, segment.name)
|
313
|
+
|
314
|
+
assert_equal TRANSACTION_GUID, node.params[:transaction_guid]
|
315
|
+
end
|
316
|
+
|
317
|
+
def cat_config
|
318
|
+
{
|
319
|
+
:cross_process_id => "269975#22824",
|
320
|
+
:trusted_account_ids => [1,269975]
|
321
|
+
}
|
322
|
+
end
|
323
|
+
|
324
|
+
def make_app_data_payload( *args )
|
325
|
+
@obfuscator.obfuscate( args.to_json ) + "\n"
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|