ghazel-newrelic_rpm 3.1.0.1 → 3.4.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. data/CHANGELOG +120 -35
  2. data/LICENSE +29 -2
  3. data/README.rdoc +2 -2
  4. data/bin/mongrel_rpm +0 -0
  5. data/bin/newrelic +0 -0
  6. data/bin/newrelic_cmd +0 -0
  7. data/lib/new_relic/agent.rb +50 -38
  8. data/lib/new_relic/agent/agent.rb +459 -337
  9. data/lib/new_relic/agent/beacon_configuration.rb +71 -11
  10. data/lib/new_relic/agent/browser_monitoring.rb +73 -14
  11. data/lib/new_relic/agent/busy_calculator.rb +11 -3
  12. data/lib/new_relic/agent/chained_call.rb +2 -2
  13. data/lib/new_relic/agent/database.rb +223 -0
  14. data/lib/new_relic/agent/error_collector.rb +231 -183
  15. data/lib/new_relic/agent/instrumentation.rb +2 -2
  16. data/lib/new_relic/agent/instrumentation/active_merchant.rb +10 -2
  17. data/lib/new_relic/agent/instrumentation/active_record.rb +138 -0
  18. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +7 -1
  19. data/lib/new_relic/agent/instrumentation/authlogic.rb +6 -0
  20. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +46 -14
  21. data/lib/new_relic/agent/instrumentation/data_mapper.rb +8 -2
  22. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +11 -3
  23. data/lib/new_relic/agent/instrumentation/memcache.rb +49 -25
  24. data/lib/new_relic/agent/instrumentation/merb/controller.rb +7 -2
  25. data/lib/new_relic/agent/instrumentation/merb/errors.rb +7 -1
  26. data/lib/new_relic/agent/instrumentation/metric_frame.rb +31 -4
  27. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -5
  28. data/lib/new_relic/agent/instrumentation/net.rb +8 -2
  29. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +5 -2
  30. data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
  31. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +66 -35
  32. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +7 -1
  33. data/lib/new_relic/agent/instrumentation/rails/errors.rb +7 -1
  34. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +121 -1
  35. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +7 -1
  36. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +21 -0
  37. data/lib/new_relic/agent/instrumentation/resque.rb +80 -0
  38. data/lib/new_relic/agent/instrumentation/sinatra.rb +46 -20
  39. data/lib/new_relic/agent/instrumentation/sunspot.rb +6 -0
  40. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +7 -2
  41. data/lib/new_relic/agent/method_tracer.rb +205 -99
  42. data/lib/new_relic/agent/new_relic_service.rb +221 -0
  43. data/lib/new_relic/agent/pipe_channel_manager.rb +161 -0
  44. data/lib/new_relic/agent/pipe_service.rb +54 -0
  45. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +89 -0
  46. data/lib/new_relic/agent/samplers/memory_sampler.rb +6 -7
  47. data/lib/new_relic/agent/shim_agent.rb +5 -5
  48. data/lib/new_relic/agent/sql_sampler.rb +282 -0
  49. data/lib/new_relic/agent/stats_engine.rb +2 -0
  50. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +123 -0
  51. data/lib/new_relic/agent/stats_engine/metric_stats.rb +35 -30
  52. data/lib/new_relic/agent/stats_engine/samplers.rb +10 -4
  53. data/lib/new_relic/agent/stats_engine/transactions.rb +28 -87
  54. data/lib/new_relic/agent/transaction_info.rb +74 -0
  55. data/lib/new_relic/agent/transaction_sample_builder.rb +18 -3
  56. data/lib/new_relic/agent/transaction_sampler.rb +108 -20
  57. data/lib/new_relic/agent/worker_loop.rb +14 -6
  58. data/lib/new_relic/collection_helper.rb +19 -11
  59. data/lib/new_relic/command.rb +1 -1
  60. data/lib/new_relic/commands/deployments.rb +2 -2
  61. data/lib/new_relic/commands/install.rb +2 -13
  62. data/lib/new_relic/control.rb +2 -3
  63. data/lib/new_relic/control/class_methods.rb +12 -6
  64. data/lib/new_relic/control/configuration.rb +57 -8
  65. data/lib/new_relic/control/frameworks.rb +10 -0
  66. data/lib/new_relic/control/frameworks/external.rb +4 -4
  67. data/lib/new_relic/control/frameworks/merb.rb +2 -1
  68. data/lib/new_relic/control/frameworks/rails.rb +35 -22
  69. data/lib/new_relic/control/frameworks/rails3.rb +12 -7
  70. data/lib/new_relic/control/frameworks/ruby.rb +5 -5
  71. data/lib/new_relic/control/frameworks/sinatra.rb +1 -4
  72. data/lib/new_relic/control/instance_methods.rb +38 -12
  73. data/lib/new_relic/control/instrumentation.rb +23 -4
  74. data/lib/new_relic/control/logging_methods.rb +70 -15
  75. data/lib/new_relic/control/server_methods.rb +22 -9
  76. data/lib/new_relic/delayed_job_injection.rb +16 -3
  77. data/lib/new_relic/helper.rb +21 -0
  78. data/lib/new_relic/language_support.rb +95 -0
  79. data/lib/new_relic/local_environment.rb +92 -48
  80. data/lib/new_relic/metric_data.rb +7 -2
  81. data/lib/new_relic/metric_spec.rb +12 -9
  82. data/lib/new_relic/noticed_error.rb +6 -1
  83. data/lib/new_relic/rack/browser_monitoring.rb +18 -19
  84. data/lib/new_relic/rack/developer_mode.rb +3 -2
  85. data/lib/new_relic/recipes.rb +8 -4
  86. data/lib/new_relic/stats.rb +17 -60
  87. data/lib/new_relic/transaction_analysis.rb +2 -1
  88. data/lib/new_relic/transaction_analysis/segment_summary.rb +4 -2
  89. data/lib/new_relic/transaction_sample.rb +60 -75
  90. data/lib/new_relic/transaction_sample/segment.rb +31 -79
  91. data/lib/new_relic/version.rb +2 -2
  92. data/lib/newrelic_rpm.rb +1 -1
  93. data/newrelic.yml +2 -2
  94. data/newrelic_rpm.gemspec +46 -54
  95. data/test/active_record_fixtures.rb +3 -3
  96. data/test/config/newrelic.yml +1 -1
  97. data/test/fixtures/proc_cpuinfo.txt +575 -0
  98. data/test/new_relic/agent/agent/connect_test.rb +128 -25
  99. data/test/new_relic/agent/agent/start_test.rb +9 -94
  100. data/test/new_relic/agent/agent/start_worker_thread_test.rb +2 -4
  101. data/test/new_relic/agent/agent_test.rb +51 -78
  102. data/test/new_relic/agent/agent_test_controller.rb +1 -1
  103. data/test/new_relic/agent/agent_test_controller_test.rb +49 -33
  104. data/test/new_relic/agent/beacon_configuration_test.rb +12 -5
  105. data/test/new_relic/agent/browser_monitoring_test.rb +99 -50
  106. data/test/new_relic/agent/database_test.rb +161 -0
  107. data/test/new_relic/agent/error_collector_test.rb +47 -23
  108. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +96 -42
  109. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +0 -2
  110. data/test/new_relic/agent/instrumentation/instrumentation_test.rb +1 -1
  111. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +3 -11
  112. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +9 -9
  113. data/test/new_relic/agent/instrumentation/queue_time_test.rb +6 -11
  114. data/test/new_relic/agent/memcache_instrumentation_test.rb +54 -18
  115. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -1
  116. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -1
  117. data/test/new_relic/agent/method_tracer_test.rb +3 -2
  118. data/test/new_relic/agent/new_relic_service_test.rb +151 -0
  119. data/test/new_relic/agent/pipe_channel_manager_test.rb +114 -0
  120. data/test/new_relic/agent/pipe_service_test.rb +113 -0
  121. data/test/new_relic/agent/rpm_agent_test.rb +4 -31
  122. data/test/new_relic/agent/sql_sampler_test.rb +192 -0
  123. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +19 -18
  124. data/test/new_relic/agent/stats_engine_test.rb +41 -6
  125. data/test/new_relic/agent/transaction_info_test.rb +13 -0
  126. data/test/new_relic/agent/transaction_sample_builder_test.rb +27 -4
  127. data/test/new_relic/agent/transaction_sampler_test.rb +68 -46
  128. data/test/new_relic/agent/worker_loop_test.rb +3 -3
  129. data/test/new_relic/agent_test.rb +242 -0
  130. data/test/new_relic/collection_helper_test.rb +50 -28
  131. data/test/new_relic/control/configuration_test.rb +77 -0
  132. data/test/new_relic/control/logging_methods_test.rb +49 -21
  133. data/test/new_relic/control_test.rb +115 -54
  134. data/test/new_relic/delayed_job_injection_test.rb +21 -0
  135. data/test/new_relic/fake_collector.rb +210 -0
  136. data/test/new_relic/fake_service.rb +44 -0
  137. data/test/new_relic/local_environment_test.rb +14 -1
  138. data/test/new_relic/metric_parser/metric_parser_test.rb +11 -0
  139. data/test/new_relic/rack/browser_monitoring_test.rb +84 -23
  140. data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
  141. data/test/new_relic/rack/developer_mode_test.rb +31 -0
  142. data/test/new_relic/stats_test.rb +3 -18
  143. data/test/new_relic/transaction_analysis/segment_summary_test.rb +14 -0
  144. data/test/new_relic/transaction_analysis_test.rb +3 -3
  145. data/test/new_relic/transaction_sample/segment_test.rb +15 -80
  146. data/test/new_relic/transaction_sample_test.rb +25 -18
  147. data/test/script/build_test_gem.sh +51 -0
  148. data/test/script/ci.sh +140 -0
  149. data/test/script/ci_agent-tests_runner.sh +82 -0
  150. data/test/script/ci_bench.sh +52 -0
  151. data/test/script/ci_multiverse_runner.sh +63 -0
  152. data/test/test_contexts.rb +1 -0
  153. data/test/test_helper.rb +18 -5
  154. data/ui/helpers/developer_mode_helper.rb +14 -8
  155. data/ui/helpers/google_pie_chart.rb +0 -1
  156. data/ui/views/newrelic/index.rhtml +2 -2
  157. data/vendor/gems/dependency_detection-0.0.1.build/LICENSE +4 -18
  158. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +10 -0
  159. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +11 -11
  160. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +17 -4
  161. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +4 -0
  162. metadata +50 -36
  163. data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +0 -108
  164. data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +0 -112
  165. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +0 -40
  166. data/lib/new_relic/data_serialization.rb +0 -84
  167. data/lib/new_relic/histogram.rb +0 -91
  168. data/lib/new_relic/rack/metric_app.rb +0 -65
  169. data/lib/new_relic/rack/mongrel_rpm.ru +0 -28
  170. data/lib/new_relic/rack/newrelic.yml +0 -27
  171. data/lib/new_relic/rack_app.rb +0 -6
  172. data/test/new_relic/data_serialization_test.rb +0 -70
  173. data/vendor/gems/dependency_detection-0.0.1.build/README +0 -0
  174. data/vendor/gems/metric_parser-0.1.0.pre1/LICENSE +0 -0
  175. data/vendor/gems/metric_parser-0.1.0.pre1/README +0 -0
