scout_apm 2.6.10 → 3.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -2
  3. data/.rubocop.yml +3 -11
  4. data/CHANGELOG.markdown +4 -362
  5. data/Gemfile +1 -14
  6. data/README.markdown +7 -52
  7. data/Rakefile +1 -0
  8. data/ext/allocations/allocations.c +1 -7
  9. data/ext/allocations/extconf.rb +0 -1
  10. data/ext/rusage/rusage.c +0 -26
  11. data/ext/stacks/extconf.rb +37 -0
  12. data/ext/stacks/scout_atomics.h +86 -0
  13. data/ext/stacks/stacks.c +811 -0
  14. data/lib/scout_apm/agent/logging.rb +69 -0
  15. data/lib/scout_apm/agent/reporting.rb +126 -0
  16. data/lib/scout_apm/agent.rb +259 -138
  17. data/lib/scout_apm/app_server_load.rb +15 -41
  18. data/lib/scout_apm/attribute_arranger.rb +3 -14
  19. data/lib/scout_apm/background_job_integrations/delayed_job.rb +1 -70
  20. data/lib/scout_apm/background_job_integrations/sidekiq.rb +24 -31
  21. data/lib/scout_apm/background_worker.rb +12 -23
  22. data/lib/scout_apm/capacity.rb +57 -0
  23. data/lib/scout_apm/config.rb +37 -206
  24. data/lib/scout_apm/context.rb +4 -20
  25. data/lib/scout_apm/deploy_integrations/capistrano_2.cap +12 -0
  26. data/lib/scout_apm/deploy_integrations/capistrano_2.rb +83 -0
  27. data/lib/scout_apm/deploy_integrations/capistrano_3.cap +12 -0
  28. data/lib/scout_apm/deploy_integrations/capistrano_3.rb +88 -0
  29. data/lib/scout_apm/environment.rb +28 -42
  30. data/lib/scout_apm/fake_store.rb +0 -12
  31. data/lib/scout_apm/framework_integrations/rails_2.rb +1 -2
  32. data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +6 -17
  33. data/lib/scout_apm/framework_integrations/sinatra.rb +1 -1
  34. data/lib/scout_apm/histogram.rb +3 -12
  35. data/lib/scout_apm/instant/assets/xmlhttp_instrumentation.html +2 -2
  36. data/lib/scout_apm/instant/middleware.rb +54 -202
  37. data/lib/scout_apm/instant_reporting.rb +7 -7
  38. data/lib/scout_apm/instruments/.DS_Store +0 -0
  39. data/lib/scout_apm/instruments/action_controller_rails_2.rb +9 -15
  40. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +76 -124
  41. data/lib/scout_apm/instruments/active_record.rb +29 -324
  42. data/lib/scout_apm/instruments/delayed_job.rb +57 -0
  43. data/lib/scout_apm/instruments/elasticsearch.rb +6 -10
  44. data/lib/scout_apm/instruments/grape.rb +9 -12
  45. data/lib/scout_apm/instruments/http_client.rb +7 -14
  46. data/lib/scout_apm/instruments/influxdb.rb +6 -10
  47. data/lib/scout_apm/instruments/middleware_detailed.rb +11 -15
  48. data/lib/scout_apm/instruments/middleware_summary.rb +5 -11
  49. data/lib/scout_apm/instruments/mongoid.rb +8 -39
  50. data/lib/scout_apm/instruments/moped.rb +6 -11
  51. data/lib/scout_apm/instruments/net_http.rb +9 -27
  52. data/lib/scout_apm/instruments/percentile_sampler.rb +23 -42
  53. data/lib/scout_apm/instruments/process/process_cpu.rb +6 -11
  54. data/lib/scout_apm/instruments/process/process_memory.rb +12 -17
  55. data/lib/scout_apm/instruments/rails_router.rb +6 -12
  56. data/lib/scout_apm/instruments/redis.rb +6 -10
  57. data/lib/scout_apm/instruments/sinatra.rb +4 -5
  58. data/lib/scout_apm/job_record.rb +2 -4
  59. data/lib/scout_apm/layaway.rb +34 -88
  60. data/lib/scout_apm/layaway_file.rb +3 -13
  61. data/lib/scout_apm/layer.rb +60 -25
  62. data/lib/scout_apm/layer_converters/allocation_metric_converter.rb +6 -7
  63. data/lib/scout_apm/layer_converters/converter_base.rb +14 -203
  64. data/lib/scout_apm/layer_converters/depth_first_walker.rb +10 -22
  65. data/lib/scout_apm/layer_converters/error_converter.rb +8 -8
  66. data/lib/scout_apm/layer_converters/job_converter.rb +50 -37
  67. data/lib/scout_apm/layer_converters/metric_converter.rb +19 -18
  68. data/lib/scout_apm/layer_converters/request_queue_time_converter.rb +13 -13
  69. data/lib/scout_apm/layer_converters/slow_job_converter.rb +116 -52
  70. data/lib/scout_apm/layer_converters/slow_request_converter.rb +120 -51
  71. data/lib/scout_apm/metric_meta.rb +5 -0
  72. data/lib/scout_apm/metric_set.rb +1 -9
  73. data/lib/scout_apm/metric_stats.rb +8 -7
  74. data/lib/scout_apm/middleware.rb +9 -7
  75. data/lib/scout_apm/reporter.rb +24 -71
  76. data/lib/scout_apm/request_histograms.rb +0 -12
  77. data/lib/scout_apm/request_manager.rb +7 -5
  78. data/lib/scout_apm/scored_item_set.rb +0 -7
  79. data/lib/scout_apm/serializers/app_server_load_serializer.rb +0 -4
  80. data/lib/scout_apm/serializers/deploy_serializer.rb +16 -0
  81. data/lib/scout_apm/serializers/directive_serializer.rb +0 -4
  82. data/lib/scout_apm/serializers/payload_serializer.rb +4 -11
  83. data/lib/scout_apm/serializers/payload_serializer_to_json.rb +16 -35
  84. data/lib/scout_apm/serializers/slow_jobs_serializer_to_json.rb +1 -2
  85. data/lib/scout_apm/server_integrations/passenger.rb +1 -1
  86. data/lib/scout_apm/server_integrations/puma.rb +2 -5
  87. data/lib/scout_apm/slow_job_policy.rb +13 -25
  88. data/lib/scout_apm/slow_job_record.rb +4 -13
  89. data/lib/scout_apm/slow_request_policy.rb +13 -25
  90. data/lib/scout_apm/slow_transaction.rb +5 -25
  91. data/lib/scout_apm/store.rb +32 -99
  92. data/lib/scout_apm/trace_compactor.rb +312 -0
  93. data/lib/scout_apm/tracer.rb +31 -35
  94. data/lib/scout_apm/tracked_request.rb +95 -262
  95. data/lib/scout_apm/utils/active_record_metric_name.rb +13 -88
  96. data/lib/scout_apm/utils/backtrace_parser.rb +4 -7
  97. data/lib/scout_apm/utils/fake_stacks.rb +87 -0
  98. data/lib/scout_apm/utils/installed_gems.rb +3 -7
  99. data/lib/scout_apm/utils/klass_helper.rb +2 -8
  100. data/lib/scout_apm/utils/null_logger.rb +13 -0
  101. data/lib/scout_apm/utils/sql_sanitizer.rb +5 -16
  102. data/lib/scout_apm/utils/sql_sanitizer_regex.rb +0 -7
  103. data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +0 -6
  104. data/lib/scout_apm/utils/unique_id.rb +0 -27
  105. data/lib/scout_apm/version.rb +2 -1
  106. data/lib/scout_apm.rb +25 -84
  107. data/scout_apm.gemspec +3 -17
  108. data/test/test_helper.rb +3 -57
  109. data/test/unit/agent_test.rb +54 -1
  110. data/test/unit/background_job_integrations/sidekiq_test.rb +3 -0
  111. data/test/unit/config_test.rb +12 -25
  112. data/test/unit/context_test.rb +4 -4
  113. data/test/unit/histogram_test.rb +4 -25
  114. data/test/unit/ignored_uris_test.rb +1 -1
  115. data/test/unit/instruments/active_record_instruments_test.rb +5 -0
  116. data/test/unit/layaway_test.rb +2 -62
  117. data/test/unit/serializers/payload_serializer_test.rb +15 -43
  118. data/test/unit/slow_request_policy_test.rb +6 -15
  119. data/test/unit/sql_sanitizer_test.rb +6 -53
  120. data/test/unit/store_test.rb +4 -73
  121. data/test/unit/utils/active_record_metric_name_test.rb +5 -59
  122. data/test/unit/utils/backtrace_parser_test.rb +1 -6
  123. data/tester.rb +53 -0
  124. metadata +28 -229
  125. data/.travis.yml +0 -26
  126. data/Guardfile +0 -43
  127. data/gems/README.md +0 -28
  128. data/gems/octoshark.gemfile +0 -4
  129. data/gems/rails3.gemfile +0 -5
  130. data/gems/rails4.gemfile +0 -4
  131. data/gems/rails5.gemfile +0 -4
  132. data/gems/rails6.gemfile +0 -4
  133. data/lib/scout_apm/agent/exit_handler.rb +0 -65
  134. data/lib/scout_apm/agent/preconditions.rb +0 -81
  135. data/lib/scout_apm/agent_context.rb +0 -261
  136. data/lib/scout_apm/auto_instrument/instruction_sequence.rb +0 -31
  137. data/lib/scout_apm/auto_instrument/layer.rb +0 -23
  138. data/lib/scout_apm/auto_instrument/parser.rb +0 -27
  139. data/lib/scout_apm/auto_instrument/rails.rb +0 -175
  140. data/lib/scout_apm/auto_instrument.rb +0 -5
  141. data/lib/scout_apm/background_job_integrations/legacy_sneakers.rb +0 -55
  142. data/lib/scout_apm/background_job_integrations/que.rb +0 -134
  143. data/lib/scout_apm/background_job_integrations/resque.rb +0 -88
  144. data/lib/scout_apm/background_job_integrations/shoryuken.rb +0 -124
  145. data/lib/scout_apm/background_job_integrations/sneakers.rb +0 -87
  146. data/lib/scout_apm/background_recorder.rb +0 -48
  147. data/lib/scout_apm/db_query_metric_set.rb +0 -97
  148. data/lib/scout_apm/db_query_metric_stats.rb +0 -102
  149. data/lib/scout_apm/debug.rb +0 -37
  150. data/lib/scout_apm/detailed_trace.rb +0 -217
  151. data/lib/scout_apm/error.rb +0 -27
  152. data/lib/scout_apm/error_service/error_buffer.rb +0 -39
  153. data/lib/scout_apm/error_service/error_record.rb +0 -211
  154. data/lib/scout_apm/error_service/ignored_exceptions.rb +0 -66
  155. data/lib/scout_apm/error_service/middleware.rb +0 -32
  156. data/lib/scout_apm/error_service/notifier.rb +0 -33
  157. data/lib/scout_apm/error_service/payload.rb +0 -47
  158. data/lib/scout_apm/error_service/periodic_work.rb +0 -17
  159. data/lib/scout_apm/error_service/railtie.rb +0 -11
  160. data/lib/scout_apm/error_service/sidekiq.rb +0 -80
  161. data/lib/scout_apm/error_service.rb +0 -32
  162. data/lib/scout_apm/extensions/config.rb +0 -87
  163. data/lib/scout_apm/extensions/transaction_callback_payload.rb +0 -74
  164. data/lib/scout_apm/git_revision.rb +0 -59
  165. data/lib/scout_apm/instrument_manager.rb +0 -88
  166. data/lib/scout_apm/instruments/action_view.rb +0 -141
  167. data/lib/scout_apm/instruments/http.rb +0 -48
  168. data/lib/scout_apm/instruments/memcached.rb +0 -43
  169. data/lib/scout_apm/instruments/resque.rb +0 -39
  170. data/lib/scout_apm/instruments/samplers.rb +0 -11
  171. data/lib/scout_apm/layer_children_set.rb +0 -86
  172. data/lib/scout_apm/layer_converters/database_converter.rb +0 -70
  173. data/lib/scout_apm/layer_converters/find_layer_by_type.rb +0 -38
  174. data/lib/scout_apm/layer_converters/histograms.rb +0 -15
  175. data/lib/scout_apm/layer_converters/trace_converter.rb +0 -184
  176. data/lib/scout_apm/limited_layer.rb +0 -126
  177. data/lib/scout_apm/logger.rb +0 -158
  178. data/lib/scout_apm/periodic_work.rb +0 -47
  179. data/lib/scout_apm/rack.rb +0 -26
  180. data/lib/scout_apm/remote/message.rb +0 -27
  181. data/lib/scout_apm/remote/recorder.rb +0 -57
  182. data/lib/scout_apm/remote/router.rb +0 -49
  183. data/lib/scout_apm/remote/server.rb +0 -60
  184. data/lib/scout_apm/reporting.rb +0 -143
  185. data/lib/scout_apm/serializers/db_query_serializer_to_json.rb +0 -15
  186. data/lib/scout_apm/serializers/histograms_serializer_to_json.rb +0 -21
  187. data/lib/scout_apm/synchronous_recorder.rb +0 -30
  188. data/lib/scout_apm/tasks/doctor.rb +0 -75
  189. data/lib/scout_apm/tasks/support.rb +0 -22
  190. data/lib/scout_apm/transaction.rb +0 -13
  191. data/lib/scout_apm/transaction_time_consumed.rb +0 -51
  192. data/lib/scout_apm/utils/gzip_helper.rb +0 -24
  193. data/lib/scout_apm/utils/marshal_logging.rb +0 -90
  194. data/lib/scout_apm/utils/numbers.rb +0 -14
  195. data/lib/scout_apm/utils/scm.rb +0 -14
  196. data/lib/tasks/doctor.rake +0 -11
  197. data/test/tmp/README.md +0 -17
  198. data/test/unit/agent_context_test.rb +0 -15
  199. data/test/unit/auto_instrument/assignments-instrumented.rb +0 -31
  200. data/test/unit/auto_instrument/assignments.rb +0 -31
  201. data/test/unit/auto_instrument/controller-ast.txt +0 -57
  202. data/test/unit/auto_instrument/controller-instrumented.rb +0 -49
  203. data/test/unit/auto_instrument/controller.rb +0 -49
  204. data/test/unit/auto_instrument/rescue_from-instrumented.rb +0 -13
  205. data/test/unit/auto_instrument/rescue_from.rb +0 -13
  206. data/test/unit/auto_instrument_test.rb +0 -54
  207. data/test/unit/db_query_metric_set_test.rb +0 -67
  208. data/test/unit/db_query_metric_stats_test.rb +0 -113
  209. data/test/unit/error_service/error_buffer_test.rb +0 -25
  210. data/test/unit/error_service/ignored_exceptions_test.rb +0 -49
  211. data/test/unit/extensions/periodic_callbacks_test.rb +0 -58
  212. data/test/unit/extensions/transaction_callbacks_test.rb +0 -58
  213. data/test/unit/fake_store_test.rb +0 -10
  214. data/test/unit/git_revision_test.rb +0 -15
  215. data/test/unit/instruments/active_record_test.rb +0 -40
  216. data/test/unit/instruments/net_http_test.rb +0 -27
  217. data/test/unit/instruments/percentile_sampler_test.rb +0 -133
  218. data/test/unit/layer_children_set_test.rb +0 -97
  219. data/test/unit/layer_converters/depth_first_walker_test.rb +0 -70
  220. data/test/unit/layer_converters/metric_converter_test.rb +0 -22
  221. data/test/unit/layer_converters/stubs.rb +0 -33
  222. data/test/unit/limited_layer_test.rb +0 -53
  223. data/test/unit/logger_test.rb +0 -69
  224. data/test/unit/remote/test_message.rb +0 -13
  225. data/test/unit/remote/test_router.rb +0 -33
  226. data/test/unit/remote/test_server.rb +0 -15
  227. data/test/unit/request_histograms_test.rb +0 -17
  228. data/test/unit/tracer_test.rb +0 -76
  229. data/test/unit/tracked_request_test.rb +0 -71
  230. data/test/unit/transaction_test.rb +0 -14
  231. data/test/unit/transaction_time_consumed_test.rb +0 -46
  232. data/test/unit/utils/numbers_test.rb +0 -15
  233. data/test/unit/utils/scm.rb +0 -17
