wd_newrelic_rpm 3.3.4.1 → 3.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (290) hide show
  1. data/.gitignore +20 -0
  2. data/.project +23 -0
  3. data/.travis.yml +9 -0
  4. data/CHANGELOG +317 -39
  5. data/GUIDELINES_FOR_CONTRIBUTING.md +76 -0
  6. data/Gemfile +16 -0
  7. data/LICENSE +1 -1
  8. data/{README.rdoc → README.md} +71 -55
  9. data/Rakefile +62 -0
  10. data/bin/mongrel_rpm +1 -1
  11. data/config.dot +290 -0
  12. data/config/database.yml +5 -0
  13. data/init.rb +31 -0
  14. data/lib/new_relic/agent.rb +31 -60
  15. data/lib/new_relic/agent/agent.rb +277 -502
  16. data/lib/new_relic/agent/agent_logger.rb +165 -0
  17. data/lib/new_relic/agent/audit_logger.rb +72 -0
  18. data/lib/new_relic/agent/beacon_configuration.rb +36 -50
  19. data/lib/new_relic/agent/browser_monitoring.rb +114 -61
  20. data/lib/new_relic/agent/busy_calculator.rb +14 -6
  21. data/lib/new_relic/agent/configuration.rb +74 -0
  22. data/lib/new_relic/agent/configuration/defaults.rb +126 -0
  23. data/lib/new_relic/agent/configuration/environment_source.rb +49 -0
  24. data/lib/new_relic/agent/configuration/manager.rb +136 -0
  25. data/lib/new_relic/agent/configuration/mask_defaults.rb +10 -0
  26. data/lib/new_relic/agent/configuration/server_source.rb +27 -0
  27. data/lib/new_relic/agent/configuration/yaml_source.rb +63 -0
  28. data/lib/new_relic/agent/cross_process_monitoring.rb +43 -0
  29. data/lib/new_relic/agent/database.rb +39 -26
  30. data/lib/new_relic/agent/error_collector.rb +48 -49
  31. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
  32. data/lib/new_relic/agent/instrumentation/active_record.rb +4 -7
  33. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +1 -1
  34. data/lib/new_relic/agent/instrumentation/authlogic.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/browser_monitoring_timings.rb +41 -0
  36. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +35 -12
  37. data/lib/new_relic/agent/instrumentation/data_mapper.rb +4 -12
  38. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +2 -2
  39. data/lib/new_relic/agent/instrumentation/memcache.rb +6 -6
  40. data/lib/new_relic/agent/instrumentation/merb/controller.rb +1 -1
  41. data/lib/new_relic/agent/instrumentation/merb/errors.rb +1 -1
  42. data/lib/new_relic/agent/instrumentation/metric_frame.rb +4 -14
  43. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -1
  44. data/lib/new_relic/agent/instrumentation/net.rb +1 -1
  45. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +6 -20
  46. data/lib/new_relic/agent/instrumentation/queue_time.rb +2 -2
  47. data/lib/new_relic/agent/instrumentation/rack.rb +1 -1
  48. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +7 -7
  49. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
  50. data/lib/new_relic/agent/instrumentation/rails/errors.rb +1 -1
  51. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +5 -5
  52. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +6 -2
  53. data/lib/new_relic/agent/instrumentation/resque.rb +81 -0
  54. data/lib/new_relic/agent/instrumentation/sinatra.rb +21 -10
  55. data/lib/new_relic/agent/instrumentation/sunspot.rb +1 -1
  56. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +5 -4
  57. data/lib/new_relic/agent/method_tracer.rb +11 -9
  58. data/lib/new_relic/agent/new_relic_service.rb +379 -0
  59. data/lib/new_relic/agent/pipe_channel_manager.rb +175 -0
  60. data/lib/new_relic/agent/pipe_service.rb +58 -0
  61. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +86 -0
  62. data/lib/new_relic/agent/samplers/memory_sampler.rb +6 -8
  63. data/lib/new_relic/agent/sql_sampler.rb +31 -74
  64. data/lib/new_relic/agent/stats_engine.rb +0 -5
  65. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +40 -24
  66. data/lib/new_relic/agent/stats_engine/metric_stats.rb +89 -14
  67. data/lib/new_relic/agent/stats_engine/samplers.rb +9 -7
  68. data/lib/new_relic/agent/stats_engine/transactions.rb +20 -12
  69. data/lib/new_relic/agent/thread.rb +32 -0
  70. data/lib/new_relic/agent/thread_profiler.rb +306 -0
  71. data/lib/new_relic/agent/transaction_info.rb +24 -4
  72. data/lib/new_relic/agent/transaction_sample_builder.rb +12 -13
  73. data/lib/new_relic/agent/transaction_sampler.rb +49 -65
  74. data/lib/new_relic/agent/worker_loop.rb +31 -25
  75. data/lib/new_relic/collection_helper.rb +1 -1
  76. data/lib/new_relic/commands/deployments.rb +19 -10
  77. data/lib/new_relic/control.rb +1 -3
  78. data/lib/new_relic/control/class_methods.rb +10 -5
  79. data/lib/new_relic/control/frameworks/merb.rb +0 -6
  80. data/lib/new_relic/control/frameworks/rails.rb +30 -45
  81. data/lib/new_relic/control/frameworks/rails3.rb +23 -18
  82. data/lib/new_relic/control/frameworks/rails4.rb +23 -0
  83. data/lib/new_relic/control/frameworks/ruby.rb +2 -23
  84. data/lib/new_relic/control/instance_methods.rb +35 -73
  85. data/lib/new_relic/control/instrumentation.rb +7 -12
  86. data/lib/new_relic/control/server_methods.rb +17 -19
  87. data/lib/new_relic/delayed_job_injection.rb +2 -2
  88. data/lib/new_relic/helper.rb +34 -0
  89. data/lib/new_relic/language_support.rb +56 -37
  90. data/lib/new_relic/local_environment.rb +32 -67
  91. data/lib/new_relic/metric_data.rb +10 -2
  92. data/lib/new_relic/metric_spec.rb +7 -3
  93. data/lib/new_relic/noticed_error.rb +32 -9
  94. data/lib/new_relic/rack.rb +4 -0
  95. data/lib/new_relic/rack/browser_monitoring.rb +34 -25
  96. data/lib/new_relic/rack/developer_mode.rb +3 -0
  97. data/lib/new_relic/rack/error_collector.rb +56 -0
  98. data/lib/new_relic/stats.rb +9 -7
  99. data/lib/new_relic/transaction_sample.rb +19 -18
  100. data/lib/new_relic/transaction_sample/segment.rb +13 -15
  101. data/lib/new_relic/version.rb +19 -3
  102. data/lib/newrelic_rpm.rb +1 -1
  103. data/lib/tasks/tests.rake +6 -8
  104. data/newrelic.yml +15 -32
  105. data/newrelic_rpm.gemspec +224 -43
  106. data/newrelic_rpm.gemspec.erb +54 -0
  107. data/test/config/newrelic.yml +4 -3
  108. data/test/config/test_control.rb +18 -18
  109. data/test/fixtures/gemspec_no_build.rb +442 -0
  110. data/test/fixtures/gemspec_with_build.rb +442 -0
  111. data/test/fixtures/gemspec_with_build_and_stage.rb +442 -0
  112. data/test/intentional_fail.rb +10 -0
  113. data/test/multiverse/.gitignore +10 -0
  114. data/test/multiverse/README.md +85 -0
  115. data/test/multiverse/lib/multiverse/color.rb +13 -0
  116. data/test/multiverse/lib/multiverse/envfile.rb +66 -0
  117. data/test/multiverse/lib/multiverse/environment.rb +16 -0
  118. data/test/multiverse/lib/multiverse/output_collector.rb +29 -0
  119. data/test/multiverse/lib/multiverse/runner.rb +44 -0
  120. data/test/multiverse/lib/multiverse/suite.rb +162 -0
  121. data/test/multiverse/script/run_one +3 -0
  122. data/test/multiverse/script/runner +9 -0
  123. data/test/multiverse/suites/active_record/Envfile +13 -0
  124. data/test/multiverse/suites/active_record/ar_method_aliasing.rb +94 -0
  125. data/test/multiverse/suites/active_record/config/newrelic.yml +22 -0
  126. data/test/multiverse/suites/active_record/encoding_test.rb +26 -0
  127. data/test/multiverse/suites/agent_only/Envfile +4 -0
  128. data/test/multiverse/suites/agent_only/audit_log_test.rb +99 -0
  129. data/test/multiverse/suites/agent_only/config/newrelic.yml +22 -0
  130. data/test/multiverse/suites/agent_only/http_response_code_test.rb +53 -0
  131. data/test/multiverse/suites/agent_only/marshaling_test.rb +109 -0
  132. data/test/multiverse/suites/agent_only/method_visibility_test.rb +98 -0
  133. data/test/multiverse/suites/agent_only/pipe_manager_test.rb +33 -0
  134. data/test/multiverse/suites/agent_only/service_timeout_test.rb +29 -0
  135. data/test/multiverse/suites/agent_only/test_trace_method_with_punctuation.rb +30 -0
  136. data/test/multiverse/suites/agent_only/test_trace_transaction_with_punctuation.rb +32 -0
  137. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +80 -0
  138. data/test/multiverse/suites/config_file_loading/Envfile +7 -0
  139. data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +106 -0
  140. data/test/multiverse/suites/datamapper/Envfile +8 -0
  141. data/test/multiverse/suites/datamapper/config/newrelic.yml +22 -0
  142. data/test/multiverse/suites/datamapper/encoding_test.rb +36 -0
  143. data/test/multiverse/suites/logging/Envfile +4 -0
  144. data/test/multiverse/suites/logging/config/newrelic.yml +22 -0
  145. data/test/multiverse/suites/logging/logging_test.rb +143 -0
  146. data/test/multiverse/suites/monitor_mode_false/Envfile +2 -0
  147. data/test/multiverse/suites/monitor_mode_false/config/newrelic.yml +25 -0
  148. data/test/multiverse/suites/monitor_mode_false/no_dns_resolv.rb +29 -0
  149. data/test/multiverse/suites/no_load/Envfile +2 -0
  150. data/test/multiverse/suites/no_load/config/newrelic.yml +22 -0
  151. data/test/multiverse/suites/no_load/start_up_test.rb +14 -0
  152. data/test/multiverse/suites/rails_3_error_tracing/Envfile +15 -0
  153. data/test/multiverse/suites/rails_3_error_tracing/config/newrelic.yml +165 -0
  154. data/test/multiverse/suites/rails_3_error_tracing/error_tracing_test.rb +236 -0
  155. data/test/multiverse/suites/rails_3_gc/Envfile +8 -0
  156. data/test/multiverse/suites/rails_3_gc/config/newrelic.yml +167 -0
  157. data/test/multiverse/suites/rails_3_gc/instrumentation_test.rb +92 -0
  158. data/test/multiverse/suites/rails_3_queue_time/Envfile +15 -0
  159. data/test/multiverse/suites/rails_3_queue_time/config/newrelic.yml +165 -0
  160. data/test/multiverse/suites/rails_3_queue_time/queue_time_test.rb +75 -0
  161. data/test/multiverse/suites/rails_3_views/.gitignore +3 -0
  162. data/test/multiverse/suites/rails_3_views/Envfile +16 -0
  163. data/test/multiverse/suites/rails_3_views/app/views/foos/_foo.html.haml +1 -0
  164. data/test/multiverse/suites/rails_3_views/app/views/test/_a_partial.html.erb +1 -0
  165. data/test/multiverse/suites/rails_3_views/app/views/test/_mid_partial.html.erb +1 -0
  166. data/test/multiverse/suites/rails_3_views/app/views/test/_top_partial.html.erb +3 -0
  167. data/test/multiverse/suites/rails_3_views/app/views/test/deep_partial.html.erb +3 -0
  168. data/test/multiverse/suites/rails_3_views/app/views/test/haml_view.html.haml +6 -0
  169. data/test/multiverse/suites/rails_3_views/app/views/test/index.html.erb +4 -0
  170. data/test/multiverse/suites/rails_3_views/config/newrelic.yml +164 -0
  171. data/test/multiverse/suites/rails_3_views/view_instrumentation_test.rb +245 -0
  172. data/test/multiverse/suites/resque/Envfile +21 -0
  173. data/test/multiverse/suites/resque/config/newrelic.yml +22 -0
  174. data/test/multiverse/suites/resque/dump.rdb +0 -0
  175. data/test/multiverse/suites/resque/instrumentation_test.rb +73 -0
  176. data/test/multiverse/suites/rum_auto_instrumentation/Envfile +4 -0
  177. data/test/multiverse/suites/rum_auto_instrumentation/config/newrelic.yml +24 -0
  178. data/test/multiverse/suites/rum_auto_instrumentation/responses/worst_case_small.html +5000 -0
  179. data/test/multiverse/suites/rum_auto_instrumentation/sanity_test.rb +102 -0
  180. data/test/multiverse/suites/sinatra/Envfile +13 -0
  181. data/test/multiverse/suites/sinatra/config/newrelic.yml +24 -0
  182. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +77 -0
  183. data/test/multiverse/suites/sinatra/sinatra_routes_test.rb +46 -0
  184. data/test/multiverse/suites/sinatra/sinatra_test.rb +55 -0
  185. data/test/multiverse/test/multiverse_test.rb +55 -0
  186. data/test/multiverse/test/suite_examples/one/a/Envfile +3 -0
  187. data/test/multiverse/test/suite_examples/one/a/a_test.rb +11 -0
  188. data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +24 -0
  189. data/test/multiverse/test/suite_examples/one/b/Envfile +3 -0
  190. data/test/multiverse/test/suite_examples/one/b/b_test.rb +11 -0
  191. data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +24 -0
  192. data/test/multiverse/test/suite_examples/three/a/Envfile +2 -0
  193. data/test/multiverse/test/suite_examples/three/a/fail_test.rb +6 -0
  194. data/test/multiverse/test/suite_examples/three/b/Envfile +2 -0
  195. data/test/multiverse/test/suite_examples/three/b/win_test.rb +6 -0
  196. data/test/multiverse/test/suite_examples/two/a/Envfile +1 -0
  197. data/test/multiverse/test/suite_examples/two/a/fail_test.rb +6 -0
  198. data/test/new_relic/agent/agent/connect_test.rb +151 -227
  199. data/test/new_relic/agent/agent/start_test.rb +68 -118
  200. data/test/new_relic/agent/agent/start_worker_thread_test.rb +12 -74
  201. data/test/new_relic/agent/agent_logger_test.rb +153 -0
  202. data/test/new_relic/agent/agent_test.rb +116 -30
  203. data/test/new_relic/agent/agent_test_controller.rb +1 -1
  204. data/test/new_relic/agent/agent_test_controller_test.rb +42 -10
  205. data/test/new_relic/agent/audit_logger_test.rb +105 -0
  206. data/test/new_relic/agent/beacon_configuration_test.rb +63 -67
  207. data/test/new_relic/agent/browser_monitoring_test.rb +151 -79
  208. data/test/new_relic/agent/busy_calculator_test.rb +7 -0
  209. data/test/new_relic/agent/configuration/environment_source_test.rb +79 -0
  210. data/test/new_relic/agent/configuration/manager_test.rb +204 -0
  211. data/test/new_relic/agent/configuration/server_source_test.rb +45 -0
  212. data/test/new_relic/agent/configuration/yaml_source_test.rb +75 -0
  213. data/test/new_relic/agent/cross_process_monitoring_test.rb +77 -0
  214. data/test/new_relic/agent/database_test.rb +12 -11
  215. data/test/new_relic/agent/error_collector/notice_error_test.rb +64 -53
  216. data/test/new_relic/agent/error_collector_test.rb +33 -19
  217. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +60 -30
  218. data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +39 -0
  219. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +1 -1
  220. data/test/new_relic/agent/instrumentation/metric_frame_test.rb +6 -0
  221. data/test/new_relic/agent/instrumentation/queue_time_test.rb +14 -0
  222. data/test/new_relic/agent/instrumentation/sinatra_test.rb +25 -0
  223. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
  224. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +4 -10
  225. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +3 -15
  226. data/test/new_relic/agent/method_tracer_test.rb +7 -6
  227. data/test/new_relic/agent/mock_scope_listener.rb +3 -0
  228. data/test/new_relic/agent/new_relic_service_test.rb +376 -0
  229. data/test/new_relic/agent/pipe_channel_manager_test.rb +131 -0
  230. data/test/new_relic/agent/pipe_service_test.rb +113 -0
  231. data/test/new_relic/agent/rpm_agent_test.rb +27 -50
  232. data/test/new_relic/agent/sql_sampler_test.rb +81 -56
  233. data/test/new_relic/agent/stats_engine/metric_stats/harvest_test.rb +3 -20
  234. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +12 -1
  235. data/test/new_relic/agent/stats_engine_test.rb +17 -8
  236. data/test/new_relic/agent/thread_profiler_test.rb +537 -0
  237. data/test/new_relic/agent/thread_test.rb +89 -0
  238. data/test/new_relic/agent/threaded_test.rb +65 -0
  239. data/test/new_relic/agent/transaction_info_test.rb +45 -4
  240. data/test/new_relic/agent/transaction_sample_builder_test.rb +8 -7
  241. data/test/new_relic/agent/transaction_sampler_test.rb +193 -204
  242. data/test/new_relic/agent/worker_loop_test.rb +26 -11
  243. data/test/new_relic/agent_test.rb +113 -33
  244. data/test/new_relic/collection_helper_test.rb +7 -8
  245. data/test/new_relic/command/deployments_test.rb +18 -2
  246. data/test/new_relic/control/class_methods_test.rb +0 -18
  247. data/test/new_relic/control/frameworks/rails_test.rb +26 -0
  248. data/test/new_relic/control_test.rb +96 -137
  249. data/test/new_relic/delayed_job_injection_test.rb +6 -1
  250. data/test/new_relic/dispatcher_test.rb +54 -0
  251. data/test/new_relic/fake_collector.rb +283 -0
  252. data/test/new_relic/fake_service.rb +53 -0
  253. data/test/new_relic/fakes_sending_data.rb +30 -0
  254. data/test/new_relic/framework_test.rb +53 -0
  255. data/test/new_relic/load_test.rb +13 -0
  256. data/test/new_relic/local_environment_test.rb +11 -11
  257. data/test/new_relic/metric_data_test.rb +45 -16
  258. data/test/new_relic/noticed_error_test.rb +24 -0
  259. data/test/new_relic/rack/browser_monitoring_test.rb +20 -10
  260. data/test/new_relic/rack/developer_mode_test.rb +13 -7
  261. data/test/new_relic/rack/error_collector_test.rb +74 -0
  262. data/test/new_relic/stats_test.rb +10 -0
  263. data/test/new_relic/transaction_sample/segment_test.rb +23 -4
  264. data/test/new_relic/transaction_sample_test.rb +47 -2
  265. data/test/new_relic/version_number_test.rb +32 -0
  266. data/test/script/build_test_gem.sh +9 -3
  267. data/test/script/ci.sh +108 -35
  268. data/test/script/ci_agent-tests_runner.sh +82 -0
  269. data/test/script/ci_multiverse_runner.sh +63 -0
  270. data/test/test_contexts.rb +1 -0
  271. data/test/test_helper.rb +68 -18
  272. data/ui/helpers/developer_mode_helper.rb +21 -11
  273. data/ui/views/layouts/newrelic_default.rhtml +1 -0
  274. data/ui/views/newrelic/file/images/arrow-close.png +0 -0
  275. data/ui/views/newrelic/file/images/arrow-open.png +0 -0
  276. data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
  277. data/ui/views/newrelic/file/images/file_icon.png +0 -0
  278. data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
  279. data/ui/views/newrelic/show_sample.rhtml +1 -1
  280. data/ui/views/newrelic/threads.rhtml +2 -10
  281. data/vendor/gems/metric_parser-0.1.0.pre1/.specification +116 -0
  282. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_init.rb +7 -0
  283. metadata +191 -65
  284. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +0 -40
  285. data/lib/new_relic/control/configuration.rb +0 -206
  286. data/lib/new_relic/control/logging_methods.rb +0 -143
  287. data/lib/new_relic/data_serialization.rb +0 -151
  288. data/test/new_relic/control/configuration_test.rb +0 -84
  289. data/test/new_relic/control/logging_methods_test.rb +0 -185
  290. data/test/new_relic/data_serialization_test.rb +0 -208
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper'))
2
+ require 'new_relic/agent/instrumentation/sinatra'
3
+
4
+ class NewRelic::Agent::Instrumentation::SinatraTest < Test::Unit::TestCase
5
+ class SinatraTestApp
6
+ def initialize(response)
7
+ @response = response
8
+ end
9
+
10
+ def dispatch!
11
+ @response = response
12
+ end
13
+
14
+ include NewRelic::Agent::Instrumentation::Sinatra
15
+ alias dispatch_without_newrelic dispatch!
16
+ alias dispatch! dispatch_with_newrelic
17
+ end
18
+
19
+ def test_newrelic_request_headers
20
+ app = SinatraTestApp.new([200, {}, ["OK"]])
21
+ expected_headers = {:fake => :header}
22
+ app.expects(:request).returns(mock('request', :env => expected_headers))
23
+ assert_equal app.send(:newrelic_request_headers), expected_headers
24
+ end
25
+ end
@@ -77,8 +77,8 @@ class NewRelic::Agent::Instrumentation::TaskInstrumentationTest < Test::Unit::Te
77
77
  assert_equal 0, @agent.transaction_sampler.scope_depth, "existing unfinished sample"
