traceview 3.6.0-java → 3.7.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -1
  3. data/CHANGELOG.md +11 -0
  4. data/CONFIG.md +22 -5
  5. data/Rakefile +2 -2
  6. data/gemfiles/delayed_job.gemfile +1 -1
  7. data/gemfiles/frameworks.gemfile +1 -1
  8. data/gemfiles/libraries.gemfile +4 -3
  9. data/gemfiles/rails31.gemfile +2 -0
  10. data/gemfiles/rails32.gemfile +5 -2
  11. data/gemfiles/rails40.gemfile +5 -3
  12. data/gemfiles/rails41.gemfile +6 -4
  13. data/gemfiles/rails42.gemfile +3 -1
  14. data/gemfiles/rails50.gemfile +43 -0
  15. data/lib/rails/generators/traceview/templates/traceview_initializer.rb +56 -32
  16. data/lib/traceview/base.rb +1 -1
  17. data/lib/traceview/frameworks/rails.rb +6 -9
  18. data/lib/traceview/frameworks/rails/inst/action_controller.rb +2 -135
  19. data/lib/traceview/frameworks/rails/inst/action_controller2.rb +59 -0
  20. data/lib/traceview/frameworks/rails/inst/action_controller3.rb +49 -0
  21. data/lib/traceview/frameworks/rails/inst/action_controller4.rb +40 -0
  22. data/lib/traceview/frameworks/rails/inst/action_controller5.rb +39 -0
  23. data/lib/traceview/frameworks/rails/inst/action_view.rb +1 -1
  24. data/lib/traceview/frameworks/rails/inst/active_record.rb +6 -3
  25. data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +1 -1
  26. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +30 -36
  27. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils5x.rb +100 -0
  28. data/lib/traceview/test.rb +39 -0
  29. data/lib/traceview/version.rb +1 -1
  30. data/test/frameworks/rails3x_test.rb +163 -7
  31. data/test/frameworks/rails4x_test.rb +162 -13
  32. data/test/frameworks/rails5x_test.rb +213 -0
  33. data/test/instrumentation/excon_test.rb +3 -0
  34. data/test/instrumentation/sequel_mysql2_test.rb +2 -5
  35. data/test/instrumentation/sequel_mysql_test.rb +2 -5
  36. data/test/instrumentation/sequel_pg_test.rb +2 -5
  37. data/test/minitest_helper.rb +25 -21
  38. data/test/servers/delayed_job.rb +2 -6
  39. data/test/servers/rails3x_8140.rb +16 -6
  40. data/test/servers/rails4x_8140.rb +20 -9
  41. data/test/servers/rails5x_8140.rb +112 -0
  42. metadata +12 -3
  43. data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +0 -18
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module ConnectionAdapters
7
+ module Utils
8
+
9
+ def extract_trace_details(sql, name = nil, binds = [])
10
+ opts = {}
11
+
12
+ begin
13
+ if TraceView::Config[:sanitize_sql]
14
+ # Sanitize SQL and don't report binds
15
+ opts[:Query] = TraceView::Util.sanitize_sql(sql)
16
+ else
17
+ # Report raw SQL and any binds if they exist
18
+ opts[:Query] = sql.to_s
19
+ if binds && !binds.empty?
20
+ opts[:QueryArgs] = binds.map { |i| i.value }
21
+ end
22
+ end
23
+
24
+ opts[:Name] = name.to_s if name
25
+ opts[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:active_record][:collect_backtraces]
26
+
27
+ if ::Rails::VERSION::MAJOR == 2
28
+ config = ::Rails.configuration.database_configuration[::Rails.env]
29
+ else
30
+ config = ActiveRecord::Base.connection.instance_variable_get(:@config)
31
+ end
32
+
33
+ if config
34
+ opts[:Database] = config['database'] if config.key?('database')
35
+ opts[:RemoteHost] = config['host'] if config.key?('host')
36
+ adapter_name = config[:adapter]
37
+
38
+ case adapter_name
39
+ when /mysql/i
40
+ opts[:Flavor] = 'mysql'
41
+ when /postgres/i
42
+ opts[:Flavor] = 'postgresql'
43
+ end
44
+ end
45
+ rescue StandardError => e
46
+ TraceView.logger.debug "Exception raised capturing ActiveRecord KVs: #{e.inspect}"
47
+ TraceView.logger.debug e.backtrace.join('\n')
48
+ end
49
+
50
+ return opts || {}
51
+ end
52
+
53
+ # We don't want to trace framework caches. Only instrument SQL that
54
+ # directly hits the database.
55
+ def ignore_payload?(name)
56
+ %w(SCHEMA EXPLAIN CACHE).include?(name.to_s) ||
57
+ (name && name.to_sym == :skip_logging) ||
58
+ name == 'ActiveRecord::SchemaMigration Load'
59
+ end
60
+
61
+ def exec_query_with_traceview(sql, name = nil, binds = [], prepare: false)
62
+
63
+ if TraceView.tracing? && !ignore_payload?(name)
64
+
65
+ opts = extract_trace_details(sql, name, binds)
66
+ TraceView::API.trace('activerecord', opts || {}) do
67
+ exec_query_without_traceview(sql, name, binds)
68
+ end
69
+ else
70
+ exec_query_without_traceview(sql, name, binds)
71
+ end
72
+ end
73
+
74
+ def exec_insert_with_traceview(sql, name = nil, binds = [], *args)
75
+ if TraceView.tracing? && !ignore_payload?(name)
76
+
77
+ opts = extract_trace_details(sql, name, binds)
78
+ TraceView::API.trace('activerecord', opts || {}) do
79
+ exec_insert_without_traceview(sql, name, binds, *args)
80
+ end
81
+ else
82
+ exec_insert_without_traceview(sql, name, binds, *args)
83
+ end
84
+ end
85
+
86
+ def exec_delete_with_traceview(sql, name = nil, binds = [])
87
+ if TraceView.tracing? && !ignore_payload?(name)
88
+
89
+ opts = extract_trace_details(sql, name, binds)
90
+ TraceView::API.trace('activerecord', opts || {}) do
91
+ exec_delete_without_traceview(sql, name, binds)
92
+ end
93
+ else
94
+ exec_delete_without_traceview(sql, name, binds)
95
+ end
96
+ end
97
+ end # Utils
98
+ end
99
+ end
100
+ end
@@ -44,6 +44,45 @@ module TraceView
44
44
  def gemfile