@@ -7,7 +7,7 @@ class NewRelic::Agent::SuperclassController < ActionController::Base
7
7
  end
8
8
  # This is a controller class used in testing controller instrumentation
9
9
  class NewRelic::Agent::AgentTestController < NewRelic::Agent::SuperclassController
10
- filter_parameter_logging :social_security_number
10
+ # filter_parameter_logging :social_security_number
11
11
 
12
12
  @@headers_to_add = nil
13
13
 
@@ -7,23 +7,24 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
7
7
  self.controller_class = NewRelic::Agent::AgentTestController
8
8
 
9
9
  attr_accessor :agent, :engine
10
-
11
- # Normally you can do this with #setup but for some reason in rails 2.0.2
12
- # setup is not called.
13
- def initialize name
14
- super name
15
-
10
+
11
+ def test_initialization
16
12
  # Suggested by cee-dub for merb tests. I'm actually amazed if our tests work with merb.
17
- if defined?(Merb::Router)
18
- Merb::Router.prepare do |r|
19
- match('/:controller(/:action)(.:format)').register
20
- end
21
- else
22
- ActionController::Routing::Routes.draw do | map |
23
- map.connect '/:controller/:action.:format'
24
- map.connect '/:controller/:action'
13
+ if defined?(Merb::Router)
14
+ Merb::Router.prepare do |r|
15
+ match('/:controller(/:action)(.:format)').register
25
16
  end