78
78
  sample = @agent.transaction_sampler.last_sample
79
79
  assert_not_nil sample
80
- assert_not_nil sample.params[:cpu_time], "cpu time nil: \n#{sample}"
81
- assert sample.params[:cpu_time] >= 0, "cpu time: #{sample.params[:cpu_time]},\n#{sample}"
80
+ assert_not_nil sample.params[:custom_params][:cpu_time], "cpu time nil: \n#{sample}"
81
+ assert sample.params[:custom_params][:cpu_time] >= 0, "cpu time: #{sample.params[:cpu_time]},\n#{sample}"
82
82
  assert_equal '10', sample.params[:request_params][:level]
83
83
  end
84
84
 
@@ -35,7 +35,7 @@ module NewRelic
35
35
  end
36
36
 
37
37
  def test_default_metric_name_code
38
- assert_equal "Custom/#{name}/test_method", default_metric_name_code('test_method')
38
+ assert_equal "Custom/#{self.class.name}/test_method", self.class.default_metric_name_code('test_method')
39
39
  end
40
40
 
41
41
  def test_newrelic_method_exists_positive
@@ -44,13 +44,10 @@ module NewRelic
44
44
  end
45
45
 
46
46
  def test_newrelic_method_exists_negative
47
- self.expects(:method_defined?).returns(false)
48
- self.expects(:private_method_defined?).returns(false)
47
+ self.class.expects(:method_defined?).returns(false)
48
+ self.class.expects(:private_method_defined?).returns(false)
49
49
 
