newrelic_rpm 2.8.11 → 2.9.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of newrelic_rpm might be problematic. Click here for more details.

Files changed (137) hide show
  1. data/CHANGELOG +267 -0
  2. data/LICENSE +1 -1
  3. data/Manifest +142 -0
  4. data/README.md +138 -0
  5. data/Rakefile +10 -28
  6. data/bin/mongrel_rpm +33 -0
  7. data/cert/cacert.pem +34 -0
  8. data/init.rb +38 -0
  9. data/lib/new_relic/agent/agent.rb +160 -347
  10. data/lib/new_relic/agent/collection_helper.rb +13 -24
  11. data/lib/new_relic/agent/error_collector.rb +29 -15
  12. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +63 -76
  13. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +90 -48
  14. data/lib/new_relic/agent/instrumentation/dispatcher_instrumentation.rb +72 -47
  15. data/lib/new_relic/agent/instrumentation/error_instrumentation.rb +14 -0
  16. data/lib/new_relic/agent/instrumentation/merb/controller.rb +10 -1
  17. data/lib/new_relic/agent/instrumentation/merb/dispatcher.rb +5 -7
  18. data/lib/new_relic/agent/instrumentation/merb/errors.rb +3 -1
  19. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +7 -0
  20. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +34 -7
  21. data/lib/new_relic/agent/instrumentation/rails/dispatcher.rb +20 -12
  22. data/lib/new_relic/agent/instrumentation/rails/errors.rb +5 -4
  23. data/lib/new_relic/agent/method_tracer.rb +159 -135
  24. data/lib/new_relic/agent/patch_const_missing.rb +46 -26
  25. data/lib/new_relic/agent/sampler.rb +12 -0
  26. data/lib/new_relic/agent/samplers/cpu_sampler.rb +44 -0
  27. data/lib/new_relic/agent/samplers/memory_sampler.rb +126 -0
  28. data/lib/new_relic/agent/samplers/mongrel_sampler.rb +22 -0
  29. data/lib/new_relic/agent/shim_agent.rb +11 -0
  30. data/lib/new_relic/agent/stats_engine.rb +85 -46
  31. data/lib/new_relic/agent/transaction_sampler.rb +63 -38
  32. data/lib/new_relic/agent/worker_loop.rb +8 -18
  33. data/lib/new_relic/agent.rb +200 -25
  34. data/lib/new_relic/commands/deployments.rb +9 -9
  35. data/lib/new_relic/control/merb.rb +22 -0
  36. data/lib/new_relic/control/rails.rb +141 -0
  37. data/lib/new_relic/{config → control}/ruby.rb +13 -2
  38. data/lib/new_relic/control.rb +424 -0
  39. data/lib/new_relic/local_environment.rb +201 -79
  40. data/lib/new_relic/metric_data.rb +7 -0
  41. data/lib/new_relic/metric_parser/action_mailer.rb +9 -0
  42. data/lib/new_relic/metric_parser/active_merchant.rb +26 -0
  43. data/lib/new_relic/metric_parser/active_record.rb +11 -0
  44. data/lib/new_relic/metric_parser/controller.rb +51 -0
  45. data/lib/new_relic/metric_parser/controller_cpu.rb +38 -0
  46. data/lib/new_relic/metric_parser/database.rb +23 -0
  47. data/lib/new_relic/metric_parser/errors.rb +6 -0
  48. data/lib/new_relic/metric_parser/mem_cache.rb +12 -0
  49. data/lib/new_relic/metric_parser/view.rb +61 -0
  50. data/lib/new_relic/metric_parser/web_service.rb +9 -0
  51. data/lib/new_relic/metric_parser.rb +107 -0
  52. data/lib/new_relic/metric_spec.rb +5 -0
  53. data/lib/new_relic/noticed_error.rb +5 -1
  54. data/lib/new_relic/rack/metric_app.rb +57 -0
  55. data/lib/new_relic/rack/newrelic.ru +25 -0
  56. data/lib/new_relic/rack/newrelic.yml +25 -0
  57. data/lib/new_relic/rack.rb +5 -0
  58. data/lib/new_relic/recipes.rb +10 -3
  59. data/lib/new_relic/stats.rb +130 -144
  60. data/lib/new_relic/transaction_analysis.rb +7 -8
  61. data/lib/new_relic/transaction_sample.rb +86 -10
  62. data/lib/new_relic/version.rb +41 -160
  63. data/lib/new_relic_api.rb +7 -6
  64. data/lib/newrelic_rpm.rb +30 -17
  65. data/lib/tasks/{agent_tests.rake → tests.rake} +1 -1
  66. data/newrelic.yml +115 -62
  67. data/newrelic_rpm.gemspec +36 -0
  68. data/test/active_record_fixtures.rb +55 -0
  69. data/test/config/newrelic.yml +21 -3
  70. data/test/config/{test_config.rb → test_control.rb} +14 -10
  71. data/test/new_relic/agent/active_record_instrumentation_test.rb +189 -0
  72. data/test/new_relic/agent/agent_test.rb +104 -0
  73. data/test/new_relic/agent/agent_test_controller.rb +18 -1
  74. data/test/new_relic/agent/classloader_patch_test.rb +56 -0
  75. data/test/new_relic/agent/{tc_collection_helper.rb → collection_helper_test.rb} +28 -23
  76. data/test/new_relic/agent/controller_test.rb +107 -0
  77. data/test/new_relic/agent/dispatcher_instrumentation_test.rb +70 -0
  78. data/test/new_relic/agent/error_collector_test.rb +155 -0
  79. data/test/new_relic/agent/{tc_method_tracer.rb → method_tracer_test.rb} +6 -12
  80. data/test/new_relic/agent/metric_data_test.rb +56 -0
  81. data/test/new_relic/agent/stats_engine_test.rb +266 -0
  82. data/test/new_relic/agent/{tc_transaction_sample_builder.rb → transaction_sample_builder_test.rb} +6 -5
  83. data/test/new_relic/agent/{tc_transaction_sample.rb → transaction_sample_test.rb} +9 -13
  84. data/test/new_relic/agent/transaction_sampler_test.rb +317 -0
  85. data/test/new_relic/agent/{tc_worker_loop.rb → worker_loop_test.rb} +1 -1
  86. data/test/new_relic/control_test.rb +97 -0
  87. data/test/new_relic/{tc_deployments_api.rb → deployments_api_test.rb} +8 -4
  88. data/test/new_relic/environment_test.rb +75 -0
  89. data/test/new_relic/metric_parser_test.rb +142 -0
  90. data/test/new_relic/{tc_metric_spec.rb → metric_spec_test.rb} +28 -1
  91. data/test/new_relic/samplers_test.rb +71 -0
  92. data/test/new_relic/{tc_shim_agent.rb → shim_agent_test.rb} +1 -1
  93. data/test/new_relic/stats_test.rb +291 -0
  94. data/test/new_relic/version_number_test.rb +46 -0
  95. data/test/test_helper.rb +7 -30
  96. data/test/ui/newrelic_controller_test.rb +14 -0
  97. data/test/ui/{tc_newrelic_helper.rb → newrelic_helper_test.rb} +16 -7
  98. data/ui/controllers/newrelic_controller.rb +17 -3
  99. data/ui/helpers/newrelic_helper.rb +44 -15
  100. data/ui/views/layouts/newrelic_default.rhtml +7 -8
  101. data/ui/views/newrelic/_sample.rhtml +5 -2
  102. data/ui/views/newrelic/_segment.rhtml +1 -1
  103. data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
  104. data/ui/views/newrelic/_segment_row.rhtml +4 -4
  105. data/ui/views/newrelic/_show_sample_detail.rhtml +3 -1
  106. data/ui/views/newrelic/_show_sample_sql.rhtml +2 -1
  107. data/ui/views/newrelic/explain_sql.rhtml +2 -5
  108. data/ui/views/newrelic/images/file_icon.png +0 -0
  109. data/ui/views/newrelic/images/new_relic_rpm_desktop.gif +0 -0
  110. data/ui/views/newrelic/index.rhtml +21 -13
  111. data/ui/views/newrelic/javascript/prototype-scriptaculous.js +7288 -0
  112. data/ui/views/newrelic/show_sample.rhtml +18 -3
  113. data/ui/views/newrelic/stylesheets/style.css +39 -0
  114. data/ui/views/newrelic/threads.rhtml +52 -0
  115. metadata +192 -70
  116. data/README +0 -136
  117. data/lib/new_relic/agent/instrumentation/rails/rails.rb +0 -6
  118. data/lib/new_relic/agent/samplers/cpu.rb +0 -29
  119. data/lib/new_relic/agent/samplers/memory.rb +0 -53
  120. data/lib/new_relic/agent/samplers/mongrel.rb +0 -26
  121. data/lib/new_relic/agent/synchronize.rb +0 -40
  122. data/lib/new_relic/config/merb.rb +0 -35
  123. data/lib/new_relic/config/rails.rb +0 -114
  124. data/lib/new_relic/config.rb +0 -279
  125. data/lib/new_relic/shim_agent.rb +0 -96
  126. data/test/new_relic/agent/model_fixture.rb +0 -15
  127. data/test/new_relic/agent/tc_active_record.rb +0 -90
  128. data/test/new_relic/agent/tc_agent.rb +0 -148
  129. data/test/new_relic/agent/tc_controller.rb +0 -77
  130. data/test/new_relic/agent/tc_dispatcher_instrumentation.rb +0 -52
  131. data/test/new_relic/agent/tc_error_collector.rb +0 -127
  132. data/test/new_relic/agent/tc_stats_engine.rb +0 -218
  133. data/test/new_relic/agent/tc_synchronize.rb +0 -37
  134. data/test/new_relic/agent/tc_transaction_sampler.rb +0 -302
  135. data/test/new_relic/tc_config.rb +0 -36
  136. data/test/new_relic/tc_environment.rb +0 -94
  137. data/test/new_relic/tc_stats.rb +0 -141