@@ -1,5 +1,58 @@
1
1
  require 'test_helper'
2
+ require 'scout_apm/agent'
3
+ require 'scout_apm/slow_transaction'
4
+ require 'scout_apm/metric_meta'
5
+ require 'scout_apm/metric_stats'
6
+ require 'scout_apm/context'
7
+ require 'scout_apm/store'
2
8
 
3
9
  class AgentTest < Minitest::Test
4
- # XXX: Write tests around agent startup sequence
10
+
11
+ # Safeguard to ensure the main agent thread doesn't have any interaction with the layaway file. Contention on file locks can cause delays.
12
+ def test_start_with_lock_on_layaway_file
13
+ # setup the file, putting a lock on it.
14
+ File.open(DATA_FILE_PATH, "w") {}
15
+ f = File.open(DATA_FILE_PATH, File::RDWR | File::CREAT)
16
+ f.flock(File::LOCK_EX)
17
+
18
+ agent = ScoutApm::Agent.instance
19
+
20
+ no_timeout = true
21
+ begin
22
+ Timeout::timeout(3) { agent.start({:monitor => true, :force => true}) }
23
+ rescue Timeout::Error
24
+ no_timeout = false
25
+ ensure
26
+ f.flock(File::LOCK_UN)
27
+ f.close
28
+ end
29
+ assert no_timeout, "Agent took >= 3s to start. Possible file lock issue."
30
+ end
31
+
32
+ def test_reset_file_with_old_format
33
+ File.open(DATA_FILE_PATH, 'w') { |file| file.write(Marshal.dump(OLD_FORMAT)) }
34
+ begin
35
+ ScoutApm::Agent.instance(:force => true).process_metrics
36
+ rescue NoMethodError
37
+ # The agent will raise an exception the first time metrics are processed for scout_apm < 1.2.
38
+ #
39
+ # NoMethodError: undefined method `values' for []:Array
40
+ # /Users/dlite/projects/scout_apm_ruby/lib/scout_apm/layaway.rb:46:in `periods_ready_for_delivery'
41
+ # /Users/dlite/projects/scout_apm_ruby/lib/scout_apm/agent/reporting.rb:31:in `report_to_server'
42
+ # /Users/dlite/projects/scout_apm_ruby/lib/scout_apm/agent/reporting.rb:24:in `process_metrics'
43
+ # /Users/dlite/projects/scout_apm_ruby/test/unit/layaway_test.rb:27:in `test_reset_file_with_old_format'
44
+ end
45
+ # Data will be fine the next go-around
46
+ no_error = true
47
+ begin
48
+ ScoutApm::Agent.instance(:force => true).process_metrics
49
+ rescue Exception => e
50
+ no_error = false
51
+ end
52
+ assert no_error, "Error trying to process metrics after upgrading from < 1.2 data format: #{e.message if e}"
53
+ end
54
+
55
+ ## TODO - adds tests to ensure other potentially long-running things don't sneak in, like HTTP calls.
56
+
57
+ OLD_FORMAT = {1452533280 => {:metrics => {}, :slow_transactions => {}} } # Pre 1.2 agents used a different file format to store data.
5
58
  end