50
- fake_log = mock('log')
51
- NewRelic::Control.instance.expects(:log).returns(fake_log)
52
- fake_log.expects(:warn).with("Did not trace #{name}#test_method because that method does not exist")
53
- assert !newrelic_method_exists?('test_method')
50
+ assert !self.class.newrelic_method_exists?('test_method')
54
51
  end
55
52
 
56
53
  def test_set_deduct_call_time_based_on_metric_positive
@@ -111,9 +108,6 @@ module NewRelic
111
108
  def test_traced_method_exists_positive
112
109
  self.expects(:_traced_method_name)
113
110
  self.expects(:method_defined?).returns(true)
114
- fake_log = mock('log')
115
- NewRelic::Control.instance.expects(:log).returns(fake_log)
116
- fake_log.expects(:warn).with('Attempt to trace a method twice with the same metric: Method = test_method, Metric Name = Custom/Test/test_method')
117
111
  assert traced_method_exists?('test_method', 'Custom/Test/test_method')
118
112
  end
119
113
 
@@ -104,7 +104,6 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
104
104
  end
105
105
 
106
106
  def test_log_errors_base
107
- NewRelic::Control.instance.expects(:log).never
108
107
  ran = false
109
108
  log_errors("name", "metric") do
110
109
  ran = true