@@ -1,26 +1,30 @@
1
- require 'new_relic/config/rails'
1
+ require 'new_relic/control/rails'
2
2
  require 'new_relic/agent/agent_test_controller'
3
3
 
4
- class NewRelic::Config::Test < NewRelic::Config::Rails
4
+ class NewRelic::Control::Test < NewRelic::Control::Rails
5
5
  def env
6
6
  'test'
7
7
  end
8
+ def app
9
+ :rails
10
+ end
8
11
  def config_file
9
12
  File.join(File.dirname(__FILE__), "newrelic.yml")
10
13
  end
11
- def initialize
12
- super
13
- setup_log env
14
+ def initialize local_env
15
+ super local_env
16
+ setup_log
14
17
  end
15
18
  # when running tests, don't write out stderr
16
19
  def log!(msg, level=:info)
17
20
  log.send level, msg if log
18
21
  end
19
-
22
+
20
23
  # Add the default route in case it's missing. Need it for testing.
21
24
  def install_devmode_route
22
- if super
23
- ActionController::Routing::RouteSet.class_eval do
25
+ super
26
+ ActionController::Routing::RouteSet.class_eval do
27
+ return if defined? draw_without_test_route
24
28
  def draw_with_test_route
25
29
  draw_without_test_route do | map |
