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.
Files changed (82) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +14 -1
  3. data/lib/new_relic/agent.rb +8 -7
  4. data/lib/new_relic/agent/agent.rb +2 -0
  5. data/lib/new_relic/agent/configuration/defaults.rb +1 -1
  6. data/lib/new_relic/agent/configuration/server_source.rb +2 -1
  7. data/lib/new_relic/agent/cross_app_tracing.rb +52 -26
  8. data/lib/new_relic/agent/event_listener.rb +1 -1
  9. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +61 -0
  10. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +46 -0
  11. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +72 -0
  12. data/lib/new_relic/agent/{uri_util.rb → http_clients/uri_util.rb} +11 -17
  13. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -11
  14. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +1 -1
  15. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -2
  16. data/lib/new_relic/agent/instrumentation/excon.rb +72 -0
  17. data/lib/new_relic/agent/instrumentation/excon/connection.rb +33 -0
  18. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +45 -0
  19. data/lib/new_relic/agent/instrumentation/net.rb +3 -1
  20. data/lib/new_relic/agent/instrumentation/typhoeus.rb +73 -0
  21. data/lib/new_relic/agent/method_tracer.rb +3 -6
  22. data/lib/new_relic/agent/new_relic_service.rb +1 -1
  23. data/lib/new_relic/agent/samplers/object_sampler.rb +1 -1
  24. data/lib/new_relic/agent/stats.rb +12 -10
  25. data/lib/new_relic/agent/stats_engine/metric_stats.rb +24 -6
  26. data/lib/new_relic/agent/stats_engine/stats_hash.rb +9 -11
  27. data/lib/new_relic/agent/transaction.rb +34 -33
  28. data/lib/new_relic/agent/transaction_sampler.rb +15 -6
  29. data/lib/new_relic/language_support.rb +8 -0
  30. data/lib/new_relic/local_environment.rb +10 -14
  31. data/lib/new_relic/version.rb +1 -1
  32. data/test/agent_helper.rb +43 -0
  33. data/test/config/test.cert.crt +14 -0
  34. data/test/config/test.cert.csr +11 -0
  35. data/test/config/test.cert.key +15 -0
  36. data/test/config/testing-privkey.pem +18 -0
  37. data/test/multiverse/lib/multiverse/color.rb +9 -3
  38. data/test/multiverse/lib/multiverse/suite.rb +11 -1
  39. data/test/multiverse/suites/agent_only/audit_log_test.rb +1 -0
  40. data/test/multiverse/suites/agent_only/config/newrelic.yml +4 -0
  41. data/test/multiverse/suites/agent_only/http_response_code_test.rb +1 -1
  42. data/test/multiverse/suites/agent_only/rename_rule_test.rb +2 -1
  43. data/test/multiverse/suites/agent_only/start_up_test.rb +3 -2
  44. data/test/multiverse/suites/config_file_loading/Envfile +2 -0
  45. data/test/multiverse/suites/excon/Envfile +15 -0
  46. data/test/multiverse/suites/excon/config/newrelic.yml +21 -0
  47. data/test/multiverse/suites/excon/excon_test.rb +60 -0
  48. data/test/multiverse/suites/net_http/Envfile +6 -0
  49. data/test/multiverse/suites/net_http/config/newrelic.yml +21 -0
  50. data/test/multiverse/suites/net_http/net_http_test.rb +102 -0
  51. data/test/multiverse/suites/rails/Envfile +1 -1
  52. data/test/multiverse/suites/rails/view_instrumentation_test.rb +6 -0
  53. data/test/multiverse/suites/resque/Envfile +0 -9
  54. data/test/multiverse/suites/resque/instrumentation_test.rb +21 -6
  55. data/test/multiverse/suites/typhoeus/Envfile +46 -0
  56. data/test/multiverse/suites/typhoeus/config/newrelic.yml +21 -0
  57. data/test/multiverse/suites/typhoeus/typhoeus_test.rb +77 -0
  58. data/test/new_relic/agent/agent_test_controller_test.rb +11 -10
  59. data/test/new_relic/agent/configuration/server_source_test.rb +23 -9
  60. data/test/new_relic/agent/database_test.rb +6 -0
  61. data/test/new_relic/agent/http_clients/uri_util_test.rb +64 -0
  62. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +0 -406
  63. data/test/new_relic/agent/new_relic_service_test.rb +23 -19
  64. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +29 -12
  65. data/test/new_relic/agent/stats_hash_test.rb +24 -3
  66. data/test/new_relic/agent/stats_test.rb +4 -4
  67. data/test/new_relic/agent/transaction/pop_test.rb +1 -1
  68. data/test/new_relic/agent/transaction_sampler_test.rb +18 -0
  69. data/test/new_relic/agent/transaction_test.rb +64 -69
  70. data/test/new_relic/agent_test.rb +20 -0
  71. data/test/new_relic/dependency_detection_test.rb +99 -0
  72. data/test/new_relic/evil_server.rb +56 -0
  73. data/test/new_relic/fake_collector.rb +12 -96
  74. data/test/new_relic/fake_external_server.rb +55 -0
  75. data/test/new_relic/fake_server.rb +97 -0
  76. data/test/new_relic/http_client_test_cases.rb +444 -0
  77. data/test/new_relic/language_support_test.rb +45 -0
  78. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +25 -4
  79. metadata +37 -35
  80. metadata.gz.sig +0 -0
  81. data/test/multiverse/suites/resque/resque_setup.rb +0 -19
  82. data/test/new_relic/agent/uri_util_test.rb +0 -75