45
45
  File.basename(ENV['BUNDLE_GEMFILE']).split('.').first
46
46
  end
47
+
48
+ ##
49
+ # set_postgresql_env
50
+ #
51
+ # Used to set the postgresql specific DATABASE_URL env based
52
+ # on various conditions
53
+ def set_postgresql_env
54
+ if ENV.key?('TRAVIS_PSQL_PASS')
55
+ ENV['DATABASE_URL'] = "postgresql://postgres:#{ENV['TRAVIS_PSQL_PASS']}@127.0.0.1:5432/travis_ci_test"
56
+ else
57
+ ENV['DATABASE_URL'] = 'postgresql://postgres@127.0.0.1:5432/travis_ci_test'
58
+ end
59
+ end
60
+
61
+ ##
62
+ # set_mysql_env
63
+ #
64
+ # Used to set the mysql specific DATABASE_URL env based
65
+ # on various conditions
66
+ def set_mysql_env
67
+ if ENV.key?('TRAVIS_MYSQL_PASS')
68
+ ENV['DATABASE_URL'] = "mysql://root:#{ENV['TRAVIS_MYSQL_PASS']}@127.0.0.1:3306/travis_ci_test"
69
+ else
70
+ ENV['DATABASE_URL'] = 'mysql://root@127.0.0.1:3306/travis_ci_test'
71
+ end
72
+ end
73
+
74
+ ##
75
+ # set_mysql2_env
76
+ #
77
+ # Used to set the mysql specific DATABASE_URL env based
78
+ # on various conditions
79
+ def set_mysql2_env
80
+ if ENV.key?('TRAVIS_MYSQL_PASS')
81
+ ENV['DATABASE_URL'] = "mysql2://root:#{ENV['TRAVIS_MYSQL_PASS']}@127.0.0.1:3306/travis_ci_test"
82
+ else
83
+ ENV['DATABASE_URL'] = 'mysql2://root@127.0.0.1:3306/travis_ci_test'
84
+ end
85
+ end
47
86
  end