@@ -11,6 +11,7 @@ class SidekiqTest < Minitest::Test
11
11
  def test_middleware_call_happy_path
12
12
  fake_request = mock
13
13
  fake_request.expects(:annotate_request)
14
+ fake_request.expects(:job!)
14
15
  fake_request.expects(:start_layer).twice
15
16
  fake_request.expects(:stop_layer).twice
16
17
  fake_request.expects(:error!).never
@@ -28,6 +29,7 @@ class SidekiqTest < Minitest::Test
28
29
  def test_middleware_call_job_exception
29
30
  fake_request = mock
30
31
  fake_request.expects(:annotate_request)
32
+ fake_request.expects(:job!)
31
33
  fake_request.expects(:start_layer).twice
32
34
  fake_request.expects(:stop_layer).twice
33
35
  fake_request.expects(:error!)
@@ -45,6 +47,7 @@ class SidekiqTest < Minitest::Test
45
47
  def test_middleware_call_edge_cases
46
48
  fake_request = mock
47
49
  fake_request.expects(:annotate_request)
50
+ fake_request.expects(:job!)
48
51
  fake_request.expects(:start_layer).twice
49
52
  fake_request.expects(:stop_layer).twice
50
53
  fake_request.expects(:error!)
@@ -3,40 +3,36 @@ require 'test_helper'
3
3
  require 'scout_apm/config'
