coverband 4.2.7.rc.1 → 5.0.0.rc.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.standard.yml +26 -0
- data/.travis.yml +2 -1
- data/Gemfile +5 -7
- data/Gemfile.rails4 +0 -3
- data/Gemfile.rails6 +0 -3
- data/README.md +8 -77
- data/Rakefile +17 -17
- data/changes.md +30 -28
- data/config.ru +1 -1
- data/coverband.gemspec +31 -34
- data/lib/coverband.rb +68 -44
- data/lib/coverband/adapters/base.rb +17 -18
- data/lib/coverband/adapters/file_store.rb +38 -6
- data/lib/coverband/adapters/hash_redis_store.rb +24 -21
- data/lib/coverband/adapters/redis_store.rb +12 -12
- data/lib/coverband/adapters/stdout_store.rb +41 -0
- data/lib/coverband/adapters/web_service_store.rb +155 -0
- data/lib/coverband/at_exit.rb +1 -1
- data/lib/coverband/collectors/coverage.rb +15 -27
- data/lib/coverband/collectors/delta.rb +29 -9
- data/lib/coverband/collectors/view_tracker.rb +10 -10
- data/lib/coverband/collectors/view_tracker_service.rb +59 -0
- data/lib/coverband/configuration.rb +149 -112
- data/lib/coverband/integrations/background.rb +6 -6
- data/lib/coverband/integrations/rack_server_check.rb +3 -3
- data/lib/coverband/integrations/resque.rb +2 -2
- data/lib/coverband/reporters/base.rb +11 -12
- data/lib/coverband/reporters/console_report.rb +1 -1
- data/lib/coverband/reporters/html_report.rb +10 -30
- data/lib/coverband/reporters/web.rb +55 -50
- data/lib/coverband/utils/absolute_file_converter.rb +6 -6
- data/lib/coverband/utils/html_formatter.rb +32 -61
- data/lib/coverband/utils/railtie.rb +23 -6
- data/lib/coverband/utils/relative_file_converter.rb +2 -2
- data/lib/coverband/utils/result.rb +6 -11
- data/lib/coverband/utils/results.rb +0 -10
- data/lib/coverband/utils/source_file.rb +21 -30
- data/lib/coverband/utils/tasks.rb +8 -11
- data/lib/coverband/version.rb +1 -1
- data/public/application.js +0 -30
- data/test/benchmarks/benchmark.rake +97 -92
- data/test/benchmarks/dog.rb +1 -1
- data/test/benchmarks/init_rails.rake +4 -4
- data/test/coverband/adapters/base_test.rb +29 -30
- data/test/coverband/adapters/file_store_test.rb +19 -20
- data/test/coverband/adapters/hash_redis_store_test.rb +57 -57
- data/test/coverband/adapters/redis_store_test.rb +26 -26
- data/test/coverband/adapters/web_service_store_test.rb +56 -0
- data/test/coverband/at_exit_test.rb +2 -2
- data/test/coverband/collectors/coverage_test.rb +33 -47
- data/test/coverband/collectors/delta_test.rb +52 -23
- data/test/coverband/collectors/view_tracker_test.rb +35 -35
- data/test/coverband/configuration_test.rb +49 -36
- data/test/coverband/coverband_test.rb +11 -11
- data/test/coverband/integrations/background_middleware_test.rb +10 -10
- data/test/coverband/integrations/background_test.rb +17 -5
- data/test/coverband/integrations/rack_server_check_test.rb +7 -7
- data/test/coverband/integrations/report_middleware_test.rb +9 -9
- data/test/coverband/integrations/resque_worker_test.rb +9 -9
- data/test/coverband/integrations/test_resque_job.rb +1 -1
- data/test/coverband/reporters/base_test.rb +9 -9
- data/test/coverband/reporters/console_test.rb +6 -6
- data/test/coverband/reporters/html_test.rb +36 -48
- data/test/coverband/reporters/web_test.rb +16 -18
- data/test/coverband/utils/absolute_file_converter_test.rb +22 -22
- data/test/coverband/utils/file_hasher_test.rb +6 -12
- data/test/coverband/utils/file_list_test.rb +13 -13
- data/test/coverband/utils/html_formatter_test.rb +9 -23
- data/test/coverband/utils/lines_classifier_test.rb +29 -29
- data/test/coverband/utils/relative_file_converter_test.rb +13 -13
- data/test/coverband/utils/result_test.rb +18 -18
- data/test/coverband/utils/results_test.rb +17 -17
- data/test/coverband/utils/source_file_line_test.rb +46 -46
- data/test/coverband/utils/source_file_test.rb +38 -88
- data/test/dog.rb +1 -1
- data/test/fake_app/basic_rack.rb +2 -2
- data/test/fixtures/app/controllers/sample_controller.rb +1 -1
- data/test/fixtures/app/models/user.rb +1 -1
- data/test/fixtures/sample.rb +1 -1
- data/test/fixtures/utf-8.rb +0 -2
- data/test/forked/rails_full_stack_test.rb +24 -27
- data/test/forked/rails_rake_full_stack_test.rb +7 -26
- data/test/integration/full_stack_test.rb +11 -22
- data/test/jruby_check.rb +2 -3
- data/test/rails4_dummy/Rakefile +1 -1
- data/test/rails4_dummy/config.ru +1 -1
- data/test/rails4_dummy/config/application.rb +4 -4
- data/test/rails4_dummy/config/boot.rb +2 -2
- data/test/rails4_dummy/config/coverband.rb +1 -1
- data/test/rails4_dummy/config/coverband_missing_redis.rb +1 -1
- data/test/rails4_dummy/config/environment.rb +1 -1
- data/test/rails4_dummy/config/routes.rb +2 -2
- data/test/rails5_dummy/Rakefile +1 -1
- data/test/rails5_dummy/config.ru +1 -1
- data/test/rails5_dummy/config/application.rb +3 -3
- data/test/rails5_dummy/config/coverband.rb +8 -8
- data/test/rails5_dummy/config/coverband_missing_redis.rb +8 -8
- data/test/rails5_dummy/config/environment.rb +1 -1
- data/test/rails5_dummy/config/routes.rb +2 -2
- data/test/rails6_dummy/Rakefile +1 -1
- data/test/rails6_dummy/config.ru +1 -1
- data/test/rails6_dummy/config/application.rb +4 -4
- data/test/rails6_dummy/config/boot.rb +2 -2
- data/test/rails6_dummy/config/coverband.rb +1 -1
- data/test/rails6_dummy/config/coverband_missing_redis.rb +1 -1
- data/test/rails6_dummy/config/environment.rb +1 -1
- data/test/rails6_dummy/config/routes.rb +2 -2
- data/test/rails_test_helper.rb +11 -11
- data/test/test_helper.rb +44 -34
- data/test/unique_files.rb +10 -10
- data/views/layout.erb +2 -12
- metadata +27 -33
- data/.rubocop.yml +0 -84
- data/lib/coverband/integrations/bundler.rb +0 -8
- data/lib/coverband/utils/file_groups.rb +0 -53
- data/lib/coverband/utils/gem_list.rb +0 -31
- data/lib/coverband/utils/s3_report.rb +0 -105
- data/test/coverband/utils/file_groups_test.rb +0 -61
- data/test/coverband/utils/gem_list_test.rb +0 -48
- data/test/coverband/utils/s3_report_test.rb +0 -44
- data/views/gem_list.erb +0 -63
@@ -10,34 +10,51 @@ module Coverband
|
|
10
10
|
Rails::Engine.prepend(RailsEagerLoad)
|
11
11
|
|
12
12
|
class Railtie < Rails::Railtie
|
13
|
-
initializer
|
13
|
+
initializer "coverband.configure" do |app|
|
14
14
|
begin
|
15
15
|
app.middleware.use Coverband::BackgroundMiddleware
|
16
16
|
|
17
17
|
if Coverband.configuration.track_views
|
18
|
-
|
19
|
-
|
18
|
+
COVERBAND_VIEW_TRACKER = if Coverband.coverband_service?
|
19
|
+
Coverband::Collectors::ViewTrackerService.new
|
20
|
+
else
|
21
|
+
Coverband::Collectors::ViewTracker.new
|
22
|
+
end
|
23
|
+
|
24
|
+
Coverband.configuration.view_tracker = COVERBAND_VIEW_TRACKER
|
20
25
|
|
21
26
|
ActiveSupport::Notifications.subscribe(/render_partial.action_view|render_template.action_view/) do |name, start, finish, id, payload|
|
22
|
-
|
27
|
+
COVERBAND_VIEW_TRACKER.track_views(name, start, finish, id, payload) unless name.include?("!")
|
23
28
|
end
|
24
29
|
end
|
25
30
|
rescue Redis::CannotConnectError => error
|
26
31
|
Coverband.configuration.logger.info "Redis is not available (#{error}), Coverband not configured"
|
27
|
-
Coverband.configuration.logger.info
|
32
|
+
Coverband.configuration.logger.info "If this is a setup task like assets:precompile feel free to ignore"
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
31
36
|
config.after_initialize do
|
32
37
|
unless Coverband.tasks_to_ignore?
|
38
|
+
Coverband.configure
|
33
39
|
Coverband.eager_loading_coverage!
|
34
40
|
Coverband.report_coverage
|
35
41
|
Coverband.runtime_coverage!
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
45
|
+
config.before_configuration do
|
46
|
+
unless ENV["COVERBAND_DISABLE_AUTO_START"]
|
47
|
+
begin
|
48
|
+
Coverband.start
|
49
|
+
rescue Redis::CannotConnectError => error
|
50
|
+
Coverband.configuration.logger.info "Redis is not available (#{error}), Coverband not configured"
|
51
|
+
Coverband.configuration.logger.info "If this is a setup task like assets:precompile feel free to ignore"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
39
56
|
rake_tasks do
|
40
|
-
load
|
57
|
+
load "coverband/utils/tasks.rb"
|
41
58
|
end
|
42
59
|
end
|
43
60
|
end
|
@@ -24,8 +24,8 @@ module Coverband
|
|
24
24
|
@cache[file] ||= begin
|
25
25
|
relative_file = file
|
26
26
|
@roots.each do |root|
|
27
|
-
relative_file = file.gsub(/^#{root}/,
|
28
|
-
break relative_file if relative_file.start_with?(
|
27
|
+
relative_file = file.gsub(/^#{root}/, ".")
|
28
|
+
break relative_file if relative_file.start_with?(".")
|
29
29
|
end
|
30
30
|
relative_file
|
31
31
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "digest/sha1"
|
4
|
+
require "forwardable"
|
5
5
|
|
6
6
|
####
|
7
7
|
# Thanks for all the help SimpleCov https://github.com/colszowka/simplecov
|
@@ -31,9 +31,9 @@ module Coverband
|
|
31
31
|
def initialize(original_result)
|
32
32
|
@original_result = (original_result || {}).freeze
|
33
33
|
|
34
|
-
@files = Coverband::Utils::FileList.new(@original_result.map
|
34
|
+
@files = Coverband::Utils::FileList.new(@original_result.map { |filename, coverage|
|
35
35
|
Coverband::Utils::SourceFile.new(filename, coverage) if File.file?(filename)
|
36
|
-
|
36
|
+
}.compact.sort_by(&:short_name))
|
37
37
|
end
|
38
38
|
|
39
39
|
# Returns all filenames for source files contained in this result
|
@@ -41,11 +41,6 @@ module Coverband
|
|
41
41
|
files.map(&:filename)
|
42
42
|
end
|
43
43
|
|
44
|
-
# Returns a Hash of groups for this result. Define groups using Coverband.add_group 'Models', 'app/models'
|
45
|
-
def groups
|
46
|
-
@groups ||= FileGroups.new(files).grouped_results
|
47
|
-
end
|
48
|
-
|
49
44
|
# Defines when this result has been created. Defaults to Time.now
|
50
45
|
def created_at
|
51
46
|
@created_at ||= Time.now
|
@@ -60,8 +55,8 @@ module Coverband
|
|
60
55
|
Dir[tracked_files].each do |file|
|
61
56
|
absolute = File.expand_path(file)
|
62
57
|
result[absolute] ||= {
|
63
|
-
|
64
|
-
|
58
|
+
"data" => Array.new(File.foreach(absolute).count) { 0 },
|
59
|
+
"never_loaded" => true
|
65
60
|
}
|
66
61
|
end
|
67
62
|
end
|
@@ -45,16 +45,6 @@ module Coverband
|
|
45
45
|
eager_file.relevant_lines - eager_file.covered_lines_count
|
46
46
|
end
|
47
47
|
|
48
|
-
###
|
49
|
-
# TODO: Groups still have some issues, this should be generic for groups, but right now gem_name
|
50
|
-
# is specifically called out, need to revisit all gorups code.
|
51
|
-
###
|
52
|
-
def group_file_list_with_type(group, file_list, results_type)
|
53
|
-
return unless get_results(results_type)
|
54
|
-
|
55
|
-
get_results(results_type).groups[group].find { |gem_files| gem_files.first.gem_name == file_list.first.gem_name }
|
56
|
-
end
|
57
|
-
|
58
48
|
def file_from_path_with_type(full_path, results_type = :merged)
|
59
49
|
return unless get_results(results_type)
|
60
50
|
|
@@ -32,14 +32,14 @@ module Coverband
|
|
32
32
|
alias number line_number
|
33
33
|
|
34
34
|
def initialize(src, line_number, coverage)
|
35
|
-
raise ArgumentError,
|
36
|
-
raise ArgumentError,
|
37
|
-
raise ArgumentError,
|
35
|
+
raise ArgumentError, "Only String accepted for source" unless src.is_a?(String)
|
36
|
+
raise ArgumentError, "Only Integer accepted for line_number" unless line_number.is_a?(Integer)
|
37
|
+
raise ArgumentError, "Only Integer and nil accepted for coverage" unless coverage.is_a?(Integer) || coverage.nil?
|
38
38
|
|
39
|
-
@src
|
39
|
+
@src = src
|
40
40
|
@line_number = line_number
|
41
|
-
@coverage
|
42
|
-
@skipped
|
41
|
+
@coverage = coverage
|
42
|
+
@skipped = false
|
43
43
|
end
|
44
44
|
|
45
45
|
# Returns true if this is a line that should have been covered, but was not
|
@@ -71,10 +71,10 @@ module Coverband
|
|
71
71
|
# The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use
|
72
72
|
# as a css class in report generation
|
73
73
|
def status
|
74
|
-
return
|
75
|
-
return
|
76
|
-
return
|
77
|
-
return
|
74
|
+
return "skipped" if skipped?
|
75
|
+
return "never" if never?
|
76
|
+
return "missed" if missed?
|
77
|
+
return "covered" if covered?
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -89,17 +89,17 @@ module Coverband
|
|
89
89
|
attr_reader :last_updated_at
|
90
90
|
# meta data that the file was never loaded during boot or runtime
|
91
91
|
attr_reader :never_loaded
|
92
|
-
NOT_AVAILABLE =
|
92
|
+
NOT_AVAILABLE = "not available"
|
93
93
|
|
94
94
|
def initialize(filename, file_data)
|
95
95
|
@filename = filename
|
96
96
|
@runtime_relavant_lines = nil
|
97
97
|
if file_data.is_a?(Hash)
|
98
|
-
@coverage = file_data[
|
98
|
+
@coverage = file_data["data"]
|
99
99
|
@first_updated_at = @last_updated_at = NOT_AVAILABLE
|
100
|
-
@first_updated_at = Time.at(file_data[
|
101
|
-
@last_updated_at =
|
102
|
-
@never_loaded = file_data[
|
100
|
+
@first_updated_at = Time.at(file_data["first_updated_at"]) if file_data["first_updated_at"]
|
101
|
+
@last_updated_at = Time.at(file_data["last_updated_at"]) if file_data["last_updated_at"]
|
102
|
+
@never_loaded = file_data["never_loaded"] || false
|
103
103
|
else
|
104
104
|
# TODO: Deprecate this code path this was backwards compatability from 3-4
|
105
105
|
@coverage = file_data
|
@@ -117,14 +117,14 @@ module Coverband
|
|
117
117
|
|
118
118
|
# The path to this source file relative to the projects directory
|
119
119
|
def project_filename
|
120
|
-
@filename.sub(/^#{Coverband.configuration.root}/,
|
120
|
+
@filename.sub(/^#{Coverband.configuration.root}/, "")
|
121
121
|
end
|
122
122
|
|
123
123
|
# The source code for this file. Aliased as :source
|
124
124
|
def src
|
125
125
|
# We intentionally read source code lazily to
|
126
126
|
# suppress reading unused source code.
|
127
|
-
@src ||= File.open(filename,
|
127
|
+
@src ||= File.open(filename, "rb", &:readlines)
|
128
128
|
end
|
129
129
|
alias source src
|
130
130
|
|
@@ -138,9 +138,9 @@ module Coverband
|
|
138
138
|
def build_lines
|
139
139
|
coverage_exceeding_source_warn if coverage.size > src.size
|
140
140
|
|
141
|
-
lines = src.map.with_index(1)
|
141
|
+
lines = src.map.with_index(1) { |src, i|
|
142
142
|
Coverband::Utils::SourceFile::Line.new(src, i, coverage[i - 1])
|
143
|
-
|
143
|
+
}
|
144
144
|
|
145
145
|
process_skipped_lines(lines)
|
146
146
|
end
|
@@ -241,23 +241,14 @@ module Coverband
|
|
241
241
|
# was at the start of the file name
|
242
242
|
# I had previously patched this in my local Rails app
|
243
243
|
def short_name
|
244
|
-
filename.sub(/^#{Coverband.configuration.root}/,
|
245
|
-
|
246
|
-
.gsub(%r{^\.\/}, '')
|
244
|
+
filename.sub(/^#{Coverband.configuration.root}/, ".")
|
245
|
+
.gsub(%r{^\.\/}, "")
|
247
246
|
end
|
248
247
|
|
249
248
|
def relative_path
|
250
249
|
RelativeFileConverter.convert(filename)
|
251
250
|
end
|
252
251
|
|
253
|
-
def gem?
|
254
|
-
filename =~ %r{^.*\/gems\/}
|
255
|
-
end
|
256
|
-
|
257
|
-
def gem_name
|
258
|
-
gem? ? short_name.split('/').first.gsub(%r{^\.}, '') : nil
|
259
|
-
end
|
260
|
-
|
261
252
|
private
|
262
253
|
|
263
254
|
# ruby 1.9 could use Float#round(places) instead
|
@@ -4,25 +4,22 @@ namespace :coverband do
|
|
4
4
|
# handles configuring in require => false and COVERBAND_DISABLE_AUTO_START cases
|
5
5
|
Coverband.configure unless Coverband.configured?
|
6
6
|
|
7
|
-
desc
|
7
|
+
desc "report runtime Coverband code coverage"
|
8
8
|
task :coverage do
|
9
|
-
|
10
|
-
Coverband::Reporters::HTMLReport.new(Coverband.configuration.store).report
|
11
|
-
else
|
12
|
-
Coverband::Reporters::ConsoleReport.report(Coverband.configuration.store)
|
13
|
-
end
|
9
|
+
Coverband::Reporters::ConsoleReport.report(Coverband.configuration.store)
|
14
10
|
end
|
15
11
|
|
16
|
-
desc
|
12
|
+
desc "report runtime Coverband code coverage"
|
17
13
|
task :coverage_server do
|
18
|
-
Rake.application[
|
19
|
-
|
14
|
+
Rake.application["environment"].invoke if Rake::Task.task_defined?("environment")
|
15
|
+
Coverband.configuration.store.merge_mode = true if Coverband.configuration.store.is_a?(Coverband::Adapters::FileStore)
|
16
|
+
Rack::Server.start app: Coverband::Reporters::Web.new, Port: ENV.fetch("COVERBAND_COVERAGE_PORT", 1022).to_i
|
20
17
|
end
|
21
18
|
|
22
19
|
###
|
23
20
|
# clear data helpful for development or after configuration issues
|
24
21
|
###
|
25
|
-
desc
|
22
|
+
desc "reset Coverband coverage data, helpful for development, debugging, etc"
|
26
23
|
task :clear do
|
27
24
|
Coverband.configuration.store.clear!
|
28
25
|
end
|
@@ -30,7 +27,7 @@ namespace :coverband do
|
|
30
27
|
###
|
31
28
|
# Updates the data in the coverband store from one format to another
|
32
29
|
###
|
33
|
-
desc
|
30
|
+
desc "upgrade previous Coverband datastore to latest format"
|
34
31
|
task :migrate do
|
35
32
|
Coverband.configuration.store.migrate!
|
36
33
|
end
|
data/lib/coverband/version.rb
CHANGED
data/public/application.js
CHANGED
@@ -33,23 +33,6 @@ $(document).ready(function() {
|
|
33
33
|
]
|
34
34
|
});
|
35
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" },
|
45
|
-
null,
|
46
|
-
null,
|
47
|
-
null,
|
48
|
-
null,
|
49
|
-
null
|
50
|
-
]
|
51
|
-
});
|
52
|
-
|
53
36
|
// Syntax highlight all files up front - deactivated
|
54
37
|
// $('.source_table pre code').each(function(i, e) {hljs.highlightBlock(e, ' ')});
|
55
38
|
|
@@ -184,17 +167,6 @@ $(document).ready(function() {
|
|
184
167
|
return false;
|
185
168
|
});
|
186
169
|
|
187
|
-
$("a.gem-link").live("click", function() {
|
188
|
-
$(".file_list_container").hide();
|
189
|
-
$(".file_list_container" + $(this).attr("href")).show();
|
190
|
-
window.location.href =
|
191
|
-
window.location.href.split("#")[0] +
|
192
|
-
$(this)
|
193
|
-
.attr("href")
|
194
|
-
.replace("#", "#_");
|
195
|
-
return false;
|
196
|
-
});
|
197
|
-
|
198
170
|
if (jQuery.url.attr("anchor")) {
|
199
171
|
var anchor = jQuery.url.attr("anchor");
|
200
172
|
// source file hash
|
@@ -203,8 +175,6 @@ $(document).ready(function() {
|
|
203
175
|
} else {
|
204
176
|
if ($(".group_tabs a." + anchor.replace("_", "")).length > 0) {
|
205
177
|
$(".group_tabs a." + anchor.replace("_", "")).click();
|
206
|
-
} else {
|
207
|
-
$("a.gem-link[href=#" + anchor.replace("_", "") + "]").click();
|
208
178
|
}
|
209
179
|
}
|
210
180
|
} else {
|
@@ -14,9 +14,11 @@ namespace :benchmarks do
|
|
14
14
|
run_gc
|
15
15
|
end
|
16
16
|
|
17
|
-
def warmup_stats(*)
|
17
|
+
def warmup_stats(*)
|
18
|
+
end
|
18
19
|
|
19
|
-
def add_report(*)
|
20
|
+
def add_report(*)
|
21
|
+
end
|
20
22
|
|
21
23
|
private
|
22
24
|
|
@@ -29,46 +31,47 @@ namespace :benchmarks do
|
|
29
31
|
|
30
32
|
# desc 'setup standard benchmark'
|
31
33
|
task :setup do
|
32
|
-
require
|
33
|
-
require
|
34
|
+
require "benchmark"
|
35
|
+
require "benchmark/ips"
|
36
|
+
require "redis"
|
34
37
|
|
35
|
-
if ENV[
|
36
|
-
require
|
37
|
-
::Coverage.start(oneshot_lines: !!ENV[
|
38
|
+
if ENV["COVERAGE"] || ENV["ONESHOT"]
|
39
|
+
require "coverage"
|
40
|
+
::Coverage.start(oneshot_lines: !!ENV["ONESHOT"])
|
38
41
|
end
|
39
|
-
require
|
40
|
-
|
41
|
-
require File.join(File.dirname(__FILE__),
|
42
|
+
require "coverband"
|
43
|
+
|
44
|
+
require File.join(File.dirname(__FILE__), "dog")
|
42
45
|
end
|
43
46
|
|
44
47
|
def benchmark_redis_store
|
45
|
-
redis = if ENV[
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
redis = if ENV["REDIS_TEST_URL"]
|
49
|
+
Redis.new(url: ENV["REDIS_TEST_URL"])
|
50
|
+
else
|
51
|
+
Redis.new
|
52
|
+
end
|
50
53
|
Coverband::Adapters::RedisStore.new(redis,
|
51
|
-
|
54
|
+
redis_namespace: "coverband_bench")
|
52
55
|
end
|
53
56
|
|
54
57
|
# desc 'set up coverband with Redis'
|
55
58
|
task :setup_redis do
|
56
59
|
Coverband.configure do |config|
|
57
|
-
config.root
|
58
|
-
config.logger
|
59
|
-
config.store
|
60
|
-
config.use_oneshot_lines_coverage = true if ENV[
|
61
|
-
config.simulate_oneshot_lines_coverage = true if ENV[
|
60
|
+
config.root = Dir.pwd
|
61
|
+
config.logger = $stdout
|
62
|
+
config.store = benchmark_redis_store
|
63
|
+
config.use_oneshot_lines_coverage = true if ENV["ONESHOT"]
|
64
|
+
config.simulate_oneshot_lines_coverage = true if ENV["SIMULATE_ONESHOT"]
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
65
68
|
# desc 'set up coverband with filestore'
|
66
69
|
task :setup_file do
|
67
70
|
Coverband.configure do |config|
|
68
|
-
config.root
|
69
|
-
config.logger
|
70
|
-
file_path
|
71
|
-
config.store
|
71
|
+
config.root = Dir.pwd
|
72
|
+
config.logger = $stdout
|
73
|
+
file_path = "/tmp/benchmark_store.json"
|
74
|
+
config.store = Coverband::Adapters::FileStore.new(file_path)
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
@@ -83,14 +86,14 @@ namespace :benchmarks do
|
|
83
86
|
suite = GCSuite.new
|
84
87
|
Benchmark.ips do |x|
|
85
88
|
x.config(time: 12, warmup: 5, suite: suite)
|
86
|
-
x.report
|
89
|
+
x.report "coverband" do
|
87
90
|
work
|
88
91
|
Coverband.report_coverage
|
89
92
|
end
|
90
|
-
x.report
|
93
|
+
x.report "no coverband" do
|
91
94
|
work
|
92
95
|
end
|
93
|
-
x.hold!
|
96
|
+
x.hold! "temp_results" if hold_work
|
94
97
|
x.compare!
|
95
98
|
end
|
96
99
|
Coverband::Collectors::Coverage.instance.reset_instance
|
@@ -100,7 +103,7 @@ namespace :benchmarks do
|
|
100
103
|
NON_NIL_LINES = 18
|
101
104
|
def fake_line_numbers
|
102
105
|
LINES.times.map do |line|
|
103
|
-
coverage =
|
106
|
+
coverage = line < NON_NIL_LINES ? rand(5) : nil
|
104
107
|
end
|
105
108
|
end
|
106
109
|
|
@@ -141,18 +144,18 @@ namespace :benchmarks do
|
|
141
144
|
5.times { store.save_report(report) }
|
142
145
|
Benchmark.ips do |x|
|
143
146
|
x.config(time: 15, warmup: 5)
|
144
|
-
x.report(
|
147
|
+
x.report("store_reports_all") { store.save_report(report) }
|
145
148
|
end
|
146
149
|
keys_subset = report.keys.first(100)
|
147
150
|
report_subset = report.select { |key, _value| keys_subset.include?(key) }
|
148
151
|
Benchmark.ips do |x|
|
149
152
|
x.config(time: 20, warmup: 5)
|
150
|
-
x.report(
|
153
|
+
x.report("store_reports_subset") { store.save_report(report_subset) }
|
151
154
|
end
|
152
155
|
end
|
153
156
|
|
154
157
|
def measure_memory
|
155
|
-
require
|
158
|
+
require "memory_profiler"
|
156
159
|
report = fake_report
|
157
160
|
store = benchmark_redis_store
|
158
161
|
store.clear!
|
@@ -165,21 +168,21 @@ namespace :benchmarks do
|
|
165
168
|
capture = StringIO.new
|
166
169
|
$stdout = capture
|
167
170
|
|
168
|
-
MemoryProfiler.report
|
171
|
+
MemoryProfiler.report {
|
169
172
|
10.times { store.save_report(report) }
|
170
|
-
|
173
|
+
}.pretty_print
|
171
174
|
data = $stdout.string
|
172
175
|
$stdout = previous_out
|
173
|
-
unless data.match(
|
176
|
+
unless data.match?("Total retained: 0 bytes")
|
174
177
|
puts data
|
175
|
-
raise
|
178
|
+
raise "leaking memory!!!"
|
176
179
|
end
|
177
180
|
ensure
|
178
181
|
$stdout = previous_out
|
179
182
|
end
|
180
183
|
|
181
184
|
def measure_memory_report_coverage
|
182
|
-
require
|
185
|
+
require "memory_profiler"
|
183
186
|
report = fake_report
|
184
187
|
store = benchmark_redis_store
|
185
188
|
store.clear!
|
@@ -192,7 +195,7 @@ namespace :benchmarks do
|
|
192
195
|
capture = StringIO.new
|
193
196
|
$stdout = capture
|
194
197
|
|
195
|
-
MemoryProfiler.report
|
198
|
+
MemoryProfiler.report {
|
196
199
|
10.times do
|
197
200
|
Coverband.report_coverage
|
198
201
|
###
|
@@ -202,12 +205,12 @@ namespace :benchmarks do
|
|
202
205
|
###
|
203
206
|
Coverband::Collectors::Delta.class_variable_set(:@@previous_coverage, nil)
|
204
207
|
end
|
205
|
-
|
208
|
+
}.pretty_print
|
206
209
|
data = $stdout.string
|
207
210
|
$stdout = previous_out
|
208
|
-
unless data.match(
|
211
|
+
unless data.match?("Total retained: 0 bytes")
|
209
212
|
puts data
|
210
|
-
raise
|
213
|
+
raise "leaking memory!!!"
|
211
214
|
end
|
212
215
|
ensure
|
213
216
|
$stdout = previous_out
|
@@ -219,7 +222,7 @@ namespace :benchmarks do
|
|
219
222
|
# not including in test suite but we can try to figure it out and fix.
|
220
223
|
###
|
221
224
|
def measure_configure_memory
|
222
|
-
require
|
225
|
+
require "memory_profiler"
|
223
226
|
# warmup
|
224
227
|
3.times { Coverband.configure }
|
225
228
|
|
@@ -227,31 +230,31 @@ namespace :benchmarks do
|
|
227
230
|
capture = StringIO.new
|
228
231
|
$stdout = capture
|
229
232
|
|
230
|
-
MemoryProfiler.report
|
233
|
+
MemoryProfiler.report {
|
231
234
|
10.times do
|
232
235
|
Coverband.configure do |config|
|
233
|
-
redis_url = ENV[
|
234
|
-
config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace:
|
236
|
+
redis_url = ENV["CACHE_REDIS_URL"] || ENV["REDIS_URL"]
|
237
|
+
config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace: "coverband_bench_data")
|
235
238
|
end
|
236
239
|
end
|
237
|
-
|
240
|
+
}.pretty_print
|
238
241
|
data = $stdout.string
|
239
242
|
$stdout = previous_out
|
240
|
-
unless data.match(
|
243
|
+
unless data.match?("Total retained: 0 bytes")
|
241
244
|
puts data
|
242
|
-
raise
|
245
|
+
raise "leaking memory!!!"
|
243
246
|
end
|
244
247
|
ensure
|
245
248
|
$stdout = previous_out
|
246
249
|
end
|
247
250
|
|
248
|
-
desc
|
251
|
+
desc "checks memory of collector"
|
249
252
|
task memory_check: [:setup] do
|
250
253
|
# require 'pry-byebug'
|
251
|
-
require
|
252
|
-
puts
|
254
|
+
require "objspace"
|
255
|
+
puts "memory load check"
|
253
256
|
puts(ObjectSpace.memsize_of_all / 2**20)
|
254
|
-
data = File.read(
|
257
|
+
data = File.read("./tmp/debug_data.json")
|
255
258
|
# about 2mb
|
256
259
|
puts(ObjectSpace.memsize_of(data) / 2**20)
|
257
260
|
|
@@ -288,65 +291,67 @@ namespace :benchmarks do
|
|
288
291
|
json_data = nil
|
289
292
|
GC.start
|
290
293
|
puts(ObjectSpace.memsize_of_all / 2**20)
|
291
|
-
|
292
|
-
|
294
|
+
|
295
|
+
# dig in some more...
|
296
|
+
# debugger
|
297
|
+
puts "done"
|
293
298
|
end
|
294
299
|
|
295
|
-
desc
|
300
|
+
desc "runs memory reporting on Redis store"
|
296
301
|
task memory_reporting: [:setup] do
|
297
|
-
puts
|
302
|
+
puts "runs memory benchmarking to ensure we dont leak"
|
298
303
|
measure_memory
|
299
304
|
end
|
300
305
|
|
301
|
-
desc
|
306
|
+
desc "runs memory reporting on report_coverage"
|
302
307
|
task memory_reporting_report_coverage: [:setup] do
|
303
|
-
puts
|
308
|
+
puts "runs memory benchmarking on report_coverage to ensure we dont leak"
|
304
309
|
measure_memory_report_coverage
|
305
310
|
end
|
306
311
|
|
307
|
-
desc
|
312
|
+
desc "runs memory reporting on configure"
|
308
313
|
task memory_configure_reporting: [:setup] do
|
309
|
-
puts
|
314
|
+
puts "runs memory benchmarking on configure to ensure we dont leak"
|
310
315
|
measure_configure_memory
|
311
316
|
end
|
312
317
|
|
313
|
-
desc
|
318
|
+
desc "runs memory leak check via Rails tests"
|
314
319
|
task memory_rails: [:setup] do
|
315
|
-
puts
|
320
|
+
puts "runs memory rails test to ensure we dont leak"
|
316
321
|
puts `COVERBAND_MEMORY_TEST=true bundle exec test/forked/rails_full_stack_test.rb`
|
317
322
|
end
|
318
323
|
|
319
|
-
desc
|
324
|
+
desc "runs memory leak checks"
|
320
325
|
task memory: %i[memory_reporting memory_reporting_report_coverage memory_rails] do
|
321
|
-
puts
|
326
|
+
puts "done"
|
322
327
|
end
|
323
328
|
|
324
|
-
desc
|
329
|
+
desc "runs benchmarks on reporting large sets of files to redis"
|
325
330
|
task redis_reporting: [:setup] do
|
326
|
-
puts
|
331
|
+
puts "runs benchmarks on reporting large sets of files to redis"
|
327
332
|
reporting_speed
|
328
333
|
end
|
329
334
|
|
330
335
|
# desc 'runs benchmarks on default redis setup'
|
331
336
|
task run_redis: %i[setup setup_redis] do
|
332
|
-
puts
|
337
|
+
puts "Coverband configured with default Redis store"
|
333
338
|
run_work(true)
|
334
339
|
end
|
335
340
|
|
336
341
|
def run_big
|
337
|
-
require
|
338
|
-
require
|
342
|
+
require "memory_profiler"
|
343
|
+
require "./test/unique_files"
|
339
344
|
|
340
|
-
4000.times { |index| require_unique_file(
|
345
|
+
4000.times { |index| require_unique_file("big_dog.rb.erb", dog_number: index) }
|
341
346
|
# warmup
|
342
347
|
3.times { Coverband.report_coverage }
|
343
348
|
dogs = 400.times.map { |index| Object.const_get("Dog#{index}") }
|
344
|
-
MemoryProfiler.report
|
349
|
+
MemoryProfiler.report {
|
345
350
|
10.times do
|
346
351
|
dogs.each(&:bark)
|
347
352
|
Coverband.report_coverage
|
348
353
|
end
|
349
|
-
|
354
|
+
}.pretty_print
|
350
355
|
end
|
351
356
|
|
352
357
|
task run_big: %i[setup setup_redis] do
|
@@ -358,18 +363,18 @@ namespace :benchmarks do
|
|
358
363
|
|
359
364
|
# desc 'runs benchmarks file store'
|
360
365
|
task run_file: %i[setup setup_file] do
|
361
|
-
puts
|
366
|
+
puts "Coverband configured with file store"
|
362
367
|
run_work(true)
|
363
368
|
end
|
364
369
|
|
365
|
-
desc
|
370
|
+
desc "benchmarks external requests to coverband_demo site"
|
366
371
|
task :coverband_demo do
|
367
372
|
# for local testing
|
368
373
|
# puts `ab -n 500 -c 5 "http://127.0.0.1:3000/posts"`
|
369
374
|
puts `ab -n 2000 -c 10 "https://coverband-demo.herokuapp.com/posts"`
|
370
375
|
end
|
371
376
|
|
372
|
-
desc
|
377
|
+
desc "benchmarks external requests to coverband_demo site"
|
373
378
|
task :coverband_demo_graph do
|
374
379
|
# for local testing
|
375
380
|
# puts `ab -n 200 -c 5 "http://127.0.0.1:3000/posts"`
|
@@ -379,38 +384,38 @@ namespace :benchmarks do
|
|
379
384
|
`open tmp/timeseries.jpg`
|
380
385
|
end
|
381
386
|
|
382
|
-
desc
|
387
|
+
desc "benchmark initialization of rails"
|
383
388
|
task :init_rails do
|
384
|
-
require
|
385
|
-
require
|
389
|
+
require "benchmark"
|
390
|
+
require "benchmark/ips"
|
386
391
|
Benchmark.ips do |x|
|
387
392
|
x.config(time: 60, warmup: 0)
|
388
|
-
x.report(
|
389
|
-
system(
|
393
|
+
x.report("init_rails") do
|
394
|
+
system("bundle exec rake init_rails -f ./test/benchmarks/init_rails.rake")
|
390
395
|
end
|
391
396
|
end
|
392
397
|
end
|
393
398
|
|
394
|
-
desc
|
399
|
+
desc "compare Coverband Ruby Coverage with Filestore with normal Ruby"
|
395
400
|
task :compare_file do
|
396
|
-
puts
|
397
|
-
puts
|
401
|
+
puts "comparing Coverage loaded/not, this takes some time for output..."
|
402
|
+
puts "coverage loaded"
|
398
403
|
puts `COVERAGE=true rake benchmarks:run_file`
|
399
|
-
puts
|
404
|
+
puts "without coverage"
|
400
405
|
puts `rake benchmarks:run_file`
|
401
406
|
end
|
402
407
|
|
403
|
-
desc
|
408
|
+
desc "compare Coverband Ruby Coverage with Redis and normal Ruby"
|
404
409
|
task :compare_redis do
|
405
|
-
puts
|
406
|
-
puts
|
410
|
+
puts "comparing Coverage loaded/not, this takes some time for output..."
|
411
|
+
puts "coverage loaded"
|
407
412
|
puts `COVERAGE=true rake benchmarks:run_redis`
|
408
|
-
puts
|
413
|
+
puts "without coverage"
|
409
414
|
puts `rake benchmarks:run_redis`
|
410
415
|
end
|
411
416
|
end
|
412
417
|
|
413
|
-
desc
|
414
|
-
task benchmarks: [
|
415
|
-
|
416
|
-
|
418
|
+
desc "runs benchmarks"
|
419
|
+
task benchmarks: ["benchmarks:redis_reporting",
|
420
|
+
"benchmarks:compare_file",
|
421
|
+
"benchmarks:compare_redis"]
|