48
87
  end
49
88
  end
@@ -7,7 +7,7 @@ module TraceView
7
7
  # traceview.gemspec during gem build process
8
8
  module Version
9
9
  MAJOR = 3
10
- MINOR = 6
10
+ MINOR = 7
11
11
  PATCH = 0
12
12
  BUILD = nil
13
13
 
@@ -98,25 +98,30 @@ if defined?(::Rails)
98
98
  r.header['X-Trace'].must_equal traces[4]['X-Trace']
99
99
  end
100
100
 
101
- it "should trace rails db calls" do
101
+ it "should trace rails postgresql db calls" do
102
102
  # Skip for JRuby since the java instrumentation
103
103
  # handles DB instrumentation for JRuby
104
- skip if defined?(JRUBY_VERSION)
104
+ skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != "postgresql"
105
105
 
106
106
  uri = URI.parse('http://127.0.0.1:8140/hello/db')
107
107
  r = Net::HTTP.get_response(uri)
108
108
 
109
109
  traces = get_all_traces
110
110
 
111
- traces.count.must_equal 12
111
+ traces.count.must_equal 14
112
112
  valid_edges?(traces).must_equal true
113
113
  validate_outer_layers(traces, 'rack')
114
114
 
115
115
  traces[4]['Layer'].must_equal "activerecord"
116
116
  traces[4]['Label'].must_equal "entry"
117
117
  traces[4]['Flavor'].must_equal "postgresql"
118
- traces[4]['Query'].must_equal "SELECT \"widgets\".* FROM \"widgets\" "
119
- traces[4]['Name'].must_equal "Widget Load"
118
+
119
+ # Some versions of rails adds in another space before the ORDER keyword.
120
+ # Make 2 or more consecutive spaces just 1
121
+ sql = traces[4]['Query'].gsub(/\s{2,}/, ' ')
122
+ sql.must_equal "INSERT INTO \"widgets\" (\"created_at\", \"description\", \"name\", \"updated_at\") VALUES ($1, $2, $3, $4) RETURNING \"id\""
123
+
124
+ traces[4]['Name'].must_equal "SQL"
120
125
  traces[4].key?('Backtrace').must_equal true
121
126
 
122
127
  traces[5]['Layer'].must_equal "activerecord"
@@ -125,7 +130,60 @@ if defined?(::Rails)
125
130
  traces[6]['Layer'].must_equal "activerecord"
126
131
  traces[6]['Label'].must_equal "entry"
127
132
  traces[6]['Flavor'].must_equal "postgresql"
