newrelic_rpm 3.6.4.122 → 3.6.5.130
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 +14 -1
- data/lib/new_relic/agent.rb +8 -7
- data/lib/new_relic/agent/agent.rb +2 -0
- data/lib/new_relic/agent/configuration/defaults.rb +1 -1
- data/lib/new_relic/agent/configuration/server_source.rb +2 -1
- data/lib/new_relic/agent/cross_app_tracing.rb +52 -26
- data/lib/new_relic/agent/event_listener.rb +1 -1
- data/lib/new_relic/agent/http_clients/excon_wrappers.rb +61 -0
- data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +46 -0
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +72 -0
- data/lib/new_relic/agent/{uri_util.rb → http_clients/uri_util.rb} +11 -17
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -11
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/excon.rb +72 -0
- data/lib/new_relic/agent/instrumentation/excon/connection.rb +33 -0
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +45 -0
- data/lib/new_relic/agent/instrumentation/net.rb +3 -1
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +73 -0
- data/lib/new_relic/agent/method_tracer.rb +3 -6
- data/lib/new_relic/agent/new_relic_service.rb +1 -1
- data/lib/new_relic/agent/samplers/object_sampler.rb +1 -1
- data/lib/new_relic/agent/stats.rb +12 -10
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +24 -6
- data/lib/new_relic/agent/stats_engine/stats_hash.rb +9 -11
- data/lib/new_relic/agent/transaction.rb +34 -33
- data/lib/new_relic/agent/transaction_sampler.rb +15 -6
- data/lib/new_relic/language_support.rb +8 -0
- data/lib/new_relic/local_environment.rb +10 -14
- data/lib/new_relic/version.rb +1 -1
- data/test/agent_helper.rb +43 -0
- data/test/config/test.cert.crt +14 -0
- data/test/config/test.cert.csr +11 -0
- data/test/config/test.cert.key +15 -0
- data/test/config/testing-privkey.pem +18 -0
- data/test/multiverse/lib/multiverse/color.rb +9 -3
- data/test/multiverse/lib/multiverse/suite.rb +11 -1
- data/test/multiverse/suites/agent_only/audit_log_test.rb +1 -0
- data/test/multiverse/suites/agent_only/config/newrelic.yml +4 -0
- data/test/multiverse/suites/agent_only/http_response_code_test.rb +1 -1
- data/test/multiverse/suites/agent_only/rename_rule_test.rb +2 -1
- data/test/multiverse/suites/agent_only/start_up_test.rb +3 -2
- data/test/multiverse/suites/config_file_loading/Envfile +2 -0
- data/test/multiverse/suites/excon/Envfile +15 -0
- data/test/multiverse/suites/excon/config/newrelic.yml +21 -0
- data/test/multiverse/suites/excon/excon_test.rb +60 -0
- data/test/multiverse/suites/net_http/Envfile +6 -0
- data/test/multiverse/suites/net_http/config/newrelic.yml +21 -0
- data/test/multiverse/suites/net_http/net_http_test.rb +102 -0
- data/test/multiverse/suites/rails/Envfile +1 -1
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +6 -0
- data/test/multiverse/suites/resque/Envfile +0 -9
- data/test/multiverse/suites/resque/instrumentation_test.rb +21 -6
- data/test/multiverse/suites/typhoeus/Envfile +46 -0
- data/test/multiverse/suites/typhoeus/config/newrelic.yml +21 -0
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +77 -0
- data/test/new_relic/agent/agent_test_controller_test.rb +11 -10
- data/test/new_relic/agent/configuration/server_source_test.rb +23 -9
- data/test/new_relic/agent/database_test.rb +6 -0
- data/test/new_relic/agent/http_clients/uri_util_test.rb +64 -0
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +0 -406
- data/test/new_relic/agent/new_relic_service_test.rb +23 -19
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +29 -12
- data/test/new_relic/agent/stats_hash_test.rb +24 -3
- data/test/new_relic/agent/stats_test.rb +4 -4
- data/test/new_relic/agent/transaction/pop_test.rb +1 -1
- data/test/new_relic/agent/transaction_sampler_test.rb +18 -0
- data/test/new_relic/agent/transaction_test.rb +64 -69
- data/test/new_relic/agent_test.rb +20 -0
- data/test/new_relic/dependency_detection_test.rb +99 -0
- data/test/new_relic/evil_server.rb +56 -0
- data/test/new_relic/fake_collector.rb +12 -96
- data/test/new_relic/fake_external_server.rb +55 -0
- data/test/new_relic/fake_server.rb +97 -0
- data/test/new_relic/http_client_test_cases.rb +444 -0
- data/test/new_relic/language_support_test.rb +45 -0
- data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +25 -4
- metadata +37 -35
- metadata.gz.sig +0 -0
- data/test/multiverse/suites/resque/resque_setup.rb +0 -19
- data/test/new_relic/agent/uri_util_test.rb +0 -75
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
development:
|
3
|
+
error_collector:
|
4
|
+
capture_source: true
|
5
|
+
enabled: true
|
6
|
+
apdex_t: 0.5
|
7
|
+
ssl: false
|
8
|
+
monitor_mode: true
|
9
|
+
license_key: bootstrap_newrelic_admin_license_key_000
|
10
|
+
developer_mode: false
|
11
|
+
app_name: test
|
12
|
+
host: 127.0.0.1
|
13
|
+
api_host: 127.0.0.1
|
14
|
+
port: <%= 30_000 + ($$ % 10_000) %>
|
15
|
+
transaction_tracer:
|
16
|
+
record_sql: obfuscated
|
17
|
+
enabled: true
|
18
|
+
stack_trace_threshold: 0.5
|
19
|
+
transaction_threshold: 1.0
|
20
|
+
capture_params: false
|
21
|
+
log_level: debug
|
@@ -0,0 +1,77 @@
|
|
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 "typhoeus"
|
6
|
+
require "newrelic_rpm"
|
7
|
+
require "test/unit"
|
8
|
+
require "http_client_test_cases"
|
9
|
+
|
10
|
+
require File.join(File.dirname(__FILE__), "..", "..", "..", "agent_helper")
|
11
|
+
|
12
|
+
if NewRelic::Agent::Instrumentation::TyphoeusTracing.is_supported_version?
|
13
|
+
|
14
|
+
class TyphoeusTest < Test::Unit::TestCase
|
15
|
+
include HttpClientTestCases
|
16
|
+
|
17
|
+
USE_SSL_VERIFYPEER_VERSION = NewRelic::VersionNumber.new("0.5.0")
|
18
|
+
|
19
|
+
def ssl_option
|
20
|
+
if NewRelic::VersionNumber.new(Typhoeus::VERSION) >= USE_SSL_VERIFYPEER_VERSION
|
21
|
+
{ :ssl_verifypeer => false }
|
22
|
+
else
|
23
|
+
{ :disable_ssl_peer_verification => true }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def client_name
|
28
|
+
"Typhoeus"
|
29
|
+
end
|
30
|
+
|
31
|
+
# We use the Typhoeus::Request rather than right on Typhoeus to support
|
32
|
+
# prior to convenience methods being added on the top-level module (0.5.x)
|
33
|
+
def get_response(url=nil)
|
34
|
+
Typhoeus::Request.get(url || default_url, ssl_option)
|
35
|
+
end
|
36
|
+
|
37
|
+
def head_response
|
38
|
+
Typhoeus::Request.head(default_url, ssl_option)
|
39
|
+
end
|
40
|
+
|
41
|
+
def post_response
|
42
|
+
Typhoeus::Request.post(default_url, ssl_option.merge(:body => ""))
|
43
|
+
end
|
44
|
+
|
45
|
+
def request_instance
|
46
|
+
NewRelic::Agent::HTTPClients::TyphoeusHTTPRequest.new(Typhoeus::Request.new("http://newrelic.com"))
|
47
|
+
end
|
48
|
+
|
49
|
+
def response_instance
|
50
|
+
headers = "HTTP/1.1 200 OK \r\nX-Whatever-Man: 42"
|
51
|
+
NewRelic::Agent::HTTPClients::TyphoeusHTTPResponse.new(Typhoeus::Response.new(:response_headers => headers))
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def test_hydra
|
56
|
+
in_transaction("test") do
|
57
|
+
hydra = Typhoeus::Hydra.new
|
58
|
+
5.times { hydra.queue(Typhoeus::Request.new(default_url, ssl_option)) }
|
59
|
+
hydra.run
|
60
|
+
|
61
|
+
last_segment = find_last_transaction_segment()
|
62
|
+
assert_equal "External/Multiple/Typhoeus::Hydra/run", last_segment.metric_name
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
else
|
68
|
+
|
69
|
+
class TyphoeusNotInstrumented < Test::Unit::TestCase
|
70
|
+
def test_works_without_instrumentation
|
71
|
+
# Typhoeus.get wasn't supported back before 0.5.x
|
72
|
+
Typhoeus::Request.get("http://localhost/not/there")
|
73
|
+
assert_metrics_not_recorded(["External/all"])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -89,30 +89,31 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
|
|
89
89
|
end if ::Rails::VERSION::MAJOR.to_i <= 3
|
90
90
|
|
91
91
|
def test_new_queue_integration
|
92
|
-
|
93
|
-
Time.stubs(:now => Time.at(1360973845))
|
92
|
+
now = freeze_time
|
94
93
|
|
95
94
|
NewRelic::Agent::AgentTestController.clear_headers
|
96
95
|
engine.clear_stats
|
97
|
-
start = ((
|
96
|
+
start = ((now - 1).to_f * 1_000_000).to_i
|
98
97
|
NewRelic::Agent::AgentTestController.set_some_headers 'HTTP_X_QUEUE_START'=> "t=#{start}"
|
99
98
|
get :index
|
100
99
|
|
101
|
-
|
100
|
+
assert_metrics_recorded('WebFrontend/QueueTime' => { :total_call_time => 1 })
|
102
101
|
end
|
103
102
|
|
104
103
|
def test_new_frontend_work_integration
|
105
|
-
|
106
|
-
Time.stubs(:now => Time.at(1360973845))
|
104
|
+
now = freeze_time
|
107
105
|
|
108
106
|
engine.clear_stats
|
109
|
-
times = [
|
107
|
+
times = [now - 3, now - 2, now - 1]
|
110
108
|
times.map! {|t| (t.to_f * 1_000_000).to_i }
|
111
|
-
NewRelic::Agent::AgentTestController.set_some_headers(
|
112
|
-
|
109
|
+
NewRelic::Agent::AgentTestController.set_some_headers(
|
110
|
+
'HTTP_X_REQUEST_START' => "t=#{times[0]}",
|
111
|
+
'HTTP_X_QUEUE_START' => "t=#{times[1]}",
|
112
|
+
'HTTP_X_MIDDLEWARE_START' => "t=#{times[2]}"
|
113
|
+
)
|
113
114
|
get :index
|
114
115
|
|
115
|
-
|
116
|
+
assert_metrics_recorded('WebFrontend/QueueTime' => { :total_call_time => 3 })
|
116
117
|
end
|
117
118
|
|
118
119
|
def test_render_inline
|
@@ -54,12 +54,14 @@ module NewRelic::Agent::Configuration
|
|
54
54
|
def test_should_disable_gated_features_when_server_says_to
|
55
55
|
rsp = {
|
56
56
|
'collect_errors' => false,
|
57
|
-
'collect_traces' => false
|
57
|
+
'collect_traces' => false,
|
58
|
+
'collect_analytics_events' => false
|
58
59
|
}
|
59
60
|
existing_config = {
|
60
61
|
:'error_collector.enabled' => true,
|
61
62
|
:'slow_sql.enabled' => true,
|
62
|
-
:'transaction_tracer.enabled' => true
|
63
|
+
:'transaction_tracer.enabled' => true,
|
64
|
+
:'request_sampler.enabled' => true
|
63
65
|
}
|
64
66
|
@source = ServerSource.new(rsp, existing_config)
|
65
67
|
assert !@source[:'error_collector.enabled']
|
@@ -70,54 +72,64 @@ module NewRelic::Agent::Configuration
|
|
70
72
|
def test_should_enable_gated_features_when_server_says_to
|
71
73
|
rsp = {
|
72
74
|
'collect_errors' => true,
|
73
|
-
'collect_traces' => true
|
75
|
+
'collect_traces' => true,
|
76
|
+
'collect_analytics_events' => true
|
74
77
|
}
|
75
78
|
existing_config = {
|
76
79
|
:'error_collector.enabled' => true,
|
77
80
|
:'slow_sql.enabled' => true,
|
78
|
-
:'transaction_tracer.enabled' => true
|
81
|
+
:'transaction_tracer.enabled' => true,
|
82
|
+
:'request_sampler.enabled' => true
|
79
83
|
}
|
80
84
|
@source = ServerSource.new(rsp, existing_config)
|
81
85
|
assert @source[:'error_collector.enabled']
|
82
86
|
assert @source[:'slow_sql.enabled']
|
83
87
|
assert @source[:'transaction_tracer.enabled']
|
88
|
+
assert @source[:'request_sampler.enabled']
|
84
89
|
end
|
85
90
|
|
86
91
|
def test_should_allow_manual_disable_of_gated_features
|
87
92
|
rsp = {
|
88
93
|
'collect_errors' => true,
|
89
|
-
'collect_traces' => true
|
94
|
+
'collect_traces' => true,
|
95
|
+
'collect_analytics_events' => true
|
90
96
|
}
|
91
97
|
existing_config = {
|
92
98
|
:'error_collector.enabled' => false,
|
93
99
|
:'slow_sql.enabled' => false,
|
94
|
-
:'transaction_tracer.enabled' => false
|
100
|
+
:'transaction_tracer.enabled' => false,
|
101
|
+
:'request_sampler.enabled' => false
|
95
102
|
}
|
96
103
|
@source = ServerSource.new(rsp, existing_config)
|
97
104
|
assert !@source[:'error_collector.enabled']
|
98
105
|
assert !@source[:'slow_sql.enabled']
|
99
106
|
assert !@source[:'transaction_tracer.enabled']
|
107
|
+
assert !@source[:'request_sampler.enabled']
|
100
108
|
end
|
101
109
|
|
102
110
|
def test_should_enable_gated_features_when_server_says_yes_and_existing_says_no
|
103
111
|
rsp = {
|
104
112
|
'collect_errors' => true,
|
105
113
|
'collect_traces' => true,
|
114
|
+
'collect_analytics_events' => true,
|
106
115
|
'agent_config' => {
|
107
116
|
'transaction_tracer.enabled' => true,
|
108
117
|
'slow_sql.enabled' => true,
|
109
|
-
'error_collector.enabled' => true
|
118
|
+
'error_collector.enabled' => true,
|
119
|
+
'request_sampler.enabled' => true
|
110
120
|
}
|
111
121
|
}
|
112
122
|
existing_config = {
|
113
123
|
:'error_collector.enabled' => false,
|
114
124
|
:'slow_sql.enabled' => false,
|
115
|
-
:'transaction_tracer.enabled' => false
|
125
|
+
:'transaction_tracer.enabled' => false,
|
126
|
+
:'reqeust_sampler.enabled' => false
|
116
127
|
}
|
117
128
|
@source = ServerSource.new(rsp, existing_config)
|
118
129
|
assert @source[:'error_collector.enabled']
|
119
130
|
assert @source[:'slow_sql.enabled']
|
120
131
|
assert @source[:'transaction_tracer.enabled']
|
132
|
+
assert @source[:'request_sampler.enabled']
|
121
133
|
end
|
122
134
|
|
123
135
|
def test_should_not_gate_when_gating_keys_absent
|
@@ -125,13 +137,15 @@ module NewRelic::Agent::Configuration
|
|
125
137
|
'agent_config' => {
|
126
138
|
'transaction_tracer.enabled' => true,
|
127
139
|
'slow_sql.enabled' => true,
|
128
|
-
'error_collector.enabled' => true
|
140
|
+
'error_collector.enabled' => true,
|
141
|
+
'request_sampler.enabled' => true
|
129
142
|
}
|
130
143
|
}
|
131
144
|
@source = ServerSource.new(rsp, {})
|
132
145
|
assert @source[:'error_collector.enabled']
|
133
146
|
assert @source[:'slow_sql.enabled']
|
134
147
|
assert @source[:'transaction_tracer.enabled']
|
148
|
+
assert @source[:'request_sampler.enabled']
|
135
149
|
end
|
136
150
|
end
|
137
151
|
end
|
@@ -208,4 +208,10 @@ class NewRelic::Agent::DatabaseTest < Test::Unit::TestCase
|
|
208
208
|
|
209
209
|
assert_equal false, error_log.array.join.include?('VOLDEMORT')
|
210
210
|
end
|
211
|
+
|
212
|
+
def test_default_sql_obfuscator_obfuscates_double_quoted_literals_with_unknown_adapter
|
213
|
+
expected = "SELECT * FROM ? WHERE ? = ?"
|
214
|
+
result = NewRelic::Agent::Database.obfuscate_sql("SELECT * FROM \"table\" WHERE \"col\" = 'value'")
|
215
|
+
assert_equal expected, result
|
216
|
+
end
|
211
217
|
end
|
@@ -0,0 +1,64 @@
|
|
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/http_clients/uri_util'
|
7
|
+
|
8
|
+
class URIUtilTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def test_filter_uri
|
11
|
+
assert_filtered("http://foo.com/bar/baz",
|
12
|
+
"http://foo.com/bar/baz")
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_filter_uri_custom_port
|
16
|
+
assert_filtered("http://foo.com:1234/bar/baz",
|
17
|
+
"http://foo.com:1234/bar/baz")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_filtered_uri_omits_query_params
|
21
|
+
assert_filtered("http://foo.com/bar/baz?a=1&b=2",
|
22
|
+
"http://foo.com/bar/baz")
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_filtered_uri_omits_fragment
|
26
|
+
assert_filtered("http://foo.com/bar/baz#fragment",
|
27
|
+
"http://foo.com/bar/baz")
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_filtered_uri_omits_query_params_and_fragment
|
31
|
+
assert_filtered("http://foo.com/bar/baz?a=1&b=2#fragment",
|
32
|
+
"http://foo.com/bar/baz")
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_filtered_uri_reflects_use_of_ssl
|
36
|
+
assert_filtered('https://foo.com/bar/baz',
|
37
|
+
"https://foo.com/bar/baz")
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_filtered_uri_reflects_use_of_ssl_with_custom_port
|
41
|
+
assert_filtered('https://foo.com:9999/bar/baz',
|
42
|
+
"https://foo.com:9999/bar/baz")
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_filter_uri_with_full_uri_request_path
|
46
|
+
assert_filtered("http://foo.com/bar/baz?a=1&b=2#fragment",
|
47
|
+
"http://foo.com/bar/baz")
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_filter_uri_with_full_uri_request_path_https
|
51
|
+
assert_filtered("https://foo.com/bar/baz?a=1&b=2#fragment",
|
52
|
+
"https://foo.com/bar/baz")
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_strips_credentials_embedded_in_uri
|
56
|
+
assert_filtered("http://user:pass@foo.com/bar/baz",
|
57
|
+
"http://foo.com/bar/baz")
|
58
|
+
end
|
59
|
+
|
60
|
+
def assert_filtered(original, expected)
|
61
|
+
assert_equal(expected, NewRelic::Agent::HTTPClients::URIUtil.filter_uri(URI(original)))
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -3,54 +3,11 @@
|
|
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
|
-
|
7
6
|
require 'net/http'
|
8
7
|
require File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','test_helper'))
|
9
8
|
require 'new_relic/agent/cross_app_tracing'
|
10
9
|
|
11
|
-
# Add some stuff to Net::HTTP::HTTPResponse to facilitate building response data
|
12
|
-
class Net::HTTPResponse
|
13
|
-
def to_s
|
14
|
-
buf = ''
|
15
|
-
buf << "HTTP/%s %d %s\r\n" % [ self.http_version, self.code, self.message ]
|
16
|
-
self.each_capitalized {|k,v| buf << k << ': ' << v << "\r\n" }
|
17
|
-
buf << "\r\n"
|
18
|
-
buf << @body if @body
|
19
|
-
return buf
|
20
|
-
end
|
21
|
-
def initialize_copy( original )
|
22
|
-
@http_version = @http_version.dup
|
23
|
-
@code = @code.dup
|
24
|
-
@message = @message.dup
|
25
|
-
@body = @body.dup
|
26
|
-
@read = false
|
27
|
-
@header = @header.dup
|
28
|
-
end
|
29
|
-
|
30
|
-
unless instance_methods.map {|name| name.to_sym }.include?( :body= )
|
31
|
-
def body=( newbody )
|
32
|
-
@body = newbody
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
10
|
class NewRelic::Agent::Instrumentation::NetInstrumentationTest < Test::Unit::TestCase
|
38
|
-
include NewRelic::Agent::Instrumentation::ControllerInstrumentation,
|
39
|
-
NewRelic::Agent::CrossAppMonitor::EncodingFunctions,
|
40
|
-
NewRelic::Agent::CrossAppTracing
|
41
|
-
|
42
|
-
CANNED_RESPONSE = Net::HTTPOK.new( '1.1', '200', 'OK' )
|
43
|
-
CANNED_RESPONSE.body =
|
44
|
-
'<html><head><title>Canned Response</title></head><body>Canned response.</body></html>'
|
45
|
-
CANNED_RESPONSE['content-type'] = 'text/html; charset=UTF-8'
|
46
|
-
CANNED_RESPONSE['date'] = 'Tue, 29 Jan 2013 21:52:04 GMT'
|
47
|
-
CANNED_RESPONSE['expires'] = '-1'
|
48
|
-
CANNED_RESPONSE['server'] = 'gws'
|
49
|
-
CANNED_RESPONSE.freeze
|
50
|
-
|
51
|
-
TRANSACTION_GUID = 'BEC1BC64675138B9'
|
52
|
-
|
53
|
-
|
54
11
|
def setup
|
55
12
|
NewRelic::Agent.manual_start(
|
56
13
|
:"cross_application_tracer.enabled" => false,
|
@@ -59,344 +16,10 @@ class NewRelic::Agent::Instrumentation::NetInstrumentationTest < Test::Unit::Tes
|
|
59
16
|
:encoding_key => 'gringletoes'
|
60
17
|
)
|
61
18
|
|
62
|
-
@response = CANNED_RESPONSE.clone
|
63
19
|
@socket = fixture_tcp_socket( @response )
|
64
20
|
|
65
21
|
@engine = NewRelic::Agent.instance.stats_engine
|
66
22
|
@engine.clear_stats
|
67
|
-
|
68
|
-
|
69
|
-
@sampler = NewRelic::Agent.instance.transaction_sampler
|
70
|
-
NewRelic::Agent::TransactionInfo.get.guid = TRANSACTION_GUID
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
def teardown
|
75
|
-
NewRelic::Agent.instance.transaction_sampler.reset!
|
76
|
-
Thread::current[:newrelic_scope_stack] = nil
|
77
|
-
NewRelic::Agent.instance.stats_engine.end_transaction
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
#
|
82
|
-
# Helpers
|
83
|
-
#
|
84
|
-
|
85
|
-
def make_app_data_payload( *args )
|
86
|
-
return obfuscate_with_key( 'gringletoes', args.to_json ).gsub( /\n/, '' ) + "\n"
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
|
-
def find_last_segment
|
91
|
-
builder = NewRelic::Agent.agent.transaction_sampler.builder
|
92
|
-
last_segment = nil
|
93
|
-
builder.current_segment.each_segment {|s| last_segment = s }
|
94
|
-
|
95
|
-
return last_segment
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
#
|
101
|
-
# Tests
|
102
|
-
#
|
103
|
-
|
104
|
-
def test_get
|
105
|
-
url = URI.parse('http://www.google.com/index.html')
|
106
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
107
|
-
http.get('/index.html')
|
108
|
-
}
|
109
|
-
|
110
|
-
assert_match %r/<head>/i, res.body
|
111
|
-
assert_metrics_recorded_exclusive([
|
112
|
-
'External/all',
|
113
|
-
'External/www.google.com/Net::HTTP/GET',
|
114
|
-
'External/allOther',
|
115
|
-
'External/www.google.com/all'
|
116
|
-
])
|
117
|
-
end
|
118
|
-
|
119
|
-
def test_background
|
120
|
-
res = nil
|
121
|
-
|
122
|
-
perform_action_with_newrelic_trace("task", :category => :task) do
|
123
|
-
url = URI.parse('http://www.google.com/index.html')
|
124
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
125
|
-
http.get('/index.html')
|
126
|
-
}
|
127
|
-
end
|
128
|
-
|
129
|
-
assert_match %r/<head>/i, res.body
|
130
|
-
assert_metrics_recorded_exclusive([
|
131
|
-
'External/all',
|
132
|
-
'External/allOther',
|
133
|
-
'External/www.google.com/all',
|
134
|
-
'External/www.google.com/Net::HTTP/GET',
|
135
|
-
['External/www.google.com/Net::HTTP/GET', 'OtherTransaction/Background/NewRelic::Agent::Instrumentation::NetInstrumentationTest/task'],
|
136
|
-
'OtherTransaction/Background/NewRelic::Agent::Instrumentation::NetInstrumentationTest/task',
|
137
|
-
'OtherTransaction/Background/all',
|
138
|
-
'OtherTransaction/all'
|
139
|
-
])
|
140
|
-
end
|
141
|
-
|
142
|
-
def test_transactional
|
143
|
-
res = nil
|
144
|
-
|
145
|
-
perform_action_with_newrelic_trace("task") do
|
146
|
-
url = URI.parse('http://www.google.com/index.html')
|
147
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
148
|
-
http.get('/index.html')
|
149
|
-
}
|
150
|
-
end
|
151
|
-
|
152
|
-
assert_match %r/<head>/i, res.body
|
153
|
-
assert_metrics_recorded([
|
154
|
-
'External/all',
|
155
|
-
'External/www.google.com/Net::HTTP/GET',
|
156
|
-
'External/allWeb',
|
157
|
-
'External/www.google.com/all',
|
158
|
-
'Controller/NewRelic::Agent::Instrumentation::NetInstrumentationTest/task'
|
159
|
-
])
|
160
|
-
|
161
|
-
assert_not_includes @engine.metrics, 'External/allOther'
|
162
|
-
end
|
163
|
-
|
164
|
-
def test_get__simple
|
165
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
166
|
-
|
167
|
-
assert_metrics_recorded_exclusive([
|
168
|
-
'External/all',
|
169
|
-
'External/www.google.com/Net::HTTP/GET',
|
170
|
-
'External/allOther',
|
171
|
-
'External/www.google.com/all'
|
172
|
-
])
|
173
|
-
end
|
174
|
-
|
175
|
-
|
176
|
-
# https://newrelic.atlassian.net/browse/RUBY-835
|
177
|
-
def test_direct_get_request_doesnt_double_count
|
178
|
-
uri = URI.parse("http://www.google.com/index.html")
|
179
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
180
|
-
http.request(Net::HTTP::Get.new(uri.request_uri))
|
181
|
-
|
182
|
-
assert_metrics_recorded([
|
183
|
-
'External/www.google.com/Net::HTTP/GET'
|
184
|
-
])
|
185
|
-
end
|
186
|
-
|
187
|
-
def test_ignore
|
188
|
-
in_transaction do
|
189
|
-
NewRelic::Agent.disable_all_tracing do
|
190
|
-
url = URI.parse('http://www.google.com/index.html')
|
191
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
192
|
-
http.post('/index.html','data')
|
193
|
-
}
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
assert_metrics_recorded_exclusive([])
|
198
|
-
end
|
199
|
-
|
200
|
-
def test_head
|
201
|
-
url = URI.parse('http://www.google.com/index.html')
|
202
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
203
|
-
http.head('/index.html')
|
204
|
-
}
|
205
|
-
|
206
|
-
assert_metrics_recorded_exclusive([
|
207
|
-
'External/all',
|
208
|
-
'External/www.google.com/Net::HTTP/HEAD',
|
209
|
-
'External/allOther',
|
210
|
-
'External/www.google.com/all'
|
211
|
-
])
|
212
|
-
end
|
213
|
-
|
214
|
-
def test_post
|
215
|
-
url = URI.parse('http://www.google.com/index.html')
|
216
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
217
|
-
http.post('/index.html','data')
|
218
|
-
}
|
219
|
-
|
220
|
-
assert_metrics_recorded_exclusive([
|
221
|
-
'External/all',
|
222
|
-
'External/www.google.com/Net::HTTP/POST',
|
223
|
-
'External/allOther',
|
224
|
-
'External/www.google.com/all'
|
225
|
-
])
|
226
|
-
end
|
227
|
-
|
228
|
-
# When an http call is made, the agent should add a request header named
|
229
|
-
# X-NewRelic-ID with a value equal to the encoded cross_app_id.
|
230
|
-
|
231
|
-
def test_adds_a_request_header_to_outgoing_requests_if_xp_enabled
|
232
|
-
@socket.check_write do |data|
|
233
|
-
|
234
|
-
# assert_match /(?i:x-newrelic-id): VURQV1BZRkZdXUFT/, data
|
235
|
-
# The above assertion won't work in Ruby 2.0.0-p0 because of a bug in the
|
236
|
-
# regexp engine. Until that's fixed we'll check the header name case
|
237
|
-
# sensitively.
|
238
|
-
assert_match(/X-Newrelic-Id: VURQV1BZRkZdXUFT/, data)
|
239
|
-
end
|
240
|
-
|
241
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
242
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
def test_adds_a_request_header_to_outgoing_requests_if_old_xp_config_is_present
|
247
|
-
@socket.check_write do |data|
|
248
|
-
# assert_match /(?i:x-newrelic-id): VURQV1BZRkZdXUFT/, data
|
249
|
-
# The above assertion won't work in Ruby 2.0.0-p0 because of a bug in the
|
250
|
-
# regexp engine. Until that's fixed we'll check the header name case
|
251
|
-
# sensitively.
|
252
|
-
assert_match(/X-Newrelic-Id: VURQV1BZRkZdXUFT/, data)
|
253
|
-
end
|
254
|
-
|
255
|
-
with_config(:cross_application_tracing => true) do
|
256
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
def test_agent_doesnt_add_a_request_header_to_outgoing_requests_if_xp_disabled
|
261
|
-
@socket.check_write do |data|
|
262
|
-
# assert_no_match /(?i:x-newrelic-id): VURQV1BZRkZdXUFT/, data
|
263
|
-
# The above assertion won't work in Ruby 2.0.0-p0 because of a bug in the
|
264
|
-
# regexp engine. Until that's fixed we'll check the header name case
|
265
|
-
# sensitively.
|
266
|
-
assert_no_match(/X-Newrelic-Id: VURQV1BZRkZdXUFT/, data)
|
267
|
-
end
|
268
|
-
|
269
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
270
|
-
end
|
271
|
-
|
272
|
-
|
273
|
-
def test_instrumentation_with_crossapp_enabled_records_normal_metrics_if_no_header_present
|
274
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
275
|
-
in_transaction('test') do
|
276
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
assert_metrics_recorded_exclusive([
|
281
|
-
'External/all',
|
282
|
-
'External/allOther',
|
283
|
-
'External/www.google.com/all',
|
284
|
-
'External/www.google.com/Net::HTTP/GET',
|
285
|
-
['External/www.google.com/Net::HTTP/GET', 'test']
|
286
|
-
])
|
287
|
-
end
|
288
|
-
|
289
|
-
def test_instrumentation_with_crossapp_disabled_records_normal_metrics_even_if_header_is_present
|
290
|
-
@response[ NR_APPDATA_HEADER ] =
|
291
|
-
make_app_data_payload( '18#1884', 'txn-name', 2, 8, 0, TRANSACTION_GUID )
|
292
|
-
|
293
|
-
in_transaction('test') do
|
294
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
295
|
-
end
|
296
|
-
|
297
|
-
assert_metrics_recorded_exclusive([
|
298
|
-
'External/all',
|
299
|
-
'External/allOther',
|
300
|
-
'External/www.google.com/all',
|
301
|
-
'External/www.google.com/Net::HTTP/GET',
|
302
|
-
['External/www.google.com/Net::HTTP/GET', 'test']
|
303
|
-
])
|
304
|
-
end
|
305
|
-
|
306
|
-
|
307
|
-
def test_instrumentation_with_crossapp_enabled_records_crossapp_metrics_if_header_present
|
308
|
-
@response[ NR_APPDATA_HEADER ] =
|
309
|
-
make_app_data_payload( '18#1884', 'txn-name', 2, 8, 0, TRANSACTION_GUID )
|
310
|
-
|
311
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
312
|
-
in_transaction('test') do
|
313
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
314
|
-
|
315
|
-
last_segment = find_last_segment()
|
316
|
-
assert_includes last_segment.params.keys, :transaction_guid
|
317
|
-
assert_equal TRANSACTION_GUID, last_segment.params[:transaction_guid]
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
assert_metrics_recorded_exclusive([
|
322
|
-
'External/all',
|
323
|
-
'External/allOther',
|
324
|
-
'ExternalApp/www.google.com/18#1884/all',
|
325
|
-
'ExternalTransaction/www.google.com/18#1884/txn-name',
|
326
|
-
'External/www.google.com/all',
|
327
|
-
['ExternalTransaction/www.google.com/18#1884/txn-name', 'test']
|
328
|
-
])
|
329
|
-
end
|
330
|
-
|
331
|
-
def test_crossapp_metrics_allow_valid_utf8_characters
|
332
|
-
@response[ NR_APPDATA_HEADER ] =
|
333
|
-
make_app_data_payload( '12#1114', '世界線航跡蔵', 18.0, 88.1, 4096, TRANSACTION_GUID )
|
334
|
-
|
335
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
336
|
-
in_transaction('test') do
|
337
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
338
|
-
|
339
|
-
last_segment = find_last_segment()
|
340
|
-
assert_includes last_segment.params.keys, :transaction_guid
|
341
|
-
assert_equal TRANSACTION_GUID, last_segment.params[:transaction_guid]
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
assert_metrics_recorded_exclusive([
|
346
|
-
'External/all',
|
347
|
-
'External/allOther',
|
348
|
-
'ExternalApp/www.google.com/12#1114/all',
|
349
|
-
'External/www.google.com/all',
|
350
|
-
'ExternalTransaction/www.google.com/12#1114/世界線航跡蔵',
|
351
|
-
['ExternalTransaction/www.google.com/12#1114/世界線航跡蔵', 'test']
|
352
|
-
])
|
353
|
-
end
|
354
|
-
|
355
|
-
def test_crossapp_metrics_ignores_crossapp_header_with_malformed_crossprocess_id
|
356
|
-
@response[ NR_APPDATA_HEADER ] =
|
357
|
-
make_app_data_payload( '88#88#88', 'invalid', 1, 2, 4096, TRANSACTION_GUID )
|
358
|
-
|
359
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
360
|
-
in_transaction('test') do
|
361
|
-
Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
assert_metrics_recorded_exclusive([
|
366
|
-
'External/all',
|
367
|
-
'External/allOther',
|
368
|
-
'External/www.google.com/Net::HTTP/GET',
|
369
|
-
'External/www.google.com/all',
|
370
|
-
['External/www.google.com/Net::HTTP/GET', 'test']
|
371
|
-
])
|
372
|
-
end
|
373
|
-
|
374
|
-
def test_doesnt_affect_the_request_if_an_exception_is_raised_while_setting_up_tracing
|
375
|
-
res = nil
|
376
|
-
NewRelic::Agent.instance.stats_engine.stubs( :push_scope ).
|
377
|
-
raises( NoMethodError, "undefined method `push_scope'" )
|
378
|
-
|
379
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
380
|
-
assert_nothing_raised do
|
381
|
-
res = Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
assert_equal res, CANNED_RESPONSE.instance_variable_get( :@body )
|
386
|
-
end
|
387
|
-
|
388
|
-
def test_doesnt_affect_the_request_if_an_exception_is_raised_while_finishing_tracing
|
389
|
-
res = nil
|
390
|
-
NewRelic::Agent.instance.stats_engine.stubs( :pop_scope ).
|
391
|
-
raises( NoMethodError, "undefined method `pop_scope'" )
|
392
|
-
|
393
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
394
|
-
assert_nothing_raised do
|
395
|
-
res = Net::HTTP.get URI.parse('http://www.google.com/index.html')
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
assert_equal res, CANNED_RESPONSE.instance_variable_get( :@body )
|
400
23
|
end
|
401
24
|
|
402
25
|
def test_scope_stack_integrity_maintained_on_request_failure
|
@@ -410,33 +33,4 @@ class NewRelic::Agent::Instrumentation::NetInstrumentationTest < Test::Unit::Tes
|
|
410
33
|
end
|
411
34
|
end
|
412
35
|
|
413
|
-
def test_doesnt_misbehave_when_transaction_tracing_is_disabled
|
414
|
-
@engine.transaction_sampler = nil
|
415
|
-
|
416
|
-
# The error should have any other consequence other than logging the error, so
|
417
|
-
# this will capture logs
|
418
|
-
logger = NewRelic::Agent::MemoryLogger.new
|
419
|
-
NewRelic::Agent.logger = logger
|
420
|
-
|
421
|
-
with_config(:"cross_application_tracer.enabled" => true) do
|
422
|
-
Net::HTTP.get(URI.parse('http://www.google.com/index.html'))
|
423
|
-
end
|
424
|
-
|
425
|
-
assert_no_match( /undefined method `rename_scope_segment' for nil:NilClass/i,
|
426
|
-
logger.messages.flatten.map {|log| log.to_s }.join(' ') )
|
427
|
-
|
428
|
-
ensure
|
429
|
-
@engine.transaction_sampler = NewRelic::Agent.agent.transaction_sampler
|
430
|
-
end
|
431
|
-
|
432
|
-
def test_includes_full_url_in_transaction_trace
|
433
|
-
uri = 'http://www.google.com/index.html?foo=bar#fragment'
|
434
|
-
in_transaction do
|
435
|
-
Net::HTTP.get URI.parse(uri)
|
436
|
-
last_segment = find_last_segment()
|
437
|
-
filtered_uri = 'http://www.google.com/index.html'
|
438
|
-
assert_equal filtered_uri, last_segment.params[:uri]
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
36
|
end
|