4
4
 
5
5
  class ConfigTest < Minitest::Test
6
- def setup
7
- @context = ScoutApm::AgentContext.new
8
- end
9
-
10
6
  def test_initalize_without_a_config
11
- conf = ScoutApm::Config.without_file(@context)
7
+ conf = ScoutApm::Config.without_file
12
8
 
13
9
  # nil for random keys
14
- assert_nil conf.value('log_file_path')
10
+ assert_nil conf.value("log_file_path")
15
11
 
16
12
  # but has values for defaulted keys
17
- assert conf.value('host')
13
+ assert conf.value("host")
18
14
 
19
15
  # and still reads from ENV
20
16
  ENV['SCOUT_CONFIG_TEST_KEY'] = 'testval'
21
- assert_equal 'testval', conf.value('config_test_key')
17
+ assert_equal 'testval', conf.value("config_test_key")
22
18
  end
23
19
 
24
20
  def test_loading_a_file
25
- set_rack_env('production')
21
+ set_rack_env("production")
26
22
 
27
- conf_file = File.expand_path('../../data/config_test_1.yml', __FILE__)
28
- conf = ScoutApm::Config.with_file(@context, conf_file)
23
+ conf_file = File.expand_path("../../data/config_test_1.yml", __FILE__)
24
+ conf = ScoutApm::Config.with_file(conf_file)
29
25
 
30
- assert_equal 'debug', conf.value('log_level')
31
- assert_equal 'APM Test Conf (Production)', conf.value('name')
26
+ assert_equal "debug", conf.value('log_level')
27
+ assert_equal "APM Test Conf (Production)", conf.value('name')
32
28
  end
33
29
 
34
30
  def test_loading_file_without_env_in_file
35
31
  conf_file = File.expand_path("../../data/config_test_1.yml", __FILE__)
36
- conf = ScoutApm::Config.with_file(@context, conf_file, :environment => "staging")
32
+ conf = ScoutApm::Config.with_file(conf_file, environment: "staging")
37
33
 
38
34
  assert_equal "info", conf.value('log_level') # the default value
39
- assert_nil nil, conf.value('name') # the default value
35
+ assert_equal nil, conf.value('name') # the default value
40
36
  end
41
37
 
42
38
  def test_boolean_coercion
@@ -71,15 +67,6 @@ class ConfigTest < Minitest::Test
71
67
  assert_equal 10, coercion.coerce(10)
72
68
  assert_equal ["a"], coercion.coerce(["a"])
73
69
  end
70
+ end
74
71
 
75
- def test_any_keys_found
76
- ENV.stubs(:has_key?).returns(nil)
77
-
78
- conf = ScoutApm::Config.with_file(@context, "a_file_that_doesnt_exist.yml")
79
- assert ! conf.any_keys_found?
80
72
 
81
- ENV.stubs(:has_key?).with("SCOUT_MONITOR").returns("true")
82
- conf = ScoutApm::Config.with_file(@context, "a_file_that_doesnt_exist.yml")
83
- assert conf.any_keys_found?
84
- end
85
- end
@@ -4,25 +4,25 @@ require 'scout_apm/context'
4
4
 
5
5
  class ContextText < Minitest::Test
6
6
  def test_ignore_nil_value
7
- context = ScoutApm::Context.new(ScoutApm::AgentContext.new)
7
+ context = ScoutApm::Context.new
8
8
  assert hash = context.add(:nil_key => nil, :org => 'org')
9
9
  assert_equal ({:org => 'org'}), hash
10
10
  end
11
11
 
12
12
  def test_ignore_nil_key
13
- context = ScoutApm::Context.new(ScoutApm::AgentContext.new)
13
+ context = ScoutApm::Context.new
14
14
  assert hash = context.add(nil => nil, :org => 'org')
15
15
  assert_equal ({:org => 'org'}), hash
16
16
  end
17
17
 
18
18
  def test_ignore_unsupported_value_type
19
- context = ScoutApm::Context.new(ScoutApm::AgentContext.new)
19
+ context = ScoutApm::Context.new
20
20
  assert hash = context.add(:array => [1,2,3,4], :org => 'org')
21
21
  assert_equal ({:org => 'org'}), hash
22
22
  end
23
23
 
24
24
  def test_ignore_unsupported_key_type
25
- context = ScoutApm::Context.new(ScoutApm::AgentContext.new)
25
+ context = ScoutApm::Context.new
26
26
  assert hash = context.add([1,2,3,4] => 'hey', :org => 'org')
27
27
  assert_equal ({:org => 'org'}), hash