128
- traces[6]['Query'].must_equal "INSERT INTO \"widgets\" (\"created_at\", \"description\", \"name\", \"updated_at\") VALUES ($1, $2, $3, $4) RETURNING \"id\""
133
+ traces[6]['Query'].must_equal "SELECT \"widgets\".* FROM \"widgets\" WHERE \"widgets\".\"name\" = 'blah' LIMIT 1"
134
+ traces[6]['Name'].must_equal "Widget Load"
135
+ traces[6].key?('Backtrace').must_equal true
136
+ traces[6].key?('QueryArgs').must_equal false
137
+
138
+ traces[7]['Layer'].must_equal "activerecord"
139
+ traces[7]['Label'].must_equal "exit"
140
+
141
+ traces[8]['Layer'].must_equal "activerecord"
142
+ traces[8]['Label'].must_equal "entry"
143
+ traces[8]['Flavor'].must_equal "postgresql"
144
+
145
+ # Remove the widget id so we can test everything else
146
+ sql = traces[8]['Query'].gsub(/\d+/, 'xxx')
147
+ sql.must_equal "DELETE FROM \"widgets\" WHERE \"widgets\".\"id\" = xxx"
148
+
149
+ traces[8]['Name'].must_equal "SQL"
150
+ traces[8].key?('Backtrace').must_equal true
151
+ traces[8].key?('QueryArgs').must_equal false
152
+
153
+ traces[9]['Layer'].must_equal "activerecord"
154
+ traces[9]['Label'].must_equal "exit"
155
+
156
+ # Validate the existence of the response header
157
+ r['X-Trace'].must_equal traces[13]['X-Trace']
158
+ end
159
+
160
+ it "should trace rails mysql db calls" do
161
+ # Skip for JRuby since the java instrumentation
162
+ # handles DB instrumentation for JRuby
163
+ skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != "mysql"
164
+
165
+ uri = URI.parse('http://127.0.0.1:8140/hello/db')
166
+ r = Net::HTTP.get_response(uri)
167
+
168
+ traces = get_all_traces
169
+
170
+ traces.count.must_equal 18
171
+ valid_edges?(traces).must_equal true
172
+ validate_outer_layers(traces, 'rack')
173
+
174
+ traces[4]['Layer'].must_equal "activerecord"
175
+ traces[4]['Label'].must_equal "entry"
176
+ traces[4]['Flavor'].must_equal "mysql"
177
+ traces[4]['Query'].must_equal "BEGIN"
178
+ traces[4].key?('Backtrace').must_equal true
179
+
180
+ traces[5]['Layer'].must_equal "activerecord"
181
+ traces[5]['Label'].must_equal "exit"
182
+
183
+ traces[6]['Layer'].must_equal "activerecord"
184
+ traces[6]['Label'].must_equal "entry"
185
+ traces[6]['Flavor'].must_equal "mysql"
186
+ traces[6]['Query'].must_equal "INSERT INTO `widgets` (`created_at`, `description`, `name`, `updated_at`) VALUES (?, ?, ?, ?)"
129
187
  traces[6]['Name'].must_equal "SQL"
130
188
  traces[6].key?('Backtrace').must_equal true
131
189
  traces[6].key?('QueryArgs').must_equal true
@@ -133,9 +191,107 @@ if defined?(::Rails)
133
191
  traces[7]['Layer'].must_equal "activerecord"
134
192
  traces[7]['Label'].must_equal "exit"
135
193
 