26
- end
17
+ elsif NewRelic::Control.instance.rails_version < NewRelic::VersionNumber.new("3.0")
18
+ ActionController::Routing::Routes.draw do |map|
19
+ map.connect '/:controller/:action.:format'
20
+ map.connect '/:controller/:action'
21
+ end
22
+ else
23
+ Rails.application.routes.draw do
24
+ match '/:controller/:action.:format'
25
+ match '/:controller/:action'
26
+ end
27
+ end
27
28
 
28
29
  if defined?(Rails) && Rails.respond_to?(:application) && Rails.application.respond_to?(:routes)
29
30
  @routes = Rails.application.routes
@@ -40,6 +41,17 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
40
41
  end
41
42
  @engine = @agent.stats_engine
42
43
  end
44
+
45
+ # Normally you can do this with #setup but for some reason in rails 2.0.2
46
+ # setup is not called.
47
+ if NewRelic::Control.instance.rails_version <= '2.1.0'
48
+ def initialize name
49
+ super name
50
+ test_initialization
51
+ end
52
+ else
53
+ alias_method :setup, :test_initialization
54
+ end
43
55
 
44
56
  def teardown
45
57
  Thread.current[:newrelic_ignore_controller] = nil
@@ -71,6 +83,9 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
71
83
  end
72
84
 
73
85
  def test_new_queue_integration
86
+ # make this test deterministic
87
+ Time.stubs(:now => Time.at(2))
88
+
74
89
  NewRelic::Agent::AgentTestController.clear_headers
75
90
  engine.clear_stats
76
91
  start = ((Time.now - 1).to_f * 1_000_000).to_i
@@ -82,6 +97,9 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
82
97
 
83
98
 
84
99
  def test_new_middleware_integration
100
+ # make this test deterministic
101
+ Time.stubs(:now => Time.at(2))
102
+
85
103
  engine.clear_stats
86
104
  start = ((Time.now - 1).to_f * 1_000_000).to_i
87
105
  NewRelic::Agent::AgentTestController.set_some_headers 'HTTP_X_MIDDLEWARE_START'=> "t=#{start}"
@@ -91,6 +109,9 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
91
109
  end
92
110
 
93
111
  def test_new_server_time_integration
112
+ # make this test deterministic
113
+ Time.stubs(:now => Time.at(2))
114
+
94
115
  NewRelic::Agent::AgentTestController.clear_headers
