genki-newrelic_rpm 2.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/CHANGELOG +316 -0
  2. data/LICENSE +37 -0
  3. data/Manifest +156 -0
  4. data/README.md +138 -0
  5. data/Rakefile +22 -0
  6. data/bin/mongrel_rpm +33 -0
  7. data/bin/newrelic_cmd +4 -0
  8. data/cert/cacert.pem +34 -0
  9. data/genki-newrelic_rpm.gemspec +32 -0
  10. data/init.rb +38 -0
  11. data/install.rb +37 -0
  12. data/lib/new_relic/agent.rb +280 -0
  13. data/lib/new_relic/agent/agent.rb +627 -0
  14. data/lib/new_relic/agent/chained_call.rb +13 -0
  15. data/lib/new_relic/agent/collection_helper.rb +61 -0
  16. data/lib/new_relic/agent/error_collector.rb +125 -0
  17. data/lib/new_relic/agent/instrumentation/active_merchant.rb +18 -0
  18. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +83 -0
  19. data/lib/new_relic/agent/instrumentation/authlogic.rb +8 -0
  20. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +368 -0
  21. data/lib/new_relic/agent/instrumentation/data_mapper.rb +90 -0
  22. data/lib/new_relic/agent/instrumentation/dispatcher_instrumentation.rb +132 -0
  23. data/lib/new_relic/agent/instrumentation/memcache.rb +21 -0
  24. data/lib/new_relic/agent/instrumentation/merb/controller.rb +26 -0
  25. data/lib/new_relic/agent/instrumentation/merb/dispatcher.rb +13 -0
  26. data/lib/new_relic/agent/instrumentation/merb/errors.rb +8 -0
  27. data/lib/new_relic/agent/instrumentation/net.rb +12 -0
  28. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +20 -0
  29. data/lib/new_relic/agent/instrumentation/rack.rb +77 -0
  30. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +59 -0
  31. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +27 -0
  32. data/lib/new_relic/agent/instrumentation/rails/dispatcher.rb +38 -0
  33. data/lib/new_relic/agent/instrumentation/rails/errors.rb +27 -0
  34. data/lib/new_relic/agent/instrumentation/sinatra.rb +39 -0
  35. data/lib/new_relic/agent/method_tracer.rb +277 -0
  36. data/lib/new_relic/agent/patch_const_missing.rb +125 -0
  37. data/lib/new_relic/agent/sampler.rb +12 -0
  38. data/lib/new_relic/agent/samplers/cpu_sampler.rb +49 -0
  39. data/lib/new_relic/agent/samplers/memory_sampler.rb +137 -0
  40. data/lib/new_relic/agent/samplers/mongrel_sampler.rb +22 -0
  41. data/lib/new_relic/agent/shim_agent.rb +21 -0
  42. data/lib/new_relic/agent/stats_engine.rb +24 -0
  43. data/lib/new_relic/agent/stats_engine/metric_stats.rb +111 -0
  44. data/lib/new_relic/agent/stats_engine/samplers.rb +71 -0
  45. data/lib/new_relic/agent/stats_engine/transactions.rb +155 -0
  46. data/lib/new_relic/agent/transaction_sampler.rb +319 -0
  47. data/lib/new_relic/agent/worker_loop.rb +118 -0
  48. data/lib/new_relic/commands/deployments.rb +145 -0
  49. data/lib/new_relic/commands/new_relic_commands.rb +30 -0
  50. data/lib/new_relic/control.rb +436 -0
  51. data/lib/new_relic/control/external.rb +13 -0
  52. data/lib/new_relic/control/merb.rb +22 -0
  53. data/lib/new_relic/control/rails.rb +143 -0
  54. data/lib/new_relic/control/ruby.rb +34 -0
  55. data/lib/new_relic/control/sinatra.rb +14 -0
  56. data/lib/new_relic/histogram.rb +89 -0
  57. data/lib/new_relic/local_environment.rb +285 -0
  58. data/lib/new_relic/merbtasks.rb +6 -0
  59. data/lib/new_relic/metric_data.rb +44 -0
  60. data/lib/new_relic/metric_parser.rb +120 -0
  61. data/lib/new_relic/metric_parser/action_mailer.rb +9 -0
  62. data/lib/new_relic/metric_parser/active_merchant.rb +26 -0
  63. data/lib/new_relic/metric_parser/active_record.rb +25 -0
  64. data/lib/new_relic/metric_parser/controller.rb +54 -0
  65. data/lib/new_relic/metric_parser/controller_cpu.rb +38 -0
  66. data/lib/new_relic/metric_parser/errors.rb +6 -0
  67. data/lib/new_relic/metric_parser/external.rb +50 -0
  68. data/lib/new_relic/metric_parser/mem_cache.rb +12 -0
  69. data/lib/new_relic/metric_parser/view.rb +61 -0
  70. data/lib/new_relic/metric_parser/web_frontend.rb +14 -0
  71. data/lib/new_relic/metric_parser/web_service.rb +9 -0
  72. data/lib/new_relic/metric_spec.rb +52 -0
  73. data/lib/new_relic/metrics.rb +7 -0
  74. data/lib/new_relic/noticed_error.rb +25 -0
  75. data/lib/new_relic/rack/metric_app.rb +56 -0
  76. data/lib/new_relic/rack/newrelic.ru +25 -0
  77. data/lib/new_relic/rack/newrelic.yml +25 -0
  78. data/lib/new_relic/rack_app.rb +5 -0
  79. data/lib/new_relic/recipes.rb +82 -0
  80. data/lib/new_relic/stats.rb +360 -0
  81. data/lib/new_relic/transaction_analysis.rb +121 -0
  82. data/lib/new_relic/transaction_sample.rb +583 -0
  83. data/lib/new_relic/version.rb +54 -0
  84. data/lib/new_relic_api.rb +315 -0
  85. data/lib/newrelic_rpm.rb +40 -0
  86. data/lib/tasks/all.rb +4 -0
  87. data/lib/tasks/install.rake +7 -0
  88. data/lib/tasks/tests.rake +13 -0
  89. data/newrelic.yml +214 -0
  90. data/recipes/newrelic.rb +6 -0
  91. data/test/active_record_fixtures.rb +55 -0
  92. data/test/config/newrelic.yml +46 -0
  93. data/test/config/test_control.rb +39 -0
  94. data/test/new_relic/agent/active_record_instrumentation_test.rb +234 -0
  95. data/test/new_relic/agent/agent_controller_test.rb +107 -0
  96. data/test/new_relic/agent/agent_test.rb +117 -0
  97. data/test/new_relic/agent/agent_test_controller.rb +44 -0
  98. data/test/new_relic/agent/classloader_patch_test.rb +56 -0
  99. data/test/new_relic/agent/collection_helper_test.rb +118 -0
  100. data/test/new_relic/agent/dispatcher_instrumentation_test.rb +76 -0
  101. data/test/new_relic/agent/error_collector_test.rb +155 -0
  102. data/test/new_relic/agent/method_tracer_test.rb +335 -0
  103. data/test/new_relic/agent/metric_data_test.rb +56 -0
  104. data/test/new_relic/agent/mock_ar_connection.rb +40 -0
  105. data/test/new_relic/agent/mock_scope_listener.rb +23 -0
  106. data/test/new_relic/agent/net_instrumentation_test.rb +51 -0
  107. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +79 -0
  108. data/test/new_relic/agent/stats_engine/samplers_test.rb +78 -0
  109. data/test/new_relic/agent/stats_engine/stats_engine_test.rb +177 -0
  110. data/test/new_relic/agent/task_instrumentation_test.rb +67 -0
  111. data/test/new_relic/agent/testable_agent.rb +13 -0
  112. data/test/new_relic/agent/transaction_sample_builder_test.rb +195 -0
  113. data/test/new_relic/agent/transaction_sample_test.rb +146 -0
  114. data/test/new_relic/agent/transaction_sampler_test.rb +387 -0
  115. data/test/new_relic/agent/worker_loop_test.rb +103 -0
  116. data/test/new_relic/control_test.rb +94 -0
  117. data/test/new_relic/deployments_api_test.rb +68 -0
  118. data/test/new_relic/environment_test.rb +75 -0
  119. data/test/new_relic/metric_parser_test.rb +172 -0
  120. data/test/new_relic/metric_spec_test.rb +177 -0
  121. data/test/new_relic/shim_agent_test.rb +9 -0
  122. data/test/new_relic/stats_test.rb +291 -0
  123. data/test/new_relic/version_number_test.rb +74 -0
  124. data/test/test_helper.rb +38 -0
  125. data/test/ui/newrelic_controller_test.rb +14 -0
  126. data/test/ui/newrelic_helper_test.rb +53 -0
  127. data/ui/controllers/newrelic_controller.rb +214 -0
  128. data/ui/helpers/google_pie_chart.rb +55 -0
  129. data/ui/helpers/newrelic_helper.rb +314 -0
  130. data/ui/views/layouts/newrelic_default.rhtml +47 -0
  131. data/ui/views/newrelic/_explain_plans.rhtml +27 -0
  132. data/ui/views/newrelic/_sample.rhtml +15 -0
  133. data/ui/views/newrelic/_segment.rhtml +28 -0
  134. data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
  135. data/ui/views/newrelic/_segment_row.rhtml +14 -0
  136. data/ui/views/newrelic/_show_sample_detail.rhtml +24 -0
  137. data/ui/views/newrelic/_show_sample_sql.rhtml +20 -0
  138. data/ui/views/newrelic/_show_sample_summary.rhtml +3 -0
  139. data/ui/views/newrelic/_sql_row.rhtml +11 -0
  140. data/ui/views/newrelic/_stack_trace.rhtml +30 -0
  141. data/ui/views/newrelic/_table.rhtml +12 -0
  142. data/ui/views/newrelic/explain_sql.rhtml +42 -0
  143. data/ui/views/newrelic/images/arrow-close.png +0 -0
  144. data/ui/views/newrelic/images/arrow-open.png +0 -0
  145. data/ui/views/newrelic/images/blue_bar.gif +0 -0
  146. data/ui/views/newrelic/images/file_icon.png +0 -0
  147. data/ui/views/newrelic/images/gray_bar.gif +0 -0
  148. data/ui/views/newrelic/images/new_relic_rpm_desktop.gif +0 -0
  149. data/ui/views/newrelic/images/textmate.png +0 -0
  150. data/ui/views/newrelic/index.rhtml +45 -0
  151. data/ui/views/newrelic/javascript/prototype-scriptaculous.js +7288 -0
  152. data/ui/views/newrelic/javascript/transaction_sample.js +107 -0
  153. data/ui/views/newrelic/sample_not_found.rhtml +2 -0
  154. data/ui/views/newrelic/show_sample.rhtml +77 -0
  155. data/ui/views/newrelic/show_source.rhtml +3 -0
  156. data/ui/views/newrelic/stylesheets/style.css +433 -0
  157. data/ui/views/newrelic/threads.rhtml +52 -0
  158. metadata +327 -0