28
28
  end
@@ -35,8 +35,8 @@ class HistogramTest < Minitest::Test
35
35
  end
36
36
  }
37
37
 
38
- assert_equal 1.5, round(hist.quantile(0), 1)
39
- assert_equal 9.5, round(hist.quantile(100), 1)
38
+ assert_equal 1.5, hist.quantile(0).round(1)
39
+ assert_equal 9.5, hist.quantile(100).round(1)
40
40
  end
41
41
 
42
42
  def test_combine
@@ -55,8 +55,8 @@ class HistogramTest < Minitest::Test
55
55
  }
56
56
 
57
57
  combined = hist1.combine!(hist2)
58
- assert_equal 1.5, round(combined.quantile(0), 1)
59
- assert_equal 9.5, round(combined.quantile(100), 1)
58
+ assert_equal 1.5, combined.quantile(0).round(1)
59
+ assert_equal 9.5, combined.quantile(100).round(1)
60
60
  assert_equal 200, combined.total
61
61
  end
62
62
 
@@ -79,20 +79,6 @@ class HistogramTest < Minitest::Test
79
79
  assert combined.quantile(0) < combined.quantile(100)
80
80
  end
81
81
 
82
- def test_combine_dedups_identicals
83
- hist1 = ScoutApm::NumericHistogram.new(5)
84
- hist2 = ScoutApm::NumericHistogram.new(5)
85
- hist1.add(1)
86
- hist1.add(2)
87
- hist2.add(2)
88
- hist2.add(3)
89
-
90
- combined = hist1.combine!(hist2)
91
- assert_equal 4, combined.total
92
- assert_equal [[1, 1], [2, 2], [1, 3]],
93
- combined.bins.map{|bin| [bin.count, bin.value.to_i] }
94
- end
95
-
96
82
  def test_mean
97
83
  hist = ScoutApm::NumericHistogram.new(5)
98
84
  10.times {
@@ -103,12 +89,5 @@ class HistogramTest < Minitest::Test
103
89
 
104
90
  assert_equal 5.5, hist.mean
105
91
  end
106
-
107
- private
108
-
109
- # Ruby 1.8 compatible round with precision
110
- def round(number, precision)
111
- ((number * 10**precision).round.to_f) / (10**precision)
112
- end
113
92
  end
114
93
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require_relative '../test_helper'
2
2
 
3
3
  require 'scout_apm/ignored_uris'
4
4
 
@@ -0,0 +1,5 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveRecordInstrumentsTest < Minitest::Test
4
+ end
5
+
@@ -10,75 +10,15 @@ class LayawayTest < Minitest::Test
10
10
  def test_directory_uses_DATA_FILE_option
11
11
  FileUtils.mkdir_p '/tmp/scout_apm_test/data_file_option'
12
12
  config = make_fake_config("data_file" => "/tmp/scout_apm_test/data_file_option")
13
- context = ScoutApm::AgentContext.new().tap{|c| c.config = config }
14
- layaway = ScoutApm::Layaway.new(context)
15
13
 
16
- assert_equal Pathname.new("/tmp/scout_apm_test/data_file_option"), layaway.directory
14
+ assert_equal Pathname.new("/tmp/scout_apm_test/data_file_option"), ScoutApm::Layaway.new(config, ScoutApm::Agent.instance.environment).directory
17
15
  end
18
16
 
19
17
  def test_directory_looks_for_root_slash_tmp
20
18
  FileUtils.mkdir_p '/tmp/scout_apm_test/tmp'
21
19
  config = make_fake_config({})
22
20
  env = make_fake_environment(:root => "/tmp/scout_apm_test")
23
- context = ScoutApm::AgentContext.new().tap{|c| c.config = config; c.environment = env }
24
21
 
25
- assert_equal Pathname.new("/tmp/scout_apm_test/tmp"), ScoutApm::Layaway.new(context).directory
26
- end
27
-
28
- def test_layaway_file_limit_prevents_new_writes
29
- FileUtils.mkdir_p '/tmp/scout_apm_test/layaway_limit'
30
- config = make_fake_config("data_file" => "/tmp/scout_apm_test/layaway_limit")
31
- context = ScoutApm::AgentContext.new().tap{|c| c.config = config }
32
- layaway = ScoutApm::Layaway.new(context)
33
- layaway.delete_files_for(:all)
34
-
35
- context = ScoutApm::AgentContext.new
36
- current_time = Time.now.utc
37
- current_rp = ScoutApm::StoreReportingPeriod.new(current_time, context)
38
- stale_rp = ScoutApm::StoreReportingPeriod.new(current_time - current_time.sec - 120, context)
39
-
40
- # layaway.write_reporting_period returns nil on successful write
41
- # It should probably be changed to return true or the number of bytes written
42
- assert_nil layaway.write_reporting_period(stale_rp, 1)
43
-
44
- # layaway.write_reporting_period returns an explicit false class on failure
45
- assert layaway.write_reporting_period(current_rp, 1).is_a?(FalseClass)
46
-
47
- layaway.delete_files_for(:all)
48
- end
49
-
50
- def test_layaway_stale_regex_pattern
51
- data_dir = '/tmp/scout_apm_test/shared/scout_apm'
52
- FileUtils.mkdir_p data_dir
53
- # Clean out files
54
- FileUtils.safe_unlink(Dir.glob("#{data_dir}/scout_*_*.data"))
55
-
56
- config = make_fake_config({'data_file' => data_dir})
57
- env = make_fake_environment(:root => '/tmp/scout_apm_test')
58
- context = ScoutApm::AgentContext.new().tap{|c| c.config = config; c.environment = env }
59
- layaway = ScoutApm::Layaway.new(context)
60
-
61
-
62
- not_stale_time = Time.now
63
- not_stale_time_formatted = not_stale_time.strftime(ScoutApm::Layaway::TIME_FORMAT)
64
-
65
- stale_time = not_stale_time - (ScoutApm::Layaway::STALE_AGE + 120) # ScoutApm::Layaway::STALE_AGE is in seconds. Add another 2 minutes to STALE_AGE
66
- stale_time_formatted = stale_time.strftime(ScoutApm::Layaway::TIME_FORMAT)
67
-
68
- not_stale_file_names = [File.join(data_dir, "scout_#{not_stale_time_formatted}_1.data"),
69
- File.join(data_dir, "scout_#{not_stale_time_formatted}_20.data")]
70
- stale_file_names = [File.join(data_dir, "scout_#{stale_time_formatted}_1.data"),
71
- File.join(data_dir, "scout_#{stale_time_formatted}_20.data")]
72
- all_file_names = not_stale_file_names + stale_file_names
73
-
74
- (all_file_names).each do |filename|
75
- File.new(filename, 'w').close
76
- end
77
-
78
- assert_equal Pathname.new("/tmp/scout_apm_test/shared/scout_apm"), ScoutApm::Layaway.new(context).directory
79
- assert_equal all_file_names.sort, Dir.glob("#{data_dir}/*data").sort
80
-
81
- layaway.delete_stale_files(not_stale_time - ScoutApm::Layaway::STALE_AGE)
82
- assert_equal not_stale_file_names.sort, Dir.glob("#{data_dir}/*data").sort
22
+ assert_equal Pathname.new("/tmp/scout_apm_test/tmp"), ScoutApm::Layaway.new(config, env).directory
83
23
  end
84
24
  end
@@ -1,4 +1,13 @@
1
1
  require 'test_helper'
2
+ require 'scout_apm/attribute_arranger'
3
+ require 'scout_apm/bucket_name_splitter'
4
+ require 'scout_apm/serializers/payload_serializer'
5
+ require 'scout_apm/serializers/payload_serializer_to_json'
6
+ require 'scout_apm/slow_transaction'
7
+ require 'scout_apm/metric_meta'
8
+ require 'scout_apm/metric_stats'
9
+ require 'scout_apm/context'
10
+ require 'ostruct'
2
11
  require 'json' # to deserialize what has been manually serialized by the production code
3
12
 
4
13
  class PayloadSerializerTest < Minitest::Test
@@ -8,7 +17,7 @@ class PayloadSerializerTest < Minitest::Test
8
17
  :unique_id => "unique_idz",
9
18
  :agent_version => 123
10
19
  }