95
116
  engine.clear_stats
96
117
  start = ((Time.now - 1).to_f * 1_000_000).to_i
@@ -101,6 +122,9 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
101
122
  end
102
123
 
103
124
  def test_new_frontend_work_integration
125
+ # make this test deterministic
126
+ Time.stubs(:now => Time.at(10))
127
+
104
128
  engine.clear_stats
105
129
  times = [Time.now - 3, Time.now - 2, Time.now - 1]
106
130
  times.map! {|t| (t.to_f * 1_000_000).to_i }
@@ -240,12 +264,8 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
240
264
  assert_not_nil engine.lookup_stats('Controller/NewRelic::Agent::AgentTestController/internal_traced_action')
241
265
  end
242
266
  def test_action_instrumentation
243
- begin
244
- get :index, :foo => 'bar'
245
- assert_match /bar/, @response.body
246
- #rescue ActionController::RoutingError
247
- # you might get here if you don't have the default route installed.
248
- end
267
+ get :index, :foo => 'bar'
268
+ assert_match /bar/, @response.body
249
269
  end
250
270
 
251
271
  def test_controller_params
@@ -263,13 +283,12 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
263
283
  get :index, 'number' => "001-555-1212"
264
284
  s = agent.transaction_sampler.harvest(nil, 0.0)
265
285
  assert_equal 1, s.size
266
- assert_equal 5, s.first.params.size
286
+ assert_equal 6, s.first.params.size
267
287
  end
268
288
 
269
289
 
270
290
  def test_busycalculation
271
291
  engine.clear_stats
272
-
273
292
  assert_equal 0, NewRelic::Agent::BusyCalculator.busy_count
274
293
  get :index, 'social_security_number' => "001-555-1212", 'wait' => '0.05'
275
294
  NewRelic::Agent::BusyCalculator.harvest_busy
@@ -281,16 +300,6 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
281
300
  assert_equal 0, stats('WebFrontend/Mongrel/Average Queue Time').call_count
282
301
  end
283
302
 
284
- def test_histogram
285
- engine.clear_stats
286
- get :index, 'social_security_number' => "001-555-1212"
287
- stats_engine = NewRelic::Agent.instance.stats_engine
288
- bucket = NewRelic::Agent.instance.stats_engine.metrics.find { | m | m =~ /^Response Times/ }
289
- assert_not_nil bucket, "Bucket contents: #{bucket.inspect}, #{stats_engine.metrics.inspect}"
290
- bucket_stats = stats(bucket)
291
- assert_equal 1, bucket_stats.call_count, "expected the bucket to have a call, but instead got: #{bucket_stats.inspect}"
292
- end
293
-
294
303
  def test_queue_headers_no_header
295
304
  engine.clear_stats
296
305
  queue_length_stat = stats('Mongrel/Queue Length')
@@ -302,6 +311,9 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
302
311
  end
303
312
 
304
313
  def test_queue_headers_apache
314
+ # make this test deterministic
315
+ Time.stubs(:now => Time.at(10))
316
+
305
317
  NewRelic::Agent::AgentTestController.clear_headers
306
318
  engine.clear_stats
307
319
  queue_length_stat = stats('Mongrel/Queue Length')
@@ -318,6 +330,8 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
318
330
 
319
331
  end
320
332
  def test_queue_headers_heroku
333
+ # make this test deterministic
334
+ Time.stubs(:now => Time.at(10))
321
335
 
322
336
  engine.clear_stats
323
337
  NewRelic::Agent::AgentTestController.clear_headers
@@ -336,6 +350,8 @@ class NewRelic::Agent::AgentTestControllerTest < ActionController::TestCase
336
350
  end
337
351
 
338
352
  def test_queue_headers_heroku_queue_length
353
+ # make this test deterministic
354
+ Time.stubs(:now => Time.at(10))
339
355
 
340
356
  engine.clear_stats
341
357
  NewRelic::Agent::AgentTestController.clear_headers
@@ -19,7 +19,8 @@ class NewRelic::Agent::BeaconConfigurationTest < Test::Unit::TestCase
19
19
  assert_equal('a browser monitoring key', bc.browser_monitoring_key)
20
20
  assert_equal('an application id', bc.application_id)
21
21
  assert_equal('a beacon', bc.beacon)
22
- assert_equal(109, bc.browser_timing_header.size, "should output the javascript with all the data available")
22
+ s = "<script type=\"text/javascript\">var NREUMQ=NREUMQ||[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>"
23
+ assert_equal(s, bc.browser_timing_header)
23
24
  end
24
25
 
25
26
  def test_license_bytes_nil
@@ -81,24 +82,30 @@ class NewRelic::Agent::BeaconConfigurationTest < Test::Unit::TestCase
81
82
  def test_build_load_file_js_load_episodes_file_false
82
83
  connect_data = {'rum.load_episodes_file' => false}
83
84
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
84
- assert_equal '', bc.build_load_file_js(connect_data), "should be empty when load episodes file is false"
85
+ s = "if (!NREUMQ.f) { NREUMQ.f=function() {\nNREUMQ.push([\"load\",new Date().getTime()]);\nif(NREUMQ.a)NREUMQ.a();\n};\nNREUMQ.a=window.onload;window.onload=NREUMQ.f;\n};\n"
86
+ assert_equal(s, bc.build_load_file_js(connect_data))
85
87
  end