@@ -113,7 +112,6 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
113
112
  end
114
113
 
115
114
  def test_log_errors_with_return
116
- NewRelic::Control.instance.expects(:log).never
117
115
  ran = false
118
116
  return_val = log_errors('name', 'metric') do
119
117
  ran = true
@@ -125,13 +123,9 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
125
123
  end
126
124
 
127
125
  def test_log_errors_with_error
128
- fakelog = mock('log')
129
- NewRelic::Control.instance.expects(:log).returns(fakelog).at_least_once
130
- # normally I don't do this, but we really don't care what the
131
- # backtrace looks like, beyond that it actually gets logged. Also,
132
- # the mocks are reversed because apparently order matters.
133
- fakelog.expects(:error).with(any_parameters)
134
- fakelog.expects(:error).with("Caught exception in name. Metric name = metric, exception = should not propagate out of block")
126
+ expects_logging(:error,
127
+ includes("Caught exception in name. Metric name = metric"),
128
+ instance_of(RuntimeError))
135
129
 
136
130
  log_errors("name", "metric") do
137
131
  raise "should not propagate out of block"
@@ -221,12 +215,6 @@ class NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScopedTest <
221
215
  object
222
216
  end
223
217
 
224
-
225
- def mocked_log
226
- mocked_object('log')
227
- end
228
-
229
-
230
218
  def mocked_control
