newrelic_rpm 3.7.2.190.beta → 3.7.2.192

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +48 -0
  3. data/LICENSE +1 -1
  4. data/lib/new_relic/agent/configuration/default_source.rb +0 -6
  5. data/lib/new_relic/agent/cross_app_monitor.rb +7 -6
  6. data/lib/new_relic/agent/datastores/mongo/metric_generator.rb +8 -0
  7. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +27 -36
  8. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +21 -11
  9. data/lib/new_relic/agent/instrumentation/mongo.rb +56 -40
  10. data/lib/new_relic/agent/method_tracer.rb +10 -3
  11. data/lib/new_relic/agent/transaction_sampler.rb +0 -3
  12. data/lib/sequel/extensions/newrelic_instrumentation.rb +12 -5
  13. data/test/helpers/mongo_metric_builder.rb +1 -1
  14. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +2 -2
  15. data/test/multiverse/suites/mongo/Envfile +19 -28
  16. data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +437 -0
  17. data/test/multiverse/suites/mongo/helpers/mongo_replica_set.rb +97 -0
  18. data/test/multiverse/suites/mongo/helpers/mongo_replica_set_test.rb +82 -0
  19. data/test/multiverse/suites/mongo/helpers/mongo_server.rb +239 -0
  20. data/test/multiverse/suites/mongo/helpers/mongo_server_test.rb +176 -0
  21. data/test/multiverse/suites/mongo/mongo_connection_test.rb +40 -0
  22. data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +8 -393
  23. data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +6 -4
  24. data/test/multiverse/suites/rails/ignore_test.rb +7 -2
  25. data/test/multiverse/suites/sequel/database.rb +24 -20
  26. data/test/multiverse/suites/sequel/sequel_instrumentation_test.rb +16 -0
  27. data/test/new_relic/agent/cross_app_monitor_test.rb +4 -2
  28. data/test/new_relic/agent/datastores/mongo/metric_generator_test.rb +27 -1
  29. data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +19 -9
  30. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +497 -493
  31. data/test/new_relic/agent/method_tracer_test.rb +23 -0
  32. data/test/new_relic/agent/transaction_sampler_test.rb +5 -16
  33. data/test/new_relic/json_wrapper_test.rb +5 -6
  34. data/test/performance/suites/trace_execution_scoped.rb +32 -0
  35. metadata +34 -26
  36. metadata.gz.sig +0 -0
@@ -8,15 +8,16 @@ require 'new_relic/agent/datastores/mongo'
8
8
  require File.join(File.dirname(__FILE__), '..', '..', '..', 'agent_helper')
9
9
 
10
10
  if !NewRelic::Agent::Datastores::Mongo.is_supported_version?
11
+ require File.join(File.dirname(__FILE__), 'helpers', 'mongo_server')
11
12
 
12
- class NewRelic::Agent::Instrumentation::MongoInstrumentationTest < MiniTest::Unit::TestCase
13
+ class NewRelic::Agent::Instrumentation::MongoUnsupportedVersionTest < MiniTest::Unit::TestCase
13
14
  include Mongo
14
15
 
15
16
  def setup
16
- @client = Mongo::Connection.new(ENV["MONGO_HOST"], ENV["MONGO_PORT"].to_i)
17
- @database_name = 'multiverse'
17
+ @client = Mongo::Connection.new($mongo.host, $mongo.port)
18
+ @database_name = "multiverse"
18
19
  @database = @client.db(@database_name)
19
- @collection_name = 'tribbles'
20
+ @collection_name = "tribbles-#{SecureRandom.hex(16)}"
20
21
  @collection = @database.collection(@collection_name)
21
22
 
22
23
  @tribble = {'name' => 'soterios johnson'}
@@ -26,6 +27,7 @@ if !NewRelic::Agent::Datastores::Mongo.is_supported_version?
26
27
 
27
28
  def teardown
28
29
  NewRelic::Agent.drop_buffered_data
30
+ @database.drop_collection(@collection_name)
29
31
  end
30
32
 
31
33
  def test_records_metrics_for_insert
@@ -24,10 +24,11 @@ class IgnoredController < ApplicationController
24
24
  end
25
25
 
26
26
  class IgnoredActionsTest < ActionDispatch::IntegrationTest
27
-
28
27
  include MultiverseHelpers
29
28
 
30
- setup_and_teardown_agent
29
+ setup_and_teardown_agent(:cross_process_id => "boo",
30
+ :encoding_key => "\0",
31
+ :trusted_account_ids => [1])
31
32
 
32
33
  def after_setup
33
34
  # Make sure we've got a blank slate for doing easier metric comparisons
@@ -45,4 +46,8 @@ class IgnoredActionsTest < ActionDispatch::IntegrationTest
45
46
  assert_metrics_not_recorded(["Apdex"])
46
47
  end
47
48
 
49
+ def test_should_not_write_cat_response_headers_for_ignored_transactions
50
+ get 'ignored/action_to_ignore', nil, {'X-NewRelic-ID' => Base64.encode64('1#234')}
51
+ assert_nil @response.headers["X-NewRelic-App-Data"]
52
+ end
48
53
  end
@@ -14,6 +14,28 @@ if !defined?(DB)
14
14
  defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
15
15
  end
16
16
 
17
+ def create_tables(db)
18
+ db.create_table( :authors ) do
19
+ primary_key :id
20
+ string :name
21
+ string :login
22
+ end
23
+
24
+ db.create_table( :posts ) do
25
+ primary_key :id
26
+ string :title
27
+ string :content
28
+ time :created_at
29
+ end
30
+
31
+ db.create_table( :users ) do
32
+ primary_key :uid
33
+ string :login
34
+ string :firstname
35
+ string :lastname
36
+ end
37
+ end
38
+
17
39
  # Use an in-memory SQLite database
18
40
  if (jruby?)
19
41
  DB = Sequel.connect('jdbc:sqlite::memory:')
@@ -21,28 +43,10 @@ if !defined?(DB)
21
43
  DB = Sequel.sqlite
22
44
  end
23
45
 
24
- # Create tables and model classes for testing
25
- DB.create_table( :authors ) do
26
- primary_key :id
27
- string :name
28
- string :login
29
- end
30
- class Author < Sequel::Model; end
46
+ create_tables(DB)
31
47
 
32
- DB.create_table( :posts ) do
33
- primary_key :id
34
- string :title
35
- string :content
36
- time :created_at
37
- end
48
+ class Author < Sequel::Model; end
38
49
  class Post < Sequel::Model; end
39
-
40
- DB.create_table( :users ) do
41
- primary_key :uid
42
- string :login
43
- string :firstname
44
- string :lastname
45
- end
46
50
  class User < Sequel::Model; end
47
51
 
48
52
  # Version 4.0 of Sequel moved update_except off to a plugin
@@ -210,6 +210,22 @@ class NewRelic::Agent::Instrumentation::SequelInstrumentationTest < MiniTest::Un
210
210
  end
211
211
  end
212
212
 