86
88
 
87
89
  def test_build_load_file_js_load_episodes_file_missing
88
90
  connect_data = {}
89
91
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
90
- assert_equal(184, bc.build_load_file_js(connect_data).size, "should output the javascript when there is no configuration")
92
+ s = "if (!NREUMQ.f) { NREUMQ.f=function() {\nNREUMQ.push([\"load\",new Date().getTime()]);\nvar e=document.createElement(\"script\");\ne.type=\"text/javascript\";e.async=true;e.src=\"\";\ndocument.body.appendChild(e);\nif(NREUMQ.a)NREUMQ.a();\n};\nNREUMQ.a=window.onload;window.onload=NREUMQ.f;\n};\n"
93
+
94
+ assert_equal(s, bc.build_load_file_js(connect_data))
91
95
  end
92
96
 
93
97
  def test_build_load_file_js_load_episodes_file_present
94
98
  connect_data = {'rum.load_episodes_file' => true}
95
99
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
96
- assert_equal(184, bc.build_load_file_js(connect_data).size, "should output the javascript when rum.load_episodes_file is true")
100
+ s = "if (!NREUMQ.f) { NREUMQ.f=function() {\nNREUMQ.push([\"load\",new Date().getTime()]);\nvar e=document.createElement(\"script\");\ne.type=\"text/javascript\";e.async=true;e.src=\"\";\ndocument.body.appendChild(e);\nif(NREUMQ.a)NREUMQ.a();\n};\nNREUMQ.a=window.onload;window.onload=NREUMQ.f;\n};\n"
101
+
102
+ assert_equal(s, bc.build_load_file_js(connect_data))
97
103
  end
98
104
 
99
105
  def test_build_load_file_js_load_episodes_file_with_episodes_url
100
106
  connect_data = {'episodes_url' => 'an episodes url'}
101
107
  bc = NewRelic::Agent::BeaconConfiguration.new(connect_data)
102
- assert(bc.build_load_file_js(connect_data).include?('an episodes url'), "should include the episodes url by default")
108
+ assert(bc.build_load_file_js(connect_data).include?('an episodes url'),
109
+ "should include the episodes url by default")
103
110
  end
104
111
  end
@@ -4,22 +4,41 @@ require "new_relic/agent/browser_monitoring"
4
4
 
5
5
  class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
6
6
  include NewRelic::Agent::BrowserMonitoring
7
-
7
+ include NewRelic::Agent::Instrumentation::ControllerInstrumentation
8
+
8
9
  def setup
9
10
  NewRelic::Agent.manual_start
10
11
  @browser_monitoring_key = "fred"
11
12
  @episodes_file = "this_is_my_file"
12
13
  NewRelic::Agent.instance.instance_eval do
13
- @beacon_configuration = NewRelic::Agent::BeaconConfiguration.new({"rum.enabled" => true, "browser_key" => "browserKey", "application_id" => "apId", "beacon"=>"beacon", "episodes_url"=>"this_is_my_file"})
14
+ @beacon_configuration = NewRelic::Agent::BeaconConfiguration.new({"rum.enabled" => true, "browser_key" => "browserKey", "application_id" => "apId", "beacon"=>"beacon", "episodes_url"=>"this_is_my_file", 'rum.jsonp' => true})
14
15
  end
15
- Thread.current[:newrelic_most_recent_transaction] = "MyCoolTransaction"
16
+ Thread.current[:last_metric_frame] = nil
17
+ NewRelic::Agent::TransactionInfo.clear
16
18
  end
17
19
 
18
20
  def teardown
19
21
  mocha_teardown
20
- Thread.current[:newrelic_start_time] = nil
21
- Thread.current[:newrelic_metric_frame] = nil
22
- Thread.current[:newrelic_most_recent_transaction] = nil
22
+ end
23
+
24
+ def test_browser_monitoring_start_time_is_reset_each_request_when_auto_instrument_is_disabled
25
+ controller = Object.new
26
+ def controller.perform_action_without_newrelic_trace(method, options={});
27
+ # noop; instrument me
28
+ end
29
+ def controller.newrelic_metric_path; "foo"; end
30
+ controller.extend ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
31
+ controller.extend ::NewRelic::Agent::BrowserMonitoring
32
+ NewRelic::Control.instance['browser_monitoring'] = { 'auto_instrument' => false }
33
+
34
+ controller.perform_action_with_newrelic_trace(:index)
35
+ first_request_start_time = controller.send(:browser_monitoring_start_time)
36
+ controller.perform_action_with_newrelic_trace(:index)
37
+ second_request_start_time = controller.send(:browser_monitoring_start_time)
38
+
39
+ # assert that these aren't the same time object
40
+ # the start time should be reinitialized each request to the controller
41
+ assert !(first_request_start_time.equal? second_request_start_time)
23
42
  end
24
43
 
25
44
  def test_browser_timing_header_with_no_beacon_configuration