231
219
  mocked_object('control')
232
220
  end
@@ -244,6 +244,7 @@ class NewRelic::Agent::MethodTracerTest < Test::Unit::TestCase
244
244
  t1 = Time.now
245
245
  method_with_block(1,2,3,true,METRIC) do |scope|
246
246
  assert scope == METRIC
247
+ sleep 0.1 # pad the test a bit to increase the margin of error
247
248
  end
248
249
  elapsed = Time.now - t1
249
250
 
@@ -323,14 +324,14 @@ class NewRelic::Agent::MethodTracerTest < Test::Unit::TestCase
323
324
  end
324
325
 
325
326
  def test_add_multiple_tracers
326
- self.class.add_method_tracer :method_to_be_traced, 'X', :push_scope => false
327
+ self.class.add_method_tracer :method_to_be_traced, 'XX', :push_scope => false
327
328
  method_to_be_traced 1,2,3,true,nil
328
- self.class.add_method_tracer :method_to_be_traced, 'Y'
329
- method_to_be_traced 1,2,3,true,'Y'
330
- self.class.remove_method_tracer :method_to_be_traced, 'Y'
329
+ self.class.add_method_tracer :method_to_be_traced, 'YY'
330
+ method_to_be_traced 1,2,3,true,'YY'
331
+ self.class.remove_method_tracer :method_to_be_traced, 'YY'
331
332
  method_to_be_traced 1,2,3,true,nil
