newrelic_rpm 2.8.0

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 (107) hide show
  1. data/LICENSE +37 -0
  2. data/README +93 -0
  3. data/Rakefile +38 -0
  4. data/install.rb +37 -0
  5. data/lib/new_relic/agent.rb +26 -0
  6. data/lib/new_relic/agent/agent.rb +762 -0
  7. data/lib/new_relic/agent/chained_call.rb +13 -0
  8. data/lib/new_relic/agent/collection_helper.rb +81 -0
  9. data/lib/new_relic/agent/error_collector.rb +105 -0
  10. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +95 -0
  11. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +151 -0
  12. data/lib/new_relic/agent/instrumentation/data_mapper.rb +90 -0
  13. data/lib/new_relic/agent/instrumentation/dispatcher_instrumentation.rb +105 -0
  14. data/lib/new_relic/agent/instrumentation/memcache.rb +18 -0
  15. data/lib/new_relic/agent/instrumentation/merb/controller.rb +17 -0
  16. data/lib/new_relic/agent/instrumentation/merb/dispatcher.rb +15 -0
  17. data/lib/new_relic/agent/instrumentation/merb/errors.rb +6 -0
  18. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +35 -0
  19. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +27 -0
  20. data/lib/new_relic/agent/instrumentation/rails/dispatcher.rb +30 -0
  21. data/lib/new_relic/agent/instrumentation/rails/errors.rb +23 -0
  22. data/lib/new_relic/agent/instrumentation/rails/rails.rb +6 -0
  23. data/lib/new_relic/agent/method_tracer.rb +171 -0
  24. data/lib/new_relic/agent/patch_const_missing.rb +31 -0
  25. data/lib/new_relic/agent/samplers/cpu.rb +29 -0
  26. data/lib/new_relic/agent/samplers/memory.rb +55 -0
  27. data/lib/new_relic/agent/samplers/mongrel.rb +26 -0
  28. data/lib/new_relic/agent/stats_engine.rb +241 -0
  29. data/lib/new_relic/agent/synchronize.rb +40 -0
  30. data/lib/new_relic/agent/transaction_sampler.rb +281 -0
  31. data/lib/new_relic/agent/worker_loop.rb +128 -0
  32. data/lib/new_relic/api/deployments.rb +92 -0
  33. data/lib/new_relic/config.rb +194 -0
  34. data/lib/new_relic/config/merb.rb +35 -0
  35. data/lib/new_relic/config/rails.rb +113 -0
  36. data/lib/new_relic/config/ruby.rb +9 -0
  37. data/lib/new_relic/local_environment.rb +108 -0
  38. data/lib/new_relic/merbtasks.rb +6 -0
  39. data/lib/new_relic/metric_data.rb +26 -0
  40. data/lib/new_relic/metric_spec.rb +39 -0
  41. data/lib/new_relic/metrics.rb +7 -0
  42. data/lib/new_relic/noticed_error.rb +21 -0
  43. data/lib/new_relic/shim_agent.rb +95 -0
  44. data/lib/new_relic/stats.rb +359 -0
  45. data/lib/new_relic/transaction_analysis.rb +122 -0
  46. data/lib/new_relic/transaction_sample.rb +499 -0
  47. data/lib/new_relic/version.rb +111 -0
  48. data/lib/new_relic_api.rb +275 -0
  49. data/lib/newrelic_rpm.rb +27 -0
  50. data/lib/tasks/agent_tests.rake +14 -0
  51. data/lib/tasks/all.rb +4 -0
  52. data/lib/tasks/install.rake +7 -0
  53. data/newrelic.yml +137 -0
  54. data/recipes/newrelic.rb +46 -0
  55. data/test/config/newrelic.yml +26 -0
  56. data/test/config/test_config.rb +9 -0
  57. data/test/new_relic/agent/mock_ar_connection.rb +40 -0
  58. data/test/new_relic/agent/mock_scope_listener.rb +23 -0
  59. data/test/new_relic/agent/model_fixture.rb +17 -0
  60. data/test/new_relic/agent/tc_active_record.rb +91 -0
  61. data/test/new_relic/agent/tc_agent.rb +112 -0
  62. data/test/new_relic/agent/tc_collection_helper.rb +104 -0
  63. data/test/new_relic/agent/tc_controller.rb +98 -0
  64. data/test/new_relic/agent/tc_dispatcher_instrumentation.rb +52 -0
  65. data/test/new_relic/agent/tc_error_collector.rb +127 -0
  66. data/test/new_relic/agent/tc_method_tracer.rb +306 -0
  67. data/test/new_relic/agent/tc_stats_engine.rb +218 -0
  68. data/test/new_relic/agent/tc_synchronize.rb +37 -0
  69. data/test/new_relic/agent/tc_transaction_sample.rb +175 -0
  70. data/test/new_relic/agent/tc_transaction_sample_builder.rb +200 -0
  71. data/test/new_relic/agent/tc_transaction_sampler.rb +305 -0
  72. data/test/new_relic/agent/tc_worker_loop.rb +101 -0
  73. data/test/new_relic/agent/testable_agent.rb +13 -0
  74. data/test/new_relic/tc_config.rb +36 -0
  75. data/test/new_relic/tc_deployments_api.rb +37 -0
  76. data/test/new_relic/tc_environment.rb +94 -0
  77. data/test/new_relic/tc_metric_spec.rb +150 -0
  78. data/test/new_relic/tc_shim_agent.rb +9 -0
  79. data/test/new_relic/tc_stats.rb +141 -0
  80. data/test/test_helper.rb +39 -0
  81. data/test/ui/tc_newrelic_helper.rb +44 -0
  82. data/ui/controllers/newrelic_controller.rb +200 -0
  83. data/ui/helpers/google_pie_chart.rb +55 -0
  84. data/ui/helpers/newrelic_helper.rb +286 -0
  85. data/ui/views/layouts/newrelic_default.rhtml +49 -0
  86. data/ui/views/newrelic/_explain_plans.rhtml +27 -0
  87. data/ui/views/newrelic/_sample.rhtml +12 -0
  88. data/ui/views/newrelic/_segment.rhtml +28 -0
  89. data/ui/views/newrelic/_segment_row.rhtml +14 -0
  90. data/ui/views/newrelic/_show_sample_detail.rhtml +22 -0
  91. data/ui/views/newrelic/_show_sample_sql.rhtml +19 -0
  92. data/ui/views/newrelic/_show_sample_summary.rhtml +3 -0
  93. data/ui/views/newrelic/_sql_row.rhtml +11 -0
  94. data/ui/views/newrelic/_stack_trace.rhtml +30 -0
  95. data/ui/views/newrelic/_table.rhtml +12 -0
  96. data/ui/views/newrelic/explain_sql.rhtml +45 -0
  97. data/ui/views/newrelic/images/arrow-close.png +0 -0
  98. data/ui/views/newrelic/images/arrow-open.png +0 -0
  99. data/ui/views/newrelic/images/blue_bar.gif +0 -0
  100. data/ui/views/newrelic/images/gray_bar.gif +0 -0
  101. data/ui/views/newrelic/index.rhtml +37 -0
  102. data/ui/views/newrelic/javascript/transaction_sample.js +107 -0
  103. data/ui/views/newrelic/sample_not_found.rhtml +2 -0
  104. data/ui/views/newrelic/show_sample.rhtml +62 -0
  105. data/ui/views/newrelic/show_source.rhtml +3 -0
  106. data/ui/views/newrelic/stylesheets/style.css +394 -0
  107. metadata +180 -0