@@ -31,7 +31,7 @@ module NewRelic
31
31
  Hash[self] == Hash[other]
32
32
  end
33
33
 
34
- def record(metric_specs, value=nil)
34
+ def record(metric_specs, value=nil, aux=nil)
35
35
  Array(metric_specs).each do |metric_spec|
36
36
  stats = self[metric_spec]
37
37
  if block_given?
@@ -39,7 +39,10 @@ module NewRelic
39
39
  else
40
40
  case value
41
41
  when Numeric
42
- stats.record_data_point(value)
42
+ aux ||= value
43
+ stats.record_data_point(value, aux)
44
+ when :apdex_s, :apdex_t, :apdex_f
45
+ stats.record_apdex(value, aux)
43
46
  when NewRelic::Agent::Stats
44
47
  stats.merge!(value)
45
48
  end
@@ -58,16 +61,11 @@ module NewRelic
58
61
  self
59
62
  end
60
63
 
61
- def resolve_scopes(resolved_scope)
62
- new_stats = self.class.new
63
- self.each do |spec, stats|
64
- if spec.scope != '' &&
65
- spec.scope.to_sym == StatsEngine::SCOPE_PLACEHOLDER
66
- spec.scope = resolved_scope
67
- end
68
- new_stats[spec] = stats
64
+ def resolve_scopes!(resolved_scope)
65
+ placeholder = StatsEngine::SCOPE_PLACEHOLDER.to_s
66
+ each_pair do |spec, stats|
67
+ spec.scope = resolved_scope if spec.scope == placeholder
69
68
  end
70
- return new_stats
71
69
  end
72
70
  end
73
71
  end
@@ -96,6 +96,7 @@ module NewRelic
96
96
  def initialize(type=:controller, options={})
97
97
  @type = type
98
98
  @start_time = Time.now
99
+ @apdex_start = @start_time
99
100
  @jruby_cpu_start = jruby_cpu_time
100
101
  @process_cpu_start = process_cpu
101
102
  @filtered_params = options[:filtered_params] || {}
@@ -201,8 +202,8 @@ module NewRelic
201
202
  end
202
203
 
203
204
  def merge_stats_hash
204
- stats = stats_hash.resolve_scopes(@name)
205
- NewRelic::Agent.instance.stats_engine.merge!(stats)
205
+ stats_hash.resolve_scopes!(@name)
206
+ NewRelic::Agent.instance.stats_engine.merge!(stats_hash)
206
207
  end
207
208
 
208
209
  def record_exceptions