@@ -0,0 +1,117 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+ ##require 'new_relic/agent/agent'
3
+ ##require 'new_relic/local_environment'
4
+
5
+ class AgentTest < ActiveSupport::TestCase
6
+
7
+ attr_reader :agent
8
+
9
+ # Fake out the agent to think mongrel is running
10
+ def setup
11
+ NewRelic::Agent.manual_start
12
+ @agent = NewRelic::Agent.instance
13
+ end
14
+ def teardown
15
+ NewRelic::Control.instance['app_name']=nil
16
+ NewRelic::Control.instance['dispatcher']=nil
17
+ NewRelic::Control.instance['dispatcher_instance_id']=nil
18
+ end
19
+ def test_agent_setup
20
+ assert NewRelic::Agent.instance.class == NewRelic::Agent::Agent
21
+ assert_raise RuntimeError do
22
+ NewRelic::Control.instance.init_plugin :agent_enabled => false
23
+ end
24
+ end
25
+
26
+ def test_public_apis
27
+ assert_raise RuntimeError do
28
+ NewRelic::Agent.set_sql_obfuscator(:unknown) do |sql|
29
+ puts sql
30
+ end
31
+ end
32
+
33
+ ignore_called = false
34
+ NewRelic::Agent.ignore_error_filter do |e|
35
+ ignore_called = true
36
+ nil
37
+ end
38
+ NewRelic::Agent.notice_error(ActionController::RoutingError.new("message"), :x => "y")
39
+ assert ignore_called
40
+ end
41
+
42
+ def test_startup_shutdown
43
+ @agent = NewRelic::Agent::ShimAgent.instance
44
+ @agent.shutdown
45
+ assert (not @agent.started?)
46
+ @agent.start
47
+ assert !@agent.started?
48
+ # this installs the real agent:
49
+ NewRelic::Agent.manual_start
50
+ @agent = NewRelic::Agent.instance
51
+ assert @agent != NewRelic::Agent::ShimAgent.instance
52
+ assert @agent.started?
53
+ @agent.shutdown
54
+ assert !@agent.started?
55
+ @agent.start
56
+ assert @agent.started?
57
+ end
58
+
59
+ def test_manual_overrides
60
+ NewRelic::Agent.manual_start :app_name => "testjobs", :dispatcher_instance_id => "mailer"
61
+ assert_equal "testjobs", NewRelic::Control.instance.app_names[0]
62
+ assert_equal "mailer", NewRelic::Control.instance.dispatcher_instance_id
63
+ end
64
+ def test_restart
65
+ NewRelic::Agent.manual_start :app_name => "noapp", :dispatcher_instance_id => ""
66
+ NewRelic::Agent.manual_start :app_name => "testjobs", :dispatcher_instance_id => "mailer"
67
+ assert_equal "testjobs", NewRelic::Control.instance.app_names[0]
68
+ assert_equal "mailer", NewRelic::Control.instance.dispatcher_instance_id
69
+ end
70
+
71
+ def test_set_record_sql
72
+ @agent.set_record_sql(false)
73
+ assert !Thread::current[:record_sql]
74
+ NewRelic::Agent.disable_sql_recording do
75
+ assert_equal false, Thread::current[:record_sql]
76
+ NewRelic::Agent.disable_sql_recording do
77
+ assert_equal false, Thread::current[:record_sql]
78
+ end
79
+ assert_equal false, Thread::current[:record_sql]
80
+ end
81
+ assert !Thread::current[:record_sql], Thread::current[:record_sql]
82
+ ensure
83
+ @agent.set_record_sql(nil)
84
+ end
85
+
86
+ def test_version
87
+ assert_match /\d\.\d+\.\d+/, NewRelic::VERSION::STRING
88
+ end
89
+
90
+ def test_invoke_remote__ignore_non_200_results
91
+ NewRelic::Agent::Agent.class_eval do
92
+ public :invoke_remote
93
+ end
94
+ response_mock = mock()
95
+ Net::HTTP.any_instance.stubs(:request).returns(response_mock)
96
+ response_mock.stubs(:message).returns("bogus error")
97
+
98
+ for code in %w[500 504 400 302 503] do
99
+ assert_raise NewRelic::Agent::IgnoreSilentlyException, "Ignore #{code}" do
100
+ response_mock.stubs(:code).returns(code)
101
+ NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0
102
+ end
103
+ end
104
+ end
105
+ def test_invoke_remote__throw_other_errors
106
+ NewRelic::Agent::Agent.class_eval do
107
+ public :invoke_remote
108
+ end
109
+ response_mock = Net::HTTPSuccess.new nil, nil, nil
110
+ response_mock.stubs(:body).returns("")
111
+ Marshal.stubs(:load).raises(RuntimeError, "marshal issue")
112
+ Net::HTTP.any_instance.stubs(:request).returns(response_mock)
113
+ assert_raise RuntimeError do
114
+ NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0xFEFE
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,44 @@
1
+ # Defining a test controller class with a superclass, used to
2
+ # verify correct attribute inheritence
3
+ class NewRelic::Agent::SuperclassController < ActionController::Base
4
+ def base_action
5
+ render :text => 'none'
6
+ end
7
+ end
8
+ # This is a controller class used in testing controller instrumentation
9
+ class NewRelic::Agent::AgentTestController < NewRelic::Agent::SuperclassController
10
+ filter_parameter_logging :social_security_number
11
+
12
+ def rescue_action(e) raise e end
13
+
14
+ ActionController::Routing::Routes.draw do | map |
15
+ map.connect ':controller/:action.:format'
16
+ end
17
+
18
+ def index
19
+ render :text => params.inspect
20
+ end
21
+ def _filter_parameters(params)
22
+ filter_parameters params
23
+ end
24
+ def action_to_render
25
+ render :text => params.inspect
26
+ end
27
+ def action_to_ignore
28
+ render :text => 'unmeasured'
29
+ end
30
+ def action_to_ignore_apdex
31
+ render :text => 'unmeasured'
32
+ end
33
+ def entry_action
34
+ perform_action_with_newrelic_trace('internal_action') do
35
+ internal_action
36
+ end
37
+ end
38
+ private
39
+ def internal_action
40
+ perform_action_with_newrelic_trace(:name => 'internal_traced_action', :force => true) do
41
+ render :text => 'internal action'
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+
3
+ class ClassLoaderPatchTest < ActiveSupport::TestCase
4
+
5
+ def test_const_undefined
6
+ require 'new_relic/agent/patch_const_missing'
7
+ ClassLoadingWatcher.background_thread = Thread.current
8
+
9
+ # try loading some non-existent class
10
+ NewRelic::Control.instance.log.expects(:error).at_least_once.with{|args| args =~ /Agent background thread.*:FooBar/}
11
+ NewRelic::Control.instance.log.expects(:error).with{|args| args =~ /Agent background thread.*:FooBaz/}.never
12
+
13
+ ClassLoadingWatcher.enable_warning
14
+ assert_raise NameError do
15
+ FooBar::Bat
16
+ end
17
+
18
+ ClassLoadingWatcher.disable_warning
19
+ assert_raise NameError do
20
+ FooBaz::Bat
21
+ end
22
+ end
23
+
24
+ def test_require
25
+ require 'new_relic/agent/patch_const_missing'
26
+ ClassLoadingWatcher.background_thread = Thread.current
27
+
28
+ # try loading some non-existent class
29
+ NewRelic::Control.instance.log.expects(:error).at_least_once.with{|args| args =~ /Agent background thread.*rational/}
30
+ NewRelic::Control.instance.log.expects(:error).with{|args| args =~ /Agent background thread.*pstore/}.never
31
+
32
+ ClassLoadingWatcher.enable_warning
33
+ require('rational') # standard library probably not loaded yet
34
+
35
+ ClassLoadingWatcher.disable_warning
36
+
37
+ require 'pstore' # standard library probably not loaded yet
38
+ end
39
+
40
+ def test_load
41
+ require 'new_relic/agent/patch_const_missing'
42
+ ClassLoadingWatcher.background_thread = Thread.current
43
+
44
+ # try loading some non-existent class
45
+ NewRelic::Control.instance.log.expects(:error).with{|args| args =~ /Agent background thread.*tsort/}.at_least_once
46
+ NewRelic::Control.instance.log.expects(:error).with{|args| args =~ /Agent background thread.*getoptlong/}.never
47
+
48
+ ClassLoadingWatcher.enable_warning
49
+
50
+ load 'tsort.rb' # standard library probably not loaded yet
51
+
52
+ ClassLoadingWatcher.disable_warning
53
+
54
+ load 'getoptlong.rb' # standard library probably not loaded yet
55
+ end
56
+ end
@@ -0,0 +1,118 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+ require 'ostruct'
3
+ require 'active_record_fixtures'
4
+ class NewRelic::Agent::CollectionHelperTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ super
8
+ NewRelic::Agent.manual_start
9
+ end
10
+ def teardown
11
+ super
12
+ end
13
+
14
+ include NewRelic::Agent::CollectionHelper
15
+ def test_string
16
+ val = ('A'..'Z').to_a.join * 100
17
+ assert_equal val.first(256) + "...", normalize_params(val)
18
+ end
19
+ def test_array
20
+ new_array = normalize_params [ 1000 ] * 50
21
+ assert_equal 20, new_array.size
22
+ assert_equal '1000', new_array[0]
23
+ end
24
+ def test_boolean
25
+ np = normalize_params(NewRelic::Control.instance.settings)
26
+ assert_equal false, np['enabled']
27
+ end
28
+ class MyString < String; end
29
+ def test_kind_of_string
30
+ s = MyString.new "This is a string"
31
+ assert_equal "This is a string", s.to_s
32
+ assert_equal MyString, s.class
33
+ assert_equal String, s.to_s.class
34
+ params = normalize_params(:val => [s])
35
+ assert_equal String, params[:val][0].class
36
+ assert_equal String, flatten(s).class
37
+ assert_equal String, truncate(s, 2).class
38
+ end
39
+ def test_number
40
+ np = normalize_params({ 'one' => 1.0, 'two' => '2'})
41
+ end
42
+ def test_nil
43
+ np = normalize_params({ nil => 1.0, 'two' => nil})
44
+ assert_equal "1.0", np['']
45
+ assert_equal nil, np['two']
46
+ end
47
+ def test_hash
48
+ val = ('A'..'Z').to_a.join * 100
49
+ assert_equal Hash["ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF..." => (("0"*256) + "...")], normalize_params({ val => '0' * 512 })
50
+ end
51
+ class MyHash < Hash
52
+
53
+ end
54
+ # Test to ensure that hash subclasses are properly converted
55
+ def test_hash_subclass
56
+ h = MyHash.new
57
+ h[:mine] = 'mine'
58
+ custom_params = { :one => {:hash => { :a => :b}, :myhash => h }}
59
+ nh = normalize_params(custom_params)
60
+ myhash = custom_params[:one][:myhash]
61
+ assert_equal MyHash, myhash.class
62
+ myhash = nh[:one][:myhash]
63
+ assert_equal Hash, myhash.class
64
+ end
65
+
66
+ class MyEnumerable
67
+ include Enumerable
68
+
69
+ def each
70
+ yield "1"
71
+ end
72
+ end
73
+
74
+ def test_enumerable
75
+ e = MyEnumerable.new
76
+ custom_params = { :one => {:hash => { :a => :b}, :myenum => e }}
77
+ nh = normalize_params(custom_params)
78
+ myenum = nh[:one][:myenum]
79
+ assert_match /MyEnumerable/, myenum
80
+ end
81
+
82
+ def test_stringio
83
+ # Verify StringIO works like this normally:
84
+ s = StringIO.new "start" + ("foo bar bat " * 1000)
85
+ val = nil
86
+ s.each { | entry | val = entry; break }
87
+ assert_match /^startfoo bar/, val
88
+
89
+ # make sure stringios aren't affected by calling normalize_params:
90
+ s = StringIO.new "start" + ("foo bar bat " * 1000)
91
+ v = normalize_params({ :foo => s.string })
92
+ s.each { | entry | val = entry; break }
93
+ assert_match /^startfoo bar/, val
94
+ end
95
+
96
+ def test_object
97
+ assert_equal ["foo", '#<OpenStruct>'], normalize_params(['foo', OpenStruct.new('z'=>'q')])
98
+ end
99
+
100
+ def test_strip_backtrace
101
+ begin
102
+ ActiveRecordFixtures.setup
103
+ # ActiveRecordFixtures::Order.add_delay
104
+ ActiveRecordFixtures::Order.find 0
105
+ flunk "should throw"
106
+ rescue => e
107
+ #puts e
108
+ #puts e.backtrace.join("\n")
109
+ #puts "\n\n"
110
+ clean_trace = strip_nr_from_backtrace(e.backtrace)
111
+ assert_equal 0, clean_trace.grep(/newrelic_rpm/).size, clean_trace.grep(/newrelic_rpm/)
112
+ assert_equal 0, clean_trace.grep(/trace/).size, clean_trace.grep(/trace/)
113
+ assert_equal 3, clean_trace.grep(/find/).size, "should see three frames with 'find' in them (#{e}): \n#{clean_trace.join("\n")}"
114
+ ensure
115
+ ActiveRecordFixtures.teardown
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,76 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+
3
+ class NewRelic::Agent::DispatcherInstrumentationTest < Test::Unit::TestCase
4
+
5
+ class FunnyDispatcher
6
+ include NewRelic::Agent::Instrumentation::DispatcherInstrumentation
7
+ def newrelic_response_code; end
8
+ end
9
+ def setup
10
+ super
11
+ NewRelic::Agent.manual_start
12
+ NewRelic::Agent.instance.stats_engine.clear_stats
13
+ @instance_busy = NewRelic::Agent.agent.stats_engine.get_stats('Instance/Busy')
14
+ @dispatch_stat = NewRelic::Agent.agent.stats_engine.get_stats 'HttpDispatcher'
15
+ @mongrel_queue_stat = NewRelic::Agent.agent.stats_engine.get_stats 'WebFrontend/Mongrel/Average Queue Time'
16
+ end
17
+
18
+ def test_normal_call
19
+ d = FunnyDispatcher.new
20
+ assert_equal 0, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
21
+ d.newrelic_dispatcher_start
22
+ sleep 1.0
23
+ assert_equal 1, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
24
+ d.newrelic_dispatcher_finish
25
+ assert_equal 0, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
26
+ assert_nil Thread.current[:newrelic_t0]
27
+ NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
28
+
29
+ assert_equal 1, @instance_busy.call_count
30
+ assert_equal 1, @dispatch_stat.call_count
31
+ assert_equal 0, @mongrel_queue_stat.call_count
32
+ assert @dispatch_stat.total_call_time >= 1.0, "Total call time must be at least one second"
33
+ assert @instance_busy.total_call_time > 0.9 && @instance_busy.total_call_time <= 1.0, "instance busy = #{@instance_busy.inspect}"
34
+ end
35
+ def test_histogram
36
+ d = FunnyDispatcher.new
37
+ d.newrelic_dispatcher_start
38
+ d.newrelic_dispatcher_finish
39
+ bucket = NewRelic::Agent.instance.stats_engine.metrics.find { | m | m =~ /^Response Times/ }
40
+ assert_not_nil bucket
41
+ bucket_stats = NewRelic::Agent.instance.stats_engine.get_stats(bucket)
42
+ assert_equal 1, bucket_stats.call_count
43
+ end
44
+ def test_ignore_zero_counts
45
+ assert_equal 0, @instance_busy.call_count, "Problem with test--instance busy not starting off at zero."
46
+ NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
47
+ NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
48
+ NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
49
+ assert_equal 0, @instance_busy.call_count
50
+ end
51
+ def test_recursive_call
52
+ d0 = FunnyDispatcher.new
53
+ d1 = FunnyDispatcher.new
54
+
55
+ assert_equal 0, @instance_busy.call_count, "Problem with test--instance busy not starting off at zero."
56
+
57
+ NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
58
+ NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
59
+ assert_equal 0, @instance_busy.call_count
60
+
61
+ assert_equal 0, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
62
+ d0.newrelic_dispatcher_start
63
+ assert_equal 1, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
64
+ d1.newrelic_dispatcher_start
65
+ assert_equal 2, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
66
+ sleep 1
67
+ d0.newrelic_dispatcher_finish
68
+ assert_equal 1, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
69
+ d1.newrelic_dispatcher_finish
70
+ assert_equal 0, NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.busy_count
71
+ assert_nil Thread.current[:newrelic_t0]
72
+ NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
73
+ assert_equal 1, @instance_busy.call_count
74
+ assert @instance_busy.total_call_time.between?(1.8, 2.1), "Should be about 200%: #{@instance_busy.total_call_time}"
75
+ end
76
+ end
@@ -0,0 +1,155 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+ ##require 'new_relic/agent/error_collector'
3
+ require 'test/unit'
4
+
5
+
6
+ class FakeRequest
7
+ attr_reader :path
8
+
9
+ def initialize(path)
10
+ @path = path
11
+ end
12
+
13
+ def referer
14
+ "test_referer"
15
+ end
16
+ end
17
+
18
+ class NewRelic::Agent::ErrorCollectorTest < Test::Unit::TestCase
19
+
20
+ def setup
21
+ @error_collector = NewRelic::Agent::ErrorCollector.new(nil)
22
+ end
23
+
24
+ def test_simple
25
+ @error_collector.notice_error(Exception.new("message"), FakeRequest.new('/myurl/'), 'path', {:x => 'y'})
26
+
27
+ old_errors = []
28
+ errors = @error_collector.harvest_errors(old_errors)
29
+
30
+ assert_equal errors.length, 1
31
+
32
+ err = errors.first
33
+ assert_equal 'message', err.message
34
+ assert_equal 'y', err.params[:request_params][:x]
35
+ assert err.params[:request_uri] == '/myurl/'
36
+ assert err.params[:request_referer] == "test_referer"
37
+ assert err.path == 'path'
38
+ assert err.exception_class == 'Exception'
39
+
40
+ # the collector should now return an empty array since nothing
41
+ # has been added since its last harvest
42
+ errors = @error_collector.harvest_errors(nil)
43
+ assert errors.length == 0
44
+ end
45
+
46
+ def test_long_message
47
+ #yes, times 500. it's a 5000 byte string. Assuming strings are
48
+ #still 1 byte / char.
49
+ @error_collector.notice_error(Exception.new("1234567890" * 500), FakeRequest.new('/myurl/'), 'path', {:x => 'y'})
50
+
51
+ old_errors = []
52
+ errors = @error_collector.harvest_errors(old_errors)
53
+
54
+ assert_equal errors.length, 1
55
+
56
+ err = errors.first
57
+ assert_equal ('1234567890' * 500)[0..4096], err.message
58
+ end
59
+
60
+ def test_collect_failover
61
+ @error_collector.notice_error(Exception.new("message"), nil, 'first', {:x => 'y'})
62
+
63
+ errors = @error_collector.harvest_errors([])
64
+
65
+ @error_collector.notice_error(Exception.new("message"), nil, 'second', {:x => 'y'})
66
+ @error_collector.notice_error(Exception.new("message"), nil, 'path', {:x => 'y'})
67
+ @error_collector.notice_error(Exception.new("message"), nil, 'path', {:x => 'y'})
68
+
69
+ errors = @error_collector.harvest_errors(errors)
70
+
71
+ assert_equal 1, errors.length
72
+ assert_equal 'first', errors.first.path
73
+
74
+ # add two more
75
+ @error_collector.notice_error(Exception.new("message"), nil, 'path', {:x => 'y'})
76
+ @error_collector.notice_error(Exception.new("message"), nil, 'last', {:x => 'y'})
77
+
78
+ errors = @error_collector.harvest_errors(nil)
79
+ assert_equal 5, errors.length
80
+ assert_equal 'second', errors.first.path
81
+ assert_equal 'last', errors.last.path
82
+
83
+ end
84
+
85
+ def test_queue_overflow
86
+
87
+ max_q_length = 20 # for some reason I can't read the constant in ErrorCollector
88
+
89
+ silence_stream(::STDERR) do
90
+ (max_q_length + 5).times do |n|
91
+ @error_collector.notice_error(Exception.new("exception #{n}"), nil, "path", {:x => n})
92
+ end
93
+ end
94
+
95
+ errors = @error_collector.harvest_errors([])
96
+ assert errors.length == max_q_length
97
+ errors.each_index do |i|
98
+ err = errors.shift
99
+ assert_equal i.to_s, err.params[:request_params][:x], err.params.inspect
100
+ end
101
+ end
102
+
103
+ # Why would anyone undef these methods?
104
+ class TestClass
105
+ undef to_s
106
+ undef inspect
107
+ end
108
+
109
+
110
+ def test_supported_param_types
111
+
112
+ types = [[1, '1'],
113
+ [1.1, '1.1'],
114
+ ['hi', 'hi'],
115
+ [:hi, :hi],
116
+ [Exception.new("test"), "#<Exception>"],
117
+ [TestClass.new, "#<NewRelic::Agent::ErrorCollectorTest::TestClass>"]
118
+ ]
119
+
120
+
121
+ types.each do |test|
122
+ @error_collector.notice_error(Exception.new("message"), nil, 'path', {:x => test[0]})
123
+
124
+ assert_equal test[1], @error_collector.harvest_errors([])[0].params[:request_params][:x]
125
+ end
126
+ end
127
+
128
+
129
+ def test_exclude
130
+ @error_collector.ignore(["ActionController::RoutingError"])
131
+
132
+ @error_collector.notice_error(ActionController::RoutingError.new("message"), nil, 'path', {:x => 'y'})
133
+
134
+ errors = @error_collector.harvest_errors([])
135
+
136
+ assert_equal 0, errors.length
137
+ end
138
+
139
+ def test_exclude_block
140
+ @error_collector.ignore_error_filter do |e|
141
+ if e.is_a? ActionController::RoutingError
142
+ nil
143
+ else
144
+ e
145
+ end
146
+ end
147
+
148
+ @error_collector.notice_error(ActionController::RoutingError.new("message"), nil, 'path', {:x => 'y'})
149
+
150
+ errors = @error_collector.harvest_errors([])
151
+
152
+ assert_equal 0, errors.length
153
+ end
154
+
155
+ end