194
+ traces[8]['Layer'].must_equal "activerecord"
195
+ traces[8]['Label'].must_equal "entry"
196
+ traces[8]['Flavor'].must_equal "mysql"
197
+ traces[8]['Query'].must_equal "COMMIT"
198
+ traces[8].key?('Backtrace').must_equal true
199
+
200
+ traces[9]['Layer'].must_equal "activerecord"
201
+ traces[9]['Label'].must_equal "exit"
202
+
203
+ traces[10]['Layer'].must_equal "activerecord"
204
+ traces[10]['Label'].must_equal "entry"
205
+ traces[10]['Flavor'].must_equal "mysql"
206
+ traces[10]['Name'].must_equal "Widget Load"
207
+ traces[10].key?('Backtrace').must_equal true
208
+
209
+ # Some versions of rails adds in another space before the ORDER keyword.
210
+ # Make 2 or more consecutive spaces just 1
211
+ sql = traces[10]['Query'].gsub(/\s{2,}/, ' ')
212
+ sql.must_equal "SELECT `widgets`.* FROM `widgets` WHERE `widgets`.`name` = 'blah' LIMIT 1"
213
+
214
+ traces[11]['Layer'].must_equal "activerecord"
215
+ traces[11]['Label'].must_equal "exit"
216
+
217
+ traces[12]['Layer'].must_equal "activerecord"
218
+ traces[12]['Label'].must_equal "entry"
219
+ traces[12]['Flavor'].must_equal "mysql"
220
+ traces[12]['Name'].must_equal "SQL"
221
+ traces[12].key?('Backtrace').must_equal true
222
+ traces[12].key?('QueryArgs').must_equal false
223
+
224
+ # Replace the datestamps with xxx to make testing easier
225
+ sql = traces[12]['Query'].gsub(/\d+/, 'xxx')
226
+ sql.must_equal "DELETE FROM `widgets` WHERE `widgets`.`id` = xxx"
227
+
228
+ traces[13]['Layer'].must_equal "activerecord"
229
+ traces[13]['Label'].must_equal "exit"
230
+
231
+ traces[14]['Layer'].must_equal "actionview"
232
+ traces[14]['Label'].must_equal "entry"
233
+
234
+ # Validate the existence of the response header
235
+ r['X-Trace'].must_equal traces[17]['X-Trace']
236
+ end
237
+
238
+ it "should trace rails mysql2 db calls" do
239
+ # Skip for JRuby since the java instrumentation
240
+ # handles DB instrumentation for JRuby
241
+ skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != 'mysql2'
242
+
243
+ uri = URI.parse('http://127.0.0.1:8140/hello/db')
244
+ r = Net::HTTP.get_response(uri)
245
+
246
+ traces = get_all_traces
247
+
248
+ traces.count.must_equal 14
249
+ valid_edges?(traces).must_equal true
250
+ validate_outer_layers(traces, 'rack')
251
+
252
+ traces[4]['Layer'].must_equal "activerecord"
253
+ traces[4]['Label'].must_equal "entry"
254
+ traces[4]['Flavor'].must_equal "mysql"
255
+
256
+ # Replace the datestamps with xxx to make testing easier
257
+ sql = traces[4]['Query'].gsub(/\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d/, 'xxx')
258
+ sql.must_equal "INSERT INTO `widgets` (`created_at`, `description`, `name`, `updated_at`) VALUES ('xxx', 'This is an amazing widget.', 'blah', 'xxx')"
259
+
260
+ traces[4]['Name'].must_equal "SQL"
261
+ traces[4].key?('Backtrace').must_equal true
262
+
263
+ traces[5]['Layer'].must_equal "activerecord"
264
+ traces[5]['Label'].must_equal "exit"
265
+
266
+ traces[6]['Layer'].must_equal "activerecord"
267
+ traces[6]['Label'].must_equal "entry"
268
+ traces[6]['Flavor'].must_equal "mysql"
269
+ traces[6]['Query'].must_equal "SELECT `widgets`.* FROM `widgets` WHERE `widgets`.`name` = 'blah' LIMIT 1"
270
+ traces[6]['Name'].must_equal "Widget Load"
271
+ traces[6].key?('Backtrace').must_equal true
272
+ traces[6].key?('QueryArgs').must_equal false
273
+
274
+ traces[7]['Layer'].must_equal "activerecord"
275
+ traces[7]['Label'].must_equal "exit"
276
+
277
+ traces[8]['Layer'].must_equal "activerecord"
278
+ traces[8]['Label'].must_equal "entry"
279
+ traces[8]['Flavor'].must_equal "mysql"
280
+
281
+ # Replace the datestamps with xxx to make testing easier
282
+ sql = traces[8]['Query'].gsub(/\d+/, 'xxx')
283
+ sql.must_equal "DELETE FROM `widgets` WHERE `widgets`.`id` = xxx"
284
+
285
+ traces[8]['Name'].must_equal "SQL"
286
+ traces[8].key?('Backtrace').must_equal true
287
+ traces[8].key?('QueryArgs').must_equal false
288
+
289
+ traces[9]['Layer'].must_equal "activerecord"
290
+ traces[9]['Label'].must_equal "exit"
291
+
136
292
  # Validate the existence of the response header
137
293
  r.header.key?('X-Trace').must_equal true
138
- r.header['X-Trace'].must_equal traces[11]['X-Trace']
294
+ r.header['X-Trace'].must_equal traces[13]['X-Trace']
139
295
  end
140
296
  end
141
297
  end
@@ -8,6 +8,7 @@ if defined?(::Rails)
8
8
  describe "Rails4x" do
9
9
  before do
10
10
  clear_all_traces
11
+ ENV['DBTYPE'] = "postgresql" unless ENV['DBTYPE']
11
12
  end
12
13
 