213
+ def test_no_explain_plans_with_single_threaded_connection
214
+ connect_opts = DB.opts
215
+ single_threaded_db = Sequel.connect(connect_opts.merge(:single_threaded => true))
216
+ create_tables(single_threaded_db)
217
+ model_class = Class.new(Sequel::Model(single_threaded_db[:posts]))
218
+
219
+ with_config(:'transaction_tracer.explain_threshold' => -0.01,
220
+ :'transaction_tracer.record_sql' => 'raw') do
221
+ segment = last_segment_for do
222
+ model_class[11]
223
+ end
224
+ assert_match %r{select \* from `posts` where `id` = 11}i, segment.params[:sql]
225
+ assert_equal([], segment.params[:explain_plan], "Should not capture explain plan with single-threaded connection pool")
226
+ end
227
+ end
228
+
213
229
  def test_queries_can_get_explain_plan_with_obfuscated_sql
214
230
  config = {
215
231
  :'transaction_tracer.explain_threshold' => -0.01,
@@ -41,7 +41,6 @@ module NewRelic::Agent
41
41
 
42
42
  NewRelic::Agent.config.apply_config( @config )
43
43
  @monitor.on_finished_configuring
44
- NewRelic::Agent::TransactionState.get.request_guid = TRANSACTION_GUID
45
44
  end
46
45
 
47
46
  def teardown
@@ -195,7 +194,10 @@ module NewRelic::Agent
195
194
  def when_request_runs(request=for_id(REQUEST_CROSS_APP_ID))
196
195
  event_listener = NewRelic::Agent.instance.events
197
196
  event_listener.notify(:before_call, request)
198
- event_listener.notify(:start_transaction, 'a name')
197
+ in_transaction('transaction') do
198
+ # nothing
199
+ end
200
+ NewRelic::Agent::TransactionState.get.request_guid = TRANSACTION_GUID
199
201
  event_listener.notify(:after_call, request, [200, @response, ''])
200
202
  end
201
203
 
@@ -9,7 +9,7 @@ class NewRelic::Agent::Datastores::Mongo::MetricGeneratorTest < MiniTest::Unit::
9
9
  include ::NewRelic::TestHelpers::MongoMetricBuilder
10
10
 
11
11
  def setup
12
- @payload = { :collection => 'tribbles' }
12
+ @payload = { :collection => 'tribbles', :database => 'enterprise' }
13
13
  end
14
14
 
15
15
  def test_generate_metrics_for_includes_all_web_for_web_requests
@@ -40,4 +40,30 @@ class NewRelic::Agent::Datastores::Mongo::MetricGeneratorTest < MiniTest::Unit::
40
40
  refute metrics.include? 'Datastore/allWeb'
41
41
  end
42
42
 
43
+ def test_generate_metrics_for_is_graceful_if_exceptions_are_raised
44
+ NewRelic::Agent::Datastores::Mongo::MetricTranslator.stubs(:metrics_for).raises("Booom")
45
+ metrics = NewRelic::Agent::Datastores::Mongo::MetricGenerator.generate_metrics_for(:insert, @payload)
46
+
47
+ assert_empty metrics
48
+ end
49
+
50
+ def test_generate_instance_metric_for_returns_instance_metric_for_given_attributes
51
+ result = NewRelic::Agent::Datastores::Mongo::MetricGenerator.generate_instance_metric_for('host', 'port', 'database')
52
+ assert_equal 'Datastore/instance/MongoDB/host:port/database', result
53
+ end
54
+
55
+ def test_generate_metrics_for_does_not_include_instance_metric_without_host
56
+ result = NewRelic::Agent::Datastores::Mongo::MetricGenerator.generate_instance_metric_for(nil, 'port', 'database')
57
+ assert_nil result
58
+ end
59
+
60
+ def test_generate_metrics_for_does_not_include_instance_metric_without_port
61
+ result = NewRelic::Agent::Datastores::Mongo::MetricGenerator.generate_instance_metric_for('host', nil, 'database')
62
+ assert_nil result
63
+ end
64
+
65
+ def test_generate_metrics_for_does_not_include_instance_metric_without_database_name
66
+ result = NewRelic::Agent::Datastores::Mongo::MetricGenerator.generate_instance_metric_for('host', 'port', nil)
67
+ assert_nil result
68
+ end
43
69
  end
@@ -21,17 +21,23 @@ class NewRelic::Agent::Datastores::Mongo::MetricTranslatorTest < MiniTest::Unit:
21
21
  end
22
22
 
23
23
  def test_build_metrics_includes_web
24
- expected = 'Datastore/allWeb'
25
24
  metrics = build_test_metrics('test')
26
-
27
- assert metrics.include? expected
25
+ assert_includes metrics, 'Datastore/allWeb'
28
26
  end
29
27
 
30
28
  def test_build_metrics_includes_other
31
- expected = 'Datastore/allOther'
32
29
  metrics = build_test_metrics('test', :other)
30
+ assert_includes metrics, 'Datastore/allOther'
31
+ end
32
+
33
+ def test_build_metrics_includes_activerecord_all_on_web
34
+ metrics = build_test_metrics('test', :web)
35
+ assert_includes metrics, 'ActiveRecord/all'
36
+ end
33
37
 
34
- assert metrics.include? expected
38
+ def test_build_metrics_doesnt_include_activerecord_all_on_other
39
+ metrics = build_test_metrics('test', :other)
40
+ assert_not_includes metrics, 'ActiveRecord/all'
35
41
  end
36
42
 
37
43
  def test_metrics_for_find
@@ -263,7 +269,7 @@ class NewRelic::Agent::Datastores::Mongo::MetricTranslatorTest < MiniTest::Unit:
263
269
  :limit => -1,
264
270
  :selector => { :ismaster => 1 } }
265
271
 
266
- @collection_name = "1"
272
+ @collection_name = "$cmd"
267
273
 
268
274
  metrics = NewRelic::Agent::Datastores::Mongo::MetricTranslator.metrics_for(:find, payload)
269
275
  expected = build_test_metrics(:ismaster)
@@ -289,13 +295,17 @@ class NewRelic::Agent::Datastores::Mongo::MetricTranslatorTest < MiniTest::Unit:
289
295
  :limit => -1,
290
296
  :selector => { :mongomongomongo => @collection_name } }
291
297
 
292
- @collection_name = "UnknownCollection"
298
+ @collection_name = "$cmd"
293
299
 
294
300
  metrics = NewRelic::Agent::Datastores::Mongo::MetricTranslator.metrics_for(:find, payload)
295
- expected = build_test_metrics(:UnknownCommand)
301
+ expected = build_test_metrics(:mongomongomongo)
296
302
 
297
303
  assert_equal expected, metrics
298
- assert_metrics_recorded(["Supportability/Mongo/UnknownCommand"])
304
+ assert_metrics_recorded(["Supportability/Mongo/UnknownCollection"])
299
305
  end
300
306
 
307
+ def test_instance_metric
308
+ metric = NewRelic::Agent::Datastores::Mongo::MetricTranslator.instance_metric('localhost', '27017', @database_name)
309
+ assert_equal 'Datastore/instance/MongoDB/localhost:27017/multiverse', metric
310
+ end
301
311
  end
@@ -78,499 +78,503 @@ class NewRelic::Agent::Instrumentation::ActiveRecordInstrumentationTest < MiniTe
78
78
  end