11
- payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [], [], {}, [])
20
+ payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [])
12
21
 
13
22
  # symbol keys turn to strings
14
23
  formatted_metadata = {
@@ -46,10 +55,10 @@ class PayloadSerializerTest < Minitest::Test
46
55
  stats.min_call_time = 0.034881757
47
56
  stats.sum_of_squares = 0.007382350213180609
48
57
  stats.total_call_time = 0.113403176
49
- stats.total_exclusive_time = 0.078132088
58
+ stats.total_exclusive_time = 0.07813208899999999
50
59
  }
51
60
  }
52
- payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize({}, metrics, {}, [], [], [], {}, [])
61
+ payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize({}, metrics, {}, [], [])
53
62
  formatted_metrics = [
54
63
  {
55
64
  "key" => {
@@ -82,11 +91,10 @@ class PayloadSerializerTest < Minitest::Test
82
91
  "max_call_time" => 0.078521419,
83
92
  "min_call_time" => 0.034881757,
84
93
  "total_call_time" => 0.113403176,
85
- "total_exclusive_time" => 0.078132088,
94
+ "total_exclusive_time" => 0.07813208899999999,
86
95
  }
87
96
  ]
88
- assert_equal formatted_metrics,
89
- JSON.parse(payload)["metrics"].sort_by { |m| m["key"]["bucket"] }
97
+ assert_equal formatted_metrics, JSON.parse(payload)["metrics"]
90
98
  end
91
99
 
92
100
  def test_escapes_json_quotes
@@ -94,7 +102,7 @@ class PayloadSerializerTest < Minitest::Test
94
102
  :quotie => "here are some \"quotes\"",
95
103
  :payload_version => 2,
96
104
  }
97
- payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [], [], {}, [])
105
+ payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, {}, {}, [], [])
98
106
 
99
107
  # symbol keys turn to strings
100
108
  formatted_metadata = {
@@ -108,40 +116,4 @@ class PayloadSerializerTest < Minitest::Test
108
116
  json = { "foo" => "\bbar\nbaz\r" }
109
117
  assert_equal json, JSON.parse(ScoutApm::Serializers::PayloadSerializerToJson.jsonify_hash(json))
110
118
  end
111
-
112
- def test_escapes_escaped_quotes
113
- # Some escapes haven't ever worked on 1.8.7, and is not the issue I'm
114
- # fixing now. Remove this when we drop support for ancient ruby
115
- skip if RUBY_VERSION == "1.8.7"
116
-
117
- json = {"foo" => %q|`additional_details` = '{\"amount\":1}'|}
118
- result = ScoutApm::Serializers::PayloadSerializerToJson.jsonify_hash(json)
119
- assert_equal json, JSON.parse(result)
120
- end
121
-
122
- def test_escapes_various_special_characters
123
- # Some escapes haven't ever worked on 1.8.7, and is not the issue I'm
124
- # fixing now. Remove this when we drop support for ancient ruby
125
- skip if RUBY_VERSION == "1.8.7"
126
-
127
- json = {"foo" => [
128
- %Q|\fbar|,
129
- %Q|\rbar|,
130
- %Q|\nbar|,
131
- %Q|\tbar|,
132
- %Q|"bar|,
133
- %Q|'bar|,
134
- %Q|{bar|,
135
- %Q|}bar|,
136
- %Q|\\bar|,
137
- if RUBY_VERSION == '1.8.7'
138
- ""
139
- else
140
- %Q|\\\nbar|
141
- end,
142
- ]}
143
-
144
- result = ScoutApm::Serializers::PayloadSerializerToJson.jsonify_hash(json)
145
- assert_equal json, JSON.parse(result)
146
- end
147
119
  end
@@ -17,13 +17,9 @@ class FakeRequest
17
17
  end
18
18
 
19
19
  class SlowRequestPolicyTest < Minitest::Test
20
- def setup
21
- @context = ScoutApm::AgentContext.new
22
- end
23
-
24
20
  def test_stored_records_current_time
25
21
  test_start = Time.now
26
- policy = ScoutApm::SlowRequestPolicy.new(@context)
22
+ policy = ScoutApm::SlowRequestPolicy.new
27
23
  request = FakeRequest.new("users/index")
28
24
 
29
25
  policy.stored!(request)
@@ -31,20 +27,15 @@ class SlowRequestPolicyTest < Minitest::Test
31
27
  end
32
28
 
33
29
  def test_score
34
- policy = ScoutApm::SlowRequestPolicy.new(@context)
30
+ policy = ScoutApm::SlowRequestPolicy.new
35
31
  request = FakeRequest.new("users/index")
36
32
 
37
33
  request.set_duration(10) # 10 seconds
38
34
  policy.last_seen[request.unique_name] = Time.now - 120 # 2 minutes since last seen
39
- @context.request_histograms.add(request.unique_name, 1)
40
- @context.transaction_time_consumed.add(request.unique_name, 1)
41
-
42
- # Actual value I have in console is 4.01
43
- # Score uses Time.now to compare w/ last_seen, and will tick up slowly as
44
- # time passes, hence the range below.
45
- score = policy.score(request)
35
+ ScoutApm::Agent.instance.request_histograms.add(request.unique_name, 1)
46
36
 
47
- assert score > 3.95
48
- assert score < 4.05
37
+ # Actual value I have in console is 1.499
38
+ assert policy.score(request) > 1.45
39
+ assert policy.score(request) < 1.55
49
40
  end
50
41
  end
@@ -1,8 +1,14 @@
1
1
  require 'test_helper'
2
2
 
3
+ require 'scout_apm/utils/sql_sanitizer'
4
+
3
5
  module ScoutApm
4
6
  module Utils
5
7
  class SqlSanitizerTest < Minitest::Test
8
+ def setup
9
+ ScoutApm::Agent.instance.init_logger
10
+ end
11
+
6
12
  # Too long, and we just bail out to prevent long running instrumentation
7
13
  def test_long_sql
8
14
  sql = " " * 1001
@@ -10,8 +16,6 @@ module ScoutApm
10
16
  end
11
17
 
12
18
  def test_postgres_simple_select_of_first
13
- skip "Broken on Ruby 1.8.7 because regular expressions do not support look-behinds" if RUBY_VERSION.start_with?("1.8.")
14
-
15
19
  sql = %q|SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1|
16
20
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :postgres }
17
21
  assert_equal %q|SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1|, ss.to_s