26
30
  map.connect ':controller/:action/:id'
@@ -29,7 +33,7 @@ class NewRelic::Config::Test < NewRelic::Config::Rails
29
33
  end
30
34
  alias_method_chain :draw, :test_route
31
35
  end
32
- return true
33
- end
36
+ # Force the routes to be reloaded
37
+ ActionController::Routing::Routes.reload!
34
38
  end
35
39
  end
@@ -0,0 +1,189 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+ require 'active_record_fixtures'
3
+
4
+ class ActiveRecordInstrumentationTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ NewRelic::Agent.manual_start
8
+ NewRelic::Agent.instance.stats_engine.clear_stats
9
+ ActiveRecordFixtures.setup
10
+ NewRelic::Agent.instance.transaction_sampler.harvest
11
+ rescue
12
+ puts e
13
+ puts e.backtrace.join("\n")
14
+ end
15
+
16
+ def teardown
17
+ ActiveRecordFixtures.teardown
18
+ end
19
+ def test_agent_setup
20
+ assert NewRelic::Agent.instance.class == NewRelic::Agent::Agent
21
+ end
22
+ def test_finder
23
+ ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
24
+ ActiveRecordFixtures::Order.find(:all)
25
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
26
+ assert_equal 1, s.call_count
27
+ ActiveRecordFixtures::Order.find_all_by_name "jeff"
28
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
29
+ assert_equal 2, s.call_count
30
+ end
31
+
32
+ # multiple duplicate find calls should only cause metric trigger on the first
33
+ # call. the others are ignored.
34
+ def test_query_cache
35
+ ActiveRecordFixtures::Order.cache do
36
+ m = ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
37
+ ActiveRecordFixtures::Order.find(:all)
38
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
39
+ assert_equal 1, s.call_count
40
+
41
+ 10.times { ActiveRecordFixtures::Order.find m.id }
42
+ end
43
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
44
+ assert_equal 2, s.call_count
45
+ end
46
+
47
+ def test_metric_names
48
+ m = ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
49
+ m = ActiveRecordFixtures::Order.find(m.id)
50
+ m.id = 999
51
+ m.save!
52
+
53
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
54
+ # This doesn't work on hudson because the sampler metrics creep in.
55
+ # metrics = NewRelic::Agent.instance.stats_engine.metrics.select { |mname| mname =~ /ActiveRecord\/ActiveRecordFixtures::Order\// }.sort
56
+ expected = %W[
57
+ ActiveRecord/create
58
+ ActiveRecord/find
59
+ ActiveRecord/ActiveRecordFixtures::Order/create
60
+ ActiveRecord/ActiveRecordFixtures::Order/find
61
+ ]
62
+ expected += %W[ActiveRecord/save ActiveRecord/ActiveRecordFixtures::Order/save] if NewRelic::Control.instance.rails_version < '2.1.0'
63
+ compare_metrics expected, metrics
64
+ assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find").call_count
65
+ assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/create").call_count
66
+ end
67
+ def test_join_metrics
68
+ m = ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
69
+ m = ActiveRecordFixtures::Order.find(m.id)
70
+ s = m.shipments.create
71
+ m.shipments.to_a
72
+ m.destroy
73
+
74
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
75
+ # This doesn't work on hudson because the sampler metrics creep in.
76
+ # metrics = NewRelic::Agent.instance.stats_engine.metrics.select { |mname| mname =~ /ActiveRecord\/ActiveRecordFixtures::Order\// }.sort
77
+ compare_metrics %W[
78
+ ActiveRecord/destroy
79
+ ActiveRecord/ActiveRecordFixtures::Order/destroy
80
+ Database/SQL/insert
81
+ Database/SQL/delete
82
+ ActiveRecord/create
83
+ ActiveRecord/find
84
+ ActiveRecord/ActiveRecordFixtures::Order/create
85
+ ActiveRecord/ActiveRecordFixtures::Order/find
86
+ ActiveRecord/ActiveRecordFixtures::Shipment/find
87
+ ActiveRecord/ActiveRecordFixtures::Shipment/create
88
+ ], metrics
89
+ assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find").call_count
90
+ assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Shipment/find").call_count
91
+ assert_equal 1, NewRelic::Agent.get_stats("Database/SQL/insert").call_count
92
+ assert_equal 1, NewRelic::Agent.get_stats("Database/SQL/delete").call_count
93
+ end
94
+ def test_direct_sql
95
+ list = ActiveRecordFixtures::Order.connection.select_rows "select * from #{ActiveRecordFixtures::Order.table_name}"
96
+ metrics = NewRelic::Agent.instance.stats_engine.metrics
97
+ compare_metrics %W[
98
+ Database/SQL/select
99
+ ], metrics
100
+ assert_equal 1, NewRelic::Agent.get_stats("Database/SQL/select").call_count
101
+ end
102
+
103
+ def test_run_explains
104
+ ActiveRecordFixtures::Order.add_delay
105
+ ActiveRecordFixtures::Order.find(:all)
106
+
107
+ sample = NewRelic::Agent.instance.transaction_sampler.last_sample
108
+
109
+ segment = sample.root_segment.called_segments.first.called_segments.first
110
+ assert_match /^SELECT \* FROM ["`]?#{ActiveRecordFixtures::Order.table_name}["`]?$/i, segment.params[:sql].strip
111
+ NewRelic::TransactionSample::Segment.any_instance.expects(:explain_sql).returns([])
112
+ sample = sample.prepare_to_send(:obfuscate_sql => true, :explain_enabled => true, :explain_sql => 0.0)
113
+ segment = sample.root_segment.called_segments.first.called_segments.first
114
+ end
115
+ def test_prepare_to_send
116
+ ActiveRecordFixtures::Order.add_delay
117
+ ActiveRecordFixtures::Order.find(:all)
118
+
119
+ sample = NewRelic::Agent.instance.transaction_sampler.last_sample
120
+ #
121
+ sql_segment = sample.root_segment.called_segments.first.called_segments.first
122
+ assert_match /^SELECT /, sql_segment.params[:sql]
123
+ assert sql_segment.duration > 0.0, "Segment duration must be greater than zero."
124
+ sample = sample.prepare_to_send(:record_sql => :raw, :explain_enabled => true, :explain_sql => 0.0)
125
+ sql_segment = sample.root_segment.called_segments.first.called_segments.first
126
+ assert_match /^SELECT /, sql_segment.params[:sql]
127
+ explanations = sql_segment.params[:explanation]
128
+ if isMysql? || isPostgres?
129
+ assert_not_nil explanations, "No explains in segment: #{sql_segment}"
130
+ assert_equal 1, explanations.size,"No explains in segment: #{sql_segment}"
131
+ assert_equal 1, explanations.first.size
132
+ end
133
+ end
134
+ def test_transaction
135
+ ActiveRecordFixtures::Order.add_delay
136
+ ActiveRecordFixtures::Order.find(:all)
137
+
138
+ sample = NewRelic::Agent.instance.transaction_sampler.last_sample
139
+
140
+ sample = sample.prepare_to_send(:obfuscate_sql => true, :explain_enabled => true, :explain_sql => 0.0)
141
+ segment = sample.root_segment.called_segments.first.called_segments.first
142
+ assert_nil segment.params[:sql], "SQL should have been removed."
143
+ explanations = segment.params[:explanation]
144
+ if isMysql? || isPostgres?
145
+ assert_not_nil explanations, "No explains in segment: #{segment}"
146
+ assert_equal 1, explanations.size,"No explains in segment: #{segment}"
147
+ assert_equal 1, explanations.first.size
148
+ end
149
+ if isPostgres?
150
+ assert_equal Array, explanations.class
151
+ assert_equal Array, explanations[0].class
152
+ assert_equal Array, explanations[0][0].class
153
+ assert_match /Seq Scan on test_data/, explanations[0][0].join(";")
154
+ elsif isMysql?
155
+ assert_equal "1;SIMPLE;#{ActiveRecordFixtures::Order.table_name};ALL;;;;;1;", explanations.first.first.join(";")
156
+ end
157
+
158
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
159
+ assert_equal 1, s.call_count
160
+ end
161
+ # These are only valid for rails 2.1 and later
162
+ if NewRelic::Control.instance.rails_version >= NewRelic::VersionNumber.new("2.1.0")
163
+ ActiveRecordFixtures::Order.class_eval do
164
+ named_scope :jeffs, :conditions => { :name => 'Jeff' }
165
+ end
166
+ def test_named_scope
167
+ ActiveRecordFixtures::Order.create :name => 'Jeff'
168
+ s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
169
+ before_count = s.call_count
170
+ x = ActiveRecordFixtures::Order.jeffs.find(:all)
171
+ assert_equal 1, x.size
172
+ se = NewRelic::Agent.instance.stats_engine
173
+ assert_equal before_count+1, s.call_count
174
+ end
175
+ end
176
+
177
+ private
178
+ def compare_metrics expected_list, actual_list
179
+ actual = Set.new actual_list
180
+ expected = Set.new expected_list
181
+ assert_equal expected, actual, "extra: #{(actual - expected).to_a.join(", ")}; missing: #{(expected - actual).to_a.join(", ")}"
182
+ end
183
+ def isPostgres?
184
+ ActiveRecordFixtures::Order.configurations[RAILS_ENV]['adapter'] =~ /postgres/
185
+ end
186
+ def isMysql?
187
+ ActiveRecordFixtures::Order.connection.class.name =~ /mysql/i
188
+ end
189
+ end
@@ -0,0 +1,104 @@
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
+
39
+ NewRelic::Agent.agent.error_collector.notice_error(ActionController::RoutingError.new("message"), nil, "path", {:x => "y"} )
40
+
41
+ assert ignore_called
42
+ end
43
+
44
+ def test_startup_shutdown
45
+ @agent = NewRelic::Agent::ShimAgent.instance
46
+ @agent.shutdown
47
+ assert (not @agent.started?)
48
+ @agent.start
49
+ assert !@agent.started?
50
+ # this installs the real agent:
51
+ NewRelic::Agent.manual_start
52
+ @agent = NewRelic::Agent.instance
53
+ assert @agent != NewRelic::Agent::ShimAgent.instance
54
+ assert @agent.started?
55
+ @agent.shutdown
56
+ assert !@agent.started?
57
+ @agent.start
58
+ assert @agent.started?
59
+ end
60
+
61
+ def test_manual_overrides
62
+ NewRelic::Agent.manual_start :app_name => "testjobs", :dispatcher_instance_id => "mailer"
63
+ assert_equal "testjobs", NewRelic::Control.instance.app_names[0]
64
+ assert_equal "mailer", NewRelic::Control.instance.dispatcher_instance_id
65
+ end
66
+ def test_restart
67
+ NewRelic::Agent.manual_start :app_name => "noapp", :dispatcher_instance_id => ""
68
+ NewRelic::Agent.manual_start :app_name => "testjobs", :dispatcher_instance_id => "mailer"
69
+ assert_equal "testjobs", NewRelic::Control.instance.app_names[0]
70
+ assert_equal "mailer", NewRelic::Control.instance.dispatcher_instance_id
71
+ end
72
+
73
+ def test_version
74
+ assert_match /\d\.\d\.\d+/, NewRelic::VERSION::STRING
75
+ end
76
+
77
+ def test_invoke_remote__ignore_non_200_results
78
+ NewRelic::Agent::Agent.class_eval do
79
+ public :invoke_remote
80
+ end
81
+ response_mock = mock()
82
+ Net::HTTP.any_instance.stubs(:request).returns(response_mock)
83
+ response_mock.stubs(:message).returns("bogus error")
84
+
85
+ for code in %w[500 504 400 302 503] do
86
+ assert_raise NewRelic::Agent::IgnoreSilentlyException, "Ignore #{code}" do
87
+ response_mock.stubs(:code).returns(code)
88
+ NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0
89
+ end
90
+ end
91
+ end
92
+ def test_invoke_remote__throw_other_errors
93
+ NewRelic::Agent::Agent.class_eval do
94
+ public :invoke_remote
95
+ end
96
+ response_mock = Net::HTTPSuccess.new nil, nil, nil
97
+ response_mock.stubs(:body).returns("")
98
+ Marshal.stubs(:load).raises(RuntimeError, "marshal issue")
99
+ Net::HTTP.any_instance.stubs(:request).returns(response_mock)
100
+ assert_raise RuntimeError do
101
+ NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0xFEFE
102
+ end
103
+ end
104
+ end
@@ -1,6 +1,20 @@
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
1
8
  # This is a controller class used in testing controller instrumentation
2
- class NewRelic::Agent::AgentTestController < ActionController::Base
9
+ class NewRelic::Agent::AgentTestController < NewRelic::Agent::SuperclassController
3
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
+
4
18
  def index
5
19
  render :text => params.inspect
6
20
  end
@@ -13,6 +27,9 @@ class NewRelic::Agent::AgentTestController < ActionController::Base
13
27
  def action_to_ignore
14
28
  render :text => 'unmeasured'
15
29
  end
30
+ def action_to_ignore_apdex
31
+ render :text => 'unmeasured'
32
+ end
16
33
  def entry_action
17
34
  perform_action_with_newrelic_trace('internal_action') do
18
35
  internal_action
@@ -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
@@ -1,17 +1,13 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
2
  require 'ostruct'
3
- require 'new_relic/agent/model_fixture'
4
-
5
- class NewRelic::Agent::CollectionHelperTests < Test::Unit::TestCase
3
+ require 'active_record_fixtures'
4
+ class NewRelic::Agent::CollectionHelperTest < Test::Unit::TestCase
6
5
 
7
6
  def setup
8
7
  super
9
- NewRelic::Agent::ModelFixture.setup
10
- NewRelic::Agent.instance.start :test, :test
8
+ NewRelic::Agent.manual_start
11
9
  end
12
10
  def teardown
13
- NewRelic::Agent::ModelFixture.teardown
14
- NewRelic::Agent.instance.shutdown
15
11
  super
16
12
  end
17
13
 
@@ -26,7 +22,7 @@ class NewRelic::Agent::CollectionHelperTests < Test::Unit::TestCase
26
22
  assert_equal '1000', new_array[0]
27
23
  end
28
24
  def test_boolean
29
- np = normalize_params(NewRelic::Config.instance.settings)
25
+ np = normalize_params(NewRelic::Control.instance.settings)
30
26
  assert_equal false, np['enabled']
31
27
  end
32
28
  class MyString < String; end
@@ -68,11 +64,11 @@ class NewRelic::Agent::CollectionHelperTests < Test::Unit::TestCase
68
64
  end
69
65
 
70
66
  class MyEnumerable
71
- include Enumerable
72
-
73
- def each
74
- yield "1"
75
- end
67
+ include Enumerable
68
+
69
+ def each
70
+ yield "1"
71
+ end
76
72
  end
77
73
 
78
74
  def test_enumerable
@@ -84,30 +80,39 @@ class NewRelic::Agent::CollectionHelperTests < Test::Unit::TestCase
84
80
  end
85
81
 
86
82
  def test_stringio
87
- # make sure stringios aren't affected
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:
88
90
  s = StringIO.new "start" + ("foo bar bat " * 1000)
89
- v = normalize_params({ :foo => s })
90
- val = ""
91
- s.each { | val | break }
91
+ v = normalize_params({ :foo => s.string })
92
+ s.each { | entry | val = entry; break }
92
93
  assert_match /^startfoo bar/, val
93
94
  end
94
95
 
95
96
  def test_object
96
- assert_equal ["foo", '#<OpenStruct z="q">'], normalize_params(['foo', OpenStruct.new('z'=>'q')])
97
+ assert_equal ["foo", '#<OpenStruct>'], normalize_params(['foo', OpenStruct.new('z'=>'q')])
97
98
  end
98
99
 
99
100
  def test_strip_backtrace
100
101
  begin
101
- NewRelic::Agent::ModelFixture.find 0
102
+ ActiveRecordFixtures.setup
103
+ # ActiveRecordFixtures::Order.add_delay
104
+ ActiveRecordFixtures::Order.find 0
102
105
  flunk "should throw"
103
106
  rescue => e
104
- # puts e
105
- # puts e.backtrace.join("\n")
106
- # puts "\n\n"
107
+ #puts e
108
+ #puts e.backtrace.join("\n")
109
+ #puts "\n\n"
107
110
  clean_trace = strip_nr_from_backtrace(e.backtrace)
108
111
  assert_equal 0, clean_trace.grep(/newrelic_rpm/).size, clean_trace.grep(/newrelic_rpm/)
109
112
  assert_equal 0, clean_trace.grep(/trace/).size, clean_trace.grep(/trace/)
110
- assert_equal 3, clean_trace.grep(/find/).size, "should see three frames with 'find' in them: \n#{clean_trace.join("\n")}"
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
111
116
  end
112
117
  end
113
118
  end