13
14
  it "should trace a request to a rails stack" do
@@ -51,52 +52,201 @@ if defined?(::Rails)
51
52
  traces[6]['Label'].must_equal "exit"
52
53
 
53
54
  # Validate the existence of the response header
54
- r.header.key?('X-Trace').must_equal true
55
- r.header['X-Trace'].must_equal traces[6]['X-Trace']
55
+ r['X-Trace'].must_equal traces[6]['X-Trace']
56
56
  end
57
57
 
58
- it "should trace rails db calls" do
58
+ it "should trace rails postgres db calls" do
59
59
  # Skip for JRuby since the java instrumentation
60
60
  # handles DB instrumentation for JRuby
61
- skip if defined?(JRUBY_VERSION)
61
+ skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != 'postgresql'
62
62
 
63
63
  uri = URI.parse('http://127.0.0.1:8140/hello/db')
64
64
  r = Net::HTTP.get_response(uri)
65
65
 
66
66
  traces = get_all_traces
67
67
 
68
- traces.count.must_equal 11
68
+ traces.count.must_equal 13
69
69
  valid_edges?(traces).must_equal true
70
70
  validate_outer_layers(traces, 'rack')
71
71
 
72
72
  traces[3]['Layer'].must_equal "activerecord"
73
73
  traces[3]['Label'].must_equal "entry"
74
74
  traces[3]['Flavor'].must_equal "postgresql"
75
- traces[3]['Query'].must_equal "SELECT \"widgets\".* FROM \"widgets\" ORDER BY \"widgets\".\"id\" ASC LIMIT 1"
76
- traces[3]['Name'].must_equal "Widget Load"
75
+ traces[3]['Name'].must_equal "SQL"
77
76
  traces[3].key?('Backtrace').must_equal true
78
77
 