@@ -28,23 +32,7 @@ module ScoutApm
28
32
  sql = %q|SELECT "users".* FROM "users" INNER JOIN "blogs" ON "blogs"."user_id" = "users"."id" WHERE (blogs.title = 'hello world')|
29
33
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :postgres }
30
34
  assert_equal %q|SELECT "users".* FROM "users" INNER JOIN "blogs" ON "blogs"."user_id" = "users"."id" WHERE (blogs.title = ?)|, ss.to_s
31
- end
32
-
33
- def test_postgres_strips_after_where
34
- raw_sql = %q|SELECT DISTINCT ON (flagged_traces.metric_name) flagged_traces.metric_name, "flagged_traces"."trace_id", "flagged_traces"."trace_type", "flagged_traces"."trace_occurred_at", flagged_traces.details ->> 'uri' as uri, (flagged_traces.details ->> 'n_sum_millis')::float as potential_savings, (flagged_traces.details ->> 'n_count')::float as num_queries FROM "flagged_traces" WHERE "flagged_traces"."app_id" = 5 AND "flagged_traces"."trace_type" = 'Request' AND ("flagged_traces"."trace_occurred_at" BETWEEN '2019-04-17 12:28:00.000000' AND '2019-04-18 12:28:00.000000') AND "flagged_traces"."flag_type" = 'nplusone' ORDER BY "flagged_traces"."metric_name" ASC, potential_savings DESC|
35
- sanitized_sql = SqlSanitizer.new(raw_sql).tap { |it| it.database_engine = :postgres}
36
- expected_sql = %q|SELECT DISTINCT ON (flagged_traces.metric_name) flagged_traces.metric_name, "flagged_traces"."trace_id", "flagged_traces"."trace_type", "flagged_traces"."trace_occurred_at", flagged_traces.details ->> 'uri' as uri, (flagged_traces.details ->> 'n_sum_millis')::float as potential_savings, (flagged_traces.details ->> 'n_count')::float as num_queries FROM "flagged_traces" WHERE "flagged_traces"."app_id" = ? AND "flagged_traces"."trace_type" = ? AND ("flagged_traces"."trace_occurred_at" BETWEEN ? AND ?) AND "flagged_traces"."flag_type" = ? ORDER BY "flagged_traces"."metric_name" ASC, potential_savings DESC|
37
- assert_equal expected_sql, sanitized_sql.to_s
38
- end
39
-
40
- def test_postgres_strips_subquery_strings
41
- raw_sql = %q|"SELECT 'orgs'.* FROM "orgs" WHERE "orgs"."name" = 'Scout' AND "orgs"."created_by_user_id" IN (SELECT 'users'.'id' FROM "users" WHERE (id > AVG(id)) AND "type" = 'USER' AND "created_at" BETWEEN '2019-04-17 12:28:00.000000' AND '2019-04-18 12:28:00.000000')"|
42
- sanitized_sql = SqlSanitizer.new(raw_sql).tap { |it| it.database_engine = :postgres}
43
- expected_sql = %q|"SELECT 'orgs'.* FROM "orgs" WHERE "orgs"."name" = ? AND "orgs"."created_by_user_id" IN (SELECT 'users'.'id' FROM "users" WHERE (id > AVG(id)) AND "type" = ? AND "created_at" BETWEEN ? AND ?)"|
44
- assert_equal expected_sql, sanitized_sql.to_s
45
- end
46
35
 
47
- def test_postgres_strips_integers
48
36
  # Strip integers
49
37
  sql = %q|SELECT "blogs".* FROM "blogs" WHERE (view_count > 10)|
50
38
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :postgres }
@@ -73,8 +61,6 @@ module ScoutApm
73
61
  end
74
62
 
75
63
  def test_mysql_limit
76
- skip "Broken on Ruby 1.8.7 because regular expressions do not support look-behinds" if RUBY_VERSION.start_with?("1.8.")
77
-
78
64
  sql = %q|SELECT `blogs`.* FROM `blogs` ORDER BY `blogs`.`id` ASC LIMIT 1|
79
65
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :mysql }
80
66
  assert_equal %q|SELECT `blogs`.* FROM `blogs` ORDER BY `blogs`.`id` ASC LIMIT 1|, ss.to_s
@@ -105,33 +91,7 @@ module ScoutApm
105
91
  assert_equal %q|INSERT INTO `users` VALUES (?, ?)|, ss.to_s
106
92
  end
107
93
 