79
79
  end
80
80
 
81
- #def test_metric_names_jruby
82
- # # fails due to a bug in rails 3 - log does not provide the correct
83
- # # transaction type - it returns 'SQL' instead of 'Foo Create', for example.
84
- # return if rails3? || !defined?(JRuby)
85
- # expected = %W[
86
- # ActiveRecord/all
87
- # ActiveRecord/find
88
- # ActiveRecord/ActiveRecordFixtures::Order/find
89
- # Database/SQL/insert
90
- # RemoteService/sql/#{adapter}/localhost
91
- # ]
92
-
93
- # if NewRelic::Control.instance.rails_version < '2.1.0'
94
- # expected += %W[ActiveRecord/save ActiveRecord/ActiveRecordFixtures::Order/save]
95
- # end
96
-
97
- # assert_calls_metrics(*expected) do
98
- # m = ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
99
- # m = ActiveRecordFixtures::Order.find(m.id)
100
- # m.id = 999
101
- # m.save!
102
- # end
103
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
104
-
105
- # compare_metrics expected, metrics
106
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
107
- # # zero because jruby uses a different mysql adapter
108
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/create", 0)
109
- #end
110
-
111
- #def test_metric_names_sqlite
112
- # # fails due to a bug in rails 3 - log does not provide the correct
113
- # # transaction type - it returns 'SQL' instead of 'Foo Create', for example.
114
- # return if rails3? || !isSqlite? || defined?(JRuby)
115
-
116
- # expected = %W[
117
- # ActiveRecord/all
118
- # ActiveRecord/find
119
- # ActiveRecord/ActiveRecordFixtures::Order/find
120
- # ActiveRecord/create
121
- # ActiveRecord/ActiveRecordFixtures::Order/create]
122
-
123
- # if NewRelic::Control.instance.rails_version < '2.1.0'
124
- # expected += %W[ActiveRecord/save ActiveRecord/ActiveRecordFixtures::Order/save]
125
- # end
126
-
127
- # assert_calls_metrics(*expected) do
128
- # m = ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
129
- # m = ActiveRecordFixtures::Order.find(m.id)
130
- # m.id = 999
131
- # m.save!
132
- # end
133
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
134
-
135
- # compare_metrics expected, metrics
136
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
137
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/create", 1)
138
- #end
139
-
140
- #def test_metric_names_standard
141
- # # fails due to a bug in rails 3 - log does not provide the correct
142
- # # transaction type - it returns 'SQL' instead of 'Foo Create', for example.
143
- # return if defined?(JRuby) || isSqlite?
144
-
145
- # expected = %W[
146
- # ActiveRecord/all
147
- # ActiveRecord/find
148
- # ActiveRecord/create
149
- # ActiveRecord/ActiveRecordFixtures::Order/find
150
- # ActiveRecord/ActiveRecordFixtures::Order/create
151
- # Database/SQL/other
152
- # RemoteService/sql/#{adapter}/localhost]
153
-
154
- # if NewRelic::Control.instance.rails_version < '2.1.0'
155
- # expected += ['ActiveRecord/save',
156
- # 'ActiveRecord/ActiveRecordFixtures::Order/save']
157
- # end
158
-
159
- # if NewRelic::Control.instance.rails_version >= '3.0.0'
160
- # expected << 'Database/SQL/insert'
161
- # end
162
-
163
- # if NewRelic::Control.instance.rails_version >= '4.0'
164
- # expected << 'Database/SQL/update'
165
- # end
166
-
167
- # assert_calls_metrics(*expected) do
168
- # m = ActiveRecordFixtures::Order.create :id => 1, :name => 'donkey'
169
- # m = ActiveRecordFixtures::Order.find(m.id)
170
- # m.id = 999
171
- # m.save!
172
- # end
173
-
174
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
175
-
176
- # compare_metrics expected, metrics
177
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
178
- # if NewRelic::Control.instance.rails_version < '3.0.0'
179
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/create", 1)
180
- # else
181
- # check_metric_count("Database/SQL/insert", 1)
182
- # end
183
- #end
184
-
185
- #def test_join_metrics_jruby
186
- # return unless defined?(JRuby)
187
- # return if rails3?
188
-
189
- # expected_metrics = %W[
190
- # ActiveRecord/all
191
- # ActiveRecord/destroy
192
- # ActiveRecord/ActiveRecordFixtures::Order/destroy
193
- # Database/SQL/insert
194
- # Database/SQL/delete
195
- # Database/SQL/show
196
- # ActiveRecord/find
197
- # ActiveRecord/ActiveRecordFixtures::Order/find
198
- # ActiveRecord/ActiveRecordFixtures::Shipment/find
199
- # RemoteService/sql/#{adapter}/localhost
200
- # ]
201
-
202
- # assert_calls_metrics(*expected_metrics) do
203
- # m = ActiveRecordFixtures::Order.create :name => 'jeff'
204
- # m = ActiveRecordFixtures::Order.find(m.id)
205
- # s = m.shipments.create
206
- # m.shipments.to_a
207
- # m.destroy
208
- # end
209
-
210
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
211
-
212
- # compare_metrics expected_metrics, metrics
213
-
214
- # check_metric_time('ActiveRecord/all', NewRelic::Agent.get_stats("ActiveRecord/all").total_exclusive_time, 0)
215
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
216
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Shipment/find", 1)
217
- # check_metric_count("Database/SQL/insert", 3)
218
- # check_metric_count("Database/SQL/delete", 1)
219
- #end
220
-
221
- #def test_join_metrics_sqlite
222
- # return if (defined?(Rails) && Rails::VERSION::MAJOR.to_i == 3)
223
- # return if defined?(JRuby)
224
- # return unless isSqlite?
225
-
226
- # expected_metrics = %W[
227
- # ActiveRecord/all
228
- # ActiveRecord/destroy
229
- # ActiveRecord/ActiveRecordFixtures::Order/destroy
230
- # Database/SQL/insert
231
- # Database/SQL/delete
232
- # ActiveRecord/find
233
- # ActiveRecord/ActiveRecordFixtures::Order/find
234
- # ActiveRecord/ActiveRecordFixtures::Shipment/find
235
- # ActiveRecord/create
236
- # ActiveRecord/ActiveRecordFixtures::Shipment/create
237
- # ActiveRecord/ActiveRecordFixtures::Order/create
238
- # ]
239
-
240
- # assert_calls_metrics(*expected_metrics) do
241
- # m = ActiveRecordFixtures::Order.create :name => 'jeff'
242
- # m = ActiveRecordFixtures::Order.find(m.id)
243
- # s = m.shipments.create
244
- # m.shipments.to_a
245
- # m.destroy
246
- # end
247
-
248
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
249
- # compare_metrics expected_metrics, metrics
250
- # if !(defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /Enterprise Edition/)
251
- # check_metric_time('ActiveRecord/all', NewRelic::Agent.get_stats("ActiveRecord/all").total_exclusive_time, 0)
252
- # end
253
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
254
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Shipment/find", 1)
255
- # check_metric_count("Database/SQL/insert", 3)
256
- # check_metric_count("Database/SQL/delete", 1)
257
- #end
258
-
259
- #def test_join_metrics_standard
260
- # return if (defined?(Rails) && Rails::VERSION::MAJOR.to_i >= 3)
261
- # return if defined?(JRuby) || isSqlite?
262
-
263
- # expected_metrics = %W[
264
- # ActiveRecord/all
265
- # RemoteService/sql/#{adapter}/localhost
266
- # ActiveRecord/destroy
267
- # ActiveRecord/ActiveRecordFixtures::Order/destroy
268
- # Database/SQL/insert
269
- # Database/SQL/delete
270
- # ActiveRecord/find
271
- # ActiveRecord/ActiveRecordFixtures::Order/find
272
- # ActiveRecord/ActiveRecordFixtures::Shipment/find
273
- # Database/SQL/other
274
- # Database/SQL/show
275
- # ActiveRecord/create
276
- # ActiveRecord/ActiveRecordFixtures::Shipment/create
277
- # ActiveRecord/ActiveRecordFixtures::Order/create
278
- # ]
279
-
280
- # assert_calls_metrics(*expected_metrics) do
281
- # m = ActiveRecordFixtures::Order.create :name => 'jeff'
282
- # m = ActiveRecordFixtures::Order.find(m.id)
283
- # s = m.shipments.create
284
- # m.shipments.to_a
285
- # m.destroy
286
- # end
287
-
288
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
289
-
290
- # compare_metrics expected_metrics, metrics
291
- # if !(defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /Enterprise Edition/)
292
- # check_metric_time('ActiveRecord/all', NewRelic::Agent.get_stats("ActiveRecord/all").total_exclusive_time, 0)
293
- # end
294
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
295
- # check_metric_count("ActiveRecord/ActiveRecordFixtures::Shipment/find", 1)
296
- # check_metric_count("Database/SQL/insert", 1)
297
- # check_metric_count("Database/SQL/delete", 1)
298
- #end
299
-
300
- #def test_direct_sql
301
- # assert_nil NewRelic::Agent::Transaction.current
302
- # assert_equal 0, NewRelic::Agent.instance.stats_engine.metrics.size, NewRelic::Agent.instance.stats_engine.metrics.inspect
303
-
304
- # expected_metrics = %W[
305
- # ActiveRecord/all
306
- # Database/SQL/select
307
- # RemoteService/sql/#{adapter}/localhost
308
- # ]
309
-
310
- # assert_calls_unscoped_metrics(*expected_metrics) do
311
- # ActiveRecordFixtures::Order.connection.select_rows "select * from #{ActiveRecordFixtures::Order.table_name}"
312
- # end
313
-
314
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
315
- # compare_metrics(expected_metrics, metrics)
316
-
317
- # check_unscoped_metric_count('Database/SQL/select', 1)
318
-
319
- #end
320
-
321
- #def test_other_sql
322
- # expected_metrics = %W[
323
- # ActiveRecord/all
324
- # Database/SQL/other
325
- # RemoteService/sql/#{adapter}/localhost
326
- # ]
327
- # assert_calls_unscoped_metrics(*expected_metrics) do
328
- # ActiveRecordFixtures::Order.connection.execute "begin"
329
- # end
330
-
331
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
332
-
333
- # compare_metrics expected_metrics, metrics
334
- # check_unscoped_metric_count('Database/SQL/other', 1)
335
- #end
336
-
337
- #def test_show_sql
338
- # return if isSqlite?
339
- # return if isPostgres?
340
-
341
- # expected_metrics = %W[ActiveRecord/all Database/SQL/show RemoteService/sql/#{adapter}/localhost]
342
- # assert_calls_metrics(*expected_metrics) do
343
- # ActiveRecordFixtures::Order.connection.execute "show tables"
344
- # end
345
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
346
- # compare_metrics expected_metrics, metrics
347
- # check_unscoped_metric_count('Database/SQL/show', 1)
348
- #end
349
-
350
- #def test_blocked_instrumentation
351
- # ActiveRecordFixtures::Order.add_delay
352
- # NewRelic::Agent.disable_all_tracing do
353
- # perform_action_with_newrelic_trace :name => 'bogosity' do
354
- # all_finder(ActiveRecordFixtures::Order)
355
- # end
356
- # end
357
- # assert_nil NewRelic::Agent.instance.transaction_sampler.last_sample
358
- # metrics = NewRelic::Agent.instance.stats_engine.metrics
359
- # compare_metrics [], metrics
360
- #end
361
-
362
- #def test_run_explains
363
- # perform_action_with_newrelic_trace :name => 'bogosity' do
364
- # ActiveRecordFixtures::Order.add_delay
365
- # all_finder(ActiveRecordFixtures::Order)
366
- # end
367
-
368
- # # that's a mouthful. perhaps we should ponder our API.
369
- # segment = last_segment(NewRelic::Agent.instance.transaction_sampler.last_sample)
370
- # regex = /^SELECT (["`]?#{ActiveRecordFixtures::Order.table_name}["`]?.)?\* FROM ["`]?#{ActiveRecordFixtures::Order.table_name}["`]?$/
371
- # assert_match regex, segment.params[:sql].strip
372
- #end
373
-
374
- #def test_prepare_to_send
375
- # with_config(:'transaction_tracer.explain_enabled' => true,
376
- # :'transaction_tracer.explain_threshold' => 0.0) do
377
- # perform_action_with_newrelic_trace :name => 'bogosity' do
378
- # ActiveRecordFixtures::Order.add_delay
379
- # all_finder(ActiveRecordFixtures::Order)
380
- # end
381
- # sample = NewRelic::Agent.instance.transaction_sampler.last_sample
382
- # refute_nil sample
383
-
384
- # includes_gc = false
385
- # sample.each_segment {|s| includes_gc ||= s.metric_name =~ /GC/ }
386
-
387
- # sql_segment = last_segment(sample)
388
- # refute_nil sql_segment, sample.to_s
389
- # assert_match /^SELECT /, sql_segment.params[:sql]
390
- # assert sql_segment.duration > 0.0, "Segment duration must be greater than zero."
391
- # sample = sample.prepare_to_send!
392
- # sql_segment = last_segment(sample)
393
- # assert_match /^SELECT /, sql_segment.params[:sql]
394
- # explanations = sql_segment.params[:explain_plan]
395
- # if (isMysql? || isPostgres?) && !NewRelic::LanguageSupport.using_engine?('jruby')
396
- # refute_nil explanations, "No explains in segment: #{sql_segment}"
397
- # assert_equal(2, explanations.size,
398
- # "No explains in segment: #{sql_segment}")
399
- # end
400
- # end
401
- #end
402
-
403
- #def test_transaction_mysql
404
- # return unless isMysql? && !defined?(JRuby)
405
-
406
- # with_config(:record_sql => :obfuscated,
407
- # :'transaction_tracer.explain_enabled' => true,
408
- # :'transaction_tracer.explain_threshold' => 0.0) do
409
- # ActiveRecordFixtures.setup
410
- # sample = NewRelic::Agent.instance.transaction_sampler.reset!
411
- # perform_action_with_newrelic_trace :name => 'bogosity' do
412
- # ActiveRecordFixtures::Order.add_delay
413
- # all_finder(ActiveRecordFixtures::Order)
414
- # end
415
-
416
- # sample = NewRelic::Agent.instance.transaction_sampler.last_sample
417
- # sample = sample.prepare_to_send!
418
- # segment = last_segment(sample)
419
- # explanation = segment.params[:explain_plan]
420
- # refute_nil explanation, "No explains in segment: #{segment}"
421
- # assert_equal 2, explanation.size,"No explains in segment: #{segment}"
422
-
423
- # assert_equal 10, explanation[0].size
424
- # ['id', 'select_type', 'table'].each do |c|
425
- # assert explanation[0].include?(c)
426
- # end
427
- # ['1', 'SIMPLE', ActiveRecordFixtures::Order.table_name].each do |c|
428
- # assert explanation[1][0].include?(c)
429
- # end
430
-
431
- # s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
432
- # assert_equal 1, s.call_count
433
- # end
434
- #end
435
-
436
- #def test_transaction_postgres
437
- # return unless isPostgres?
438
-
439
- # with_config(:record_sql => :obfuscated,
440
- # :'transaction_tracer.explain_enabled' => true,
441
- # :'transaction_tracer.explain_threshold' => 0.0) do
442
- # # note that our current test builds do not use postgres, this is
443
- # # here strictly for troubleshooting, not CI builds
444
- # sample = NewRelic::Agent.instance.transaction_sampler.reset!
445
- # perform_action_with_newrelic_trace :name => 'bogosity' do
446
- # ActiveRecordFixtures::Order.add_delay
447
- # all_finder(ActiveRecordFixtures::Order)
448
- # end
449
-
450
- # sample = NewRelic::Agent.instance.transaction_sampler.last_sample
451
-
452
- # sample = sample.prepare_to_send!
453
- # segment = last_segment(sample)
454
- # explanations = segment.params[:explain_plan]
455
-
456
- # refute_nil explanations, "No explains in segment: #{segment}"
457
- # assert_equal 1, explanations.size,"No explains in segment: #{segment}"
458
- # assert_equal 1, explanations.first.size
459
-
460
- # assert_equal("Explain Plan", explanations[0][0])
461
- # assert_match /Seq Scan on test_data/, explanations[0][1].join(";")
462
-
463
- # s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
464
- # assert_equal 1, s.call_count
465
- # end
466
- #end
467
-
468
- #def test_transaction_other
469
- # return if isMysql? || isPostgres?
470
-
471
- # with_config(:record_sql => :obfuscated,
472
- # :'transaction_tracer.explain_enabled' => true,
473
- # :'transaction_tracer.explain_threshold' => 0.0) do
474
- # sample = NewRelic::Agent.instance.transaction_sampler.reset!
475
- # perform_action_with_newrelic_trace :name => 'bogosity' do
476
- # ActiveRecordFixtures::Order.add_delay
477
- # all_finder(ActiveRecordFixtures::Order)
478
- # end
479
-
480
- # sample = NewRelic::Agent.instance.transaction_sampler.last_sample
481
-
482
- # sample = sample.prepare_to_send!
483
- # segment = last_segment(sample)
484
-
485
- # s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
486
- # assert_equal 1, s.call_count
487
- # end
488
- #end
489
-
490
- ## These are only valid for rails 2.1 and later
491
- #if NewRelic::Control.instance.rails_version >= NewRelic::VersionNumber.new("2.1.0")
492
- # ActiveRecordFixtures::Order.class_eval do
493
- # if NewRelic::Control.instance.rails_version >= NewRelic::VersionNumber.new("4")
494
- # scope :jeffs, lambda { where(:name => 'Jeff') }
495
- # elsif NewRelic::Control.instance.rails_version >= NewRelic::VersionNumber.new("3.1")
496
- # scope :jeffs, :conditions => { :name => 'Jeff' }
497
- # else
498
- # named_scope :jeffs, :conditions => { :name => 'Jeff' }
499
- # end
500
- # end
501
- # def test_named_scope
502
- # ActiveRecordFixtures::Order.create :name => 'Jeff'
503
-
504
- # find_metric = "ActiveRecord/ActiveRecordFixtures::Order/find"
505
-
506
- # check_metric_count(find_metric, 0)
507
- # assert_calls_metrics(find_metric) do
508
- # if NewRelic::Control.instance.rails_version >= "4"
509
- # x = ActiveRecordFixtures::Order.jeffs.load
510
- # else
511
- # x = ActiveRecordFixtures::Order.jeffs.find(:all)
512
- # end
513
- # end
514
- # check_metric_count(find_metric, 1)
515
- # end
516
- #end
517
-
518
- ## This is to make sure the all metric is recorded for exceptional cases
519
- #def test_error_handling
520
- # # have the AR select throw an error
521
- # ActiveRecordFixtures::Order.connection.stubs(:log_info).with do | sql, x, y |
522
- # raise "Error" if sql =~ /select/
523
- # true
524
- # end
525
-
526
- # in_web_transaction do
527
- # begin
528
- # ActiveRecordFixtures::Order.connection.select_rows "select * from #{ActiveRecordFixtures::Order.table_name}"
529
- # rescue RuntimeError => e
530
- # # catch only the error we raise above
531
- # raise unless e.message == 'Error'
532
- # end
533
- # end
534
-
535
- # assert_metrics_recorded(
536
- # 'ActiveRecord/all' => { :call_count => 1 },
537
- # 'Database/SQL/select' => { :call_count => 1 }
538
- # )
539
-
540
- # if !NewRelic::LanguageSupport.using_engine?('jruby')
541
- # assert_metrics_recorded("RemoteService/sql/#{adapter}/localhost" => { :call_count => 1 })
542
- # end
543
- #end
544
-
545
- #def test_rescue_handling
546
- # # Not sure why we get a transaction error with sqlite
547
- # return if isSqlite?
548
-
549
- # begin
550
- # ActiveRecordFixtures::Order.transaction do
551
- # raise ActiveRecord::ActiveRecordError.new('preserve-me!')
552
- # end
553
- # rescue ActiveRecord::ActiveRecordError => e
554
- # assert_equal 'preserve-me!', e.message
555
- # end
556
- #end
557
-
558
- #def test_remote_service_metric_respects_dynamic_connection_config
559
- # return unless isMysql? && !NewRelic::LanguageSupport.using_engine?('jruby')
560
-
561
- # ActiveRecordFixtures::Shipment.connection.execute('SHOW TABLES');
562
- # assert_metrics_recorded(["RemoteService/sql/#{adapter}/localhost"])
563
-
564
- # config = ActiveRecordFixtures::Shipment.connection.instance_eval { @config }
565
- # config[:host] = '127.0.0.1'
566
- # connection = ActiveRecordFixtures::Shipment.establish_connection(config)
567
-
568
- # ActiveRecordFixtures::Shipment.connection.execute('SHOW TABLES');
569
- # assert_metrics_recorded(["RemoteService/sql/#{adapter}/127.0.0.1"])
570
-
571
- # config[:host] = 'localhost'
572
- # ActiveRecordFixtures::Shipment.establish_connection(config)
573
- #end
81
+ def test_metric_names_jruby
82
+ # fails due to a bug in rails 3 - log does not provide the correct
83
+ # transaction type - it returns 'SQL' instead of 'Foo Create', for example.
84
+ return if rails3? || !defined?(JRuby)
85
+ expected = %W[
86
+ ActiveRecord/all
87
+ ActiveRecord/find
88
+ ActiveRecord/ActiveRecordFixtures::Order/find
89
+ Database/SQL/insert
90
+ RemoteService/sql/#{adapter}/localhost
91
+ ]
92
+
93
+ if NewRelic::Control.instance.rails_version < '2.1.0'
94
+ expected += %W[ActiveRecord/save ActiveRecord/ActiveRecordFixtures::Order/save]
95
+ end
96
+
97
+ assert_calls_metrics(*expected) do
98
+ m = ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
99
+ m = ActiveRecordFixtures::Order.find(m.id)
100
+ m.id = 999
101
+ m.save!
102
+ end
103
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
104
+
105
+ compare_metrics expected, metrics
106
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
107
+ # zero because jruby uses a different mysql adapter
108
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/create", 0)
109
+ end
110
+
111
+ def test_metric_names_sqlite
112
+ # fails due to a bug in rails 3 - log does not provide the correct
113
+ # transaction type - it returns 'SQL' instead of 'Foo Create', for example.
114
+ return if rails3? || !isSqlite? || defined?(JRuby)
115
+
116
+ expected = %W[
117
+ ActiveRecord/all
118
+ ActiveRecord/find
119
+ ActiveRecord/ActiveRecordFixtures::Order/find
120
+ ActiveRecord/create
121
+ ActiveRecord/ActiveRecordFixtures::Order/create]
122
+
123
+ if NewRelic::Control.instance.rails_version < '2.1.0'
124
+ expected += %W[ActiveRecord/save ActiveRecord/ActiveRecordFixtures::Order/save]
125
+ end
126
+
127
+ assert_calls_metrics(*expected) do
128
+ m = ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
129
+ m = ActiveRecordFixtures::Order.find(m.id)
130
+ m.id = 999
131
+ m.save!
132
+ end
133
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
134
+
135
+ compare_metrics expected, metrics
136
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
137
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/create", 1)
138
+ end
139
+
140
+ def test_metric_names_standard
141
+ # fails due to a bug in rails 3 - log does not provide the correct
142
+ # transaction type - it returns 'SQL' instead of 'Foo Create', for example.
143
+ return if defined?(JRuby) || isSqlite?
144
+
145
+ expected = %W[
146
+ ActiveRecord/all
147
+ ActiveRecord/find
148
+ ActiveRecord/create
149
+ ActiveRecord/ActiveRecordFixtures::Order/find
150
+ ActiveRecord/ActiveRecordFixtures::Order/create
151
+ Database/SQL/other
152
+ Database/SQL/show
153
+ RemoteService/sql/#{adapter}/localhost]
154
+
155
+ if NewRelic::Control.instance.rails_version < '2.1.0'
156
+ expected += ['ActiveRecord/save',
157
+ 'ActiveRecord/ActiveRecordFixtures::Order/save']
158
+ end
159
+
160
+ if NewRelic::Control.instance.rails_version >= '3.0.0'
161
+ expected << 'Database/SQL/insert'
162
+ end
163
+
164
+ if NewRelic::Control.instance.rails_version >= '4.0'
165
+ expected << 'Database/SQL/update'
166
+ end
167
+
168
+ assert_calls_metrics(*expected) do
169
+ m = ActiveRecordFixtures::Order.create :id => 1, :name => 'donkey'
170
+ m = ActiveRecordFixtures::Order.find(m.id)
171
+ m.id = 999
172
+ m.save!
173
+ end
174
+
175
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
176
+
177
+ compare_metrics expected, metrics
178
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
179
+ if NewRelic::Control.instance.rails_version < '3.0.0'
180
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/create", 1)
181
+ else
182
+ check_metric_count("Database/SQL/insert", 1)
183
+ end
184
+ end
185
+
186
+ def test_join_metrics_jruby
187
+ return unless defined?(JRuby)
188
+ return if rails3?
189
+
190
+ expected_metrics = %W[
191
+ ActiveRecord/all
192
+ ActiveRecord/destroy
193
+ ActiveRecord/ActiveRecordFixtures::Order/destroy
194
+ Database/SQL/insert
195
+ Database/SQL/delete
196
+ Database/SQL/show
197
+ ActiveRecord/find
198
+ ActiveRecord/ActiveRecordFixtures::Order/find
199
+ ActiveRecord/ActiveRecordFixtures::Shipment/find
200
+ RemoteService/sql/#{adapter}/localhost
201
+ ]
202
+
203
+ assert_calls_metrics(*expected_metrics) do
204
+ m = ActiveRecordFixtures::Order.create :name => 'jeff'
205
+ m = ActiveRecordFixtures::Order.find(m.id)
206
+ s = m.shipments.create
207
+ m.shipments.to_a
208
+ m.destroy
209
+ end
210
+
211
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
212
+
213
+ compare_metrics expected_metrics, metrics
214
+
215
+ check_metric_time('ActiveRecord/all', NewRelic::Agent.get_stats("ActiveRecord/all").total_exclusive_time, 0)
216
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
217
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Shipment/find", 1)
218
+ check_metric_count("Database/SQL/insert", 3)
219
+ check_metric_count("Database/SQL/delete", 1)
220
+ end
221
+
222
+ def test_join_metrics_sqlite
223
+ return if (defined?(Rails) && Rails::VERSION::MAJOR.to_i == 3)
224
+ return if defined?(JRuby)
225
+ return unless isSqlite?
226
+
227
+ expected_metrics = %W[
228
+ ActiveRecord/all
229
+ ActiveRecord/destroy
230
+ ActiveRecord/ActiveRecordFixtures::Order/destroy
231
+ Database/SQL/insert
232
+ Database/SQL/delete
233
+ ActiveRecord/find
234
+ ActiveRecord/ActiveRecordFixtures::Order/find
235
+ ActiveRecord/ActiveRecordFixtures::Shipment/find
236
+ ActiveRecord/create
237
+ ActiveRecord/ActiveRecordFixtures::Shipment/create
238
+ ActiveRecord/ActiveRecordFixtures::Order/create
239
+ ]
240
+
241
+ assert_calls_metrics(*expected_metrics) do
242
+ m = ActiveRecordFixtures::Order.create :name => 'jeff'
243
+ m = ActiveRecordFixtures::Order.find(m.id)
244
+ s = m.shipments.create
245
+ m.shipments.to_a
246
+ m.destroy
247
+ end
248
+
249
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
250
+ compare_metrics expected_metrics, metrics
251
+ if !(defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /Enterprise Edition/)
252
+ check_metric_time('ActiveRecord/all', NewRelic::Agent.get_stats("ActiveRecord/all").total_exclusive_time, 0)
253
+ end
254
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
255
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Shipment/find", 1)
256
+ check_metric_count("Database/SQL/insert", 3)
257
+ check_metric_count("Database/SQL/delete", 1)
258
+ end
259
+
260
+ def test_join_metrics_standard
261
+ return if (defined?(Rails) && Rails::VERSION::MAJOR.to_i >= 3)
262
+ return if defined?(JRuby) || isSqlite?
263
+
264
+ expected_metrics = %W[
265
+ ActiveRecord/all
266
+ RemoteService/sql/#{adapter}/localhost
267
+ ActiveRecord/destroy
268
+ ActiveRecord/ActiveRecordFixtures::Order/destroy
269
+ Database/SQL/insert
270
+ Database/SQL/delete
271
+ ActiveRecord/find
272
+ ActiveRecord/ActiveRecordFixtures::Order/find
273
+ ActiveRecord/ActiveRecordFixtures::Shipment/find
274
+ Database/SQL/other
275
+ Database/SQL/show
276
+ ActiveRecord/create
277
+ ActiveRecord/ActiveRecordFixtures::Shipment/create
278
+ ActiveRecord/ActiveRecordFixtures::Order/create
279
+ ]
280
+
281
+ assert_calls_metrics(*expected_metrics) do
282
+ m = ActiveRecordFixtures::Order.create :name => 'jeff'
283
+ m = ActiveRecordFixtures::Order.find(m.id)
284
+ s = m.shipments.create
285
+ m.shipments.to_a
286
+ m.destroy
287
+ end
288
+
289
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
290
+
291
+ compare_metrics expected_metrics, metrics
292
+ if !(defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /Enterprise Edition/)
293
+ check_metric_time('ActiveRecord/all', NewRelic::Agent.get_stats("ActiveRecord/all").total_exclusive_time, 0)
294
+ end
295
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Order/find", 1)
296
+ check_metric_count("ActiveRecord/ActiveRecordFixtures::Shipment/find", 1)
297
+ check_metric_count("Database/SQL/insert", 1)
298
+ check_metric_count("Database/SQL/delete", 1)
299
+ end
300
+
301
+ def test_direct_sql
302
+ assert_nil NewRelic::Agent::Transaction.current
303
+ assert_equal 0, NewRelic::Agent.instance.stats_engine.metrics.size, NewRelic::Agent.instance.stats_engine.metrics.inspect
304
+
305
+ expected_metrics = %W[
306
+ ActiveRecord/all
307
+ Database/SQL/select
308
+ RemoteService/sql/#{adapter}/localhost
309
+ ]
310
+
311
+ assert_calls_unscoped_metrics(*expected_metrics) do
312
+ ActiveRecordFixtures::Order.connection.select_rows "select * from #{ActiveRecordFixtures::Order.table_name}"
313
+ end
314
+
315
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
316
+ compare_metrics(expected_metrics, metrics)
317
+
318
+ check_unscoped_metric_count('Database/SQL/select', 1)
319
+
320
+ end
321
+
322
+ def test_other_sql
323
+ expected_metrics = %W[
324
+ ActiveRecord/all
325
+ Database/SQL/other
326
+ RemoteService/sql/#{adapter}/localhost
327
+ ]
328
+ assert_calls_unscoped_metrics(*expected_metrics) do
329
+ ActiveRecordFixtures::Order.connection.execute "begin"
330
+ end
331
+
332
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
333
+
334
+ compare_metrics expected_metrics, metrics
335
+ check_unscoped_metric_count('Database/SQL/other', 1)
336
+ ensure
337
+ # Make sure we get the transaction closed up for other tests
338
+ ActiveRecordFixtures::Order.connection.execute "commit"
339
+ end
340
+
341
+ def test_show_sql
342
+ return if isSqlite?
343
+ return if isPostgres?
344
+
345
+ expected_metrics = %W[ActiveRecord/all Database/SQL/show RemoteService/sql/#{adapter}/localhost]
346
+ assert_calls_metrics(*expected_metrics) do
347
+ ActiveRecordFixtures::Order.connection.execute "show tables"
348
+ end
349
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
350
+ compare_metrics expected_metrics, metrics
351
+ check_unscoped_metric_count('Database/SQL/show', 1)
352
+ end
353
+
354
+ def test_blocked_instrumentation
355
+ ActiveRecordFixtures::Order.add_delay
356
+ NewRelic::Agent.disable_all_tracing do
357
+ perform_action_with_newrelic_trace :name => 'bogosity' do
358
+ all_finder(ActiveRecordFixtures::Order)
359
+ end
360
+ end
361
+ assert_nil NewRelic::Agent.instance.transaction_sampler.last_sample
362
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
363
+ compare_metrics [], metrics
364
+ end
365
+
366
+ def test_run_explains
367
+ perform_action_with_newrelic_trace :name => 'bogosity' do
368
+ ActiveRecordFixtures::Order.add_delay
369
+ all_finder(ActiveRecordFixtures::Order)
370
+ end
371
+
372
+ # that's a mouthful. perhaps we should ponder our API.
373
+ segment = last_segment(NewRelic::Agent.instance.transaction_sampler.last_sample)
374
+ regex = /^SELECT (["`]?#{ActiveRecordFixtures::Order.table_name}["`]?.)?\* FROM ["`]?#{ActiveRecordFixtures::Order.table_name}["`]?$/
375
+ assert_match regex, segment.params[:sql].strip
376
+ end
377
+
378
+ def test_prepare_to_send
379
+ with_config(:'transaction_tracer.explain_enabled' => true,
380
+ :'transaction_tracer.explain_threshold' => 0.0) do
381
+ perform_action_with_newrelic_trace :name => 'bogosity' do
382
+ ActiveRecordFixtures::Order.add_delay
383
+ all_finder(ActiveRecordFixtures::Order)
384
+ end
385
+ sample = NewRelic::Agent.instance.transaction_sampler.last_sample
386
+ refute_nil sample
387
+
388
+ includes_gc = false
389
+ sample.each_segment {|s| includes_gc ||= s.metric_name =~ /GC/ }
390
+
391
+ sql_segment = last_segment(sample)
392
+ refute_nil sql_segment, sample.to_s
393
+ assert_match /^SELECT /, sql_segment.params[:sql]
394
+ assert sql_segment.duration > 0.0, "Segment duration must be greater than zero."
395
+ sample = sample.prepare_to_send!
396
+ sql_segment = last_segment(sample)
397
+ assert_match /^SELECT /, sql_segment.params[:sql]
398
+ explanations = sql_segment.params[:explain_plan]
399
+ if (isMysql? || isPostgres?) && !NewRelic::LanguageSupport.using_engine?('jruby')
400
+ refute_nil explanations, "No explains in segment: #{sql_segment}"
401
+ assert_equal(2, explanations.size,
402
+ "No explains in segment: #{sql_segment}")
403
+ end
404
+ end
405
+ end
406
+
407
+ def test_transaction_mysql
408
+ return unless isMysql? && !defined?(JRuby)
409
+
410
+ with_config(:record_sql => :obfuscated,
411
+ :'transaction_tracer.explain_enabled' => true,
412
+ :'transaction_tracer.explain_threshold' => 0.0) do
413
+ ActiveRecordFixtures.setup
414
+ sample = NewRelic::Agent.instance.transaction_sampler.reset!
415
+ perform_action_with_newrelic_trace :name => 'bogosity' do
416
+ ActiveRecordFixtures::Order.add_delay
417
+ all_finder(ActiveRecordFixtures::Order)
418
+ end
419
+
420
+ sample = NewRelic::Agent.instance.transaction_sampler.last_sample
421
+ sample = sample.prepare_to_send!
422
+ segment = last_segment(sample)
423
+ explanation = segment.params[:explain_plan]
424
+ refute_nil explanation, "No explains in segment: #{segment}"
425
+ assert_equal 2, explanation.size,"No explains in segment: #{segment}"
426
+
427
+ assert_equal 10, explanation[0].size
428
+ ['id', 'select_type', 'table'].each do |c|
429
+ assert explanation[0].include?(c)
430
+ end
431
+ ['1', 'SIMPLE', ActiveRecordFixtures::Order.table_name].each do |c|
432
+ assert explanation[1][0].include?(c)
433
+ end
434
+
435
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
436
+ assert_equal 1, s.call_count
437
+ end
438
+ end
439
+
440
+ def test_transaction_postgres
441
+ return unless isPostgres?
442
+
443
+ with_config(:record_sql => :obfuscated,
444
+ :'transaction_tracer.explain_enabled' => true,
445
+ :'transaction_tracer.explain_threshold' => 0.0) do
446
+ # note that our current test builds do not use postgres, this is
447
+ # here strictly for troubleshooting, not CI builds
448
+ sample = NewRelic::Agent.instance.transaction_sampler.reset!
449
+ perform_action_with_newrelic_trace :name => 'bogosity' do
450
+ ActiveRecordFixtures::Order.add_delay
451
+ all_finder(ActiveRecordFixtures::Order)
452
+ end
453
+
454
+ sample = NewRelic::Agent.instance.transaction_sampler.last_sample
455
+
456
+ sample = sample.prepare_to_send!
457
+ segment = last_segment(sample)
458
+ explanations = segment.params[:explain_plan]
459
+
460
+ refute_nil explanations, "No explains in segment: #{segment}"
461
+ assert_equal 1, explanations.size,"No explains in segment: #{segment}"
462
+ assert_equal 1, explanations.first.size
463
+
464
+ assert_equal("Explain Plan", explanations[0][0])
465
+ assert_match /Seq Scan on test_data/, explanations[0][1].join(";")
466
+
467
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
468
+ assert_equal 1, s.call_count
469
+ end
470
+ end
471
+
472
+ def test_transaction_other
473
+ return if isMysql? || isPostgres?
474
+
475
+ with_config(:record_sql => :obfuscated,
476
+ :'transaction_tracer.explain_enabled' => true,
477
+ :'transaction_tracer.explain_threshold' => 0.0) do
478
+ sample = NewRelic::Agent.instance.transaction_sampler.reset!
479
+ perform_action_with_newrelic_trace :name => 'bogosity' do
480
+ ActiveRecordFixtures::Order.add_delay
481
+ all_finder(ActiveRecordFixtures::Order)
482
+ end
483
+
484
+ sample = NewRelic::Agent.instance.transaction_sampler.last_sample
485
+
486
+ sample = sample.prepare_to_send!
487
+ segment = last_segment(sample)
488
+
489
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
490
+ assert_equal 1, s.call_count
491
+ end
492
+ end
493
+
494
+ # These are only valid for rails 2.1 and later
495
+ if NewRelic::Control.instance.rails_version >= NewRelic::VersionNumber.new("2.1.0")
496
+ ActiveRecordFixtures::Order.class_eval do
497
+ if NewRelic::Control.instance.rails_version >= NewRelic::VersionNumber.new("4")
498
+ scope :jeffs, lambda { where(:name => 'Jeff') }
499
+ elsif NewRelic::Control.instance.rails_version >= NewRelic::VersionNumber.new("3.1")
500
+ scope :jeffs, :conditions => { :name => 'Jeff' }
501
+ else
502
+ named_scope :jeffs, :conditions => { :name => 'Jeff' }
503
+ end
504
+ end
505
+ def test_named_scope
506
+ ActiveRecordFixtures::Order.create :name => 'Jeff'
507
+
508
+ find_metric = "ActiveRecord/ActiveRecordFixtures::Order/find"
509
+
510
+ check_metric_count(find_metric, 0)
511
+ assert_calls_metrics(find_metric) do
512
+ if NewRelic::Control.instance.rails_version >= "4"
513
+ x = ActiveRecordFixtures::Order.jeffs.load
514
+ else
515
+ x = ActiveRecordFixtures::Order.jeffs.find(:all)
516
+ end
517
+ end
518
+ check_metric_count(find_metric, 1)
519
+ end
520
+ end
521
+
522
+ # This is to make sure the all metric is recorded for exceptional cases
523
+ def test_error_handling
524
+ # have the AR select throw an error
525
+ ActiveRecordFixtures::Order.connection.stubs(:log_info).with do | sql, x, y |
526
+ raise "Error" if sql =~ /select/
527
+ true
528
+ end
529
+
530
+ in_web_transaction do
531
+ begin
532
+ ActiveRecordFixtures::Order.connection.select_rows "select * from #{ActiveRecordFixtures::Order.table_name}"
533
+ rescue RuntimeError => e
534
+ # catch only the error we raise above
535
+ raise unless e.message == 'Error'
536
+ end
537
+ end
538
+
539
+ assert_metrics_recorded(
540
+ 'ActiveRecord/all' => { :call_count => 1 },
541
+ 'Database/SQL/select' => { :call_count => 1 }
542
+ )
543
+
544
+ if !NewRelic::LanguageSupport.using_engine?('jruby')
545
+ assert_metrics_recorded("RemoteService/sql/#{adapter}/localhost" => { :call_count => 1 })
546
+ end
547
+ end
548
+
549
+ def test_rescue_handling
550
+ # Not sure why we get a transaction error with sqlite
551
+ return if isSqlite?
552
+
553
+ begin
554
+ ActiveRecordFixtures::Order.transaction do
555
+ raise ActiveRecord::ActiveRecordError.new('preserve-me!')
556
+ end
557
+ rescue ActiveRecord::ActiveRecordError => e
558
+ assert_equal 'preserve-me!', e.message
559
+ end
560
+ end
561
+
562
+ def test_remote_service_metric_respects_dynamic_connection_config
563
+ return unless isMysql? && !NewRelic::LanguageSupport.using_engine?('jruby')
564
+
565
+ ActiveRecordFixtures::Shipment.connection.execute('SHOW TABLES');
566
+ assert_metrics_recorded(["RemoteService/sql/#{adapter}/localhost"])
567
+
568
+ config = ActiveRecordFixtures::Shipment.connection.instance_eval { @config }
569
+ config[:host] = '127.0.0.1'
570
+ connection = ActiveRecordFixtures::Shipment.establish_connection(config)
571
+
572
+ ActiveRecordFixtures::Shipment.connection.execute('SHOW TABLES');
573
+ assert_metrics_recorded(["RemoteService/sql/#{adapter}/127.0.0.1"])
574
+
575
+ config[:host] = 'localhost'
576
+ ActiveRecordFixtures::Shipment.establish_connection(config)
577
+ end
574
578
 
575
579
  private
576
580