coverband 4.2.0 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -9
  3. data/.travis.yml +10 -1
  4. data/Gemfile +3 -1
  5. data/Gemfile.rails4 +1 -0
  6. data/README.md +40 -15
  7. data/Rakefile +14 -3
  8. data/changes.md +47 -12
  9. data/coverband.gemspec +3 -1
  10. data/lib/coverband/adapters/base.rb +60 -36
  11. data/lib/coverband/adapters/file_store.rb +8 -8
  12. data/lib/coverband/adapters/redis_store.rb +18 -10
  13. data/lib/coverband/at_exit.rb +2 -11
  14. data/lib/coverband/collectors/coverage.rb +32 -36
  15. data/lib/coverband/collectors/delta.rb +34 -28
  16. data/lib/coverband/configuration.rb +76 -32
  17. data/lib/coverband/integrations/background.rb +8 -4
  18. data/lib/coverband/integrations/{middleware.rb → background_middleware.rb} +2 -6
  19. data/lib/coverband/integrations/bundler.rb +8 -0
  20. data/lib/coverband/integrations/report_middleware.rb +15 -0
  21. data/lib/coverband/integrations/resque.rb +3 -5
  22. data/lib/coverband/reporters/base.rb +39 -14
  23. data/lib/coverband/reporters/html_report.rb +21 -27
  24. data/lib/coverband/reporters/web.rb +13 -21
  25. data/lib/coverband/utils/file_list.rb +16 -5
  26. data/lib/coverband/utils/file_path_helper.rb +14 -3
  27. data/lib/coverband/utils/html_formatter.rb +25 -8
  28. data/lib/coverband/utils/lines_classifier.rb +5 -0
  29. data/lib/coverband/utils/railtie.rb +11 -12
  30. data/lib/coverband/utils/result.rb +1 -37
  31. data/lib/coverband/utils/results.rb +51 -0
  32. data/lib/coverband/utils/source_file.rb +31 -6
  33. data/lib/coverband/utils/tasks.rb +9 -10
  34. data/lib/coverband/version.rb +1 -1
  35. data/lib/coverband.rb +32 -21
  36. data/public/application.js +27 -0
  37. data/test/benchmarks/benchmark.rake +144 -26
  38. data/test/coverband/adapters/base_test.rb +73 -42
  39. data/test/coverband/adapters/file_store_test.rb +48 -37
  40. data/test/coverband/adapters/redis_store_test.rb +41 -10
  41. data/test/coverband/at_exit_test.rb +0 -2
  42. data/test/coverband/collectors/coverage_test.rb +57 -9
  43. data/test/coverband/collectors/delta_test.rb +36 -6
  44. data/test/coverband/configuration_test.rb +47 -7
  45. data/test/coverband/coverband_test.rb +14 -2
  46. data/test/coverband/integrations/background_middleware_test.rb +44 -0
  47. data/test/coverband/integrations/background_test.rb +1 -3
  48. data/test/coverband/integrations/report_middleware_test.rb +44 -0
  49. data/test/coverband/integrations/resque_worker_test.rb +4 -3
  50. data/test/coverband/integrations/test_resque_job.rb +3 -1
  51. data/test/coverband/reporters/base_test.rb +4 -4
  52. data/test/coverband/reporters/console_test.rb +1 -2
  53. data/test/coverband/reporters/html_test.rb +58 -19
  54. data/test/coverband/reporters/web_test.rb +0 -10
  55. data/test/coverband/utils/file_groups_test.rb +11 -5
  56. data/test/coverband/utils/file_list_test.rb +5 -5
  57. data/test/coverband/utils/html_formatter_test.rb +43 -0
  58. data/test/coverband/utils/result_test.rb +6 -47
  59. data/test/coverband/utils/results_test.rb +54 -0
  60. data/test/coverband/utils/s3_report_test.rb +2 -0
  61. data/test/coverband/utils/source_file_test.rb +50 -0
  62. data/test/dog.rb.erb +12 -0
  63. data/test/forked/rails_full_stack_test.rb +106 -0
  64. data/test/forked/rails_rake_full_stack_test.rb +40 -0
  65. data/test/integration/full_stack_test.rb +17 -15
  66. data/test/rails4_dummy/Rakefile +6 -0
  67. data/test/rails4_dummy/config/application.rb +8 -9
  68. data/test/rails4_dummy/config/coverband.rb +5 -3
  69. data/test/rails5_dummy/Rakefile +6 -0
  70. data/test/rails5_dummy/config/application.rb +6 -10
  71. data/test/rails5_dummy/config/coverband.rb +4 -2
  72. data/test/rails_test_helper.rb +22 -5
  73. data/test/test_helper.rb +42 -4
  74. data/test/unique_files.rb +17 -9
  75. data/views/file_list.erb +2 -2
  76. data/views/gem_list.erb +10 -1
  77. data/views/layout.erb +10 -3
  78. data/views/source_file.erb +13 -4
  79. data/views/source_file_loader.erb +1 -1
  80. metadata +52 -9
  81. data/test/coverband/integrations/middleware_test.rb +0 -96
  82. data/test/integration/rails_full_stack_test.rb +0 -95
