coverband 3.0.0 → 3.0.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.
- checksums.yaml +5 -5
- data/.gitignore +2 -1
- data/.travis.yml +3 -0
- data/Gemfile +1 -0
- data/Gemfile.rails4 +7 -0
- data/Gemfile.rails4.lock +164 -0
- data/README.md +16 -14
- data/changes.md +17 -4
- data/coverband.gemspec +11 -4
- data/lib/coverband/adapters/base.rb +57 -8
- data/lib/coverband/adapters/file_store.rb +4 -22
- data/lib/coverband/adapters/redis_store.rb +7 -27
- data/lib/coverband/collectors/coverage.rb +5 -0
- data/lib/coverband/configuration.rb +4 -1
- data/lib/coverband/integrations/background.rb +25 -1
- data/lib/coverband/integrations/rack_server_check.rb +27 -0
- data/lib/coverband/reporters/simple_cov_report.rb +1 -7
- data/lib/coverband/reporters/web.rb +2 -20
- data/lib/coverband/utils/s3_report.rb +108 -0
- data/lib/coverband/version.rb +1 -1
- data/lib/coverband.rb +4 -1
- data/test/benchmarks/benchmark.rake +47 -1
- data/test/rails4_dummy/app/controllers/dummy_controller.rb +5 -0
- data/test/rails4_dummy/config/application.rb +15 -0
- data/test/rails4_dummy/config/boot.rb +3 -0
- data/test/rails4_dummy/config/coverband.rb +8 -0
- data/test/rails4_dummy/config/environment.rb +5 -0
- data/test/rails4_dummy/config/routes.rb +3 -0
- data/test/rails4_dummy/config/secrets.yml +3 -0
- data/test/rails4_dummy/config.ru +4 -0
- data/test/rails5_dummy/app/controllers/dummy_controller.rb +5 -0
- data/test/rails5_dummy/config/application.rb +16 -0
- data/test/rails5_dummy/config/coverband.rb +8 -0
- data/test/rails5_dummy/config/environment.rb +2 -0
- data/test/rails5_dummy/config/routes.rb +3 -0
- data/test/rails5_dummy/config.ru +3 -0
- data/test/rails_test_helper.rb +11 -0
- data/test/test_helper.rb +14 -9
- data/test/unit/adapters_base_test.rb +34 -13
- data/test/unit/adapters_file_store_test.rb +8 -4
- data/test/unit/adapters_redis_store_test.rb +7 -13
- data/test/unit/background_test.rb +16 -0
- data/test/unit/collectors_coverage_test.rb +24 -0
- data/test/unit/configuration_test.rb +12 -0
- data/test/unit/coverband_test.rb +26 -0
- data/test/unit/rack_server_checkout_test.rb +24 -0
- data/test/unit/rails_full_stack_test.rb +16 -0
- data/test/unit/reports_base_test.rb +0 -2
- data/test/unit/reports_console_test.rb +1 -0
- data/test/unit/reports_simple_cov_test.rb +1 -10
- data/test/unit/reports_web_test.rb +1 -3
- data/test/unit/utils_s3_report_test.rb +44 -0
- metadata +78 -9
- data/lib/coverband/utils/s3_report_writer.rb +0 -59
- data/test/unit/utils_s3_report_writer_test.rb +0 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 6e6e4e2aa7c0271b100b0ce9dc5740719a85b6be
|
|
4
|
+
data.tar.gz: 4be906bc977953bcba78c7d2bcf11f288fa21d15
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f60a464c8df70d9663ae550ce40e85a3d3c72dc3e32fc27f5ea64af405b57b7354aec420b78cd83a3e60fe018cecd9b80d8f0ae26424a44b90a97f294a488345
|
|
7
|
+
data.tar.gz: fee9a14503b7009ac42025df790d1c70ab78a33e79eb89bf18349ec25db1213ae6730036f866e1211cb9d4f652fda29becfacf18b0bf82052bc9834328af2056
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.rails4
ADDED
data/Gemfile.rails4.lock
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
coverband (3.0.1.alpha)
|
|
5
|
+
simplecov (> 0.11.1)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
actionmailer (4.2.10)
|
|
11
|
+
actionpack (= 4.2.10)
|
|
12
|
+
actionview (= 4.2.10)
|
|
13
|
+
activejob (= 4.2.10)
|
|
14
|
+
mail (~> 2.5, >= 2.5.4)
|
|
15
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
16
|
+
actionpack (4.2.10)
|
|
17
|
+
actionview (= 4.2.10)
|
|
18
|
+
activesupport (= 4.2.10)
|
|
19
|
+
rack (~> 1.6)
|
|
20
|
+
rack-test (~> 0.6.2)
|
|
21
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
22
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
23
|
+
actionview (4.2.10)
|
|
24
|
+
activesupport (= 4.2.10)
|
|
25
|
+
builder (~> 3.1)
|
|
26
|
+
erubis (~> 2.7.0)
|
|
27
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
29
|
+
activejob (4.2.10)
|
|
30
|
+
activesupport (= 4.2.10)
|
|
31
|
+
globalid (>= 0.3.0)
|
|
32
|
+
activemodel (4.2.10)
|
|
33
|
+
activesupport (= 4.2.10)
|
|
34
|
+
builder (~> 3.1)
|
|
35
|
+
activerecord (4.2.10)
|
|
36
|
+
activemodel (= 4.2.10)
|
|
37
|
+
activesupport (= 4.2.10)
|
|
38
|
+
arel (~> 6.0)
|
|
39
|
+
activesupport (4.2.10)
|
|
40
|
+
i18n (~> 0.7)
|
|
41
|
+
minitest (~> 5.1)
|
|
42
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
|
43
|
+
tzinfo (~> 1.1)
|
|
44
|
+
arel (6.0.4)
|
|
45
|
+
aws-sdk (2.11.174)
|
|
46
|
+
aws-sdk-resources (= 2.11.174)
|
|
47
|
+
aws-sdk-core (2.11.174)
|
|
48
|
+
aws-sigv4 (~> 1.0)
|
|
49
|
+
jmespath (~> 1.0)
|
|
50
|
+
aws-sdk-resources (2.11.174)
|
|
51
|
+
aws-sdk-core (= 2.11.174)
|
|
52
|
+
aws-sigv4 (1.0.3)
|
|
53
|
+
benchmark-ips (2.7.2)
|
|
54
|
+
builder (3.2.3)
|
|
55
|
+
byebug (10.0.2)
|
|
56
|
+
classifier-reborn (2.2.0)
|
|
57
|
+
fast-stemmer (~> 1.0)
|
|
58
|
+
coderay (1.1.2)
|
|
59
|
+
concurrent-ruby (1.1.3)
|
|
60
|
+
crass (1.0.4)
|
|
61
|
+
docile (1.3.1)
|
|
62
|
+
erubis (2.7.0)
|
|
63
|
+
fast-stemmer (1.0.2)
|
|
64
|
+
globalid (0.4.1)
|
|
65
|
+
activesupport (>= 4.2.0)
|
|
66
|
+
i18n (0.9.5)
|
|
67
|
+
concurrent-ruby (~> 1.0)
|
|
68
|
+
jmespath (1.4.0)
|
|
69
|
+
json (2.1.0)
|
|
70
|
+
loofah (2.2.3)
|
|
71
|
+
crass (~> 1.0.2)
|
|
72
|
+
nokogiri (>= 1.5.9)
|
|
73
|
+
m (1.5.1)
|
|
74
|
+
method_source (>= 0.6.7)
|
|
75
|
+
rake (>= 0.9.2.2)
|
|
76
|
+
mail (2.7.1)
|
|
77
|
+
mini_mime (>= 0.1.1)
|
|
78
|
+
memory_profiler (0.9.12)
|
|
79
|
+
metaclass (0.0.4)
|
|
80
|
+
method_source (0.9.2)
|
|
81
|
+
mini_mime (1.0.1)
|
|
82
|
+
mini_portile2 (2.3.0)
|
|
83
|
+
minitest (5.11.3)
|
|
84
|
+
mocha (0.14.0)
|
|
85
|
+
metaclass (~> 0.0.1)
|
|
86
|
+
nokogiri (1.8.5)
|
|
87
|
+
mini_portile2 (~> 2.3.0)
|
|
88
|
+
power_assert (1.1.3)
|
|
89
|
+
pry (0.12.2)
|
|
90
|
+
coderay (~> 1.1.0)
|
|
91
|
+
method_source (~> 0.9.0)
|
|
92
|
+
pry-byebug (3.6.0)
|
|
93
|
+
byebug (~> 10.0)
|
|
94
|
+
pry (~> 0.10)
|
|
95
|
+
rack (1.6.11)
|
|
96
|
+
rack-test (0.6.3)
|
|
97
|
+
rack (>= 1.0)
|
|
98
|
+
rails (4.2.10)
|
|
99
|
+
actionmailer (= 4.2.10)
|
|
100
|
+
actionpack (= 4.2.10)
|
|
101
|
+
actionview (= 4.2.10)
|
|
102
|
+
activejob (= 4.2.10)
|
|
103
|
+
activemodel (= 4.2.10)
|
|
104
|
+
activerecord (= 4.2.10)
|
|
105
|
+
activesupport (= 4.2.10)
|
|
106
|
+
bundler (>= 1.3.0, < 2.0)
|
|
107
|
+
railties (= 4.2.10)
|
|
108
|
+
sprockets-rails
|
|
109
|
+
rails-deprecated_sanitizer (1.0.3)
|
|
110
|
+
activesupport (>= 4.2.0.alpha)
|
|
111
|
+
rails-dom-testing (1.0.9)
|
|
112
|
+
activesupport (>= 4.2.0, < 5.0)
|
|
113
|
+
nokogiri (~> 1.6)
|
|
114
|
+
rails-deprecated_sanitizer (>= 1.0.1)
|
|
115
|
+
rails-html-sanitizer (1.0.4)
|
|
116
|
+
loofah (~> 2.2, >= 2.2.2)
|
|
117
|
+
railties (4.2.10)
|
|
118
|
+
actionpack (= 4.2.10)
|
|
119
|
+
activesupport (= 4.2.10)
|
|
120
|
+
rake (>= 0.8.7)
|
|
121
|
+
thor (>= 0.18.1, < 2.0)
|
|
122
|
+
rake (12.3.1)
|
|
123
|
+
redis (4.0.3)
|
|
124
|
+
simplecov (0.16.1)
|
|
125
|
+
docile (~> 1.1)
|
|
126
|
+
json (>= 1.8, < 3)
|
|
127
|
+
simplecov-html (~> 0.10.0)
|
|
128
|
+
simplecov-html (0.10.2)
|
|
129
|
+
sprockets (3.7.2)
|
|
130
|
+
concurrent-ruby (~> 1.0)
|
|
131
|
+
rack (> 1, < 3)
|
|
132
|
+
sprockets-rails (3.2.1)
|
|
133
|
+
actionpack (>= 4.0)
|
|
134
|
+
activesupport (>= 4.0)
|
|
135
|
+
sprockets (>= 3.0.0)
|
|
136
|
+
test-unit (3.2.8)
|
|
137
|
+
power_assert
|
|
138
|
+
thor (0.20.3)
|
|
139
|
+
thread_safe (0.3.6)
|
|
140
|
+
tzinfo (1.2.5)
|
|
141
|
+
thread_safe (~> 0.1)
|
|
142
|
+
|
|
143
|
+
PLATFORMS
|
|
144
|
+
ruby
|
|
145
|
+
|
|
146
|
+
DEPENDENCIES
|
|
147
|
+
aws-sdk (~> 2)
|
|
148
|
+
benchmark-ips
|
|
149
|
+
bundler (~> 1.3)
|
|
150
|
+
classifier-reborn
|
|
151
|
+
coverband!
|
|
152
|
+
m
|
|
153
|
+
memory_profiler
|
|
154
|
+
mocha (~> 0.14.0)
|
|
155
|
+
pry-byebug
|
|
156
|
+
rack
|
|
157
|
+
rack-test
|
|
158
|
+
rails (~> 4)
|
|
159
|
+
rake
|
|
160
|
+
redis
|
|
161
|
+
test-unit
|
|
162
|
+
|
|
163
|
+
BUNDLED WITH
|
|
164
|
+
1.16.2
|
data/README.md
CHANGED
|
@@ -194,8 +194,9 @@ run ActionController::Dispatcher.new
|
|
|
194
194
|
# Verify Correct Installation
|
|
195
195
|
|
|
196
196
|
* boot up your application
|
|
197
|
+
* run app and hit a controller (via a web request, at least one request must complete)
|
|
197
198
|
* run `rake coverband:coverage` this will show app initialization coverage
|
|
198
|
-
*
|
|
199
|
+
* make another request, or enough that your reporting frequency will trigger
|
|
199
200
|
* run `rake coverband:coverage` and you should see coverage increasing for the endpoints you hit.
|
|
200
201
|
|
|
201
202
|
## Installation Session
|
|
@@ -469,21 +470,20 @@ end
|
|
|
469
470
|
|
|
470
471
|
# protect with http basic auth
|
|
471
472
|
# curl --user foo:bar http://localhost:3000/coverage
|
|
472
|
-
basic_constraint = lambda do |request|
|
|
473
|
-
return true if Rails.env.development?
|
|
474
|
-
if ActionController::HttpAuthentication::Basic.has_basic_credentials?(request)
|
|
475
|
-
credentials = ActionController::HttpAuthentication::Basic.decode_credentials(request)
|
|
476
|
-
email, password = credentials.split(':')
|
|
477
|
-
|
|
478
|
-
email == 'foo' && password = 'bar'
|
|
479
|
-
end
|
|
480
|
-
end
|
|
481
|
-
|
|
482
473
|
Rails.application.routes.draw do
|
|
483
474
|
# ... lots of routes
|
|
484
|
-
|
|
485
|
-
|
|
475
|
+
|
|
476
|
+
# Create a Rack wrapper around the Coverband Web Reporter to support & prompt the user for basic authentication.
|
|
477
|
+
AuthenticatedCoverband = Rack::Builder.new do
|
|
478
|
+
use Rack::Auth::Basic do |username, password|
|
|
479
|
+
username == 'foo' && password == 'bar'
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
run Coverband::Reporters::Web.new
|
|
486
483
|
end
|
|
484
|
+
|
|
485
|
+
# Connect the wrapper app to your desired endpoint.
|
|
486
|
+
mount AuthenticatedCoverband, at: '/coverage'
|
|
487
487
|
end
|
|
488
488
|
```
|
|
489
489
|
|
|
@@ -526,7 +526,9 @@ If you are working on adding features, PRs, or bugfixes to Coverband this sectio
|
|
|
526
526
|
|
|
527
527
|
If you submit a change please make sure the tests and benchmarks are passing.
|
|
528
528
|
|
|
529
|
-
* run tests:
|
|
529
|
+
* run tests:
|
|
530
|
+
* `bundle exec rake`
|
|
531
|
+
* `BUNDLE_GEMFILE=Gemfile.rails4 bundle exec rake` (Same tests using rails 4 instead of 5)
|
|
530
532
|
* view test coverage: `open coverage/index.html`
|
|
531
533
|
* run the benchmarks before and after your change to see impact
|
|
532
534
|
* `rake benchmarks`
|
data/changes.md
CHANGED
|
@@ -30,7 +30,7 @@ Will be the fully modern release that drops maintenance legacy support in favor
|
|
|
30
30
|
Will be a stable and fast release that drops maintenance legacy support in favor of increased performance and maintainability.
|
|
31
31
|
|
|
32
32
|
- expects to drop Tracepoint collection engine
|
|
33
|
-
-
|
|
33
|
+
- drop anything below Ruby 2.3
|
|
34
34
|
- release begins to simplify ease of use
|
|
35
35
|
- drop collectors adapter
|
|
36
36
|
- reduced configuration options
|
|
@@ -44,6 +44,9 @@ Will be a stable and fast release that drops maintenance legacy support in favor
|
|
|
44
44
|
- add additional config / protection options on Coverage clear
|
|
45
45
|
- add memory benchmarks showing memory overhead of coverband
|
|
46
46
|
- add articles / podcasts like prontos readme https://github.com/prontolabs/pronto
|
|
47
|
+
- 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
|
+
- use full stack tests to prove no memory leaks when used in Rails
|
|
47
50
|
|
|
48
51
|
### Coverband_jam_session
|
|
49
52
|
|
|
@@ -68,13 +71,23 @@ Feature Ideas:
|
|
|
68
71
|
|
|
69
72
|
# Alpha
|
|
70
73
|
|
|
71
|
-
### Coverband
|
|
72
|
-
|
|
73
|
-
* ??? ;)
|
|
74
|
+
### Coverband ???
|
|
74
75
|
|
|
76
|
+
* Add support for Railties integration
|
|
75
77
|
|
|
76
78
|
# Released
|
|
77
79
|
|
|
80
|
+
### Coverband 3.0.1
|
|
81
|
+
|
|
82
|
+
* update documentation around verification steps (https://github.com/danmayer/coverband/issues/135), thanks @kbaum
|
|
83
|
+
* resolve coverage drift issue, https://github.com/danmayer/coverband/issues/118, thanks for MD5 hash ideas @dnasseri and @kbaum
|
|
84
|
+
* first version of background thread coverage reporting https://github.com/danmayer/coverband/pull/138, thanks @kbaum
|
|
85
|
+
* auto-detection of Rack & Rails thanks @kbaum
|
|
86
|
+
* improved tests allowing exceptions to raise in tests @kbaum
|
|
87
|
+
* add support for both aws-sdk 1.x and 2.x thanks @jared
|
|
88
|
+
* adds memory test ensuring no memory leaks
|
|
89
|
+
* full stack Rails tests for Rails 4 and 5 thanks @kbaum
|
|
90
|
+
|
|
78
91
|
### Coverband 3.0.0
|
|
79
92
|
|
|
80
93
|
* drops Tracepoint
|
data/coverband.gemspec
CHANGED
|
@@ -19,22 +19,29 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
20
|
spec.require_paths = ['lib']
|
|
21
21
|
|
|
22
|
+
# to test support for sdk 1, uncomment this line
|
|
23
|
+
# spec.add_development_dependency 'aws-sdk', '~> 1'
|
|
24
|
+
# to test sdk 2 use this one
|
|
22
25
|
spec.add_development_dependency 'aws-sdk', '~> 2'
|
|
26
|
+
spec.add_development_dependency 'benchmark-ips'
|
|
23
27
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
|
24
28
|
spec.add_development_dependency 'mocha', '~> 0.14.0'
|
|
25
29
|
spec.add_development_dependency 'rack'
|
|
26
30
|
spec.add_development_dependency 'rack-test'
|
|
27
31
|
spec.add_development_dependency 'rake'
|
|
28
|
-
spec.add_development_dependency 'test-unit'
|
|
29
32
|
spec.add_development_dependency 'redis'
|
|
30
|
-
spec.add_development_dependency '
|
|
33
|
+
spec.add_development_dependency 'test-unit'
|
|
34
|
+
spec.add_development_dependency 'm'
|
|
35
|
+
spec.add_development_dependency 'memory_profiler'
|
|
36
|
+
|
|
31
37
|
# used for benchmarking and tests
|
|
32
38
|
spec.add_development_dependency 'classifier-reborn'
|
|
33
39
|
# add when debugging
|
|
34
40
|
# require 'byebug'; byebug
|
|
35
|
-
spec.add_development_dependency 'byebug'
|
|
41
|
+
spec.add_development_dependency 'pry-byebug'
|
|
36
42
|
|
|
37
|
-
#
|
|
43
|
+
# TODO: make an optional dependency for simplecov reports
|
|
38
44
|
# also likely should just require simplecov-html not the whole lib
|
|
45
|
+
# I tried this but it was harder than I thought
|
|
39
46
|
spec.add_runtime_dependency 'simplecov', '> 0.11.1'
|
|
40
47
|
end
|
|
@@ -4,36 +4,70 @@ module Coverband
|
|
|
4
4
|
module Adapters
|
|
5
5
|
class Base
|
|
6
6
|
def initialize
|
|
7
|
-
|
|
7
|
+
@file_hash_cache = {}
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def clear!
|
|
11
11
|
raise 'abstract'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
# Note: This could lead to slight race on redis
|
|
15
|
+
# where multiple processes pull the old coverage and add to it then push
|
|
16
|
+
# the Coverband 2 had the same issue,
|
|
17
|
+
# and the tradeoff has always been acceptable
|
|
18
|
+
def save_report(report)
|
|
19
|
+
data = report.dup
|
|
20
|
+
merge_reports(data, get_report)
|
|
21
|
+
save_coverage(data)
|
|
16
22
|
end
|
|
17
23
|
|
|
18
24
|
def coverage
|
|
19
|
-
|
|
25
|
+
simple_report(get_report)
|
|
20
26
|
end
|
|
21
27
|
|
|
22
28
|
def covered_files
|
|
29
|
+
coverage.keys || []
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def covered_lines_for_file(file)
|
|
33
|
+
coverage[file] || []
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
protected
|
|
37
|
+
|
|
38
|
+
def save_coverage
|
|
23
39
|
raise 'abstract'
|
|
24
40
|
end
|
|
25
41
|
|
|
26
|
-
def
|
|
42
|
+
def get_report
|
|
27
43
|
raise 'abstract'
|
|
28
44
|
end
|
|
29
45
|
|
|
30
|
-
|
|
46
|
+
def file_hash(file)
|
|
47
|
+
@file_hash_cache[file] ||= Digest::MD5.file(file).hexdigest
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def expand_report(report)
|
|
51
|
+
report_time = Time.now.to_i
|
|
52
|
+
report.each_pair do |key, line_data|
|
|
53
|
+
extended_data = {
|
|
54
|
+
'first_updated_at' => report_time,
|
|
55
|
+
'last_updated_at' => report_time,
|
|
56
|
+
'file_hash' => file_hash(key),
|
|
57
|
+
'data' => line_data
|
|
58
|
+
}
|
|
59
|
+
report[key] = extended_data
|
|
60
|
+
end
|
|
61
|
+
end
|
|
31
62
|
|
|
32
63
|
def merge_reports(new_report, old_report)
|
|
64
|
+
new_report = expand_report(new_report)
|
|
33
65
|
keys = (new_report.keys + old_report.keys).uniq
|
|
34
66
|
keys.each do |file|
|
|
35
|
-
new_report[file] = if new_report[file] &&
|
|
36
|
-
|
|
67
|
+
new_report[file] = if new_report[file] &&
|
|
68
|
+
old_report[file] &&
|
|
69
|
+
new_report[file]['file_hash'] == old_report[file]['file_hash']
|
|
70
|
+
merge_expanded_data(new_report[file], old_report[file])
|
|
37
71
|
elsif new_report[file]
|
|
38
72
|
new_report[file]
|
|
39
73
|
else
|
|
@@ -43,9 +77,24 @@ module Coverband
|
|
|
43
77
|
new_report
|
|
44
78
|
end
|
|
45
79
|
|
|
80
|
+
def merge_expanded_data(new_expanded, old_expanded)
|
|
81
|
+
{
|
|
82
|
+
'first_updated_at' => old_expanded['first_updated_at'],
|
|
83
|
+
'last_updated_at' => new_expanded['last_updated_at'],
|
|
84
|
+
'file_hash' => new_expanded['file_hash'],
|
|
85
|
+
'data' => array_add(new_expanded['data'], old_expanded['data'])
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
|
|
46
89
|
def array_add(latest, original)
|
|
47
90
|
latest.map.with_index { |v, i| (v && original[i]) ? v + original[i] : nil }
|
|
48
91
|
end
|
|
92
|
+
|
|
93
|
+
def simple_report(report)
|
|
94
|
+
report.each_with_object({}) do |(key, extended_data), simple|
|
|
95
|
+
simple[key] = extended_data['data']
|
|
96
|
+
end
|
|
97
|
+
end
|
|
49
98
|
end
|
|
50
99
|
end
|
|
51
100
|
end
|
|
@@ -8,9 +8,8 @@ module Coverband
|
|
|
8
8
|
# Not recommended for production deployment
|
|
9
9
|
###
|
|
10
10
|
class FileStore < Base
|
|
11
|
-
attr_accessor :path
|
|
12
|
-
|
|
13
11
|
def initialize(path, _opts = {})
|
|
12
|
+
super()
|
|
14
13
|
@path = path
|
|
15
14
|
|
|
16
15
|
config_dir = File.dirname(@path)
|
|
@@ -21,32 +20,15 @@ module Coverband
|
|
|
21
20
|
File.delete(path) if File.exist?(path)
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
def save_report(report)
|
|
25
|
-
merge_reports(report, coverage)
|
|
26
|
-
save_coverage(report)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def coverage
|
|
30
|
-
existing_data(path)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def covered_files
|
|
34
|
-
report = existing_data(path)
|
|
35
|
-
existing_data(path).merge(report).keys || []
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def covered_lines_for_file(file)
|
|
39
|
-
report = existing_data(path)
|
|
40
|
-
report[file] || []
|
|
41
|
-
end
|
|
42
|
-
|
|
43
23
|
private
|
|
44
24
|
|
|
25
|
+
attr_accessor :path
|
|
26
|
+
|
|
45
27
|
def save_coverage(report)
|
|
46
28
|
File.open(path, 'w') { |f| f.write(report.to_json) }
|
|
47
29
|
end
|
|
48
30
|
|
|
49
|
-
def
|
|
31
|
+
def get_report
|
|
50
32
|
if File.exist?(path)
|
|
51
33
|
JSON.parse(File.read(path))
|
|
52
34
|
else
|
|
@@ -6,9 +6,10 @@ module Coverband
|
|
|
6
6
|
# RedisStore store a merged coverage file to redis
|
|
7
7
|
###
|
|
8
8
|
class RedisStore < Base
|
|
9
|
-
BASE_KEY = '
|
|
9
|
+
BASE_KEY = 'coverband3_1'
|
|
10
10
|
|
|
11
11
|
def initialize(redis, opts = {})
|
|
12
|
+
super()
|
|
12
13
|
@redis = redis
|
|
13
14
|
@ttl = opts[:ttl]
|
|
14
15
|
@redis_namespace = opts[:redis_namespace]
|
|
@@ -18,27 +19,6 @@ module Coverband
|
|
|
18
19
|
@redis.del(base_key)
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
def save_report(report)
|
|
22
|
-
# Note: This could lead to slight races
|
|
23
|
-
# where multiple processes pull the old coverage and add to it then push
|
|
24
|
-
# the Coverband 2 had the same issue,
|
|
25
|
-
# and the tradeoff has always been acceptable
|
|
26
|
-
merge_reports(report, coverage)
|
|
27
|
-
save_coverage(base_key, report)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def coverage
|
|
31
|
-
get_report(base_key)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def covered_files
|
|
35
|
-
coverage.keys
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def covered_lines_for_file(file)
|
|
39
|
-
coverage[file]
|
|
40
|
-
end
|
|
41
|
-
|
|
42
22
|
private
|
|
43
23
|
|
|
44
24
|
attr_reader :redis
|
|
@@ -47,13 +27,13 @@ module Coverband
|
|
|
47
27
|
@base_key ||= [BASE_KEY, @redis_namespace].compact.join('.')
|
|
48
28
|
end
|
|
49
29
|
|
|
50
|
-
def save_coverage(
|
|
51
|
-
redis.set
|
|
52
|
-
redis.expire(
|
|
30
|
+
def save_coverage(data)
|
|
31
|
+
redis.set base_key, data.to_json
|
|
32
|
+
redis.expire(base_key, @ttl) if @ttl
|
|
53
33
|
end
|
|
54
34
|
|
|
55
|
-
def get_report
|
|
56
|
-
data = redis.get
|
|
35
|
+
def get_report
|
|
36
|
+
data = redis.get base_key
|
|
57
37
|
data ? JSON.parse(data) : {}
|
|
58
38
|
end
|
|
59
39
|
end
|
|
@@ -24,12 +24,16 @@ module Coverband
|
|
|
24
24
|
@verbose = Coverband.configuration.verbose
|
|
25
25
|
@logger = Coverband.configuration.logger
|
|
26
26
|
@current_thread = Thread.current
|
|
27
|
+
@test_env = Coverband.configuration.test_env
|
|
28
|
+
@background_reporting_enabled = Coverband.configuration.background_reporting_enabled
|
|
27
29
|
Thread.current[:coverband_instance] = nil
|
|
28
30
|
self
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def report_coverage(force_report = false)
|
|
34
|
+
return Background.start if @background_reporting_enabled
|
|
32
35
|
return if !ready_to_report? && !force_report
|
|
36
|
+
|
|
33
37
|
unless @store
|
|
34
38
|
@logger.debug 'no store set, no-op'
|
|
35
39
|
return
|
|
@@ -44,6 +48,7 @@ module Coverband
|
|
|
44
48
|
@logger.error "error: #{err.inspect} #{err.message}"
|
|
45
49
|
@logger.error err.backtrace
|
|
46
50
|
end
|
|
51
|
+
raise err if @test_env
|
|
47
52
|
end
|
|
48
53
|
|
|
49
54
|
protected
|
|
@@ -7,7 +7,8 @@ module Coverband
|
|
|
7
7
|
:reporter, :reporting_frequency,
|
|
8
8
|
:disable_on_failure_for,
|
|
9
9
|
:redis_namespace, :redis_ttl,
|
|
10
|
-
:safe_reload_files
|
|
10
|
+
:safe_reload_files, :background_reporting_enabled,
|
|
11
|
+
:background_reporting_sleep_seconds, :test_env
|
|
11
12
|
|
|
12
13
|
attr_writer :logger, :s3_region, :s3_bucket, :s3_access_key_id, :s3_secret_access_key
|
|
13
14
|
|
|
@@ -29,6 +30,8 @@ module Coverband
|
|
|
29
30
|
@s3_secret_access_key = nil
|
|
30
31
|
@redis_namespace = nil
|
|
31
32
|
@redis_ttl = nil
|
|
33
|
+
@test_env = nil
|
|
34
|
+
@background_reporting_sleep_seconds = 30
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
def logger
|
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
module Coverband
|
|
4
4
|
class Background
|
|
5
|
-
|
|
5
|
+
@semaphore = Mutex.new
|
|
6
|
+
|
|
7
|
+
def self.start
|
|
8
|
+
return if @background_reporting_running
|
|
9
|
+
|
|
10
|
+
logger = Coverband.configuration.logger
|
|
11
|
+
@semaphore.synchronize do
|
|
12
|
+
return if @background_reporting_running
|
|
13
|
+
|
|
14
|
+
@background_reporting_running = true
|
|
15
|
+
sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds
|
|
16
|
+
Thread.new do
|
|
17
|
+
loop do
|
|
18
|
+
Coverband::Collectors::Coverage.instance.report_coverage
|
|
19
|
+
logger&.debug("Reported coverage from thread. Sleeping for #{sleep_seconds} seconds")
|
|
20
|
+
sleep(sleep_seconds)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
at_exit do
|
|
25
|
+
Coverband::Collectors::Coverage.instance.report_coverage
|
|
26
|
+
logger&.debug("Reported coverage before exit")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
6
30
|
end
|
|
7
31
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coverband
|
|
4
|
+
class RackServerCheck
|
|
5
|
+
def self.running?
|
|
6
|
+
new(Kernel.caller_locations).running?
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(stack)
|
|
10
|
+
@stack = stack
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def running?
|
|
14
|
+
rack_server? || rails_server?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def rack_server?
|
|
18
|
+
@stack.any? { |line| line.path.include?('lib/rack/') }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def rails_server?
|
|
22
|
+
@stack.any? do |location|
|
|
23
|
+
location.path.include?('rails/commands/commands_tasks.rb') && location.label == 'server'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -38,13 +38,7 @@ module Coverband
|
|
|
38
38
|
Coverband.configuration.logger.info "report is ready and viewable: open #{SimpleCov.coverage_dir}/index.html"
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
region: Coverband.configuration.s3_region,
|
|
43
|
-
access_key_id: Coverband.configuration.s3_access_key_id,
|
|
44
|
-
secret_access_key: Coverband.configuration.s3_secret_access_key
|
|
45
|
-
}
|
|
46
|
-
Coverband::Utils::S3ReportWriter.new(Coverband.configuration.s3_bucket,
|
|
47
|
-
s3_writer_options).persist! if Coverband.configuration.s3_bucket
|
|
41
|
+
Coverband::Utils::S3Report.instance.persist! if Coverband.configuration.s3_bucket
|
|
48
42
|
end
|
|
49
43
|
end
|
|
50
44
|
end
|