coverband 4.1.1 → 4.2.0
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 +4 -4
- data/.gitignore +2 -0
- data/README.md +50 -43
- data/changes.md +31 -4
- data/lib/coverband/adapters/base.rb +24 -1
- data/lib/coverband/adapters/redis_store.rb +28 -7
- data/lib/coverband/at_exit.rb +19 -2
- data/lib/coverband/collectors/coverage.rb +35 -79
- data/lib/coverband/collectors/delta.rb +67 -0
- data/lib/coverband/integrations/background.rb +4 -3
- data/lib/coverband/integrations/rack_server_check.rb +4 -1
- data/lib/coverband/integrations/resque.rb +4 -0
- data/lib/coverband/reporters/base.rb +21 -14
- data/lib/coverband/reporters/html_report.rb +40 -15
- data/lib/coverband/reporters/web.rb +29 -6
- data/lib/coverband/utils/html_formatter.rb +20 -4
- data/lib/coverband/utils/railtie.rb +8 -0
- data/lib/coverband/utils/result.rb +3 -2
- data/lib/coverband/utils/results.rb +63 -0
- data/lib/coverband/utils/source_file.rb +5 -0
- data/lib/coverband/version.rb +1 -1
- data/lib/coverband.rb +23 -3
- data/public/application.css +5 -0
- data/public/application.js +108 -1644
- data/public/dependencies.js +1581 -0
- data/test/coverband/adapters/redis_store_test.rb +26 -9
- data/test/coverband/collectors/coverage_test.rb +15 -9
- data/test/coverband/collectors/delta_test.rb +52 -0
- data/test/coverband/coverband_test.rb +7 -0
- data/test/coverband/integrations/background_test.rb +14 -11
- data/test/coverband/integrations/middleware_test.rb +1 -0
- data/test/coverband/integrations/resque_worker_test.rb +7 -1
- data/test/coverband/reporters/base_test.rb +4 -4
- data/test/coverband/reporters/console_test.rb +1 -1
- data/test/coverband/reporters/html_test.rb +6 -7
- data/test/integration/full_stack_test.rb +10 -8
- data/test/integration/rails_full_stack_test.rb +23 -4
- data/test/rails4_dummy/config/application.rb +1 -1
- data/test/rails4_dummy/config/coverband.rb +4 -1
- data/test/rails5_dummy/config/application.rb +1 -1
- data/test/rails5_dummy/config/coverband.rb +3 -1
- data/test/rails_test_helper.rb +13 -8
- data/test/test_helper.rb +8 -1
- data/views/file_list.erb +9 -0
- data/views/gem_list.erb +1 -1
- data/views/layout.erb +4 -3
- data/views/source_file.erb +16 -4
- data/views/source_file_loader.erb +7 -0
- metadata +8 -4
- data/test/integration/rails_gems_full_stack_test.rb +0 -36
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e214b1bd6119046657daa64ed6d69f77f821c6c670b72e98d307ede5f08e61f
|
|
4
|
+
data.tar.gz: 469d9470799f90b5b52d53d3a630fae75b3b6bff0390375987902331878f530e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f1b0f503941ab9dbc2dee6a184fe6d6d937a5f505a5c9112ae7343197372586d6cb42df758f24effde0ee30fb359c0e2e651c64a1f5ee4c9a588a4499683dc73
|
|
7
|
+
data.tar.gz: ee700abfe4c730011dcc5c1c8521f55a2cc7ec5149e44b08187c8d09419023160a0f7c8aaba4b2aa0bb405eb13f4aeee1d8ce9cabce4860738d4ea94cac63c04
|
data/.gitignore
CHANGED
data/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<img src="https://raw.github.com/danmayer/coverband/master/docs/assets/logo/heads.svg?sanitize=true" width='300'>
|
|
2
|
+
|
|
1
3
|
# Coverband
|
|
2
4
|
|
|
3
5
|
[](https://travis-ci.org/danmayer/coverband)
|
|
@@ -15,24 +17,24 @@
|
|
|
15
17
|
|
|
16
18
|
A gem to measure production code usage, showing a counter for the number of times each line of code that is executed. Coverband allows easy configuration to collect and report on production code usage. It reports in the background via a thread or can be used as Rack middleware, or manually configured to meet any need.
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
**Note:** Coverband is not intended for test code coverage, for that we recommended using [SimpleCov](https://github.com/colszowka/simplecov).
|
|
19
21
|
|
|
20
22
|
## Key Features
|
|
21
23
|
|
|
22
24
|
The primary goal of Coverband is giving deep insight into your production runtime usage of your application code, while having the least impact on performance possible.
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
- Low performance overhead
|
|
27
|
+
- Very simple setup and configuration
|
|
28
|
+
- Out of the box support for all standard code execution paths (web, cron, background jobs, rake tasks, etc)
|
|
29
|
+
- Easy to understand actionable insights from the report
|
|
30
|
+
- Development mode, offers deep insight of code usage details (number of LOC execution during single request, etc) during development.
|
|
31
|
+
- Mountable web interface to easily share reports
|
|
30
32
|
|
|
31
33
|
# Installation
|
|
32
34
|
|
|
33
35
|
## Redis
|
|
34
36
|
|
|
35
|
-
Coverband stores coverage data in Redis. The Redis endpoint is looked for in this order:
|
|
37
|
+
Coverband stores coverage data in Redis. The Redis endpoint is looked for in this order:
|
|
36
38
|
|
|
37
39
|
1. `ENV['COVERBAND_REDIS_URL']`
|
|
38
40
|
2. `ENV['REDIS_URL']`
|
|
@@ -54,7 +56,6 @@ If [tracking gem usage](#collecting-gem--library-usage), be sure to include cove
|
|
|
54
56
|
|
|
55
57
|
The Railtie integration means you shouldn't need to do anything anything else other than ensure coverband is required after rails within your Gemfile.
|
|
56
58
|
|
|
57
|
-
|
|
58
59
|
## Sinatra
|
|
59
60
|
|
|
60
61
|
For the best coverage you want this loaded as early as possible. I have been putting it directly in my `config.ru` but you could use an initializer, though you may end up missing some boot up coverage. To start collection require Coverband as early as possible.
|
|
@@ -77,7 +78,7 @@ Rails.application.routes.draw do
|
|
|
77
78
|
end
|
|
78
79
|
```
|
|
79
80
|
|
|
80
|
-
But don't forget to
|
|
81
|
+
But don't forget to _protect your source code with proper authentication_. Something like this when using devise:
|
|
81
82
|
|
|
82
83
|
```ruby
|
|
83
84
|
Rails.application.routes.draw do
|
|
@@ -92,11 +93,12 @@ end
|
|
|
92
93
|
The web endpoint is a barebones endpoint that you can either expose direct (after authentication) or you can just link to the actions you wish to expose. The index is intended as a example to showcase all the features.
|
|
93
94
|
|
|
94
95
|

|
|
96
|
+
|
|
95
97
|
> The web index as available on the Coverband Demo site
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
- **force coverage collection:** This triggers coverage collection on the current webserver process
|
|
100
|
+
- **reload Coverband files:** This has Coverband reload files as configured (force reload of some files that might not capture Coverage on boot). This can be used to reload files on demand.
|
|
101
|
+
- **clear coverage report:** This will clear the coverage data. This wipes out all collected data (**dangerous**)
|
|
100
102
|
|
|
101
103
|
### Rake Tasks
|
|
102
104
|
|
|
@@ -118,17 +120,16 @@ Details on an example Sinatra app
|
|
|
118
120
|
|
|
119
121
|
# Verify Correct Installation
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
- boot up your application
|
|
124
|
+
- run app and hit a controller (via a web request, at least one request must complete)
|
|
125
|
+
- run `rake coverband:coverage` this will show app initialization coverage
|
|
126
|
+
- make another request, or enough that your reporting frequency will trigger
|
|
127
|
+
- run `rake coverband:coverage` and you should see coverage increasing for the endpoints you hit.
|
|
126
128
|
|
|
127
129
|
# Coverband Demo
|
|
128
130
|
|
|
129
131
|
Take Coverband for a spin on the live Heroku deployed [Coverband Demo](https://coverband-demo.herokuapp.com/). The [full source code for the demo](https://github.com/danmayer/coverband_demo) is available to help with installation, configuration, and understanding of basic usage.
|
|
130
132
|
|
|
131
|
-
|
|
132
133
|
### Example apps
|
|
133
134
|
|
|
134
135
|
- [Rails 5.2.x App](https://github.com/danmayer/coverband_demo)
|
|
@@ -137,14 +138,12 @@ Take Coverband for a spin on the live Heroku deployed [Coverband Demo](https://c
|
|
|
137
138
|
|
|
138
139
|
# Advanced Config
|
|
139
140
|
|
|
140
|
-
|
|
141
141
|
If you need to configure coverband, this can be done by creating a `config/coverband.rb` file relative to your project root.
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
* Redis endpoint is looked for in this order: `ENV['COVERBAND_REDIS_URL']`, `ENV['REDIS_URL']`, or `localhost`
|
|
143
|
+
- See [lib/coverband/configuration.rb](https://github.com/danmayer/coverband/blob/master/lib/coverband/configuration.rb) for all options
|
|
144
|
+
- By default Coverband will try to stored data to Redis \* Redis endpoint is looked for in this order: `ENV['COVERBAND_REDIS_URL']`, `ENV['REDIS_URL']`, or `localhost`
|
|
146
145
|
|
|
147
|
-
|
|
146
|
+
Below is an example config file for a Rails 5 app:
|
|
148
147
|
|
|
149
148
|
```ruby
|
|
150
149
|
#config/coverband.rb
|
|
@@ -170,14 +169,12 @@ end
|
|
|
170
169
|
Sometimes you have files that are known to be valuable perhaps in other environments or something that is just run very infrequently. Opposed to having to mentally filter them out of the report, you can just have them ignored in the Coverband reporting by using `config.ignore` as shown below. Ignore takes a string but can also match with regex rules see how below ignores all rake tasks as an example.
|
|
171
170
|
|
|
172
171
|
```
|
|
173
|
-
config.ignore
|
|
172
|
+
config.ignore += ['config/application.rb',
|
|
174
173
|
'config/boot.rb',
|
|
175
174
|
'config/puma.rb',
|
|
176
175
|
'config/schedule.rb',
|
|
177
|
-
'
|
|
178
|
-
'config/environments
|
|
179
|
-
'config/environments/staging.rb',
|
|
180
|
-
'config/environments/production.rb',
|
|
176
|
+
'bin/*'
|
|
177
|
+
'config/environments/*',
|
|
181
178
|
'lib/tasks/*']
|
|
182
179
|
```
|
|
183
180
|
|
|
@@ -208,8 +205,7 @@ Between the release of 4.0 and 4.1 our data format changed. This resets all your
|
|
|
208
205
|
|
|
209
206
|
`rake coverband:migrate`
|
|
210
207
|
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
- We will be working to support migrations going forward, when possible
|
|
213
209
|
|
|
214
210
|
### Clear Coverage
|
|
215
211
|
|
|
@@ -250,8 +246,8 @@ Coverband.configure do |config|
|
|
|
250
246
|
config.safe_reload_files = ['config/coverband.rb']
|
|
251
247
|
end
|
|
252
248
|
```
|
|
253
|
-
By adding any files above you will get reporting on those files as part of your coverage runtime report. The files are reloaded when Coverband first starts, you can also trigger a reload via the web interface.
|
|
254
249
|
|
|
250
|
+
By adding any files above you will get reporting on those files as part of your coverage runtime report. The files are reloaded when Coverband first starts, you can also trigger a reload via the web interface.
|
|
255
251
|
|
|
256
252
|
### Collecting Gem / Library Usage
|
|
257
253
|
|
|
@@ -278,6 +274,17 @@ end
|
|
|
278
274
|
|
|
279
275
|
This flag exposes line by line usage of gem files. Unfortunately due to the way the coverband report is currently rendered, enabling `gem_details` slows down viewing of the coverage report in the browser and is not yet recommended.
|
|
280
276
|
|
|
277
|
+
### Manually Starting Coverband
|
|
278
|
+
|
|
279
|
+
Coverband starts on require of the the library which is usually done within the Gemfile. This can be disabled by setting the `COVERBAND_DISABLE_AUTO_START` environment variable. This environment variable can be useful to toggle coverband on and off in certain environments.
|
|
280
|
+
|
|
281
|
+
In order to start coverband manually yourself when this flag is enabled, call `Coverband.configure` followed by `Coverband.start`.
|
|
282
|
+
|
|
283
|
+
```ruby
|
|
284
|
+
Coverband.configure
|
|
285
|
+
Coverband.start
|
|
286
|
+
```
|
|
287
|
+
|
|
281
288
|
### Verbose Debug / Development Mode
|
|
282
289
|
|
|
283
290
|
Note: To debug issues getting Coverband working. I recommend running in development mode, by turning verbose logging on `config.verbose = true` and passing in the Rails.logger `config.logger = Rails.logger` to the Coverband config. This makes it easy to follow in development mode. Be careful to not leave these on in production as they will affect performance.
|
|
@@ -304,8 +311,8 @@ If you are trying to debug locally wondering what code is being run during a req
|
|
|
304
311
|
|
|
305
312
|
# Prerequisites
|
|
306
313
|
|
|
307
|
-
|
|
308
|
-
|
|
314
|
+
- Coverband 3.0.X+ requires Ruby 2.3+
|
|
315
|
+
- Coverband currently requires Redis for production usage
|
|
309
316
|
|
|
310
317
|
# Contributing To Coverband
|
|
311
318
|
|
|
@@ -322,18 +329,18 @@ If you are working on adding features, PRs, or bugfixes to Coverband this sectio
|
|
|
322
329
|
|
|
323
330
|
If you submit a change please make sure the tests and benchmarks are passing.
|
|
324
331
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
332
|
+
- run tests:
|
|
333
|
+
- `bundle exec rake`
|
|
334
|
+
- `BUNDLE_GEMFILE=Gemfile.rails4 bundle exec rake` (Same tests using rails 4 instead of 5)
|
|
335
|
+
- view test coverage: `open coverage/index.html`
|
|
336
|
+
- run the benchmarks before and after your change to see impact
|
|
337
|
+
- `rake benchmarks`
|
|
331
338
|
|
|
332
339
|
### Known Issues
|
|
333
340
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
341
|
+
- **total fail** on front end code, because of the precompiled template step basically coverage doesn't work well for `erb`, `slim`, and the like.
|
|
342
|
+
- related it will try to report something, but the line numbers reported for `ERB` files are often off and aren't considered useful. I recommend filtering out .erb using the `config.ignore` option. The default configuration excludes these files
|
|
343
|
+
- coverage doesn't show for Rails `config/application.rb` or `config/boot.rb` as they get loaded when loading the Rake environment prior to starting the `Coverage` library. See [reload files section](#forcing-coverband-to-track-coverage-on-files-loaded-during-boot-safe_reload_files).
|
|
337
344
|
|
|
338
345
|
### Debugging Redis Store
|
|
339
346
|
|
data/changes.md
CHANGED
|
@@ -37,6 +37,16 @@ Will be the fully modern release that drops maintenance legacy support in favor
|
|
|
37
37
|
- See if we can add support for views / templates
|
|
38
38
|
- using this technique https://github.com/ioquatix/covered
|
|
39
39
|
- Better default grouping (could use groups features for gems for rails controllers, models, lib, etc)
|
|
40
|
+
- Improved logging for easier debugging and development
|
|
41
|
+
- drop the verbose mode and better support standard logger levels
|
|
42
|
+
- Possibly setup a build assets system
|
|
43
|
+
- my JS rules expanded the compressed JS at the top of application.js, basically we want to stitch together JS
|
|
44
|
+
- I guess we could also load multiple JS files as most of the JS is just default compressed JS and a tiny amount of actual app JS.
|
|
45
|
+
- lazy load for Coverband results
|
|
46
|
+
- view layer file coverage
|
|
47
|
+
- move all code to work with relative paths leaving only stdlib Coverage working on full paths
|
|
48
|
+
- add gem_safe_lists to track only some gems
|
|
49
|
+
- add gem_details_safe list to report on details on some gems
|
|
40
50
|
|
|
41
51
|
### Coverband_jam_session
|
|
42
52
|
|
|
@@ -63,14 +73,31 @@ Feature Ideas:
|
|
|
63
73
|
|
|
64
74
|
# Alpha
|
|
65
75
|
|
|
66
|
-
### Coverband 4.
|
|
76
|
+
### Coverband 4.3.0?
|
|
67
77
|
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
- perf speedup on gem details views
|
|
78
|
+
- further improvements on eager_loading detection
|
|
79
|
+
- ?
|
|
71
80
|
|
|
72
81
|
# Released
|
|
73
82
|
|
|
83
|
+
### Coverband 4.2.0
|
|
84
|
+
|
|
85
|
+
**NOTE:** This release introduces load time and runtime Coverage. To get the full benifit of this feature you need to reset you coverage data (`rake coverband:clear` or clear via the web UI). Until you clear the combined result is still correct, but your runtime data will be mixed with previous data. This is due to an additive change in how we store coverage. We didn't reset by default as the coverage history for some folks may be more important than runtime breakdown.
|
|
86
|
+
|
|
87
|
+
- loadtime vs runtime coverage
|
|
88
|
+
- This fixes the coverage last seen date to exclude just load time data
|
|
89
|
+
- now you can see boot time coverage vs code hit during production execution
|
|
90
|
+
- list view shows runtime percentage and runtime hits
|
|
91
|
+
- file view shows line hits load, runtime, and combined
|
|
92
|
+
- perf speedup on gem details views
|
|
93
|
+
- ajax load code views for more responsive pages on large projects
|
|
94
|
+
- fix for issues with COVERBAND_DISABLE_AUTO_START
|
|
95
|
+
- silence warnings
|
|
96
|
+
- move from thread based reporter instance to process based instance
|
|
97
|
+
- thanks Karl Baum for much of the above mentioned work
|
|
98
|
+
- clear coverage on individual files
|
|
99
|
+
- we have a logo, thanks Dave Woodall
|
|
100
|
+
|
|
74
101
|
### Coverband 4.1.1
|
|
75
102
|
|
|
76
103
|
- fix bug on info page when using namespaces
|
|
@@ -4,6 +4,7 @@ module Coverband
|
|
|
4
4
|
module Adapters
|
|
5
5
|
class Base
|
|
6
6
|
include Coverband::Utils::FilePathHelper
|
|
7
|
+
attr_accessor :type
|
|
7
8
|
|
|
8
9
|
def initialize
|
|
9
10
|
@file_hash_cache = {}
|
|
@@ -13,6 +14,10 @@ module Coverband
|
|
|
13
14
|
raise 'abstract'
|
|
14
15
|
end
|
|
15
16
|
|
|
17
|
+
def clear_file!(_file)
|
|
18
|
+
raise 'abstract'
|
|
19
|
+
end
|
|
20
|
+
|
|
16
21
|
def migrate!
|
|
17
22
|
raise 'abstract'
|
|
18
23
|
end
|
|
@@ -39,6 +44,11 @@ module Coverband
|
|
|
39
44
|
get_report
|
|
40
45
|
end
|
|
41
46
|
|
|
47
|
+
def get_coverage_report
|
|
48
|
+
data = Coverband.configuration.store.split_coverage(Coverband::TYPES)
|
|
49
|
+
data.merge(Coverband::MERGED_TYPE => Coverband.configuration.store.merged_coverage(Coverband::TYPES))
|
|
50
|
+
end
|
|
51
|
+
|
|
42
52
|
def covered_files
|
|
43
53
|
coverage.keys || []
|
|
44
54
|
end
|
|
@@ -50,6 +60,18 @@ module Coverband
|
|
|
50
60
|
|
|
51
61
|
protected
|
|
52
62
|
|
|
63
|
+
def split_coverage(types)
|
|
64
|
+
types.reduce({}) do |data, type|
|
|
65
|
+
data.update(type => get_report(type))
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def merged_coverage(types)
|
|
70
|
+
types.reduce({}) do |data, type|
|
|
71
|
+
merge_reports(data, get_report(type), skip_expansion: true)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
53
75
|
def save_coverage
|
|
54
76
|
raise 'abstract'
|
|
55
77
|
end
|
|
@@ -65,10 +87,11 @@ module Coverband
|
|
|
65
87
|
def expand_report(report)
|
|
66
88
|
expanded = {}
|
|
67
89
|
report_time = Time.now.to_i
|
|
90
|
+
updated_time = self.type == Coverband::EAGER_TYPE ? nil : report_time
|
|
68
91
|
report.each_pair do |key, line_data|
|
|
69
92
|
extended_data = {
|
|
70
93
|
'first_updated_at' => report_time,
|
|
71
|
-
'last_updated_at' =>
|
|
94
|
+
'last_updated_at' => updated_time,
|
|
72
95
|
'file_hash' => file_hash(key),
|
|
73
96
|
'data' => line_data
|
|
74
97
|
}
|
|
@@ -22,7 +22,17 @@ module Coverband
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def clear!
|
|
25
|
-
|
|
25
|
+
Coverband::TYPES.each do |type|
|
|
26
|
+
@redis.del(type_base_key(type))
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def clear_file!(filename)
|
|
31
|
+
Coverband::TYPES.each do |type|
|
|
32
|
+
data = get_report(type)
|
|
33
|
+
data.delete(filename)
|
|
34
|
+
save_coverage(data, type)
|
|
35
|
+
end
|
|
26
36
|
end
|
|
27
37
|
|
|
28
38
|
def size
|
|
@@ -51,6 +61,11 @@ module Coverband
|
|
|
51
61
|
save_coverage(merge_reports(get_report, relative_path_report, skip_expansion: true))
|
|
52
62
|
end
|
|
53
63
|
|
|
64
|
+
def type=(type)
|
|
65
|
+
super
|
|
66
|
+
reset_base_key
|
|
67
|
+
end
|
|
68
|
+
|
|
54
69
|
private
|
|
55
70
|
|
|
56
71
|
attr_reader :redis
|
|
@@ -60,16 +75,22 @@ module Coverband
|
|
|
60
75
|
end
|
|
61
76
|
|
|
62
77
|
def base_key
|
|
63
|
-
@base_key ||= [@format_version, @redis_namespace].compact.join('.')
|
|
78
|
+
@base_key ||= [@format_version, @redis_namespace, type].compact.join('.')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def type_base_key(local_type)
|
|
82
|
+
[@format_version, @redis_namespace, local_type].compact.join('.')
|
|
64
83
|
end
|
|
65
84
|
|
|
66
|
-
def save_coverage(data)
|
|
67
|
-
|
|
68
|
-
redis.
|
|
85
|
+
def save_coverage(data, local_type = nil)
|
|
86
|
+
local_type ||= type
|
|
87
|
+
redis.set type_base_key(local_type), data.to_json
|
|
88
|
+
redis.expire(type_base_key(local_type), @ttl) if @ttl
|
|
69
89
|
end
|
|
70
90
|
|
|
71
|
-
def get_report
|
|
72
|
-
|
|
91
|
+
def get_report(local_type = nil)
|
|
92
|
+
local_type ||= type
|
|
93
|
+
data = redis.get type_base_key(local_type)
|
|
73
94
|
data ? JSON.parse(data) : {}
|
|
74
95
|
end
|
|
75
96
|
end
|
data/lib/coverband/at_exit.rb
CHANGED
|
@@ -4,15 +4,32 @@ module Coverband
|
|
|
4
4
|
class AtExit
|
|
5
5
|
@semaphore = Mutex.new
|
|
6
6
|
|
|
7
|
+
@at_exit_registered = nil
|
|
7
8
|
def self.register
|
|
9
|
+
return if ENV['COVERBAND_DISABLE_AT_EXIT']
|
|
8
10
|
return if @at_exit_registered
|
|
11
|
+
|
|
9
12
|
@semaphore.synchronize do
|
|
10
13
|
return if @at_exit_registered
|
|
14
|
+
|
|
11
15
|
@at_exit_registered = true
|
|
12
16
|
at_exit do
|
|
13
17
|
::Coverband::Background.stop
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
#####
|
|
20
|
+
# TODO: This is is brittle and not a great solution to avoid deploy time
|
|
21
|
+
# actions polluting the 'runtime' metrics
|
|
22
|
+
#
|
|
23
|
+
# * should we skip /bin/rails webpacker:compile ?
|
|
24
|
+
# * Perhaps detect heroku deployment ENV var opposed to tasks?
|
|
25
|
+
#####
|
|
26
|
+
default_heroku_tasks = ['assets:clean', 'assets:precompile']
|
|
27
|
+
if defined?(Rake) && Rake.respond_to?(:application) && (Rake&.application&.top_level_tasks || []).any? { |task| default_heroku_tasks.include?(task) }
|
|
28
|
+
# skip reporting
|
|
29
|
+
else
|
|
30
|
+
Coverband.report_coverage(true)
|
|
31
|
+
#Coverband.configuration.logger&.debug('Coverband: Reported coverage before exit')
|
|
32
|
+
end
|
|
16
33
|
end
|
|
17
34
|
end
|
|
18
35
|
end
|
|
@@ -1,48 +1,60 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
require 'singleton'
|
|
3
|
+
require_relative 'delta'
|
|
2
4
|
|
|
3
5
|
module Coverband
|
|
4
6
|
module Collectors
|
|
5
7
|
###
|
|
6
|
-
#
|
|
7
|
-
# StandardError seems line be better option
|
|
8
|
+
# StandardError seems like be better option
|
|
8
9
|
# coverband previously had RuntimeError here
|
|
9
10
|
# but runtime error can let a large number of error crash this method
|
|
10
11
|
# and this method is currently in a ensure block in middleware and threads
|
|
11
12
|
###
|
|
12
13
|
class Coverage
|
|
13
|
-
|
|
14
|
-
Thread.current[:coverband_instance] ||= Coverband::Collectors::Coverage.new
|
|
15
|
-
end
|
|
14
|
+
include Singleton
|
|
16
15
|
|
|
17
16
|
def reset_instance
|
|
18
17
|
@project_directory = File.expand_path(Coverband.configuration.root)
|
|
19
|
-
@file_line_usage = {}
|
|
20
18
|
@ignore_patterns = Coverband.configuration.ignore + ['internal:prelude', 'schema.rb']
|
|
21
19
|
@reporting_frequency = Coverband.configuration.reporting_frequency
|
|
22
20
|
@store = Coverband.configuration.store
|
|
23
21
|
@verbose = Coverband.configuration.verbose
|
|
24
22
|
@logger = Coverband.configuration.logger
|
|
25
|
-
@current_thread = Thread.current
|
|
26
23
|
@test_env = Coverband.configuration.test_env
|
|
27
24
|
@track_gems = Coverband.configuration.track_gems
|
|
28
|
-
|
|
29
|
-
Thread.current[:coverband_instance] = nil
|
|
25
|
+
Delta.reset
|
|
30
26
|
self
|
|
31
27
|
end
|
|
32
28
|
|
|
29
|
+
def runtime!
|
|
30
|
+
@store.type = nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def eager_loading!
|
|
34
|
+
@store.type = Coverband::EAGER_TYPE
|
|
35
|
+
end
|
|
36
|
+
|
|
33
37
|
def report_coverage(force_report = false)
|
|
34
38
|
return if !ready_to_report? && !force_report
|
|
35
39
|
raise 'no Coverband store set' unless @store
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
original_previous_set = Delta.previous_results
|
|
42
|
+
files_with_line_usage = filtered_files(Delta.results)
|
|
43
|
+
|
|
44
|
+
###
|
|
45
|
+
# Hack to prevent processes and threads from reporting first Coverage hit
|
|
46
|
+
# when we are in runtime collection mode, which do not have a cache of previous
|
|
47
|
+
# coverage to remove the initial stdlib Coverage loading data
|
|
48
|
+
###
|
|
49
|
+
if ((original_previous_set.nil? && @store.type == Coverband::EAGER_TYPE) ||
|
|
50
|
+
(original_previous_set && @store.type != Coverband::EAGER_TYPE))
|
|
51
|
+
@store.save_report(files_with_line_usage)
|
|
52
|
+
end
|
|
41
53
|
rescue StandardError => err
|
|
42
54
|
if @verbose
|
|
43
|
-
@logger
|
|
44
|
-
@logger
|
|
45
|
-
@logger
|
|
55
|
+
@logger&.error 'coverage failed to store'
|
|
56
|
+
@logger&.error "error: #{err.inspect} #{err.message}"
|
|
57
|
+
@logger&.error err.backtrace
|
|
46
58
|
end
|
|
47
59
|
raise err if @test_env
|
|
48
60
|
end
|
|
@@ -59,81 +71,27 @@ module Coverband
|
|
|
59
71
|
@ignore_patterns.none? do |pattern|
|
|
60
72
|
file.include?(pattern)
|
|
61
73
|
end && (file.start_with?(@project_directory) ||
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
(@track_gems &&
|
|
75
|
+
Coverband.configuration.gem_paths.any? { |path| file.start_with?(path) }))
|
|
64
76
|
end
|
|
65
77
|
|
|
66
78
|
private
|
|
67
79
|
|
|
68
|
-
def
|
|
69
|
-
new_results.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
end
|
|
80
|
+
def filtered_files(new_results)
|
|
81
|
+
new_results.each_with_object({}) do |(file, line_counts), file_line_usage|
|
|
82
|
+
file_line_usage[file] = line_counts if track_file?(file)
|
|
83
|
+
end.select { |_file_name, coverage| coverage.any? { |value| value&.nonzero? } }
|
|
73
84
|
end
|
|
74
85
|
|
|
75
86
|
def ready_to_report?
|
|
76
87
|
(rand * 100.0) >= (100.0 - @reporting_frequency)
|
|
77
88
|
end
|
|
78
89
|
|
|
79
|
-
def get_new_coverage_results
|
|
80
|
-
@semaphore.synchronize { new_coverage(::Coverage.peek_result.dup) }
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def files_with_line_usage
|
|
84
|
-
@file_line_usage.select do |_file_name, coverage|
|
|
85
|
-
coverage.any? { |value| value&.nonzero? }
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def array_diff(latest, original)
|
|
90
|
-
latest.map.with_index do |v, i|
|
|
91
|
-
if (v && original[i])
|
|
92
|
-
[0, v - original[i]].max
|
|
93
|
-
else
|
|
94
|
-
nil
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def previous_results
|
|
100
|
-
@@previous_results
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def add_previous_results(val)
|
|
104
|
-
@@previous_results = val
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def new_coverage(current_coverage)
|
|
108
|
-
if previous_results
|
|
109
|
-
new_results = {}
|
|
110
|
-
current_coverage.each_pair do |file, line_counts|
|
|
111
|
-
if previous_results[file]
|
|
112
|
-
new_results[file] = array_diff(line_counts, previous_results[file])
|
|
113
|
-
else
|
|
114
|
-
new_results[file] = line_counts
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
else
|
|
118
|
-
new_results = current_coverage
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
add_previous_results(current_coverage)
|
|
122
|
-
new_results.dup
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def add_file(file, line_counts)
|
|
126
|
-
@file_line_usage[file] = line_counts
|
|
127
|
-
end
|
|
128
|
-
|
|
129
90
|
def initialize
|
|
130
91
|
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3.0')
|
|
131
92
|
raise NotImplementedError, 'not supported until Ruby 2.3.0 and later'
|
|
132
93
|
end
|
|
133
|
-
|
|
134
|
-
# puts 'loading coverage'
|
|
135
|
-
require 'coverage'
|
|
136
|
-
end
|
|
94
|
+
require 'coverage'
|
|
137
95
|
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
|
|
138
96
|
::Coverage.start unless ::Coverage.running?
|
|
139
97
|
else
|
|
@@ -144,8 +102,6 @@ module Coverband
|
|
|
144
102
|
load safe_file
|
|
145
103
|
end
|
|
146
104
|
end
|
|
147
|
-
@semaphore = Mutex.new
|
|
148
|
-
@@previous_results = nil
|
|
149
105
|
reset_instance
|
|
150
106
|
end
|
|
151
107
|
end
|