@@ -11,6 +11,8 @@ module Coverband
11
11
  module Utils
12
12
  class SourceFile
13
13
  include Coverband::Utils::FilePathHelper
14
+
15
+ # TODO: Refactor Line into its own file
14
16
  # Representation of a single line in a source file including
15
17
  # this specific line's source code, line_number and code coverage,
16
18
  # with the coverage being either nil (coverage not applicable, e.g. comment
@@ -35,6 +37,7 @@ module Coverband
35
37
  raise ArgumentError, 'Only String accepted for source' unless src.is_a?(String)
36
38
  raise ArgumentError, 'Only Integer accepted for line_number' unless line_number.is_a?(Integer)
37
39
  raise ArgumentError, 'Only Integer and nil accepted for coverage' unless coverage.is_a?(Integer) || coverage.nil?
40
+
38
41
  @src = src
39
42
  @line_number = line_number
40
43
  @coverage = coverage
@@ -48,7 +51,7 @@ module Coverband
48
51
 
49
52
  # Returns true if this is a line that has been covered
50
53
  def covered?
51
- !never? && !skipped? && coverage > 0
54
+ !never? && !skipped? && coverage.positive?
52
55
  end
53
56
 
54
57
  # Returns true if this line is not relevant for coverage
@@ -64,7 +67,7 @@ module Coverband
64
67
  # Returns true if this line was skipped, false otherwise. Lines are skipped if they are wrapped with
65
68
  # # :nocov: comment lines.
66
69
  def skipped?
67
- !!skipped
70
+ skipped
68
71
  end
69
72
 
70
73
  # The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use
@@ -90,18 +93,27 @@ module Coverband
90
93
 
91
94
  def initialize(filename, file_data)
92
95
  @filename = filename
96
+ @runtime_relavant_lines = nil
93
97
  if file_data.is_a?(Hash)
94
98
  @coverage = file_data['data']
95
99
  @first_updated_at = @last_updated_at = NOT_AVAILABLE
96
100
  @first_updated_at = Time.at(file_data['first_updated_at']) if file_data['first_updated_at']
97
101
  @last_updated_at = Time.at(file_data['last_updated_at']) if file_data['last_updated_at']
98
102
  else
103
+ # TODO: Deprecate this code path this was backwards compatability from 3-4
99
104
  @coverage = file_data
100
105
  @first_updated_at = NOT_AVAILABLE
101
106
  @last_updated_at = NOT_AVAILABLE
102
107
  end
103
108
  end
104
109
 
110
+ def runtime_relavant_calculations(runtime_relavant_lines)
111
+ @runtime_relavant_lines = runtime_relavant_lines
112
+ yield self
113
+ ensure
114
+ @runtime_relavant_lines = nil
115
+ end
116
+
105
117
  # The path to this source file relative to the projects directory
106
118
  def project_filename