78
+ # Use a regular expression to test the SQL string since field order varies between
79
+ # Rails versions
80
+ match_data = traces[3]['Query'].match(/INSERT\sINTO\s\"widgets\"\s\(.*\)\sVALUES\s\(\$1,\s\$2,\s\$3,\s\$4\)\sRETURNING\s\"id\"/)
81
+ match_data.wont_equal nil
82
+ match_data.class.must_equal MatchData
83
+
79
84
  traces[4]['Layer'].must_equal "activerecord"
80
85
  traces[4]['Label'].must_equal "exit"
81
86
 
82
87
  traces[5]['Layer'].must_equal "activerecord"
83
88
  traces[5]['Label'].must_equal "entry"
84
89
  traces[5]['Flavor'].must_equal "postgresql"
85
- traces[5]['Query'].must_equal "INSERT INTO \"widgets\" (\"name\", \"description\", \"created_at\", \"updated_at\") VALUES ($1, $2, $3, $4) RETURNING \"id\""
86
- traces[5]['Name'].must_equal "SQL"
90
+
91
+ # Some versions of rails adds in another space before the ORDER keyword.
92
+ # Make 2 or more consecutive spaces just 1
93
+ sql = traces[5]['Query'].gsub(/\s{2,}/, ' ')
94
+ sql.must_equal "SELECT \"widgets\".* FROM \"widgets\" WHERE \"widgets\".\"name\" = $1 ORDER BY \"widgets\".\"id\" ASC LIMIT 1"
95
+
96
+ traces[5]['Name'].must_equal "Widget Load"
87
97
  traces[5].key?('Backtrace').must_equal true
88
98
  traces[5].key?('QueryArgs').must_equal true
89
99
 
90
100
  traces[6]['Layer'].must_equal "activerecord"
91
101
  traces[6]['Label'].must_equal "exit"
92
102
 
103
+ traces[7]['Layer'].must_equal "activerecord"
104
+ traces[7]['Label'].must_equal "entry"
105
+ traces[7]['Flavor'].must_equal "postgresql"
106
+ traces[7]['Query'].must_equal "DELETE FROM \"widgets\" WHERE \"widgets\".\"id\" = $1"
107
+ traces[7]['Name'].must_equal "SQL"
108
+ traces[7].key?('Backtrace').must_equal true
109
+ traces[7].key?('QueryArgs').must_equal true
110
+
111
+ traces[8]['Layer'].must_equal "activerecord"
112
+ traces[8]['Label'].must_equal "exit"
113
+
93
114
  # Validate the existence of the response header
94
115
  r.header.key?('X-Trace').must_equal true
95
- r.header['X-Trace'].must_equal traces[10]['X-Trace']
116
+ r.header['X-Trace'].must_equal traces[12]['X-Trace']
96
117
  end
97
118
 
98
- it "should trace a request to a rails metal stack" do
119
+ it "should trace rails mysql db calls" do
120
+ # Skip for JRuby since the java instrumentation
121
+ # handles DB instrumentation for JRuby
122
+ skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != "mysql"
123
+
124
+ uri = URI.parse('http://127.0.0.1:8140/hello/db')
125
+ r = Net::HTTP.get_response(uri)
126
+
127
+ traces = get_all_traces
128
+
129
+ traces.count.must_equal 17
130
+ valid_edges?(traces).must_equal true
131
+ validate_outer_layers(traces, 'rack')
132
+
133
+ traces[3]['Layer'].must_equal "activerecord"
134
+ traces[3]['Label'].must_equal "entry"
135
+ traces[3]['Flavor'].must_equal "mysql"
136
+ traces[3]['Query'].must_equal "BEGIN"
137
+ traces[3].key?('Backtrace').must_equal true
138
+
139
+ traces[4]['Layer'].must_equal "activerecord"
140
+ traces[4]['Label'].must_equal "exit"
141
+
142
+ traces[5]['Layer'].must_equal "activerecord"
143
+ traces[5]['Label'].must_equal "entry"
144
+ traces[5]['Flavor'].must_equal "mysql"
145
+ traces[5]['Query'].must_equal "INSERT INTO `widgets` (`name`, `description`, `created_at`, `updated_at`) VALUES (?, ?, ?, ?)"
146
+ traces[5]['Name'].must_equal "SQL"
147
+ traces[5].key?('Backtrace').must_equal true
148
+ traces[5].key?('QueryArgs').must_equal true
149
+
150
+ traces[6]['Layer'].must_equal "activerecord"
151
+ traces[6]['Label'].must_equal "exit"
152
+
153
+ traces[7]['Layer'].must_equal "activerecord"
154
+ traces[7]['Label'].must_equal "entry"
155
+ traces[7]['Flavor'].must_equal "mysql"
156
+ traces[7]['Query'].must_equal "COMMIT"
157
+ traces[7].key?('Backtrace').must_equal true
158
+
159
+ traces[8]['Layer'].must_equal "activerecord"
160
+ traces[8]['Label'].must_equal "exit"
161
+
162
+ traces[9]['Layer'].must_equal "activerecord"
163
+ traces[9]['Label'].must_equal "entry"
164
+ traces[9]['Flavor'].must_equal "mysql"
165
+ traces[9]['Name'].must_equal "Widget Load"
166
+ traces[9].key?('Backtrace').must_equal true
167
+
168
+ # Some versions of rails adds in another space before the ORDER keyword.
169
+ # Make 2 or more consecutive spaces just 1
170
+ sql = traces[9]['Query'].gsub(/\s{2,}/, ' ')
171
+ sql.must_equal "SELECT `widgets`.* FROM `widgets` WHERE `widgets`.`name` = ? ORDER BY `widgets`.`id` ASC LIMIT 1"
172
+
173
+ traces[10]['Layer'].must_equal "activerecord"
174
+ traces[10]['Label'].must_equal "exit"
175
+
176
+ traces[11]['Layer'].must_equal "activerecord"
177
+ traces[11]['Label'].must_equal "entry"
178
+ traces[11]['Flavor'].must_equal "mysql"
179
+ traces[11]['Name'].must_equal "SQL"
180
+ traces[11].key?('Backtrace').must_equal true
181
+ traces[11].key?('QueryArgs').must_equal true
182
+ traces[11]['Query'].must_equal "DELETE FROM `widgets` WHERE `widgets`.`id` = ?"
99
183
 
184
+ traces[12]['Layer'].must_equal "activerecord"
185
+ traces[12]['Label'].must_equal "exit"
186
+
187
+ traces[13]['Layer'].must_equal "actionview"
188
+ traces[13]['Label'].must_equal "entry"
189
+
190
+ # Validate the existence of the response header
191
+ r['X-Trace'].must_equal traces[16]['X-Trace']
192
+ end
193
+
194
+ it "should trace rails mysql2 db calls" do
195
+ # Skip for JRuby since the java instrumentation
196
+ # handles DB instrumentation for JRuby
197
+ skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != "mysql2"
198
+
199
+ uri = URI.parse('http://127.0.0.1:8140/hello/db')
200
+ r = Net::HTTP.get_response(uri)
201
+
202
+ traces = get_all_traces
203
+
204
+ traces.count.must_equal 13
205
+ valid_edges?(traces).must_equal true
206
+ validate_outer_layers(traces, 'rack')
207
+
208
+ traces[3]['Layer'].must_equal "activerecord"
209
+ traces[3]['Label'].must_equal "entry"
210
+ traces[3]['Flavor'].must_equal "mysql"
211
+
212
+ # Replace the datestamps with xxx to make testing easier
213
+ sql = traces[3]['Query'].gsub(/\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d/, 'xxx')
214
+ sql.must_equal "INSERT INTO `widgets` (`name`, `description`, `created_at`, `updated_at`) VALUES ('blah', 'This is an amazing widget.', 'xxx', 'xxx')"
215
+
216
+ traces[3]['Name'].must_equal "SQL"
217
+ traces[3].key?('Backtrace').must_equal true
218
+ traces[3].key?('QueryArgs').must_equal true
219
+
220
+ traces[4]['Layer'].must_equal "activerecord"
221
+ traces[4]['Label'].must_equal "exit"
222
+
223
+ traces[5]['Layer'].must_equal "activerecord"
224
+ traces[5]['Label'].must_equal "entry"
225
+ traces[5]['Flavor'].must_equal "mysql"
226
+ traces[5]['Query'].must_equal "SELECT `widgets`.* FROM `widgets` WHERE `widgets`.`name` = 'blah' ORDER BY `widgets`.`id` ASC LIMIT 1"
227
+ traces[5]['Name'].must_equal "Widget Load"
228
+ traces[5].key?('Backtrace').must_equal true
229
+
230
+ traces[6]['Layer'].must_equal "activerecord"
231
+ traces[6]['Label'].must_equal "exit"
232
+
233
+ traces[7]['Layer'].must_equal "activerecord"
234
+ traces[7]['Label'].must_equal "entry"
235
+ traces[7]['Flavor'].must_equal "mysql"
236
+ traces[7]['Name'].must_equal "SQL"
237
+ traces[7].key?('Backtrace').must_equal true
238
+
239
+ sql = traces[7]['Query'].gsub(/\d+/, 'xxx')
240
+ sql.must_equal "DELETE FROM `widgets` WHERE `widgets`.`id` = xxx"
241
+
242
+ traces[8]['Layer'].must_equal "activerecord"
243
+ traces[8]['Label'].must_equal "exit"
244
+
245
+ # Validate the existence of the response header
246
+ r['X-Trace'].must_equal traces[12]['X-Trace']
247
+ end
248
+
249
+ it "should trace a request to a rails metal stack" do
100
250
  uri = URI.parse('http://127.0.0.1:8140/hello/metal')
101
251
  r = Net::HTTP.get_response(uri)
102
252
 
@@ -134,8 +284,7 @@ if defined?(::Rails)
134
284
  traces[4]['Label'].must_equal "exit"
135
285
 
136
286
  # Validate the existence of the response header
137
- r.header.key?('X-Trace').must_equal true
138
- r.header['X-Trace'].must_equal traces[4]['X-Trace']
287
+ r['X-Trace'].must_equal traces[4]['X-Trace']
139
288
  end
140
289
  end
141
290
  end