@@ -213,17 +214,17 @@ module NewRelic
213
214
  end
214
215
 
215
216
  OVERVIEW_SPECS = [
216
- [:web_duration, MetricSpec.new('HttpDispatcher')],
217
- [:queue_duration, MetricSpec.new('WebFrontend/QueueTime')],
218
- [:external_duration, MetricSpec.new('External/allWeb')],
219
- [:database_duration, MetricSpec.new('ActiveRecord/all')],
220
- [:gc_cumulative, MetricSpec.new("GC/cumulative")],
221
- [:memcache_duration, MetricSpec.new('Memcache/allWeb')]
217
+ [:webDuration, MetricSpec.new('HttpDispatcher')],
218
+ [:queueDuration, MetricSpec.new('WebFrontend/QueueTime')],
219
+ [:externalDuration, MetricSpec.new('External/allWeb')],
220
+ [:databaseDuration, MetricSpec.new('ActiveRecord/all')],
221
+ [:gcCumulative, MetricSpec.new("GC/cumulative")],
222
+ [:memcacheDuration, MetricSpec.new('Memcache/allWeb')]
222
223
  ]
223
224
 
224
225
  def transaction_overview_metrics
225
226
  metrics = {}
226
- stats = agent.stats_engine.transaction_stats_hash
227
+ stats = @stats_hash
227
228
  OVERVIEW_SPECS.each do |(dest_key, spec)|
228
229
  metrics[dest_key] = stats[spec].total_call_time if stats.key?(spec)
229
230
  end
@@ -283,12 +284,23 @@ module NewRelic
283
284
  (current) ? current.user_attributes : {}
284
285
  end
285
286
 
286
- def record_apdex(metric_name, end_time=Time.now)
287
+ APDEX_METRIC_SPEC = NewRelic::MetricSpec.new('Apdex').freeze
288
+
289
+ def record_apdex(end_time=Time.now, is_error=nil)
287
290
  return unless recording_web_transaction? && NewRelic::Agent.is_execution_traced?
288
- metric_parser = NewRelic::MetricParser::MetricParser \
289
- .for_metric_named(metric_name)
290
291
 