@@ -30,13 +49,13 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
30
49
 
31
50
  def test_browser_timing_header
32
51
  header = browser_timing_header
33
- assert_equal "<script type=\"text/javascript\">var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>", header
52
+ assert_equal "<script type=\"text/javascript\">var NREUMQ=NREUMQ||[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>", header
34
53
  end
35
54
 
36
55
  def test_browser_timing_header_with_rum_enabled_not_specified
37
56
  NewRelic::Agent.instance.expects(:beacon_configuration).at_least_once.returns( NewRelic::Agent::BeaconConfiguration.new({"browser_key" => "browserKey", "application_id" => "apId", "beacon"=>"beacon", "episodes_url"=>"this_is_my_file"}))
38
57
  header = browser_timing_header
39
- assert_equal "<script type=\"text/javascript\">var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>", header
58
+ assert_equal "<script type=\"text/javascript\">var NREUMQ=NREUMQ||[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>", header
40
59
  end
41
60
 
42
61
  def test_browser_timing_header_with_rum_enabled_false
@@ -65,18 +84,13 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
65
84
  browser_timing_header
66
85
  NewRelic::Control.instance.expects(:license_key).returns("a" * 13)
67
86
 
68
- Thread.current[:newrelic_start_time] = Time.now
69
-
70
87
  footer = browser_timing_footer
71
- snippet = "<script type=\"text/javascript\">(function(){var d=document;var e=d.createElement(\"script\");e.async=true;e.src=\"this_is_my_file\";e.type=\"text/javascript\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})();NREUMQ.push([\"nrf2\","
88
+ snippet = '<script type="text/javascript">if (!NREUMQ.f) { NREUMQ.f=function() {
89
+ NREUMQ.push(["load",new Date().getTime()]);
90
+ var e=document.createElement("script");'
72
91
  assert footer.include?(snippet), "Expected footer to include snippet: #{snippet}, but instead was #{footer}"
73
92
  end
74
93
 
75
- def test_browser_timing_footer_without_calling_header
76
- footer = browser_timing_footer
77
- assert_equal "", footer
78
- end
79
-
80
94
  def test_browser_timing_footer_with_no_browser_key_rum_enabled
81
95
  browser_timing_header
82
96
  NewRelic::Agent.instance.expects(:beacon_configuration).returns( NewRelic::Agent::BeaconConfiguration.new({"rum.enabled" => true, "application_id" => "apId", "beacon"=>"beacon", "episodes_url"=>"this_is_my_file"}))
@@ -93,15 +107,16 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
93
107
 
94
108
  def test_browser_timing_footer_with_rum_enabled_not_specified
95
109
  browser_timing_header
96
- Thread.current[:newrelic_start_time] = Time.now
97
110
 
98
111
  license_bytes = [];
99
112
  ("a" * 13).each_byte {|byte| license_bytes << byte}
100
113
  config = NewRelic::Agent::BeaconConfiguration.new({"browser_key" => "browserKey", "application_id" => "apId", "beacon"=>"beacon", "episodes_url"=>"this_is_my_file", "license_bytes" => license_bytes})
101
- config.expects(:license_bytes).returns(license_bytes)
114
+ config.expects(:license_bytes).returns(license_bytes).at_least_once
102
115
  NewRelic::Agent.instance.expects(:beacon_configuration).returns(config).at_least_once
103
116
  footer = browser_timing_footer
104
- beginning_snippet = "(function(){var d=document;var e=d.createElement(\"script\");e.async=true;e.src=\"this_is_my_file\";e.type=\"text/javascript\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})();NREUMQ.push([\"nrf2\","
117
+ beginning_snippet = '<script type="text/javascript">if (!NREUMQ.f) { NREUMQ.f=function() {
118
+ NREUMQ.push(["load",new Date().getTime()]);
119
+ var e=document.createElement("script");'
105
120
  ending_snippet = "])</script>"
106
121
  assert(footer.include?(beginning_snippet), "expected footer to include beginning snippet: #{beginning_snippet}, but was #{footer}")
107
122
  assert(footer.include?(ending_snippet), "expected footer to include ending snippet: #{ending_snippet}, but was #{footer}")
@@ -114,14 +129,6 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
114
129
  assert_equal "", footer
115
130
  end
116
131
 
117
- def test_browser_timing_footer_with_no_start_time
118
- browser_timing_header
119
- Thread.current[:newrelic_start_time] = nil
120
- NewRelic::Agent.instance.expects(:beacon_configuration).returns( NewRelic::Agent::BeaconConfiguration.new({"browser_key" => "browserKey", "application_id" => "apId", "beacon"=>"beacon", "episodes_url"=>"this_is_my_file"}))
121
- footer = browser_timing_footer
122
- assert_equal('', footer)
123
- end
124
-
125
132
 
126
133
  def test_browser_timing_footer_disable_all_tracing
127
134
  browser_timing_header
@@ -153,37 +160,62 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
153
160
 
154
161
  def test_generate_footer_js_null_case
155
162
  self.expects(:browser_monitoring_start_time).returns(nil)