@@ -0,0 +1,46 @@
1
+ # To be included in Capistrano deploy.rb files
2
+ #
3
+ # Defined deploy:notify_rpm which will send information about the deploy to RPM.
4
+ # The task will run on app servers except where no_release is true.
5
+ # If it fails, it will not affect the task execution or do a rollback.
6
+ #
7
+
8
+ make_notify_task = lambda do
9
+
10
+ namespace :newrelic do
11
+
12
+ # on all deployments, notify RPM
13
+ desc "Record a deployment in New Relic RPM (rpm.newrelic.com)"
14
+ task :notice_deployment, :roles => :app, :except => {:no_release => true } do
15
+ rails_env = fetch(:rails_env, "production")
16
+ from_revision = source.next_revision(current_revision)
17
+ log_command = source.log(from_revision)
18
+ # I don't believe this will work if rpm is installed as a gem, or
19
+ # if they put the plugin elsewhere. Need to revisit.
20
+ script = [ "vendor/plugins/newrelic_rpm/lib/new_relic_api.rb" ] <<
21
+ "deployments" <<
22
+ "-u" << ENV['USER'] <<
23
+ "-r" << current_revision <<
24
+ "-c"
25
+ script = script.map { | arg | "'#{arg}'" }.join(" ")
26
+ begin
27
+ run "cd #{current_release}; #{log_command} | script/runner -e #{rails_env} #{script}" do | io, stream_id, output |
28
+ logger.trace(output)
29
+ end
30
+ rescue CommandError
31
+ logger.info "unable to notify New Relic of the deployment... skipping"
32
+ end
33
+ # For rollbacks, let's update the deployment we created with an indication of the failure:
34
+ #on_rollback do
35
+ # run(command.gsub(/Subject:.*\\n/, "Subject: #{ENV['USER']} deployed a ROLLBACK\\n"))
36
+ #end
37
+ end
38
+ end
39
+ end
40
+
41
+ instance = Capistrano::Configuration.instance
42
+ if instance
43
+ instance.load make_notify_task
44
+ else
45
+ make_notify_task.call
46
+ end
@@ -0,0 +1,26 @@
1
+ # This is the config file loaded when running unit tests locally.
2
+
3
+ test:
4
+ erb_value: <%= 'hey'*3 %>
5
+ host: localhost
6
+ port: 3000
7
+ log_level: debug
8
+ capture_params: true
9
+ enabled: false
10
+ developer: true
11
+ monitor_daemons: false
12
+ message: '<%= generated_for_user %>'
13
+ license_key: '<%= license_key %>'
14
+ transaction_tracer:
15
+ enabled: true
16
+ record_sql: raw
17
+ transaction_threshold: 0.500
18
+ explain_threshold: 0.1
19
+ explain_enabled: true
20
+ stack_trace_threshold: 0.1
21
+
22
+ error_collector:
23
+ enabled: true
24
+ capture_source: true
25
+
26
+
@@ -0,0 +1,9 @@
1
+ require 'new_relic/config/rails'
2
+ class NewRelic::Config::Test < NewRelic::Config::Rails
3
+ def env
4
+ 'test'
5
+ end
6
+ def config_file
7
+ File.join(File.dirname(__FILE__), "newrelic.yml")
8
+ end
9
+ end
@@ -0,0 +1,40 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ def test_connection(config)
5
+ @connect ||= Connection.new
6
+ end
7
+ end
8
+ end
9
+
10
+ class Connection
11
+ attr_accessor :throw
12
+ attr_reader :disconnected
13
+
14
+ def initialize
15
+ @disconnected = false
16
+ @throw = false
17
+ end
18
+
19
+ def disconnect!()
20
+ @disconnected = true
21
+ end
22
+
23
+ def find()
24
+ # used to test that we've instrumented this...
25
+ end
26
+
27
+ def select_rows(s)
28
+ execute(s)
29
+ end
30
+ def execute(s)
31
+ fail "" if @throw
32
+ if s != "EXPLAIN #{::SQL_STATEMENT}"
33
+ fail "Unexpected sql statement #{s}"
34
+ end
35
+ s
36
+ end
37
+ end
38
+ end
39
+
40
+
@@ -0,0 +1,23 @@
1
+
2
+ class NewRelic::Agent::MockScopeListener
3
+
4
+ attr_reader :scope
5
+
6
+ def initialize
7
+ @scope = {}
8
+ end
9
+
10
+ def notice_first_scope_push(time)
11
+ end
12
+
13
+ def notice_push_scope(scope, time)
14
+ @scope[scope] = true
15
+ end
16
+
17
+ def notice_pop_scope(scope, time)
18
+ end
19
+
20
+ def notice_scope_empty(time)
21
+
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # A test model object
2
+ # Be sure and call setup and teardown
3
+ class NewRelic::Agent::ModelFixture < ActiveRecord::Base
4
+ self.table_name = 'test_data'
5
+ def self.setup
6
+ connection.create_table :test_data, :force => true do |t|
7
+ t.column :name, :string
8
+ end
9
+ connection.setup_slow
10
+ end
11
+
12
+ def self.teardown
13
+ connection.teardown_slow
14
+ connection.drop_table :test_data
15
+ end
16
+
17
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+ require 'new_relic/agent/model_fixture'
3
+
4
+
5
+ class ActiveRecordInstrumentationTests < Test::Unit::TestCase
6
+
7
+ def setup
8
+ super
9
+ begin
10
+ NewRelic::Agent::ModelFixture.setup
11
+ rescue => e
12
+ puts e
13
+ raise e
14
+ end
15
+ @agent = NewRelic::Agent.instance
16
+ @agent.start :test, :test
17
+ @agent.transaction_sampler.harvest_slowest_sample
18
+ end
19
+
20
+ def teardown
21
+ @agent.shutdown
22
+ @agent.stats_engine.harvest_timeslice_data Hash.new, Hash.new
23
+ NewRelic::Agent::ModelFixture.teardown
24
+ super
25
+ end
26
+
27
+ def test_finder
28
+ NewRelic::Agent::ModelFixture.create :id => 0, :name => 'jeff'
29
+ NewRelic::Agent::ModelFixture.find(:all)
30
+ s = NewRelic::Agent.get_stats("ActiveRecord/NewRelic::Agent::ModelFixture/find")
31
+ assert_equal 1, s.call_count
32
+ NewRelic::Agent::ModelFixture.find_all_by_name "jeff"
33
+ s = NewRelic::Agent.get_stats("ActiveRecord/NewRelic::Agent::ModelFixture/find")
34
+ assert_equal 2, s.call_count
35
+ end
36
+
37
+ def test_run_explains
38
+ NewRelic::Agent::ModelFixture.find(:all)
39
+ sample = @agent.transaction_sampler.harvest_slowest_sample
40
+ segment = sample.root_segment.called_segments.first.called_segments.first
41
+ assert_equal "SELECT * FROM `test_data`", segment.params[:sql].strip
42
+ NewRelic::TransactionSample::Segment.any_instance.expects(:explain_sql).returns([])
43
+ sample = sample.prepare_to_send(:obfuscate_sql => true, :explain_enabled => true, :explain_sql => 0.0)
44
+ segment = sample.root_segment.called_segments.first.called_segments.first
45
+ end
46
+ def test_prepare_to_send
47
+ NewRelic::Agent::ModelFixture.find(:all)
48
+ sample = @agent.transaction_sampler.harvest_slowest_sample
49
+ segment = sample.root_segment.called_segments.first.called_segments.first
50
+ assert_match /^SELECT /, segment.params[:sql]
51
+ assert segment.duration > 0.0, "Segment duration must be greater than zero."
52
+ sample = sample.prepare_to_send(:record_sql => :raw, :explain_enabled => true, :explain_sql => 0.0)
53
+ segment = sample.root_segment.called_segments.first.called_segments.first
54
+ assert_match /^SELECT /, segment.params[:sql]
55
+ explanations = segment.params[:explanation]
56
+ assert_not_nil explanations, "No explains in segment: #{segment}"
57
+ assert_equal 1, explanations.size,"No explains in segment: #{segment}"
58
+ assert_equal 1, explanations.first.size
59
+
60
+ end
61
+ def test_transaction
62
+
63
+ NewRelic::Agent::ModelFixture.find(:all)
64
+ sample = @agent.transaction_sampler.harvest_slowest_sample
65
+ sample = sample.prepare_to_send(:obfuscate_sql => true, :explain_enabled => true, :explain_sql => 0.0)
66
+ segment = sample.root_segment.called_segments.first.called_segments.first
67
+ assert_nil segment.params[:sql], "SQL should have been removed."
68
+ explanations = segment.params[:explanation]
69
+ assert_not_nil explanations, "No explains in segment: #{segment}"
70
+ assert_equal 1, explanations.size,"No explains in segment: #{segment}"
71
+ assert_equal 1, explanations.first.size
72
+
73
+ if isPostgres?
74
+ assert_equal Array, explanations.class
75
+ assert_equal Array, explanations[0].class
76
+ assert_equal Array, explanations[0][0].class
77
+ assert_match /Seq Scan on test_data/, explanations[0][0].join(";")
78
+ else
79
+ assert_equal "1;SIMPLE;test_data;ALL;;;;;1;", explanations.first.first.join(";")
80
+ end
81
+
82
+ s = NewRelic::Agent.get_stats("ActiveRecord/NewRelic::Agent::ModelFixture/find")
83
+ assert_equal 1, s.call_count
84
+ end
85
+
86
+ private
87
+ def isPostgres?
88
+ NewRelic::Agent::ModelFixture.configurations[RAILS_ENV]['adapter'] =~ /postgres/
89
+ end
90
+
91
+ end
@@ -0,0 +1,112 @@
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
+ require 'net/http'
5
+
6
+ class AgentTests < ActiveSupport::TestCase
7
+
8
+ attr_reader :agent
9
+
10
+ # Fake out the agent to think mongrel is running
11
+ def setup
12
+ @agent = NewRelic::Agent.instance
13
+ @agent.start :test, :test
14
+ end
15
+
16
+ # Remove the port method so it won't think mongrel
17
+ # is available
18
+ def teardown
19
+ @agent.shutdown
20
+ super
21
+ end
22
+
23
+ def test_public_apis
24
+ begin
25
+ NewRelic::Agent.set_sql_obfuscator(:unknown) do |sql|
26
+ puts sql
27
+ end
28
+ fail
29
+ rescue
30
+ # ok
31
+ end
32
+
33
+
34
+ ignore_called = false
35
+ NewRelic::Agent.ignore_error_filter do |e|
36
+ ignore_called = true
37
+ nil
38
+ end
39
+
40
+ NewRelic::Agent.agent.error_collector.notice_error('path', nil, {:x => 'y'}, ActionController::RoutingError.new("message"))
41
+
42
+ assert ignore_called
43
+ end
44
+
45
+ def test_startup_shutdown
46
+ @agent.shutdown
47
+ assert (not @agent.started?)
48
+ @agent.start "ruby", "test1"
49
+ assert @agent.started?
50
+ @agent.shutdown
51
+ @agent.start "ruby", "test2"
52
+ end
53
+ def test_setup_log_default
54
+ assert @agent.log.instance_of?(Logger), @agent.log
55
+ logfile = @agent.log.instance_eval { @logdev.filename }
56
+ assert_match /\/log\/newrelic_agent\..*\.log$/,logfile
57
+ @agent.shutdown
58
+ end
59
+
60
+ def test_classloading_patch
61
+ require 'new_relic/agent/patch_const_missing'
62
+ NewRelic::Agent::Agent.newrelic_set_agent_thread(Thread.current)
63
+ # try loading some non-existent class
64
+ NewRelic::Config.instance.log.expects(:warn).at_least_once.with{|args| args =~ /calling const_missing.*:FooBar/}
65
+ NewRelic::Config.instance.log.expects(:warn).with{|args| args =~ /calling const_missing.*:FooBaz/}.never
66
+ NewRelic::Agent::Agent.newrelic_enable_warning
67
+ assert_raise NameError do
68
+ FooBar::Bat
69
+ end
70
+ NewRelic::Agent::Agent.newrelic_disable_warning
71
+ assert_raise NameError do
72
+ FooBaz::Bat
73
+ end
74
+ end
75
+ def test_info
76
+ props = NewRelic::Config.instance.app_config_info
77
+ list = props.assoc('Plugin List').last.sort
78
+ assert_equal 4, (list & %w[active_merchant active_scaffold acts_as_list acts_as_state_machine ]).size, list.join("\n")
79
+ assert_equal 'mysql', props.assoc('Database adapter').last
80
+ end
81
+ def test_version
82
+ assert_match /\d\.\d\.\d+/, NewRelic::VERSION::STRING
83
+ end
84
+
85
+ def test_invoke_remote__ignore_non_200_results
86
+ NewRelic::Agent::Agent.class_eval do
87
+ public :invoke_remote
88
+ end
89
+ response_mock = mock()
90
+ Net::HTTP.any_instance.stubs(:request).returns(response_mock)
91
+ response_mock.stubs(:message).returns("bogus error")
92
+
93
+ for code in %w[500 504 400 302 503] do
94
+ assert_raise NewRelic::Agent::IgnoreSilentlyException, "Ignore #{code}" do
95
+ response_mock.stubs(:code).returns(code)
96
+ NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0
97
+ end
98
+ end
99
+ end
100
+ def test_invoke_remote__throw_other_errors
101
+ NewRelic::Agent::Agent.class_eval do
102
+ public :invoke_remote
103
+ end
104
+ response_mock = Net::HTTPSuccess.new nil, nil, nil
105
+ response_mock.stubs(:body).returns("")
106
+ Marshal.stubs(:load).raises(RuntimeError, "marshal issue")
107
+ Net::HTTP.any_instance.stubs(:request).returns(response_mock)
108
+ assert_raise RuntimeError do
109
+ NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0xFEFE
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,104 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
2
+ require 'ostruct'
3
+ require 'new_relic/agent/model_fixture'
4
+
5
+ class NewRelic::Agent::CollectionHelperTests < Test::Unit::TestCase
6
+
7
+ def setup
8
+ super
9
+ NewRelic::Agent::ModelFixture.setup
10
+ NewRelic::Agent.instance.start :test, :test
11
+ end
12
+ def teardown
13
+ NewRelic::Agent::ModelFixture.teardown
14
+ NewRelic::Agent.instance.shutdown
15
+ super
16
+ end
17
+
18
+ include NewRelic::Agent::CollectionHelper
19
+ def test_string
20
+ val = ('A'..'Z').to_a.join * 100
21
+ assert_equal val.first(256) + "...", normalize_params(val)
22
+ end
23
+ def test_array
24
+ new_array = normalize_params [ 1000 ] * 50
25
+ assert_equal 20, new_array.size
26
+ assert_equal '1000', new_array[0]
27
+ end
28
+ def test_boolean
29
+ np = normalize_params(APP_CONFIG)
30
+ assert_equal false, np['disable_ui']
31
+ end
32
+ def test_coercible_string
33
+ s = CoercibleString.new "This is a string"
34
+ assert_equal "This is a string", s.to_s
35
+ assert_equal CoercibleString, s.class
36
+ assert_equal String, s.to_s.class
37
+ params = normalize_params(:val => [s])
38
+ assert_equal String, params[:val][0].class
39
+ assert_equal String, flatten(s).class
40
+ assert_equal String, truncate(s, 2).class
41
+ end
42
+ def test_number
43
+ np = normalize_params({ 'one' => 1.0, 'two' => '2'})
44
+ end
45
+ def test_nil
46
+ np = normalize_params({ nil => 1.0, 'two' => nil})
47
+ assert_equal "1.0", np['']
48
+ assert_equal nil, np['two']
49
+ end
50
+ def test_hash
51
+ val = ('A'..'Z').to_a.join * 100
52
+ assert_equal Hash["ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF..." => (("0"*256) + "...")], normalize_params({ val => '0' * 512 })
53
+ end
54
+ class MyHash < Hash
55
+
56
+ end
57
+ # Test to ensure that hash subclasses are properly converted
58
+ def test_hash_subclass
59
+ h = MyHash.new
60
+ h[:mine] = 'mine'
61
+ custom_params = { :one => {:hash => { :a => :b}, :myhash => h }}
62
+ nh = normalize_params(custom_params)
63
+ myhash = custom_params[:one][:myhash]
64
+ assert_equal MyHash, myhash.class
65
+ myhash = nh[:one][:myhash]
66
+ assert_equal Hash, myhash.class
67
+ end
68
+
69
+ class MyEnumerable
70
+ include Enumerable
71
+
72
+ def each
73
+ yield "1"
74
+ end
75
+ end
76
+
77
+ def test_enumerable
78
+ e = MyEnumerable.new
79
+ custom_params = { :one => {:hash => { :a => :b}, :myenum => e }}
80
+ nh = normalize_params(custom_params)
81
+ myenum = nh[:one][:myenum]
82
+ assert_equal ["1"], myenum
83
+ end
84
+
85
+
86
+ def test_object
87
+ assert_equal ["foo", '#<OpenStruct z="q">'], normalize_params(['foo', OpenStruct.new('z'=>'q')])
88
+ end
89
+
90
+ def test_strip_backtrace
91
+ begin
92
+ NewRelic::Agent::ModelFixture.find 0
93
+ flunk "should throw"
94
+ rescue => e
95
+ # puts e
96
+ # puts e.backtrace.join("\n")
97
+ # puts "\n\n"
98
+ clean_trace = strip_nr_from_backtrace(e.backtrace)
99
+ assert_equal 0, clean_trace.grep(/newrelic_rpm/).size, clean_trace.grep(/newrelic_rpm/)
100
+ assert_equal 0, clean_trace.grep(/trace/).size, clean_trace.grep(/trace/)
101
+ assert_equal 3, clean_trace.grep(/find/).size, "should see three frames with 'find' in them: \n#{clean_trace.join("\n")}"
102
+ end
103
+ end
104
+ end