291
- self.class.record_apdex(metric_parser, end_time - start_time, end_time - apdex_start, exceptions.any?)
292
+ freeze_name
293
+ apdex_t = TransactionInfo.get.apdex_t
294
+ action_duration = end_time - start_time
295
+ total_duration = end_time - apdex_start
296
+ is_error = is_error.nil? ? !exceptions.empty? : is_error
297
+
298
+ apdex_bucket_global = self.class.apdex_bucket(total_duration, is_error, apdex_t)
299
+ apdex_bucket_txn = self.class.apdex_bucket(action_duration, is_error, apdex_t)
300
+
301
+ @stats_hash.record(APDEX_METRIC_SPEC, apdex_bucket_global, apdex_t)
302
+ txn_apdex_metric = NewRelic::MetricSpec.new(@name.gsub(/^[^\/]+\//, 'Apdex/'))
303
+ @stats_hash.record(txn_apdex_metric, apdex_bucket_txn, apdex_t)
292
304
  end
293
305
 
294
306
  # Yield to a block that is run with a database metric name context. This means
@@ -364,34 +376,23 @@ module NewRelic
364
376
  return approximate_uri[%r{^(https?://.*?)?(/[^?]*)}, 2] || '/' if approximate_uri # '
365
377
  end
366
378
 
367
- def self.record_apdex(current_metric, action_duration, total_duration, is_error)
368
- agent.stats_engine.record_metrics('Apdex') do |stat|
369
- update_apdex(stat, total_duration, is_error)
370
- end
371
- agent.stats_engine.record_metrics(current_metric.apdex_metric_path) do |stat|
372
- update_apdex(stat, action_duration, is_error)
373
- end
379
+
380
+
381
+ def self.record_apdex(end_time, is_error)
382
+ current && current.record_apdex(end_time, is_error)
374
383
  end
375
384
 
376
- # Record an apdex value for the given stat. when `failed`
377
- # the apdex should be recorded as a failure regardless of duration.
378
- def self.update_apdex(stat, duration, failed)
379
- apdex_t = TransactionInfo.get.apdex_t
380
- duration = duration.to_f
385
+ def self.apdex_bucket(duration, failed, apdex_t)
381
386
  case
382
387
  when failed
383
- stat.record_apdex_f
388
+ :apdex_f
384
389
  when duration <= apdex_t
385
- stat.record_apdex_s
390
+ :apdex_s
386
391
  when duration <= 4 * apdex_t
387
- stat.record_apdex_t
392
+ :apdex_t
388
393
  else
389
- stat.record_apdex_f
394
+ :apdex_f
390
395
  end
391
- # Apdex min and max values should be initialized to the
392
- # current apdex_t
393
- stat.min_call_time = apdex_t
394
- stat.max_call_time = apdex_t
395
396
  end
396
397
 
397
398
  private
@@ -313,16 +313,25 @@ module NewRelic
313
313
  # duration is seconds, float value.
314
314
  def notice_sql(sql, config, duration, &explainer)
315
315
  if NewRelic::Agent.is_sql_recorded?
316
- statement = Database::Statement.new(self.class.truncate_message(sql))
317
- if config
318
- statement.adapter = config[:adapter]
319
- statement.config = config
320
- end
321
- statement.explainer = explainer
316
+ statement = build_database_statement(sql, config, explainer)
322
317
  notice_extra_data(statement, duration, :sql)
323
318
  end
324
319
  end
325
320
 
321
+ def build_database_statement(sql, config, explainer)
322
+ statement = Database::Statement.new(self.class.truncate_message(sql))
323
+ if config
324
+ statement.adapter = config[:adapter]
325
+ statement.config = config
326
+ end
327
+ if Agent.config[:override_sql_obfuscation_adapter]
328
+ statement.adapter = Agent.config[:override_sql_obfuscation_adapter]
329
+ end
330
+ statement.explainer = explainer
331
+
332
+ statement
333
+ end
334
+
326
335
  # Adds non-sql metadata to a segment - generally the memcached
327
336
  # key
328
337
  #
@@ -64,6 +64,14 @@ module NewRelic::LanguageSupport
64
64
  end
65
65
  end
66
66
 
67
+ def object_space_enabled?
68
+ if defined?(::JRuby) && JRuby.respond_to?(:runtime)
69
+ JRuby.runtime.is_object_space_enabled
70
+ else
71
+ defined?(::ObjectSpace) ? true : false
72
+ end
73
+ end
74
+
67
75
  def using_version?(version)
68
76
  numbers = version.split('.')
69
77
  numbers == ::RUBY_VERSION.split('.')[0, numbers.size]
@@ -49,17 +49,13 @@ module NewRelic
49
49
  @dispatcher_instance_id
50
50
  end
51
51
 
52
- # it's a working jruby if it has the runtime method, and object
53
- # space is enabled
54
- def working_jruby?
55
- !(defined?(::JRuby) && JRuby.respond_to?(:runtime) && !JRuby.runtime.is_object_space_enabled)
56
- end
57
-
58
52
  # Runs through all the objects in ObjectSpace to find the first one that
59
53
  # match the provided class
60
54
  def find_class_in_object_space(klass)
61
- ObjectSpace.each_object(klass) do |x|
62
- return x
55
+ if NewRelic::LanguageSupport.object_space_enabled?
56
+ ObjectSpace.each_object(klass) do |x|
57
+ return x
58
+ end
63
59
  end
64
60
  return nil
65
61
  end
@@ -68,7 +64,7 @@ module NewRelic
68
64
  def mongrel
69
65
  return @mongrel if @looked_for_mongrel
70
66
  @looked_for_mongrel = true
71
- if defined?(::Mongrel) && defined?(::Mongrel::HttpServer) && working_jruby?
67
+ if defined?(::Mongrel) && defined?(::Mongrel::HttpServer)
72
68
  @mongrel = find_class_in_object_space(::Mongrel::HttpServer)
73
69
  end
74
70
  @mongrel
@@ -135,10 +131,10 @@ module NewRelic
135
131
  end
136
132
 
137
133
  # Get the port from the configurator if one was created
138
- if @dispatcher_instance_id.nil? && defined?(::Mongrel::Configurator)
134
+ if NewRelic::LanguageSupport.object_space_enabled? && @dispatcher_instance_id.nil? && defined?(::Mongrel::Configurator)
139
135
  ObjectSpace.each_object(Mongrel::Configurator) do |mongrel|
140
136
  @dispatcher_instance_id = mongrel.defaults[:port] && mongrel.defaults[:port].to_s
141
- end unless defined?(::JRuby) && !JRuby.runtime.is_object_space_enabled
137
+ end
142
138
  end
143
139
 
144
140
  # Still can't find the port. Let's look at ARGV to fall back
@@ -149,14 +145,14 @@ module NewRelic
149
145
  end
150
146
 
151
147
  def check_for_unicorn
152
- if (defined?(::Unicorn) && defined?(::Unicorn::HttpServer)) && working_jruby?
148
+ if (defined?(::Unicorn) && defined?(::Unicorn::HttpServer)) && NewRelic::LanguageSupport.object_space_enabled?
153
149
  v = find_class_in_object_space(::Unicorn::HttpServer)
154
150
  @discovered_dispatcher = :unicorn if v
155
151
  end
156
152
  end
157
153
 
158
154
  def check_for_rainbows
159
- if (defined?(::Rainbows) && defined?(::Rainbows::HttpServer)) && working_jruby?
155
+ if (defined?(::Rainbows) && defined?(::Rainbows::HttpServer)) && NewRelic::LanguageSupport.object_space_enabled?
160
156
  v = find_class_in_object_space(::Rainbows::HttpServer)
161
157
  @discovered_dispatcher = :rainbows if v
162
158
  end
@@ -178,7 +174,7 @@ module NewRelic
178
174
  end
179
175
 
180
176
  def check_for_thin
181
- if defined?(::Thin) && defined?(::Thin::Server)
177
+ if defined?(::Thin) && defined?(::Thin::Server) && NewRelic::LanguageSupport.object_space_enabled?
182
178
  # This case covers the thin web dispatcher
183
179
  # Same issue as above- we assume only one instance per process
184
180
  ObjectSpace.each_object(Thin::Server) do |thin_dispatcher|
@@ -12,7 +12,7 @@ module NewRelic
12
12
 
13
13
  MAJOR = 3
14
14
  MINOR = 6
15
- TINY = 4
15
+ TINY = 5
16
16
 
17
17
  begin
18
18
  require File.join(File.dirname(__FILE__), 'build')
data/test/agent_helper.rb CHANGED
@@ -187,6 +187,7 @@ def in_transaction(*args)
187
187
  name = args.first || 'dummy'
188
188
  defaults = { :type => :other }
189
189
  options = defaults.merge(opts)
190
+
190
191
  NewRelic::Agent.instance.instance_variable_set(:@transaction_sampler,
191
192
  NewRelic::Agent::TransactionSampler.new)
192
193
  NewRelic::Agent.instance.stats_engine.transaction_sampler = \
@@ -205,6 +206,14 @@ def in_web_transaction(name='dummy')
205
206
  end
206
207
  end
207
208
 
209
+ def find_last_transaction_segment
210
+ builder = NewRelic::Agent.agent.transaction_sampler.builder
211
+ last_segment = nil
212
+ builder.current_segment.each_segment {|s| last_segment = s }
213
+
214
+ return last_segment
215
+ end
216
+
208
217
  def with_config(config_hash, opts={})
209
218
  opts = { :level => 0, :do_not_cast => false }.merge(opts)
210
219
  if opts[:do_not_cast]
@@ -222,8 +231,42 @@ end
222
231
 
223
232
  def freeze_time(now=Time.now)
224
233
  Time.stubs(:now).returns(now)
234
+ now
225
235
  end
226
236
 
227
237
  def advance_time(seconds)
228
238
  freeze_time(Time.now + seconds)
229
239
  end
240
+
241
+ def define_constant(constant_symbol, implementation)
242
+ if Object.const_defined?(constant_symbol)
243
+ existing_implementation = Object.send(:remove_const, constant_symbol)
244
+ end
245
+
246
+ Object.const_set(constant_symbol, implementation)
247
+
248
+ yield
249
+ ensure
250
+ Object.send(:remove_const, constant_symbol)
251
+
252
+ if existing_implementation
253
+ Object.const_set(constant_symbol, existing_implementation)
254
+ end
255
+ end
256
+
257
+ def undefine_constant(constant_symbol)
258
+ return yield unless Object.const_defined?(constant_symbol)
259
+ removed_constant = Object.send(:remove_const, constant_symbol)
260
+ yield
261
+ ensure
262
+ Object.const_set(constant_symbol, removed_constant) if removed_constant
263
+ end
264
+
265
+ def internet_connection?
266
+ if ENV['NO_INTERNET']
267
+ puts " - No internet connection, skipping"
268
+ false
269
+ else
270
+ true
271
+ end
272
+ end
@@ -0,0 +1,14 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICLzCCAZgCCQCnkGSReKv/pTANBgkqhkiG9w0BAQUFADBcMQswCQYDVQQGEwJV
3
+ UzEPMA0GA1UECBMGT3JlZ29uMREwDwYDVQQHEwhQb3J0bGFuZDESMBAGA1UEChMJ
4
+ TmV3IFJlbGljMRUwEwYDVQQDEwxuZXdyZWxpYy5jb20wHhcNMTMwNjIxMTcxNzEy
5
+ WhcNMjMwNjE5MTcxNzEyWjBcMQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29u
6
+ MREwDwYDVQQHEwhQb3J0bGFuZDESMBAGA1UEChMJTmV3IFJlbGljMRUwEwYDVQQD
7
+ EwxuZXdyZWxpYy5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOsuntDM
8
+ BSdK2YHRYzzqzm5adZspXUrEMZJa/D/vp/xtf3b7WCtKpstvS/wkhvHmpLGbrI+Q
9
+ SnhijZKBVsps1eGDBXD+7ieHLSmI/74VL/PayHn5OKXb9RJ1VmYavM+1AWFNv75A
10
+ akqNL84vykpeqk13nfJGqjzpiqnMg1xg1usNAgMBAAEwDQYJKoZIhvcNAQEFBQAD
11
+ gYEAeG8F0vIQY6nCgUQl/k+JTG40PAQUdASpzkxgINX/CbzReFIp6r29/szjTI0n
12
+ kujAl1XWmIf1Q+xapoW23eWEo0eqlWdjiz+F27VjCraTo1I84+LtGwFZfAAi3wCl
13
+ qwZz9vdk1wUN8Pfo3fSZsnk97//c7+UFPMdyDlSlLbYJ8NI=
14
+ -----END CERTIFICATE-----
@@ -0,0 +1,11 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIIBnDCCAQUCAQAwXDELMAkGA1UEBhMCVVMxDzANBgNVBAgTBk9yZWdvbjERMA8G
3
+ A1UEBxMIUG9ydGxhbmQxEjAQBgNVBAoTCU5ldyBSZWxpYzEVMBMGA1UEAxMMbmV3
4
+ cmVsaWMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrLp7QzAUnStmB
5
+ 0WM86s5uWnWbKV1KxDGSWvw/76f8bX92+1grSqbLb0v8JIbx5qSxm6yPkEp4Yo2S
6
+ gVbKbNXhgwVw/u4nhy0piP++FS/z2sh5+Til2/USdVZmGrzPtQFhTb++QGpKjS/O
7
+ L8pKXqpNd53yRqo86YqpzINcYNbrDQIDAQABoAAwDQYJKoZIhvcNAQEFBQADgYEA
8
+ RQKG4gae3akIGmm0lx+zupp6hsHQCfnR4p0z5TqcEuvKbZ5+hhQD/PgbP/KGg+be
9
+ +k1TyoGGaPlmU9hUjOYbw4EdgWIryKEF74/krAeUPkx1nZveAXOUpa8UkWizNXIc
10
+ EleS52kU8iSjcyiqJZlz5H5VBJwQvGFE5kqA9k8saLU=
11
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,15 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIICXAIBAAKBgQDrLp7QzAUnStmB0WM86s5uWnWbKV1KxDGSWvw/76f8bX92+1gr
3
+ SqbLb0v8JIbx5qSxm6yPkEp4Yo2SgVbKbNXhgwVw/u4nhy0piP++FS/z2sh5+Til
4
+ 2/USdVZmGrzPtQFhTb++QGpKjS/OL8pKXqpNd53yRqo86YqpzINcYNbrDQIDAQAB
5
+ AoGABbLXfk+zQER8CL0+HlfCMMJYXy4daJZgbR9vRU1VULSGhieI92OTrxI/URjB
6
+ fFMOYo9XGxNv+oLI02f25mjEtepGahrD/8/26dPyYWRaOIC9rO7YWxPzlo9QV+z4
7
+ AyNlTfgfO8qUYW3M/egk8rualpSNN9TS5nUdTC+dlbeEhIECQQD4wOWwFm85aJN9
8
+ 6Nh7qn7ZW7gx7adECRqnpRve/TsqiAKr+kshCVE7JGrgzqeqAcA9oYLn3B1UZEGm
9
+ KoZaGfdpAkEA8giDYTQpJ+2REYEUO3AKIVDCVuI4lESM8AuwjQH7KlJ1nbVXv0U+
10
+ nHSLGu+Qj7CVGmvuEutBwa7nCQs9qs+mBQJALW4FRMiEHab0sN0SlFtJ+WZf2HZ/
11
+ wtQq0w07btkushDO9ButFuZ9uGBpSI9VXZ4ePuM9Zhz0GlKJDtDbYp81aQJAGl5b
12
+ EegA49y6BVIuxhr6v45w3c5fo6ekQzLC1Vn15zJ8peXv3WLJ43m+/fxDn6P5WpuP
13
+ oHgI/fT0LsQOv+FHkQJBAKn0+5AMaAcQPQRBofT3i9SYQBjZKwshTRni1ktwGu7S
14
+ 19BkWaPJR9h9xxnPxC7U8PG0HuZ7jYOt0PgypJU2/No=
15
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,18 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ Proc-Type: 4,ENCRYPTED
3
+ DEK-Info: DES-EDE3-CBC,4534BD2C19948E2F
4
+
5
+ 2OJj77TnPwQ1whh+9HYmeth5qWu9NnitO0/grQfgNhuag4j+KLsRUTjeYbpXaHuT
6
+ iRQ3ik9r4RNUil/uwPPb/cIpYsnYCOWMnpNuj+NSum07TAOFz+trrcw6oMU0SVFz
7
+ m5jOeMuUwrc1Gvc6tRfqI+kNUtT8mRfNINiato1ATnkzXSHiR4kStldkqQZVO7cr
8
+ pa2r03VJCik1yICxay7Q2fZgwvuuGrdM61cOQms3s07TLXIOF+IezzYPRsWcZFV1
9
+ M9lrIGX2jR6lAhx2NOOvNlpW4Z8GYzNn2TGWDuld9Ou6qEG9i++GP3TuwOM/rpTP
10
+ al826dwKpeN3tF1L5CPMsvca/G6hPRjiCw/bs1JvIo+hqdqVOhYoJBwvDmP+j/VW
11
+ iArK8/VJCAETspcm5FQDuzqH02ZqMAxMz2kIdKYo2w/+dgNvaJaUGvH1yT5X+x9M
12
+ 8AvcMDkh8X3HPJDmCLNZufDafmvT/m0dhJ8JPlGP7QXFKQaNSC7f03JR3RN6Xqtb
13
+ a2tidGmcrNI8/OfE3FFLvs0hudnScqdHoxJLHQapeZQe7/0l6xBmauF8MDPW5Ylx
14
+ 5mjBfkDcyE77qxJwvuTOuaEA+Pj/G7Gc31oDFtroFG8dTNnUyNiUf5yOWame5j+V
15
+ GJUIuWmj2wS9Zhn834bXL5hmClvblMXgErsfwpqe1F8RwdZaatws4dZD/BEi0/Ua
16
+ PW1ej4e7fGe8S6Gf0oK6Wb7/Rz29MGt9djm9MGIsCDKJdu0RC6Cb22HlcsAhzJ8s
17
+ KQie9XWhR5k1iluzc1QuJW18tgeRC5avOrCOhSeSlq+iX/giryENhw==
18
+ -----END RSA PRIVATE KEY-----
@@ -4,14 +4,20 @@
4
4
 
5
5
  module Multiverse
6
6
  module Color
7
+ def colorize(color_code, content)
8
+ STDOUT.tty? ? "\e[#{color_code}m#{content}\e[0m" : content
9
+ end
10
+
7
11
  def red(string)
8
- "\e[0;31;49m#{string}\e[0m "
12
+ colorize("0;31;49", string)
9
13
  end
14
+
10
15
  def green(string)
11
- "\e[0;32;49m#{string}\e[0m "
16
+ colorize("0;32;49", string)
12
17
  end
18
+
13
19
  def yellow(string)
14
- "\e[0;33;49m#{string}\e[0m "
20
+ colorize("0;33;49", string)
15
21
  end
16
22
  end
17
23
  end
@@ -53,8 +53,8 @@ module Multiverse
53
53
  require 'rubygems'
54
54
  require 'bundler'
55
55
  bundler_out = `bundle`
56
+ puts bundler_out if verbose? || $? != 0
56
57
  raise "bundle command failed with (#{$?})" unless $? == 0
57
- puts bundler_out if verbose?
58
58
  Bundler.require
59
59
 
60
60
  # Ensure mocha is loaded after the test framework by deferring until here
@@ -74,6 +74,7 @@ module Multiverse
74
74
  f.puts ' source :rubygems' unless local
75
75
  f.print gemfile_text
76
76
  f.puts newrelic_gemfile_line unless gemfile_text =~ /^\s*gem .newrelic_rpm./
77
+ f.puts jruby_openssl_line unless gemfile_text =~ /^\s*gem .jruby-openssl./
77
78
  if RUBY_VERSION > '1.8.7'
78
79
  f.puts " gem 'test-unit', :require => 'test/unit'"
79
80
  f.puts " gem 'debugger'" if include_debugger
@@ -95,6 +96,10 @@ module Multiverse
95
96
  line
96
97
  end
97
98
 
99
+ def jruby_openssl_line
100
+ "gem 'jruby-openssl', :require => false, :platforms => [:jruby]"
101
+ end
102
+
98
103
  def print_environment
99
104
  puts yellow("Environment loaded with:") if verbose?
100
105
  gems = Bundler.definition.specs.inject([]) do |m, s|
@@ -133,7 +138,9 @@ module Multiverse
133
138
 
134
139
  def execute_with_pipe(env)
135
140
  OutputCollector.buffers.push('')
141
+ puts yellow("Running #{directory.inspect} for Envfile entry #{env}")
136
142
  IO.popen("#{__FILE__} #{directory} #{env}") do |io|
143
+ puts yellow("Starting tests in child PID #{io.pid}")
137
144
  while chars = io.read(8) do
138
145
  OutputCollector.buffers.last << chars
139
146
  print chars
@@ -183,5 +190,8 @@ end
183
190
  # Exectute the suite. We need this if we want to execute a suite by spawning a
184
191
  # new process instead of forking.
185
192
  if $0 == __FILE__
193
+ # Redirect stderr to stdout so that we can capture both in the popen that
194
+ # feeds into the OutputCollector above.
195
+ $stderr.reopen($stdout)
186
196
  Multiverse::Suite.new(ARGV[0], ARGV[2]).execute_child_environment(ARGV[1].to_i)
187
197
  end