332
- self.class.remove_method_tracer :method_to_be_traced, 'X'
333
- method_to_be_traced 1,2,3,false,'X'
333
+ self.class.remove_method_tracer :method_to_be_traced, 'XX'
334
+ method_to_be_traced 1,2,3,false,'XX'
334
335
  end
335
336
 
336
337
  def trace_no_push_scope
@@ -18,6 +18,9 @@ class NewRelic::Agent::MockScopeListener
18
18
  end
19
19
 
20
20
  def notice_scope_empty(time)
21
+ end
21
22
 
23
+ def enabled?
24
+ true
22
25
  end
23
26
  end
@@ -0,0 +1,376 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
2
+ require 'new_relic/agent/thread_profiler'
3
+
4
+ class NewRelicServiceTest < Test::Unit::TestCase
5
+ def initialize(*_)
6
+ [ :HTTPSuccess,
7
+ :HTTPUnauthorized,
8
+ :HTTPNotFound,
9
+ :HTTPRequestEntityTooLarge,
10
+ :HTTPUnsupportedMediaType ].each do |class_name|
11
+ extend_with_mock(class_name)
12
+ end
13
+ super
14
+ end
15
+
16
+ def extend_with_mock(class_name)
17
+ if !self.class.const_defined?(class_name)
18
+ klass = self.class.const_set(class_name,
19
+ Class.new(Object.const_get(:Net).const_get(class_name)))
20
+ klass.class_eval { include HTTPResponseMock }
21
+ end
22
+ end
23
+ protected :extend_with_mock
24
+
25
+ def setup
26
+ @server = NewRelic::Control::Server.new('somewhere.example.com',
27
+ 30303, '10.10.10.10')
28
+ @service = NewRelic::Agent::NewRelicService.new('license-key', @server)
29
+ @http_handle = HTTPHandle.new
30
+ NewRelic::Control.instance.stubs(:http_connection).returns(@http_handle)
31
+
32
+ @http_handle.respond_to(:get_redirect_host, 'localhost')
33
+ connect_response = {
34
+ 'config' => 'some config directives',
35
+ 'agent_run_id' => 1
36
+ }
37
+ @http_handle.respond_to(:connect, connect_response)
38
+
39
+ @reverse_encoder = Module.new do
40
+ def self.encode(data)
41
+ data.reverse
42
+ end
43
+ end
44
+ end
45
+
46
+ def test_initialize_uses_correct_license_key_settings
47
+ with_config(:license_key => 'abcde') do
48
+ service = NewRelic::Agent::NewRelicService.new
49
+ assert_equal 'abcde', service.instance_variable_get(:@license_key)
50
+ end
51
+ end
52
+
53
+ def test_connect_sets_agent_id_and_config_data
54
+ response = @service.connect
55
+ assert_equal 1, response['agent_run_id']
56
+ assert_equal 'some config directives', response['config']
57
+ end
58
+
59
+ def test_connect_sets_redirect_host
60
+ assert_equal 'somewhere.example.com', @service.collector.name
61
+ @service.connect
62
+ assert_equal 'localhost', @service.collector.name
63
+ end
64
+
65
+ def test_connect_resets_cached_ip_address
66
+ assert_equal '10.10.10.10', @service.collector.ip
67
+ @service.connect
68
+ assert_nil @service.collector.ip # 'localhost' resolves to nil
69
+ end
70
+
71
+ def test_connect_uses_proxy_collector_if_no_redirect_host
72
+ @http_handle.reset
73
+ @http_handle.respond_to(:get_redirect_host, nil)
74
+ @http_handle.respond_to(:connect, 'agent_run_id' => 1)
75
+
76
+ @service.connect
77
+ assert_equal 'somewhere.example.com', @service.collector.name
78
+ end
79
+
80
+ def test_connect_sets_agent_id
81
+ @http_handle.reset
82
+ @http_handle.respond_to(:get_redirect_host, 'localhost')
83
+ @http_handle.respond_to(:connect, 'agent_run_id' => 666)
84
+
85
+ @service.connect
86
+ assert_equal 666, @service.agent_id
87
+ end
88
+
89
+ def test_get_redirect_host
90
+ assert_equal 'localhost', @service.get_redirect_host
91
+ end
92
+
93
+ def test_shutdown
94
+ @service.agent_id = 666
95
+ @http_handle.respond_to(:shutdown, 'shut this bird down')
96
+ response = @service.shutdown(Time.now)
97
+ assert_equal 'shut this bird down', response
98
+ end
99
+
100
+ def test_should_not_shutdown_if_never_connected
101
+ @http_handle.respond_to(:shutdown, 'shut this bird down')
102
+ response = @service.shutdown(Time.now)
103
+ assert_nil response
104
+ end
105
+
106
+ def test_metric_data
107
+ @http_handle.respond_to(:metric_data, 'met rick date uhhh')
108
+ response = @service.metric_data((Time.now - 60).to_f, Time.now.to_f, {})
109
+ assert_equal 'met rick date uhhh', response
110
+ end
111
+
112
+ def test_error_data
113
+ @http_handle.respond_to(:error_data, 'too human')
114
+ response = @service.error_data([])
115
+ assert_equal 'too human', response
116
+ end
117
+
118
+ def test_transaction_sample_data
119
+ @http_handle.respond_to(:transaction_sample_data, 'MPC1000')
120
+ response = @service.transaction_sample_data([])
121
+ assert_equal 'MPC1000', response
122
+ end
123
+
124
+ def test_sql_trace_data
125
+ @http_handle.respond_to(:sql_trace_data, 'explain this')
126
+ response = @service.sql_trace_data([])
127
+ assert_equal 'explain this', response
128
+ end
129
+
130
+
131
+ # Thread profiling only available in certain versions
132
+ if NewRelic::Agent::ThreadProfiler.is_supported?
133
+ def test_profile_data
134
+ @http_handle.respond_to(:profile_data, 'profile' => 123)
135
+ response = @service.profile_data(NewRelic::Agent::ThreadProfile.new(0, 0, 0, true))
136
+ assert_equal({ "profile" => 123 }, response)
137
+ end
138
+
139
+ def test_get_agent_commands
140
+ @service.agent_id = 666
141
+ @http_handle.respond_to(:get_agent_commands, [1,2,3])
142
+
143
+ response = @service.get_agent_commands
144
+ assert_equal [1,2,3], response
145
+ end
146
+
147
+ def test_get_agent_commands_with_no_response
148
+ @service.agent_id = 666
149
+ @http_handle.respond_to(:get_agent_commands, nil)
150
+
151
+ response = @service.get_agent_commands
152
+ assert_equal nil, response
153
+ end
154
+
155
+ def test_agent_command_results
156
+ @http_handle.respond_to(:agent_command_results, {})
157
+ response = @service.agent_command_results(4200)
158
+ assert_equal({}, response)
159
+ end
160
+
161
+ def test_agent_command_results_with_errors
162
+ @http_handle.respond_to(:agent_command_results, [123])
163
+ response = @service.agent_command_results(4200, 'Boo!')
164
+ assert_equal [123], response
165
+ end
166
+ end
167
+
168
+ def test_request_timeout
169
+ with_config(:timeout => 600) do
170
+ service = NewRelic::Agent::NewRelicService.new('abcdef', @server)
171
+ assert_equal 600, service.request_timeout
172
+ end
173
+ end
174
+
175
+ def test_should_throw_received_errors
176
+ assert_raise NewRelic::Agent::ServerConnectionException do
177
+ @service.send(:invoke_remote, :bogus_method)
178
+ end
179
+ end
180
+
181
+ def test_should_connect_to_proxy_only_once_per_run
182
+ @service.expects(:get_redirect_host).once
183
+
184
+ @service.connect
185
+ @http_handle.respond_to(:metric_data, 0)
186
+ @service.metric_data((Time.now - 60).to_f, Time.now.to_f, {})
187
+
188
+ @http_handle.respond_to(:transaction_sample_data, 1)
189
+ @service.transaction_sample_data([])
190
+
191
+ @http_handle.respond_to(:sql_trace_data, 2)
192
+ @service.sql_trace_data([])
193
+ end
194
+
195
+ # for PRUBY proxy compatibility
196
+ def test_should_raise_exception_on_401
197
+ @http_handle.reset
198
+ @http_handle.respond_to(:get_redirect_host, 'bad license', :code => 401)
199
+ assert_raise NewRelic::Agent::LicenseException do
200
+ @service.get_redirect_host
201
+ end
202
+ end
203
+
204
+ # protocol 9
205
+ def test_should_raise_exception_on_413
206
+ @http_handle.respond_to(:metric_data, 'too big', :code => 413)
207
+ assert_raise NewRelic::Agent::UnrecoverableServerException do
208
+ @service.metric_data((Time.now - 60).to_f, Time.now.to_f, {})
209
+ end
210
+ end
211
+
212
+ # protocol 9
213
+ def test_should_raise_exception_on_415
214
+ @http_handle.respond_to(:metric_data, 'too big', :code => 415)
215
+ assert_raise NewRelic::Agent::UnrecoverableServerException do
216
+ @service.metric_data((Time.now - 60).to_f, Time.now.to_f, {})
217
+ end
218
+ end
219
+
220
+ if NewRelic::LanguageSupport.using_version?('1.9')
221
+ def test_json_marshaller_handles_responses_from_collector
222
+ marshaller = NewRelic::Agent::NewRelicService::JsonMarshaller.new
223
+ assert_equal ['beep', 'boop'], marshaller.load('{"return_value": ["beep","boop"]}')
224
+ end
225
+
226
+ def test_json_marshaller_handles_errors_from_collector
227
+ marshaller = NewRelic::Agent::NewRelicService::JsonMarshaller.new
228
+ assert_raise(NewRelic::Agent::NewRelicService::CollectorError,
229
+ 'JavaCrash: error message') do
230
+ marshaller.load('{"exception": {"message": "error message", "error_type": "JavaCrash"}}')
231
+ end
232
+ end
233
+ end
234
+
235
+ def test_pruby_marshaller_handles_errors_from_collector
236
+ marshaller = NewRelic::Agent::NewRelicService::PrubyMarshaller.new
237
+ assert_raise(NewRelic::Agent::NewRelicService::CollectorError, 'error message') do
238
+ marshaller.load(Marshal.dump({"exception" => {"message" => "error message",
239
+ "error_type" => "JavaCrash"}}))
240
+ end
241
+ end
242
+
243
+ def test_compress_request_if_needed_compresses_large_payloads
244
+ large_payload = 'a' * 65 * 1024
245
+ body, encoding = @service.compress_request_if_needed(large_payload)
246
+ assert_equal(large_payload, Zlib::Inflate.inflate(body))
247
+ assert_equal('deflate', encoding)
248
+ end
249
+
250
+ def test_compress_request_if_needed_passes_thru_small_payloads
251
+ payload = 'a' * 100
252
+ body, encoding = @service.compress_request_if_needed(payload)
253
+ assert_equal(payload, body)
254
+ assert_equal('identity', encoding)
255
+ end
256
+
257
+ def test_marshaller_obeys_requested_encoder
258
+ dummy = ['hello there']
259
+ def dummy.to_collector_array(encoder)
260
+ self.map { |x| encoder.encode(x) }
261
+ end
262
+ marshaller = NewRelic::Agent::NewRelicService::Marshaller.new
263
+
264
+ identity_encoder = NewRelic::Agent::NewRelicService::Encoders::Identity
265
+
266
+ prepared = marshaller.prepare(dummy, :encoder => identity_encoder)
267
+ assert_equal(dummy, prepared)
268
+
269
+ prepared = marshaller.prepare(dummy, :encoder => @reverse_encoder)
270
+ decoded = prepared.map { |x| x.reverse }
271
+ assert_equal(dummy, decoded)
272
+ end
273
+
274
+ def test_marshaller_prepare_passes_on_options
275
+ inner_array = ['abcd']
276
+ def inner_array.to_collector_array(encoder)
277
+ self.map { |x| encoder.encode(x) }
278
+ end
279
+ dummy = [[inner_array]]
280
+ marshaller = NewRelic::Agent::NewRelicService::Marshaller.new
281
+ prepared = marshaller.prepare(dummy, :encoder => @reverse_encoder)
282
+ assert_equal([[['dcba']]], prepared)
283
+ end
284
+
285
+ def test_marshaller_handles_known_errors
286
+ error_data = {
287
+ 'error_type' => 'NewRelic::Agent::ForceRestartException',
288
+ 'message' => 'test'
289
+ }
290
+ error = @service.marshaller.parsed_error(error_data)
291
+ assert_equal NewRelic::Agent::ForceRestartException, error.class
292
+ assert_equal 'test', error.message
293
+ end
294
+
295
+ def test_marshaller_handles_unknown_errors
296
+ error = @service.marshaller.parsed_error('error_type' => 'OogBooga',
297
+ 'message' => 'test')
298
+ assert_equal NewRelic::Agent::NewRelicService::CollectorError, error.class
299
+ assert_equal 'OogBooga: test', error.message
300
+ end
301
+
302
+ class HTTPHandle
303
+ attr_accessor :read_timeout, :route_table
304
+
305
+ def initialize
306
+ reset
307
+ end
308
+
309
+ def respond_to(method, payload, opts={})
310
+ if NewRelic::Agent::NewRelicService::JsonMarshaller.is_supported?
311
+ format = :json
312
+ else
313
+ format = :pruby
314
+ end
315
+
316
+ opts = {
317
+ :code => 200,
318
+ :format => format
319
+ }.merge(opts)
320
+
321
+ if opts[:code] == 401
322
+ klass = HTTPUnauthorized
323
+ elsif opts[:code] == 413
324
+ klass = HTTPRequestEntityTooLarge
325
+ elsif opts[:code] == 415
326
+ klass = HTTPUnsupportedMediaType
327
+ elsif opts[:code] >= 400
328
+ klass = HTTPServerError
329
+ else
330
+ klass = HTTPSuccess
331
+ end
332
+
333
+ if opts[:format] == :json
334
+ register(klass.new(JSON.dump('return_value' => payload), opts[:code])) do |request|
335
+ request.path.include?(method.to_s)
336
+ end
337
+ else
338
+ register(klass.new(Marshal.dump('return_value' => payload), opts[:code])) do |request|
339
+ request.path.include?(method.to_s)
340
+ end
341
+ end
342
+ end
343
+
344
+ def register(response, &block)
345
+ @route_table[block] = response
346
+ end
347
+
348
+ def request(*args)
349
+ @route_table.each_pair do |condition, response|
350
+ if condition.call(args[0])
351
+ return response
352
+ end
353
+ end
354
+ HTTPNotFound.new('not found', 404)
355
+ end
356
+
357
+ def reset
358
+ @route_table = {}
359
+ end
360
+ end
361
+
362
+ module HTTPResponseMock
363
+ attr_accessor :code, :body, :message, :headers
364
+
365
+ def initialize(body, code=200, message='OK')
366
+ @code = code
367
+ @body = body
368
+ @message = message
369
+ @headers = {}
370
+ end
371
+
372
+ def [](key)
373
+ @headers[key]
374
+ end
375
+ end
376
+ end