PageRenderTime 33ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/test/new_relic/agent/task_instrumentation_test.rb

https://github.com/reillyse/rpm
Ruby | 188 lines | 162 code | 20 blank | 6 comment | 2 complexity | 042f8f6b7247a1b87bc7f741677eac7f MD5 | raw file
  1. # Run faster standalone
  2. ENV['SKIP_RAILS'] = 'true'
  3. require File.expand_path('../../../test_helper', __FILE__)
  4. class TaskInstrumentationTest < Test::Unit::TestCase
  5. include NewRelic::Agent::Instrumentation::ControllerInstrumentation
  6. extend TestContexts
  7. attr_accessor :agent
  8. with_running_agent do
  9. should "run" do
  10. run_task_inner 0
  11. stat_names = %w[Controller/TaskInstrumentationTest/inner_task_0
  12. HttpDispatcher
  13. Apdex Apdex/TaskInstrumentationTest/inner_task_0].sort
  14. expected_but_missing = stat_names - @agent.stats_engine.metrics
  15. assert_equal 0, expected_but_missing.size, @agent.stats_engine.metrics.map { |n|
  16. stat = @agent.stats_engine.get_stats_no_scope(n)
  17. "#{'%-26s' % n}: #{stat.call_count} calls @ #{stat.average_call_time} sec/call"
  18. }.join("\n ") + "\nmissing: #{expected_but_missing.inspect}"
  19. assert_equal 0, @agent.stats_engine.get_stats_no_scope('Controller').call_count
  20. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_0').call_count
  21. end
  22. should "run_recursive" do
  23. run_task_inner(3)
  24. assert_equal 1, @agent.stats_engine.lookup_stats(
  25. 'Controller/TaskInstrumentationTest/inner_task_0',
  26. 'Controller/TaskInstrumentationTest/inner_task_1').call_count
  27. assert_equal 1, @agent.stats_engine.lookup_stats(
  28. 'Controller/TaskInstrumentationTest/inner_task_1',
  29. 'Controller/TaskInstrumentationTest/inner_task_2').call_count
  30. assert_equal 1, @agent.stats_engine.lookup_stats(
  31. 'Controller/TaskInstrumentationTest/inner_task_2',
  32. 'Controller/TaskInstrumentationTest/inner_task_3').call_count
  33. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_0').call_count
  34. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_1').call_count
  35. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_2').call_count
  36. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_3').call_count
  37. assert_equal 0, @agent.stats_engine.get_stats_no_scope('Controller').call_count
  38. end
  39. should "run_nested" do
  40. run_task_outer(3)
  41. @agent.stats_engine.metrics.sort.each do |n|
  42. stat = @agent.stats_engine.get_stats_no_scope(n)
  43. # puts "#{'%-26s' % n}: #{stat.call_count} calls @ #{stat.average_call_time} sec/call"
  44. end
  45. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/outer_task').call_count
  46. assert_equal 2, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_0').call_count
  47. end
  48. should "reentrancy" do
  49. assert_equal 0, NewRelic::Agent::BusyCalculator.busy_count
  50. run_task_inner(1)
  51. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_0').call_count
  52. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_1').call_count
  53. compare_metrics %w[
  54. Controller/TaskInstrumentationTest/inner_task_0:Controller/TaskInstrumentationTest/inner_task_1
  55. Controller/TaskInstrumentationTest/inner_task_0
  56. Controller/TaskInstrumentationTest/inner_task_1
  57. ], @agent.stats_engine.metrics.grep(/^Controller/)
  58. end
  59. should "transaction" do
  60. assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
  61. assert_nil @agent.transaction_sampler.last_sample
  62. assert_equal @agent.transaction_sampler, @agent.stats_engine.instance_variable_get("@transaction_sampler")
  63. run_task_outer(10)
  64. assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
  65. @agent.stats_engine.metrics.sort.each do |n|
  66. stat = @agent.stats_engine.get_stats_no_scope(n)
  67. # puts "#{'%-26s' % n}: #{stat.call_count} calls @ #{stat.average_call_time} sec/call"
  68. end
  69. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/outer_task').call_count
  70. assert_equal 0, @agent.stats_engine.get_stats_no_scope('Controller').call_count
  71. assert_equal 2, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/inner_task_0').call_count
  72. assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
  73. sample = @agent.transaction_sampler.last_sample
  74. assert_not_nil sample
  75. assert_not_nil sample.params[:cpu_time], "cpu time nil: \n#{sample}"
  76. assert sample.params[:cpu_time] >= 0, "cpu time: #{sample.params[:cpu_time]},\n#{sample}"
  77. assert_equal '10', sample.params[:request_params][:level]
  78. end
  79. should "abort" do
  80. @acct = 'Redrocks'
  81. perform_action_with_newrelic_trace(:name => 'hello', :force => true, :params => { :account => @acct}) do
  82. self.class.inspect
  83. NewRelic::Agent.abort_transaction!
  84. end
  85. # We record the controller metric still, but abort any transaction recording.
  86. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/hello').call_count
  87. assert_nil @agent.transaction_sampler.last_sample
  88. end
  89. should "block" do
  90. assert_equal @agent, NewRelic::Agent.instance
  91. @acct = 'Redrocks'
  92. perform_action_with_newrelic_trace(:name => 'hello', :force => true, :params => { :account => @acct}) do
  93. self.class.inspect
  94. end
  95. @agent.stats_engine.metrics.sort.each do |n|
  96. stat = @agent.stats_engine.get_stats_no_scope(n)
  97. #puts "#{'%-26s' % n}: #{stat.call_count} calls @ #{stat.average_call_time} sec/call"
  98. end
  99. assert_equal @agent, NewRelic::Agent.instance
  100. assert_equal 1, @agent.stats_engine.get_stats_no_scope('Controller/TaskInstrumentationTest/hello').call_count
  101. sample = @agent.transaction_sampler.last_sample
  102. assert_not_nil sample
  103. assert_equal 'Redrocks', sample.params[:request_params][:account]
  104. end
  105. should "error_handling" do
  106. @agent.error_collector.ignore_error_filter
  107. @agent.error_collector.harvest_errors([])
  108. @agent.error_collector.expects(:notice_error).once
  109. assert_equal @agent.error_collector, NewRelic::Agent.instance.error_collector
  110. assert_raise RuntimeError do
  111. run_task_exception
  112. end
  113. end
  114. should "custom_params" do
  115. @agent.error_collector.stubs(:enabled).returns(true)
  116. @agent.error_collector.ignore_error_filter
  117. @agent.error_collector.harvest_errors([])
  118. assert_equal @agent.error_collector, NewRelic::Agent.instance.error_collector
  119. assert_raise RuntimeError do
  120. run_task_exception
  121. end
  122. errors = @agent.error_collector.harvest_errors([])
  123. assert_equal 1, errors.size
  124. error = errors.first
  125. assert_equal "Controller/TaskInstrumentationTest/run_task_exception", error.path
  126. assert_not_nil error.params[:stack_trace]
  127. assert_not_nil error.params[:custom_params]
  128. end
  129. should "instrument_bg" do
  130. run_background_job
  131. stat_names = %w[OtherTransaction/Background/TaskInstrumentationTest/run_background_job
  132. OtherTransaction/Background/all
  133. OtherTransaction/all].sort
  134. expected_but_missing = stat_names - @agent.stats_engine.metrics
  135. assert_equal 0, expected_but_missing.size, @agent.stats_engine.metrics.map { |n|
  136. stat = @agent.stats_engine.get_stats_no_scope(n)
  137. "#{'%-26s' % n}: #{stat.call_count} calls @ #{stat.average_call_time} sec/call"
  138. }.join("\n ") + "\nmissing: #{expected_but_missing.inspect}"
  139. assert_equal 1, @agent.stats_engine.get_stats_no_scope('OtherTransaction/all').call_count
  140. assert_equal 1, @agent.stats_engine.get_stats_no_scope('OtherTransaction/Background/all').call_count
  141. end
  142. end
  143. private
  144. def run_task_inner(n)
  145. sleep 0.1
  146. return if n == 0
  147. assert_equal 1, NewRelic::Agent::BusyCalculator.busy_count
  148. run_task_inner(n-1)
  149. end
  150. def run_task_outer(n=0)
  151. assert_equal 1, NewRelic::Agent::BusyCalculator.busy_count
  152. run_task_inner(n)
  153. run_task_inner(n)
  154. end
  155. def run_task_exception
  156. NewRelic::Agent.add_custom_parameters(:custom_one => 'one custom val')
  157. assert_equal 1, NewRelic::Agent::BusyCalculator.busy_count
  158. raise "This is an error"
  159. end
  160. def run_background_job
  161. "This is a background job"
  162. end
  163. add_transaction_tracer :run_task_exception
  164. add_transaction_tracer :run_task_inner, :name => 'inner_task_#{args[0]}'
  165. add_transaction_tracer :run_task_outer, :name => 'outer_task', :params => '{ :level => args[0] }'
  166. # Eventually we need th change this to :category => :task
  167. add_transaction_tracer :run_background_job, :category => 'OtherTransaction/Background'
  168. end