156
- assert_equal('', generate_footer_js, "should not send javascript when there is no start time")
163
+ assert_equal('', generate_footer_js(NewRelic::Agent.instance.beacon_configuration), "should not send javascript when there is no start time")
157
164
  end
158
-
165
+
159
166
  def test_generate_footer_js_with_start_time
160
167
  self.expects(:browser_monitoring_start_time).returns(Time.at(100))
161
168
  fake_bc = mock('beacon configuration')
162
169
  fake_bc.expects(:application_id).returns(1)
163
170
  fake_bc.expects(:beacon).returns('beacon')
164
171
  fake_bc.expects(:browser_monitoring_key).returns('a' * 40)
165
- NewRelic::Agent.instance.expects(:beacon_configuration).returns(fake_bc)
166
- self.expects(:footer_js_string).with('beacon', 'a' * 40, 1).returns('footer js')
167
- assert_equal('footer js', generate_footer_js, 'should generate and return the footer JS when there is a start time')
172
+ NewRelic::Agent.instance.stubs(:beacon_configuration).returns(fake_bc)
173
+ self.expects(:footer_js_string).with(NewRelic::Agent.instance.beacon_configuration, 'beacon', 'a' * 40, 1).returns('footer js')
174
+ assert_equal('footer js', generate_footer_js(NewRelic::Agent.instance.beacon_configuration), 'should generate and return the footer JS when there is a start time')
168
175
  end
169
176
 
170
177
  def test_browser_monitoring_transaction_name_basic
171
- Thread.current[:newrelic_most_recent_transaction] = 'a transaction name'
178
+ mock = mock('transaction sample')
179
+ NewRelic::Agent::TransactionInfo.set(mock)
180
+ mock.stubs(:transaction_name).returns('a transaction name')
181
+
172
182
  assert_equal('a transaction name', browser_monitoring_transaction_name, "should take the value from the thread local")
173
183
  end
174
184
 
175
185
  def test_browser_monitoring_transaction_name_empty
176
- Thread.current[:newrelic_most_recent_transaction] = ''
186
+ mock = mock('transaction sample')
187
+ NewRelic::Agent::TransactionInfo.set(mock)
188
+
189
+ mock.stubs(:transaction_name).returns('')
177
190
  assert_equal('', browser_monitoring_transaction_name, "should take the value even when it is empty")
178
191
  end
179
192
 
180
193
  def test_browser_monitoring_transaction_name_nil
181
- Thread.current[:newrelic_most_recent_transaction] = nil
182
- assert_equal('<unknown>', browser_monitoring_transaction_name, "should fill in a default when it is nil")
194
+ assert_equal('(unknown)', browser_monitoring_transaction_name, "should fill in a default when it is nil")
183
195
  end
196
+
197
+ def test_browser_monitoring_transaction_name_when_tt_disabled
198
+ @sampler = NewRelic::Agent.instance.transaction_sampler
199
+ @sampler.disable
184
200
 
201
+ perform_action_with_newrelic_trace(:name => 'disabled_transactions') do
202
+ self.class.inspect
203
+ end
204
+
205
+ assert_match(/disabled_transactions/, browser_monitoring_transaction_name,
206
+ "should name transaction when transaction tracing disabled")
207
+ ensure
208
+ @sampler.enable
209
+ end
210
+
211
+
185
212
  def test_browser_monitoring_start_time
186
- Thread.current[:newrelic_start_time] = Time.at(100)
213
+ mock = mock('transaction info')
214
+
215
+ NewRelic::Agent::TransactionInfo.set(mock)
216
+
217
+ mock.stubs(:start_time).returns(Time.at(100))
218
+ mock.stubs(:guid).returns('ABC')
187
219
  assert_equal(Time.at(100), browser_monitoring_start_time, "should take the value from the thread local")
188
220
  end
189
221
 
@@ -201,22 +233,24 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
201
233
  end
202
234
 
203
235
  def test_browser_monitoring_queue_time_nil
204
- Thread.current[:newrelic_queue_time] = nil
205
236
  assert_equal(0.0, browser_monitoring_queue_time, 'should return zero when there is no queue time')
206
237
  end
207
238
 
208
239
  def test_browser_monitoring_queue_time_zero
209
- Thread.current[:newrelic_queue_time] = 0.0
240
+ frame = Thread.current[:last_metric_frame] = mock('metric frame')
241
+ frame.expects(:queue_time).returns(0.0)
210
242
  assert_equal(0.0, browser_monitoring_queue_time, 'should return zero when there is zero queue time')
211
243
  end
212
244
 
213
245
  def test_browser_monitoring_queue_time_ducks
214
- Thread.current[:newrelic_queue_time] = 'a duck'
246
+ frame = Thread.current[:last_metric_frame] = mock('metric frame')
247
+ frame.expects(:queue_time).returns('a duck')
215
248
  assert_equal(0.0, browser_monitoring_queue_time, 'should return zero when there is an incorrect queue time')
216
249
  end
217
250
 
218
251
  def test_browser_monitoring_queue_time_nonzero
