coverband 3.0.1 → 4.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile.rails4.lock +2 -2
- data/README.md +138 -331
- data/changes.md +28 -17
- data/coverband.gemspec +8 -3
- data/lib/coverband.rb +10 -2
- data/lib/coverband/collectors/coverage.rb +4 -12
- data/lib/coverband/configuration.rb +25 -14
- data/lib/coverband/integrations/background.rb +4 -3
- data/lib/coverband/integrations/middleware.rb +5 -1
- data/lib/coverband/reporters/web.rb +1 -1
- data/lib/coverband/utils/railtie.rb +17 -0
- data/lib/coverband/utils/tasks.rb +6 -6
- data/lib/coverband/version.rb +1 -1
- data/test/benchmarks/benchmark.rake +6 -1
- data/test/unit/background_test.rb +11 -3
- data/test/unit/collectors_coverage_test.rb +2 -12
- data/test/unit/full_stack_test.rb +2 -1
- data/test/unit/middleware_test.rb +19 -0
- data/test/unit/rails_full_stack_test.rb +45 -1
- metadata +25 -24
data/changes.md
CHANGED
@@ -23,30 +23,20 @@ Will be the fully modern release that drops maintenance legacy support in favor
|
|
23
23
|
- Support for file versions
|
24
24
|
- md5 or release tags
|
25
25
|
- add coverage timerange support
|
26
|
-
- Drop Simplecov dependency
|
27
|
-
|
28
|
-
### Coverband 3.X
|
29
|
-
|
30
|
-
Will be a stable and fast release that drops maintenance legacy support in favor of increased performance and maintainability.
|
31
|
-
|
32
|
-
- expects to drop Tracepoint collection engine
|
33
|
-
- drop anything below Ruby 2.3
|
34
|
-
- release begins to simplify ease of use
|
35
|
-
- drop collectors adapter
|
36
|
-
- reduced configuration options
|
26
|
+
- Drop Simplecov dependency
|
37
27
|
- improved web reporting
|
38
28
|
- no longer relying directly on HTML in S3 but dynamically generated from any adapter
|
39
29
|
- lists current config options
|
40
30
|
- eventually allow updating remote config
|
41
31
|
- full theming
|
42
|
-
- list redis data dump for debugging
|
32
|
+
- list redis data dump for debugging
|
43
33
|
- additional adapters: Memcache, S3, and ActiveRecord
|
44
|
-
- add additional config / protection options on Coverage clear
|
45
|
-
- add memory benchmarks showing memory overhead of coverband
|
46
34
|
- add articles / podcasts like prontos readme https://github.com/prontolabs/pronto
|
35
|
+
- Add detailed Gem usage report, if we collect and send gem usage we can give percentage of gem code used, which should help application developers know when to remove gem dependencies (0%) or perhaps inline single methods for little usage (using <= 5%) for example.
|
36
|
+
- add additional config / protection options on Coverage clear
|
47
37
|
- add meta data information first seen last recorded to the coverage report views (probably need to drop simplecov for that).
|
48
|
-
- more details in this issue: https://github.com/danmayer/coverband/issues/118
|
49
|
-
-
|
38
|
+
- more details in this issue: https://github.com/danmayer/coverband/issues/118
|
39
|
+
- Make good video on setup, install, usage
|
50
40
|
|
51
41
|
### Coverband_jam_session
|
52
42
|
|
@@ -68,15 +58,36 @@ Feature Ideas:
|
|
68
58
|
- tagging of reported Coverage
|
69
59
|
- allow only to collect coverage based on route (limiting or scoped coverage)
|
70
60
|
- coverage over some other variable like a set of alpha users
|
61
|
+
- document how to use this on staging / selenium test suite runs
|
62
|
+
- possible add API to pull report at end of run
|
71
63
|
|
72
64
|
# Alpha
|
73
65
|
|
74
|
-
### Coverband
|
66
|
+
### Coverband 4.0.0
|
75
67
|
|
76
68
|
* Add support for Railties integration
|
69
|
+
* Reduce configuration options
|
70
|
+
* Default to background reporting vs middleware reporting
|
71
|
+
* Resolves issue requiring submitting initial coverage data pre-fork
|
72
|
+
* Simplified setup with just works sensible defaults for configuration out of the box
|
73
|
+
* Fixes on the pilot release of background reporting in 3.0.1
|
74
|
+
* Rake tasks automatically configured
|
75
|
+
* Updated and simplified documentation
|
77
76
|
|
78
77
|
# Released
|
79
78
|
|
79
|
+
### Coverband 3.X
|
80
|
+
|
81
|
+
Will be a stable and fast release that drops maintenance legacy support in favor of increased performance and maintainability.
|
82
|
+
|
83
|
+
- expects to drop Tracepoint collection engine
|
84
|
+
- drop anything below Ruby 2.3
|
85
|
+
- release begins to simplify ease of use
|
86
|
+
- drop collectors adapter
|
87
|
+
- reduced configuration options
|
88
|
+
- add memory benchmarks showing memory overhead of coverband
|
89
|
+
- use full stack tests to prove no memory leaks when used in Rails
|
90
|
+
|
80
91
|
### Coverband 3.0.1
|
81
92
|
|
82
93
|
* update documentation around verification steps (https://github.com/danmayer/coverband/issues/135), thanks @kbaum
|
data/coverband.gemspec
CHANGED
@@ -25,14 +25,13 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency 'aws-sdk', '~> 2'
|
26
26
|
spec.add_development_dependency 'benchmark-ips'
|
27
27
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
28
|
+
spec.add_development_dependency 'm'
|
29
|
+
spec.add_development_dependency 'memory_profiler'
|
28
30
|
spec.add_development_dependency 'mocha', '~> 0.14.0'
|
29
31
|
spec.add_development_dependency 'rack'
|
30
32
|
spec.add_development_dependency 'rack-test'
|
31
33
|
spec.add_development_dependency 'rake'
|
32
|
-
spec.add_development_dependency 'redis'
|
33
34
|
spec.add_development_dependency 'test-unit'
|
34
|
-
spec.add_development_dependency 'm'
|
35
|
-
spec.add_development_dependency 'memory_profiler'
|
36
35
|
|
37
36
|
# used for benchmarking and tests
|
38
37
|
spec.add_development_dependency 'classifier-reborn'
|
@@ -40,6 +39,12 @@ Gem::Specification.new do |spec|
|
|
40
39
|
# require 'byebug'; byebug
|
41
40
|
spec.add_development_dependency 'pry-byebug'
|
42
41
|
|
42
|
+
# TODO: Remove when other production adapters exist
|
43
|
+
# because the default configuration of redis store, we really do require
|
44
|
+
# redis now. I was reluctant to add this, but until we offer another production
|
45
|
+
# quality adapter, I think this is more honest about requirements and reduces confusion
|
46
|
+
# without this there was a race condition on calling coverband configure before redis was loaded
|
47
|
+
spec.add_runtime_dependency 'redis'
|
43
48
|
# TODO: make an optional dependency for simplecov reports
|
44
49
|
# also likely should just require simplecov-html not the whole lib
|
45
50
|
# I tried this but it was harder than I thought
|
data/lib/coverband.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'logger'
|
4
4
|
require 'json'
|
5
|
+
require 'redis'
|
5
6
|
|
6
7
|
require 'coverband/version'
|
7
8
|
require 'coverband/configuration'
|
@@ -9,6 +10,7 @@ require 'coverband/adapters/base'
|
|
9
10
|
require 'coverband/adapters/redis_store'
|
10
11
|
require 'coverband/adapters/file_store'
|
11
12
|
require 'coverband/utils/s3_report'
|
13
|
+
require 'coverband/utils/railtie' if defined? ::Rails::Railtie
|
12
14
|
require 'coverband/collectors/coverage'
|
13
15
|
require 'coverband/reporters/base'
|
14
16
|
require 'coverband/reporters/simple_cov_report'
|
@@ -35,8 +37,7 @@ module Coverband
|
|
35
37
|
elsif File.exist?(configuration_file)
|
36
38
|
require configuration_file
|
37
39
|
else
|
38
|
-
|
39
|
-
raise ArgumentError, msg
|
40
|
+
configuration.logger&.debug('using default configuration')
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
@@ -48,4 +49,11 @@ module Coverband
|
|
48
49
|
Coverband::Collectors::Coverage.instance
|
49
50
|
Background.start if configuration.background_reporting_enabled && !RackServerCheck.running?
|
50
51
|
end
|
52
|
+
|
53
|
+
unless ENV['COVERBAND_DISABLE_AUTO_START']
|
54
|
+
# Coverband should be setup as early as possible
|
55
|
+
# to capture usage of things loaded by initializers or other Rails engines
|
56
|
+
configure
|
57
|
+
start
|
58
|
+
end
|
51
59
|
end
|
@@ -17,7 +17,6 @@ module Coverband
|
|
17
17
|
def reset_instance
|
18
18
|
@project_directory = File.expand_path(Coverband.configuration.root)
|
19
19
|
@file_line_usage = {}
|
20
|
-
@ignored_files = Set.new
|
21
20
|
@ignore_patterns = Coverband.configuration.ignore + ['internal:prelude', 'schema.rb']
|
22
21
|
@reporting_frequency = Coverband.configuration.reporting_frequency
|
23
22
|
@store = Coverband.configuration.store
|
@@ -25,19 +24,15 @@ module Coverband
|
|
25
24
|
@logger = Coverband.configuration.logger
|
26
25
|
@current_thread = Thread.current
|
27
26
|
@test_env = Coverband.configuration.test_env
|
28
|
-
|
27
|
+
@@previous_results = nil
|
29
28
|
Thread.current[:coverband_instance] = nil
|
30
29
|
self
|
31
30
|
end
|
32
31
|
|
33
32
|
def report_coverage(force_report = false)
|
34
|
-
return Background.start if @background_reporting_enabled
|
35
33
|
return if !ready_to_report? && !force_report
|
34
|
+
raise 'no Coverband store set' unless @store
|
36
35
|
|
37
|
-
unless @store
|
38
|
-
@logger.debug 'no store set, no-op'
|
39
|
-
return
|
40
|
-
end
|
41
36
|
new_results = get_new_coverage_results
|
42
37
|
add_filtered_files(new_results)
|
43
38
|
@store.save_report(files_with_line_usage)
|
@@ -63,7 +58,6 @@ module Coverband
|
|
63
58
|
|
64
59
|
def add_filtered_files(new_results)
|
65
60
|
new_results.each_pair do |file, line_counts|
|
66
|
-
next if @ignored_files.include?(file)
|
67
61
|
next unless track_file?(file)
|
68
62
|
add_file(file, line_counts)
|
69
63
|
end
|
@@ -74,14 +68,12 @@ module Coverband
|
|
74
68
|
end
|
75
69
|
|
76
70
|
def get_new_coverage_results
|
77
|
-
|
78
|
-
@semaphore.synchronize { coverage_results = new_coverage(::Coverage.peek_result.dup) }
|
79
|
-
coverage_results
|
71
|
+
@semaphore.synchronize { new_coverage(::Coverage.peek_result.dup) }
|
80
72
|
end
|
81
73
|
|
82
74
|
def files_with_line_usage
|
83
75
|
@file_line_usage.select do |_file_name, coverage|
|
84
|
-
coverage.any? { |value| value
|
76
|
+
coverage.any? { |value| value&.nonzero? }
|
85
77
|
end
|
86
78
|
end
|
87
79
|
|
@@ -2,10 +2,9 @@
|
|
2
2
|
|
3
3
|
module Coverband
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :root_paths, :root,
|
6
6
|
:ignore, :additional_files, :verbose,
|
7
7
|
:reporter, :reporting_frequency,
|
8
|
-
:disable_on_failure_for,
|
9
8
|
:redis_namespace, :redis_ttl,
|
10
9
|
:safe_reload_files, :background_reporting_enabled,
|
11
10
|
:background_reporting_sleep_seconds, :test_env
|
@@ -15,13 +14,16 @@ module Coverband
|
|
15
14
|
def initialize
|
16
15
|
@root = Dir.pwd
|
17
16
|
@root_paths = []
|
18
|
-
@ignore =
|
17
|
+
@ignore = %w(vendor .erb$ .slim$)
|
19
18
|
@additional_files = []
|
20
19
|
@reporting_frequency = 0.0
|
21
20
|
@verbose = false
|
22
21
|
@reporter = 'scov'
|
23
|
-
@logger =
|
22
|
+
@logger = nil
|
24
23
|
@store = nil
|
24
|
+
@background_reporting_enabled = true
|
25
|
+
@background_reporting_sleep_seconds = 30
|
26
|
+
@test_env = nil
|
25
27
|
|
26
28
|
# TODO: should we push these to adapter configs
|
27
29
|
@s3_region = nil
|
@@ -30,12 +32,14 @@ module Coverband
|
|
30
32
|
@s3_secret_access_key = nil
|
31
33
|
@redis_namespace = nil
|
32
34
|
@redis_ttl = nil
|
33
|
-
@test_env = nil
|
34
|
-
@background_reporting_sleep_seconds = 30
|
35
35
|
end
|
36
36
|
|
37
37
|
def logger
|
38
|
-
@logger ||=
|
38
|
+
@logger ||= if defined?(Rails)
|
39
|
+
Rails.logger
|
40
|
+
else
|
41
|
+
Logger.new(STDOUT)
|
42
|
+
end
|
39
43
|
end
|
40
44
|
|
41
45
|
def s3_bucket
|
@@ -55,19 +59,26 @@ module Coverband
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def store
|
58
|
-
|
59
|
-
raise 'no valid store configured'
|
62
|
+
@store ||= Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_store_options)
|
60
63
|
end
|
61
64
|
|
62
65
|
def store=(store)
|
63
66
|
if store.is_a?(Coverband::Adapters::Base)
|
64
67
|
@store = store
|
65
|
-
|
66
|
-
|
67
|
-
redis_namespace: Coverband.configuration.redis_namespace)
|
68
|
-
elsif store.is_a?(String)
|
69
|
-
@store = Coverband::Adapters::FileStore.new(store)
|
68
|
+
else
|
69
|
+
raise 'please pass in an subclass of Coverband::Adapters for supported stores'
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def redis_url
|
76
|
+
ENV['COVERBAND_REDIS_URL'] || ENV['REDIS_URL']
|
77
|
+
end
|
78
|
+
|
79
|
+
def redis_store_options
|
80
|
+
{ ttl: Coverband.configuration.redis_ttl,
|
81
|
+
redis_namespace: Coverband.configuration.redis_namespace }
|
82
|
+
end
|
72
83
|
end
|
73
84
|
end
|
@@ -10,20 +10,21 @@ module Coverband
|
|
10
10
|
logger = Coverband.configuration.logger
|
11
11
|
@semaphore.synchronize do
|
12
12
|
return if @background_reporting_running
|
13
|
+
logger&.debug('Starting background reporting')
|
13
14
|
|
14
15
|
@background_reporting_running = true
|
15
16
|
sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds
|
16
17
|
Thread.new do
|
17
18
|
loop do
|
18
|
-
Coverband::Collectors::Coverage.instance.report_coverage
|
19
|
+
Coverband::Collectors::Coverage.instance.report_coverage(true)
|
19
20
|
logger&.debug("Reported coverage from thread. Sleeping for #{sleep_seconds} seconds")
|
20
21
|
sleep(sleep_seconds)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
at_exit do
|
25
|
-
Coverband::Collectors::Coverage.instance.report_coverage
|
26
|
-
logger&.debug(
|
26
|
+
Coverband::Collectors::Coverage.instance.report_coverage(true)
|
27
|
+
logger&.debug('Reported coverage before exit')
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
@@ -9,7 +9,11 @@ module Coverband
|
|
9
9
|
def call(env)
|
10
10
|
@app.call(env)
|
11
11
|
ensure
|
12
|
-
Coverband
|
12
|
+
if Coverband.configuration.background_reporting_enabled
|
13
|
+
Coverband::Background.start
|
14
|
+
else
|
15
|
+
Coverband::Collectors::Coverage.instance.report_coverage
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
@@ -93,7 +93,7 @@ module Coverband
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def collect_coverage
|
96
|
-
Coverband::Collectors::Coverage.instance.report_coverage
|
96
|
+
Coverband::Collectors::Coverage.instance.report_coverage(true)
|
97
97
|
notice = 'coverband coverage collected'
|
98
98
|
[301, { 'Location' => "#{base_path}?notice=#{notice}" }, []]
|
99
99
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coverband
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
initializer 'coverband.configure' do |app|
|
6
|
+
app.middleware.use Coverband::Middleware
|
7
|
+
end
|
8
|
+
|
9
|
+
config.after_initialize do
|
10
|
+
Coverband::Collectors::Coverage.instance.report_coverage(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
rake_tasks do
|
14
|
+
load 'coverband/utils/tasks.rb'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
namespace :coverband do
|
4
|
+
Coverband.configure
|
5
|
+
|
4
6
|
###
|
5
|
-
#
|
7
|
+
# NOTE: If your project has set many simplecov filters.
|
6
8
|
# You might want to override them and clear the filters.
|
7
9
|
# Or run the task `coverage_no_filters` below.
|
8
10
|
###
|
9
|
-
desc 'report runtime
|
11
|
+
desc 'report runtime Coverband code coverage'
|
10
12
|
task coverage: :environment do
|
11
13
|
if Coverband.configuration.reporter == 'scov'
|
12
14
|
Coverband::Reporters::SimpleCovReport.report(Coverband.configuration.store)
|
@@ -30,11 +32,9 @@ namespace :coverband do
|
|
30
32
|
end
|
31
33
|
|
32
34
|
###
|
33
|
-
#
|
34
|
-
# You may want to have a hook that saves current coverband data on deploy
|
35
|
-
# and then resets the coverband store data.
|
35
|
+
# clear data helpful for development or after configuration issues
|
36
36
|
###
|
37
|
-
desc 'reset
|
37
|
+
desc 'reset Coverband coverage data, helpful for development, debugging, etc'
|
38
38
|
task clear: :environment do
|
39
39
|
Coverband.configuration.store.clear!
|
40
40
|
end
|
data/lib/coverband/version.rb
CHANGED
@@ -78,7 +78,6 @@ namespace :benchmarks do
|
|
78
78
|
# desc 'set up coverband with Redis'
|
79
79
|
task :setup_redis do
|
80
80
|
Coverband.configure do |config|
|
81
|
-
config.redis = Redis.new
|
82
81
|
config.root = Dir.pwd
|
83
82
|
config.reporting_frequency = 100.0
|
84
83
|
config.logger = $stdout
|
@@ -222,6 +221,12 @@ namespace :benchmarks do
|
|
222
221
|
measure_memory
|
223
222
|
end
|
224
223
|
|
224
|
+
desc 'runs memory leak check via Rails tests'
|
225
|
+
task memory_rails: [:setup] do
|
226
|
+
puts 'runs memory rails test to ensure we dont leak'
|
227
|
+
puts `COVERBAND_MEMORY_TEST=true bundle exec m test/unit/rails_full_stack_test.rb:22`
|
228
|
+
end
|
229
|
+
|
225
230
|
desc 'runs benchmarks on reporting large sets of files to redis'
|
226
231
|
task redis_reporting: [:setup] do
|
227
232
|
puts 'runs benchmarks on reporting large sets of files to redis'
|
@@ -3,14 +3,22 @@
|
|
3
3
|
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
4
4
|
|
5
5
|
class BackgroundTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
Coverband::Collectors::Coverage.instance.reset_instance
|
8
|
+
Coverband.configure do |config|
|
9
|
+
config.store = Coverband::Adapters::RedisStore.new(Redis.new)
|
10
|
+
config.background_reporting_enabled = true
|
11
|
+
end
|
12
|
+
Coverband::Background.instance_variable_set(:@background_reporting_running, nil)
|
13
|
+
end
|
14
|
+
|
6
15
|
def test_start
|
7
16
|
Thread.expects(:new).yields
|
8
17
|
Coverband::Background.expects(:loop).yields
|
9
|
-
|
18
|
+
|
10
19
|
Coverband::Background.expects(:sleep).with(30)
|
11
20
|
Coverband::Background.expects(:at_exit).yields
|
12
|
-
Coverband::Collectors::Coverage.instance.expects(:report_coverage)
|
21
|
+
Coverband::Collectors::Coverage.instance.expects(:report_coverage).twice
|
13
22
|
2.times { Coverband::Background.start }
|
14
23
|
end
|
15
24
|
end
|
16
|
-
|
@@ -29,29 +29,19 @@ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0')
|
|
29
29
|
assert_equal Coverband::Adapters::RedisStore, coverband.instance_variable_get('@store').class
|
30
30
|
end
|
31
31
|
|
32
|
-
test 'reports coverage in background when background reporting enabled' do
|
33
|
-
Coverband.configuration.stubs(:background_reporting_enabled).returns(true)
|
34
|
-
@coverband.reset_instance
|
35
|
-
Coverband::Background.expects(:start)
|
36
|
-
@coverband.report_coverage
|
37
|
-
end
|
38
|
-
|
39
32
|
test 'report_coverage raises errors in tests' do
|
40
|
-
Coverband.configuration.stubs(:background_reporting_enabled).returns(true)
|
41
33
|
@coverband.reset_instance
|
42
|
-
|
34
|
+
@coverband.expects(:ready_to_report?).raises('Oh no')
|
43
35
|
assert_raise RuntimeError do
|
44
36
|
@coverband.report_coverage
|
45
37
|
end
|
46
38
|
end
|
47
39
|
|
48
40
|
test 'report_coverage does not raise errors in non-test mode' do
|
49
|
-
Coverband.configuration.stubs(:background_reporting_enabled).returns(true)
|
50
41
|
Coverband.configuration.stubs(:test_env).returns(false)
|
42
|
+
@coverband.expects(:ready_to_report?).raises('Oh no')
|
51
43
|
@coverband.reset_instance
|
52
|
-
Coverband::Background.expects(:start).raises("Oh no")
|
53
44
|
@coverband.report_coverage
|
54
45
|
end
|
55
|
-
|
56
46
|
end
|
57
47
|
end
|