108
- def test_sqlserver_integers
109
- skip "SQLServer Support requires Ruby 1.9+ For Regexes"
110
-
111
- sql = "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE (age > 50) ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY', N'@0 int', @0 = 10"
112
- ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :sqlserver }
113
- assert_equal %q|SELECT [users].* FROM [users] WHERE (age > ?) ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @0 ROWS ONLY|, ss.to_s
114
- end
115
-
116
- def test_sqlserver_strings
117
- skip "SQLServer Support requires Ruby 1.9+ For Regexes"
118
-
119
- sql = "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE [users].[email] = @0 ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @1 ROWS ONLY', N'@0 nvarchar(4000), @1 int', @0 = N'foo', @1 = 10"
120
- ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :sqlserver }
121
- assert_equal %q|SELECT [users].* FROM [users] WHERE [users].[email] = @0 ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @1 ROWS ONLY|, ss.to_s
122
- end
123
-
124
- def test_sqlserver_in_clause
125
- skip "SQLServer Support requires Ruby 1.9+ For Regexes"
126
-
127
- sql = "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE (id IN (1,2,3)) ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY', N'@0 int', @0 = 10"
128
- ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :sqlserver }
129
- assert_equal %q|SELECT [users].* FROM [users] WHERE (id IN (?)) ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @0 ROWS ONLY|, ss.to_s
130
- end
131
-
132
94
  def test_scrubs_invalid_encoding
133
- skip "Ruby 1.8.7 has no concept of encoding" if RUBY_VERSION.start_with?("1.8.")
134
-
135
95
  sql = "SELECT `blogs`.* FROM `blogs` WHERE (title = 'a\255c')".force_encoding('UTF-8')
136
96
  assert_equal false, sql.valid_encoding?
137
97
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :mysql }
@@ -139,13 +99,6 @@ module ScoutApm
139
99
  assert_equal %q|SELECT `blogs`.* FROM `blogs` WHERE (title = ?)|, ss.to_s
140
100
  end
141
101
 
142
- def test_set_columns
143
- sql = %q|UPDATE "mytable" SET "myfield" = 'fieldcontent', "countofthings" = 10 WHERE "user_id" = 10|
144
-
145
- ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :postgres }
146
- assert_equal %q|UPDATE "mytable" SET "myfield" = ?, "countofthings" = ? WHERE "user_id" = ?|, ss.to_s
147
- end
148
-
149
102
  def assert_faster_than(target_seconds)
150
103
  t1 = ::Time.now
151
104
  yield
@@ -3,90 +3,21 @@ require 'test_helper'
3
3
  require 'scout_apm/store'
4
4
 
5
5
  class FakeFailingLayaway
6
- attr_reader :rps_written
7
6
  def write_reporting_period(rp)
8
- @rps_written ||= []
9
- @rps_written << rp
7
+ raise "Always fails. Sucks."
10
8
  end
11
9
  end
12
10
 
13
11
  class StoreTest < Minitest::Test
14
12
  # TODO: Introduce a clock object to avoid having to use 'force'
15
13
  def test_writing_layaway_removes_timestamps
16
- s = ScoutApm::Store.new(ScoutApm::AgentContext.new)
14
+ s = ScoutApm::Store.new
17
15
  s.track_one!("Controller", "user/show", 10)
18
16
 
19
- assert_equal(1, s.instance_variable_get('@reporting_periods').size)
17
+ assert_equal(1, s.reporting_periods.size)
20
18
 
21
19
  s.write_to_layaway(FakeFailingLayaway.new, true)
22
20
 
23
- assert_equal({}, s.instance_variable_get('@reporting_periods'))
24
- end
25
-
26
- def test_writing_layaway_removes_stale_timestamps
27
- context = ScoutApm::AgentContext.new
28
- current_time = Time.now.utc
29
- current_rp = ScoutApm::StoreReportingPeriod.new(current_time, context)
30
- stale_rp = ScoutApm::StoreReportingPeriod.new(current_time - current_time.sec - 120, context)
31
-
32
- s = ScoutApm::Store.new(context)
33
- ScoutApm::Instruments::Process::ProcessMemory.new(context).metrics(stale_rp.timestamp, s)
34
- ScoutApm::Instruments::Process::ProcessMemory.new(context).metrics(current_rp.timestamp, s)
35
- assert_equal 2, s.instance_variable_get('@reporting_periods').size
36
-
37
- s.write_to_layaway(FakeFailingLayaway.new, true)
38
-
39
- assert_equal({}, s.instance_variable_get('@reporting_periods'))
40
- end
41
- end
42
-
43
- class StoreReportingPeriodTest < Minitest::Test
44
- HistogramReport = ScoutApm::Instruments::HistogramReport
45
-
46
- attr_reader :subject
47
-
48
- def setup
49
- @subject = ScoutApm::StoreReportingPeriod.new(ScoutApm::StoreReportingPeriodTimestamp.new(Time.now), ScoutApm::AgentContext.new)
50
- end
51
-
52
- # Check default values at creation time
53
- def test_empty_values
54
- assert_equal [], subject.histograms
55
- assert_equal ScoutApm::ScoredItemSet.new, subject.request_traces
56
- assert_equal ScoutApm::ScoredItemSet.new, subject.job_traces
57
- assert_equal ScoutApm::MetricSet.new, subject.metric_set
58
- end
59
-
60
- def test_merge_histograms
61
- histogramFoo1 = histogram
62
- histogramFoo2 = histogram
63
- histogramBar1 = histogram
64
- histogramBar2 = histogram
65
-
66
- # This assertion may be fragile to reordering in the merge_histograms! function.
67
- histogramFoo1.expects(:combine!).with(histogramFoo2)
68
- histogramBar1.expects(:combine!).with(histogramBar2)
69
-
70
- subject.merge_histograms!([
71
- HistogramReport.new("foo", histogramFoo1),
72
- HistogramReport.new("bar", histogramBar1),
73
- ])
74
-
75
- subject.merge_histograms!([
76
- HistogramReport.new("foo", histogramFoo2),
77
- HistogramReport.new("bar", histogramBar2),
78
- ])
79
-
80
- result = subject.histograms
81
- assert_equal 2, result.length
82
- assert_equal ["bar", "foo"], result.map(&:name).sort
83
- end
84
-
85
- ###############################################################################
86
- # Helpers
87
- ###############################################################################
88
- def histogram
89
- max_bins = 20
90
- ScoutApm::NumericHistogram.new(max_bins)
21
+ assert_equal({}, s.reporting_periods)
91
22
  end
92
23
  end