219
- Thread.current[:newrelic_queue_time] = 3.00002
252
+ frame = Thread.current[:last_metric_frame] = mock('metric frame')
253
+ frame.expects(:queue_time).returns(3.00002)
220
254
  assert_equal(3000, browser_monitoring_queue_time, 'should return a rounded time')
221
255
  end
222
256
 
@@ -225,16 +259,31 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
225
259
  license_key = ''
226
260
  application_id = 1
227
261
 
228
- Thread.current[:newrelic_queue_time] = nil
229
262
  # mocking this because JRuby thinks that Time.now - Time.now
230
263
  # always takes at least 1ms
231
264
  self.expects(:browser_monitoring_app_time).returns(0)
232
- Thread.current[:newrelic_most_recent_transaction] = 'most recent transaction'
233
-
234
- self.expects(:obfuscate).with('most recent transaction').returns('most recent transaction')
235
-
236
- value = footer_js_string(beacon, license_key, application_id)
237
- assert_equal('<script type="text/javascript">(function(){var d=document;var e=d.createElement("script");e.async=true;e.src="this_is_my_file";e.type="text/javascript";var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(e,s);})();NREUMQ.push(["nrf2","","",1,"most recent transaction",0,0,new Date().getTime()])</script>', value, "should return the javascript given some default values")
265
+ frame = Thread.current[:last_metric_frame] = mock('metric frame')
266
+ user_attributes = {:user => "user", :account => "account", :product => "product"}
267
+ frame.expects(:user_attributes).returns(user_attributes).at_least_once
268
+ frame.expects(:queue_time).returns(0)
269
+
270
+ sample = mock('transaction info')
271
+ NewRelic::Agent::TransactionInfo.set(sample)
272
+
273
+ sample.stubs(:start_time).returns(Time.at(100))
274
+ sample.stubs(:guid).returns('ABC')
275
+ sample.stubs(:transaction_name).returns('most recent transaction')
276
+ sample.stubs(:include_guid?).returns(true)
277
+ sample.stubs(:duration).returns(12.0)
278
+ sample.stubs(:token).returns('0123456789ABCDEF')
279
+
280
+ self.expects(:obfuscate).with(NewRelic::Agent.instance.beacon_configuration, 'most recent transaction').returns('most recent transaction')
281
+ self.expects(:obfuscate).with(NewRelic::Agent.instance.beacon_configuration, 'user').returns('user')
282
+ self.expects(:obfuscate).with(NewRelic::Agent.instance.beacon_configuration, 'account').returns('account')
283
+ self.expects(:obfuscate).with(NewRelic::Agent.instance.beacon_configuration, 'product').returns('product')
284
+
285
+ value = footer_js_string(NewRelic::Agent.instance.beacon_configuration, beacon, license_key, application_id)
286
+ assert_equal("<script type=\"text/javascript\">if (!NREUMQ.f) { NREUMQ.f=function() {\nNREUMQ.push([\"load\",new Date().getTime()]);\nvar e=document.createElement(\"script\");\ne.type=\"text/javascript\";e.async=true;e.src=\"this_is_my_file\";\ndocument.body.appendChild(e);\nif(NREUMQ.a)NREUMQ.a();\n};\nNREUMQ.a=window.onload;window.onload=NREUMQ.f;\n};\nNREUMQ.push([\"nrfj\",\"\",\"\",1,\"most recent transaction\",0,0,new Date().getTime(),\"ABC\",\"0123456789ABCDEF\",\"user\",\"account\",\"product\"])</script>", value, "should return the javascript given some default values")
238
287
  end
239
288
 
240
289
  def test_html_safe_if_needed_unsafed
@@ -260,7 +309,7 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
260
309
  text = 'a happy piece of small text'
261
310
  key = (1..40).to_a
262
311
  NewRelic::Agent.instance.beacon_configuration.expects(:license_bytes).returns(key)
263
- output = obfuscate(text)
312
+ output = obfuscate(NewRelic::Agent.instance.beacon_configuration, text)
264
313
  assert_equal('YCJrZXV2fih5Y25vaCFtZSR2a2ZkZSp/aXV1', output, "should output obfuscated text")
265
314
  end
266
315
 
@@ -268,7 +317,7 @@ class NewRelic::Agent::BrowserMonitoringTest < Test::Unit::TestCase
268
317
  text = 'a happy piece of small text' * 5
269
318
  key = (1..40).to_a
270
319
  NewRelic::Agent.instance.beacon_configuration.expects(:license_bytes).returns(key)
271
- output = obfuscate(text)
320
+ output = obfuscate(NewRelic::Agent.instance.beacon_configuration, text)
272
321
  assert_equal('YCJrZXV2fih5Y25vaCFtZSR2a2ZkZSp/aXV1YyNsZHZ3cSl6YmluZCJsYiV1amllZit4aHl2YiRtZ3d4cCp7ZWhiZyNrYyZ0ZWhmZyx5ZHp3ZSVuZnh5cyt8ZGRhZiRqYCd7ZGtnYC11Z3twZCZvaXl6cix9aGdgYSVpYSh6Z2pgYSF2Znxx', output, "should output obfuscated text")
273
322
  end
274
323
  end