107
119
  @filename.sub(/^#{Coverband.configuration.root}/, '')
@@ -148,7 +160,12 @@ module Coverband
148
160
 
149
161
  return 0.0 if relevant_lines.zero?
150
162
 
151
- Float(covered_lines.size * 100.0 / relevant_lines.to_f)
163
+ # handle edge case where runtime in dev can go over 100%
164
+ [Float(covered_lines.size * 100.0 / relevant_lines.to_f), 100.0].min
165
+ end
166
+
167
+ def formatted_covered_percent
168
+ covered_percent&.round(2)
152
169
  end
153
170
 
154
171
  def covered_strength
@@ -166,7 +183,7 @@ module Coverband
166
183
  end
167
184
 
168
185
  def relevant_lines
169
- lines.size - never_lines.size - skipped_lines.size
186
+ @runtime_relavant_lines || (lines.size - never_lines.size - skipped_lines.size)
170
187
  end
171
188
 
172
189
  # Returns all covered lines as SimpleCov::SourceFile::Line
@@ -174,6 +191,14 @@ module Coverband
174
191
  @covered_lines ||= lines.select(&:covered?)
175
192
  end
176
193
 
194
+ def covered_lines_count
195
+ covered_lines&.count
196
+ end
197
+
198
+ def line_coverage(index)
199
+ lines[index]&.coverage
200
+ end
201
+
177
202
  # Returns all lines that should have been, but were not covered
178
203
  # as instances of SimpleCov::SourceFile::Line
179
204
  def missed_lines
@@ -216,7 +241,7 @@ module Coverband
216
241
  # I had previously patched this in my local Rails app
217
242
  def short_name
218
243
  filename.sub(/^#{Coverband.configuration.root}/, '.')
219
- .sub(%r{^.*\/gems}, '.')
244
+ .sub(%r{^.*\/gems\/}, '.')
220
245
  .gsub(%r{^\.\/}, '')
221
246
  end
222
247
 
@@ -229,7 +254,7 @@ module Coverband
229
254
  end
230
255
 
231
256
  def gem_name
232
- gem? ? short_name.split('/').first : nil
257
+ gem? ? short_name.split('/').first.gsub(%r{^\.}, '') : nil
233
258
  end
234
259
 
235
260
  private
@@ -1,37 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :coverband do
4
- Coverband.configure
5
-
6
- def environment
7
- Rake.application['environment'].invoke if Rake::Task.task_defined?('environment')
8
- end
4
+ # handles configuring in require => false and COVERBAND_DISABLE_AUTO_START cases
5
+ Coverband.configure unless Coverband.configured?
9
6
 
10
7
  desc 'report runtime Coverband code coverage'
11
8
  task :coverage do
12
- environment
13
9
  if Coverband.configuration.reporter == 'scov'
14
- Coverband::Reporters::HTMLReport.report(Coverband.configuration.store)
10
+ Coverband::Reporters::HTMLReport.new(Coverband.configuration.store).report
15
11
  else
16
12
  Coverband::Reporters::ConsoleReport.report(Coverband.configuration.store)
17
13
  end
18
14
  end
19
15
 
16
+ desc 'report runtime Coverband code coverage'
17
+ task :coverage_server do
18
+ Rack::Server.start app: Coverband::Reporters::Web.new, Port: ENV.fetch('COVERBAND_COVERAGE_PORT', 1022).to_i
19
+ end
20
+
20
21
  ###
21
22
  # clear data helpful for development or after configuration issues
22
23
  ###
23
24
  desc 'reset Coverband coverage data, helpful for development, debugging, etc'
24
25
  task :clear do
25
- environment
26
26
  Coverband.configuration.store.clear!
27
27
  end
28
28
 
29
29
  ###
30
- # clear data helpful for development or after configuration issues
30
+ # Updates the data in the coverband store from one format to another
31
31
  ###
32
32
  desc 'upgrade previous Coverband datastore to latest format'
33
33
  task :migrate do
34
- environment
35
34
  Coverband.configuration.store.migrate!
36
35
  end
37
36
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coverband
4
- VERSION = '4.2.0'
4
+ VERSION = '4.2.1'
5
5
  end
data/lib/coverband.rb CHANGED
@@ -23,24 +23,20 @@ require 'coverband/collectors/coverage'
23
23
  require 'coverband/reporters/base'
24
24
  require 'coverband/reporters/html_report'
25
25
  require 'coverband/reporters/console_report'
26
- require 'coverband/integrations/background'
27
- require 'coverband/integrations/rack_server_check'
28
26
  require 'coverband/reporters/web'
29
- require 'coverband/integrations/middleware'
30
27
  require 'coverband/integrations/background'
28
+ require 'coverband/integrations/background_middleware'
29
+ require 'coverband/integrations/rack_server_check'
31
30
 
32
31
  module Coverband
32
+ @@configured = false
33
33
  CONFIG_FILE = './config/coverband.rb'
34
- RUNTIME_TYPE = nil
34
+ RUNTIME_TYPE = :runtime
35
35
  EAGER_TYPE = :eager_loading
36
36
  MERGED_TYPE = :merged
37
37
  TYPES = [RUNTIME_TYPE, EAGER_TYPE]
38
38
  ALL_TYPES = TYPES + [:merged]
39
39
 
40
- class << self
41
- attr_accessor :configuration_data
42
- end
43
-
44
40
  def self.configure(file = nil)
45
41
  configuration_file = file || ENV.fetch('COVERBAND_CONFIG', CONFIG_FILE)
46
42
  configuration
@@ -49,45 +45,60 @@ module Coverband
49
45
  elsif File.exist?(configuration_file)
50
46
  load configuration_file
51
47
  else
52
- configuration.logger&.debug('using default configuration')
48
+ configuration.logger.debug('using default configuration')
53
49
  end
54
- coverage.reset_instance
50
+ @@configured = true
51
+ coverage_instance.reset_instance
52
+ end
53
+
54
+ def self.configured?
55
+ @@configured
55
56
  end
56
57
 
57
- def self.report_coverage(force_report = false)
58
- Coverband::Collectors::Coverage.instance.report_coverage(force_report)
58
+ def self.report_coverage
59
+ coverage_instance.report_coverage
59
60
  end
60
61
 
61
62
  def self.configuration
62
- self.configuration_data ||= Configuration.new
63
+ @configuration ||= Configuration.new
63
64
  end
64
65
 
65
66
  def self.start
66
67
  Coverband::Collectors::Coverage.instance
67
- # TODO Railtie sets up at_exit after forks, via middleware, perhaps this hsould be
68
+ # TODO: Railtie sets up at_exit after forks, via middleware, perhaps this should be
68
69
  # added if not rails or if rails but not rackserverrunning
69
- AtExit.register
70
- Background.start if configuration.background_reporting_enabled && !RackServerCheck.running?
70
+ AtExit.register unless tasks_to_ignore?
71
+ Background.start if configuration.background_reporting_enabled && !RackServerCheck.running? && !tasks_to_ignore?
72
+ end
73
+
74
+ def self.tasks_to_ignore?
75
+ (defined?(Rake) &&
76
+ Rake.respond_to?(:application) &&
77
+ (Rake&.application&.top_level_tasks || []).any? { |task| Coverband::Configuration::IGNORE_TASKS.include?(task) })
71
78
  end
72
79
 
73
80
  def self.eager_loading_coverage!
74
- coverage.eager_loading!
81
+ coverage_instance.eager_loading!
82
+ end
83
+
84
+ def self.eager_loading_coverage(&block)
85
+ coverage_instance.eager_loading(&block)
75
86
  end
76
87
 
77
88
  def self.runtime_coverage!
78
- coverage.runtime!
89
+ coverage_instance.runtime!
79
90
  end
80
91
 
81
- def self.coverage
92
+ private_class_method def self.coverage_instance
82
93
  Coverband::Collectors::Coverage.instance
83
94
  end
84
-
85
95
  unless ENV['COVERBAND_DISABLE_AUTO_START']
86
96
  # Coverband should be setup as early as possible
87
97
  # to capture usage of things loaded by initializers or other Rails engines
88
98
  configure
89
99
  start
90
100
  require 'coverband/utils/railtie' if defined? ::Rails::Railtie
91
- require 'coverband/integrations/resque' if defined? Resque
101
+ require 'coverband/integrations/resque' if defined? ::Resque
102
+ require 'coverband/integrations/bundler' if defined? ::Bundler
92
103
  end
93
104
  end
@@ -1,4 +1,14 @@
1
1
  $(document).ready(function() {
2
+ // remove the url params like notice=message so they don't stick around
3
+ window.history.replaceState(
4
+ "object or string",
5
+ "Coverband",
6
+ window.location.href.replace(/notice=.*/, "")
7
+ );
8
+ $(".notice")
9
+ .delay(3000)
10
+ .fadeOut("slow");
11
+
2
12
  $(".del").click(function() {
3
13
  if (!confirm("Do you want to delete")) {
4
14
  return false;
@@ -13,8 +23,25 @@ $(document).ready(function() {
13
23
  aoColumns: [
14
24
  null,
15
25
  { sType: "percent" },
26
+ { sType: "percent" },
27
+ null,
28
+ null,
29
+ null,
16
30
  null,
17
31
  null,
32
+ null
33
+ ]
34
+ });
35
+
36
+ // Configuration for fancy sortable tables for source file groups
37
+ $(".gem_list").dataTable({
38
+ aaSorting: [[1, "asc"]],
39
+ bPaginate: false,
40
+ bJQueryUI: true,
41
+ aoColumns: [
42
+ null,
43
+ { sType: "percent" },
44
+ { sType: "percent" },
18
45
  null,
19
46
  null,
20
47
  null,
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  namespace :benchmarks do
3
4
  # https://github.com/evanphx/benchmark-ips
4
5
  # Enable and start GC before each job run. Disable GC afterwards.
@@ -13,11 +14,9 @@ namespace :benchmarks do
13
14
  run_gc
14
15
  end
15
16
 
16
- def warmup_stats(*)
17
- end
17
+ def warmup_stats(*); end
18
18
 
19
- def add_report(*)
20
- end
19
+ def add_report(*); end
21
20
 
22
21
  private
23
22
 
@@ -33,11 +32,7 @@ namespace :benchmarks do
33
32
  end
34
33
 
35
34
  def clone_classifier
36
- # rubocop:disable Style/IfUnlessModifier
37
- unless Dir.exist? classifier_dir
38
- system "git clone https://github.com/jekyll/classifier-reborn.git #{classifier_dir}"
39
- end
40
- # rubocop:enable Style/IfUnlessModifier
35
+ system "git clone https://github.com/jekyll/classifier-reborn.git #{classifier_dir}" unless Dir.exist? classifier_dir
41
36
  end
42
37
 
43
38
  # desc 'setup standard benchmark'
@@ -56,9 +51,9 @@ namespace :benchmarks do
56
51
  # moving from 5 second of time to 12 still shows slower based on when classifier is required
57
52
  # make sure to be plugged in while benchmarking ;) Otherwise you get very unreliable results
58
53
  require 'classifier-reborn'
59
- if ENV['COVERAGE']
54
+ if ENV['COVERAGE'] || ENV['ONESHOT']
60
55
  require 'coverage'
61
- ::Coverage.start
56
+ ::Coverage.start(oneshot_lines: !!ENV['ONESHOT'])
62
57
  end
63
58
  require 'redis'
64
59
  require 'coverband'
@@ -79,9 +74,10 @@ namespace :benchmarks do
79
74
  task :setup_redis do
80
75
  Coverband.configure do |config|
81
76
  config.root = Dir.pwd
82
- config.reporting_frequency = 100.0
83
77
  config.logger = $stdout
84
78
  config.store = benchmark_redis_store
79
+ config.use_oneshot_lines_coverage = true if ENV['ONESHOT']
80
+ config.simulate_oneshot_lines_coverage = true if ENV['SIMULATE_ONESHOT']
85
81
  end
86
82
  end
87
83
 
@@ -89,7 +85,6 @@ namespace :benchmarks do
89
85
  task :setup_file do
90
86
  Coverband.configure do |config|
91
87
  config.root = Dir.pwd
92
- config.reporting_frequency = 100.0
93
88
  config.logger = $stdout
94
89
  file_path = '/tmp/benchmark_store.json'
95
90
  config.store = Coverband::Adapters::FileStore.new(file_path)
@@ -134,7 +129,7 @@ namespace :benchmarks do
134
129
  x.config(time: 12, warmup: 5, suite: suite)
135
130
  x.report 'coverband' do
136
131
  work
137
- Coverband.report_coverage(true)
132
+ Coverband.report_coverage
138
133
  end
139
134
  x.report 'no coverband' do
140
135
  work
@@ -160,6 +155,7 @@ namespace :benchmarks do
160
155
  def adjust_report(report)
161
156
  report.keys.each do |file|
162
157
  next unless rand < 0.15
158
+
163
159
  report[file] = fake_line_numbers
164
160
  end
165
161
  report
@@ -170,11 +166,7 @@ namespace :benchmarks do
170
166
  # this is a hack because in the benchmark we don't have real files
171
167
  ###
172
168
  def store.file_hash(file)
173
- if @file_hash_cache[file]
174
- @file_hash_cache[file]
175
- else
176
- @file_hash_cache[file] = Digest::MD5.file(__FILE__).hexdigest
177
- end
169
+ @file_hash_cache[file] || @file_hash_cache[file] = Digest::MD5.file(__FILE__).hexdigest
178
170
  end
179
171
 
180
172
  def store.full_path_to_relative(file)
@@ -214,11 +206,54 @@ namespace :benchmarks do
214
206
  end.pretty_print
215
207
  data = $stdout.string
216
208
  $stdout = previous_out
217
- raise 'leaking memory!!!' unless data.match('Total retained: 0 bytes')
209
+ unless data.match('Total retained: 0 bytes')
210
+ puts data
211
+ raise 'leaking memory!!!'
212
+ end
218
213
  ensure
219
214
  $stdout = previous_out
220
215
  end
221
216
 
217
+ def measure_memory_report_coverage
218
+ require 'memory_profiler'
219
+ report = fake_report
220
+ store = benchmark_redis_store
221
+ store.clear!
222
+ mock_files(store)
223
+
224
+ # warmup
225
+ 3.times { Coverband.report_coverage }
226
+
227
+ previous_out = $stdout
228
+ capture = StringIO.new
229
+ $stdout = capture
230
+
231
+ MemoryProfiler.report do
232
+ 10.times do
233
+ Coverband.report_coverage
234
+ ###
235
+ # Set to nil not {} as it is easier to verify that no memory is retained when nil gets released
236
+ # don't use Coverband::Collectors::Delta.reset which sets to {}
237
+ # we clear this as this one variable is expected to retain memory and is a false positive
238
+ ###
239
+ Coverband::Collectors::Delta.class_variable_set(:@@previous_coverage, nil)
240
+ end
241
+ end.pretty_print
242
+ data = $stdout.string
243
+ $stdout = previous_out
244
+ unless data.match('Total retained: 0 bytes')
245
+ puts data
246
+ raise 'leaking memory!!!'
247
+ end
248
+ ensure
249
+ $stdout = previous_out
250
+ end
251
+
252
+ ###
253
+ # TODO: This currently fails, as it holds a string in redis adapter
254
+ # but really Coverband shouldn't be configured multiple times and the leak is small
255
+ # not including in test suite but we can try to figure it out and fix.
256
+ ###
222
257
  def measure_configure_memory
223
258
  require 'memory_profiler'
224
259
  # warmup
@@ -232,24 +267,79 @@ namespace :benchmarks do
232
267
  10.times do
233
268
  Coverband.configure do |config|
234
269
  redis_url = ENV['CACHE_REDIS_URL'] || ENV['REDIS_URL']
235
- config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace: 'coverband_data')
270
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace: 'coverband_bench_data')
236
271
  end
237
272
  end
238
273
  end.pretty_print
239
274
  data = $stdout.string
240
275
  $stdout = previous_out
241
- puts data
242
- raise 'leaking memory!!!' unless data.match('Total retained: 0 bytes')
276
+ unless data.match('Total retained: 0 bytes')
277
+ puts data
278
+ raise 'leaking memory!!!'
279
+ end
243
280
  ensure
244
281
  $stdout = previous_out
245
282
  end
246
283
 
284
+ desc 'checks memory of collector'
285
+ task memory_check: [:setup] do
286
+ require 'pry-byebug'
287
+ require 'objspace'
288
+ puts 'memory load check'
289
+ puts(ObjectSpace.memsize_of_all / 2**20)
290
+ data = File.read('./tmp/debug_data.json')
291
+ # about 2mb
292
+ puts(ObjectSpace.memsize_of(data) / 2**20)
293
+
294
+ json_data = JSON.parse(data)
295
+ # this seems to just show the value of the pointer
296
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
297
+ # implies json takes 10-12 mb
298
+ puts(ObjectSpace.memsize_of_all / 2**20)
299
+
300
+ json_data = nil
301
+ GC.start
302
+ json_data = JSON.parse(data)
303
+ # this seems to just show the value of the pointer
304
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
305
+ # implies json takes 10-12 mb
306
+ puts(ObjectSpace.memsize_of_all / 2**20)
307
+
308
+ json_data = nil
309
+ GC.start
310
+ json_data = JSON.parse(data)
311
+ # this seems to just show the value of the pointer
312
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
313
+ # implies json takes 10-12 mb
314
+ puts(ObjectSpace.memsize_of_all / 2**20)
315
+
316
+ json_data = nil
317
+ GC.start
318
+ json_data = JSON.parse(data)
319
+ # this seems to just show the value of the pointer
320
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
321
+ # implies json takes 10-12 mb
322
+ puts(ObjectSpace.memsize_of_all / 2**20)
323
+
324
+ json_data = nil
325
+ GC.start
326
+ puts(ObjectSpace.memsize_of_all / 2**20)
327
+ debugger
328
+ puts 'done'
329
+ end
330
+
247
331
  desc 'runs memory reporting on Redis store'
248
332
  task memory_reporting: [:setup] do
249
333
  puts 'runs memory benchmarking to ensure we dont leak'
250
334
  measure_memory
251
335
  end
252
336
 
337
+ desc 'runs memory reporting on report_coverage'
338
+ task memory_reporting_report_coverage: [:setup] do
339
+ puts 'runs memory benchmarking on report_coverage to ensure we dont leak'
340
+ measure_memory_report_coverage
341
+ end
342
+
253
343
  desc 'runs memory reporting on configure'
254
344
  task memory_configure_reporting: [:setup] do
255
345
  puts 'runs memory benchmarking on configure to ensure we dont leak'
@@ -259,7 +349,12 @@ namespace :benchmarks do
259
349
  desc 'runs memory leak check via Rails tests'
260
350
  task memory_rails: [:setup] do
261
351
  puts 'runs memory rails test to ensure we dont leak'
262
- puts `COVERBAND_MEMORY_TEST=true bundle exec m test/unit/rails_full_stack_test.rb:22`
352
+ puts `COVERBAND_MEMORY_TEST=true bundle exec test/forked/rails_full_stack_test.rb`
353
+ end
354
+
355
+ desc 'runs memory leak checks'
356
+ task memory: %i[memory_reporting memory_reporting_report_coverage memory_rails] do
357
+ puts 'done'
263
358
  end
264
359
 
265
360
  desc 'runs benchmarks on reporting large sets of files to redis'
@@ -269,13 +364,36 @@ namespace :benchmarks do
269
364
  end
270
365
 
271
366
  # desc 'runs benchmarks on default redis setup'
272
- task run_redis: [:setup, :setup_redis] do
367
+ task run_redis: %i[setup setup_redis] do
273
368
  puts 'Coverband configured with default Redis store'
274
369
  run_work(true)
275
370
  end
276
371
 
372
+ def run_big
373
+ require 'memory_profiler'
374
+ require './test/unique_files'
375
+
376
+ 4000.times { |index| require_unique_file('dog.rb.erb', dog_number: index) }
377
+ # warmup
378
+ 3.times { Coverband.report_coverage }
379
+ dogs = 400.times.map { |index| Object.const_get("Dog#{index}") }
380
+ MemoryProfiler.report do
381
+ 10.times do
382
+ dogs.each(&:bark)
383
+ Coverband.report_coverage
384
+ end
385
+ end.pretty_print
386
+ end
387
+
388
+ task run_big: %i[setup setup_redis] do
389
+ # ensure we cleared from last run
390
+ benchmark_redis_store.clear!
391
+
392
+ run_big
393
+ end
394
+
277
395
  # desc 'runs benchmarks file store'
278
- task run_file: [:setup, :setup_file] do
396
+ task run_file: %i[setup setup_file] do
279
397
  puts 'Coverband configured with file store'
280
398
  run_work(true)
281
399
  end