coverband 2.0.2 → 2.0.3.alpha

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d053a25d6140b3254fe2d2f1afa6a92fc06f0d3e
4
- data.tar.gz: 069d15a21f7c2909fcdcb7a2f955fecc2daef168
3
+ metadata.gz: f64bc911c54a44ba522c2e10ae79e0ce7d7d90e9
4
+ data.tar.gz: 84d3605cc8c8454ba045319a3b13ede37be8898d
5
5
  SHA512:
6
- metadata.gz: 8b4dfdbe5797949ab92ac9ec869f4fb4776162b0c681427436733fa4bbc4bdf4bf02be159559e8e1baf613704ecc8044256cd21e8dca3d6f3f575be00e7908f7
7
- data.tar.gz: de454d222f4545cd6db08d9043fe97a1d5aa71aa339c5c0b9b6cd5694d252cb344fca4183a6cb55c30e052a709ff251de9ebeb2d1e2c79d2572594faa3e1411f
6
+ metadata.gz: 4a0f028257b276cbadd8c721c21aa299431a2fb3f8cce233491da8443a769d7b425a3432ca3875081c44c72fd78d0398f24dceb0be4783241c67849bcbbc208f
7
+ data.tar.gz: dd05e38601f80feebe393b3c5d91769512980b68df15acf9ab3504f99997eadf77531810007f34cb3959c51e3a0dd4e0a42d1f10ad60fba84395645b862babda
data/changes.md CHANGED
@@ -16,7 +16,14 @@ Will be the fully modern release that drops maintenance legacy support in favor
16
16
 
17
17
  # Alpha
18
18
 
19
- ### ???
19
+ ### 3.0.0
20
+
21
+ * drop Tracepoint
22
+ * background thread reporter
23
+
24
+ # 2.0.3
25
+
26
+ * don''t include docs in the gemfile thanks @bquorning
20
27
 
21
28
 
22
29
  # Released
@@ -30,6 +37,7 @@ Will be the fully modern release that drops maintenance legacy support in favor
30
37
  * fix on baseline to show an issue by @viktor-silakov
31
38
  * remove all coverband:baseline related features and documentation
32
39
  * dropped Sinatra requirement for web mountable page
40
+ * fix on filestore by @danrabinowitz
33
41
  * fixes to the MemoryCacheStore by @kbaum
34
42
 
35
43
  ### 2.0.1
data/coverband.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = 'https://github.com/danmayer/coverband'
15
15
  spec.license = 'MIT'
16
16
 
17
- spec.files = `git ls-files`.split("\n")
17
+ spec.files = `git ls-files`.split("\n").reject { |f| f.start_with?('docs') }
18
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ['lib']
@@ -23,9 +23,10 @@ module Coverband
23
23
  def save_report(report)
24
24
  store_array(base_key, report.keys)
25
25
 
26
- report.each do |file, lines|
27
- store_map("#{base_key}.#{file}", lines)
28
- end
26
+ file_keys = report.keys.map {|file| "#{base_key}.#{file}"}
27
+ existing_records = existing_records(file_keys)
28
+ combined_report = combined_report(file_keys, report, existing_records)
29
+ pipelined_save(combined_report)
29
30
  end
30
31
 
31
32
  def coverage
@@ -47,16 +48,42 @@ module Coverband
47
48
  private
48
49
 
49
50
  attr_reader :redis
51
+
52
+ def pipelined_save(combined_report)
53
+ redis.pipelined do
54
+ combined_report.each do |file, values|
55
+ existing = values[:existing]
56
+ new = values[:new]
57
+ unless values.empty?
58
+ # in redis all file_keys are strings
59
+ new_string_values = Hash[new.map {|k, val| [k.to_s, val]}]
60
+ new_string_values.merge!(existing) {|_k, old_v, new_v| old_v.to_i + new_v.to_i}
61
+ redis.mapped_hmset(file, new_string_values)
62
+ redis.expire(file, @ttl) if @ttl
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ def existing_records(file_keys)
69
+ redis.pipelined do
70
+ file_keys.each do |key|
71
+ redis.hgetall(key)
72
+ end
73
+ end
74
+ end
75
+
76
+ def combined_report(file_keys, report, existing_records)
77
+ combined_report = {}
50
78
 
51
- def store_map(key, values)
52
- unless values.empty?
53
- existing = redis.hgetall(key)
54
- # in redis all keys are strings
55
- values = Hash[values.map { |k, val| [k.to_s, val] }]
56
- values.merge!(existing) { |_k, old_v, new_v| old_v.to_i + new_v.to_i }
57
- redis.mapped_hmset(key, values)
58
- redis.expire(key, @ttl) if @ttl
79
+ file_keys.each_with_index do |key, i|
80
+ combined_report[key] = {
81
+ new: report.values[i],
82
+ existing: existing_records[i]
83
+ }
59
84
  end
85
+
86
+ return combined_report
60
87
  end
61
88
 
62
89
  def store_array(key, values)
@@ -36,7 +36,7 @@ module Coverband
36
36
  end
37
37
 
38
38
  if @store
39
- @store.save_report(@file_line_usage)
39
+ @store.save_report(files_with_line_usage)
40
40
  @file_line_usage.clear
41
41
  elsif @verbose
42
42
  @logger.debug 'coverage report: '
@@ -57,6 +57,12 @@ module Coverband
57
57
 
58
58
  private
59
59
 
60
+ def files_with_line_usage
61
+ @file_line_usage.select do |_file_name, coverage|
62
+ coverage.values.any? { |value| value != 0 }
63
+ end
64
+ end
65
+
60
66
  def array_diff(latest, original)
61
67
  latest.map.with_index { |v, i| (v && original[i]) ? v - original[i] : nil }
62
68
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coverband
4
- VERSION = '2.0.2'
4
+ VERSION = '2.0.3.alpha'
5
5
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  namespace :benchmarks do
3
-
4
3
  # https://github.com/evanphx/benchmark-ips
5
4
  # Enable and start GC before each job run. Disable GC afterwards.
6
5
  #
@@ -48,7 +47,7 @@ namespace :benchmarks do
48
47
  require 'benchmark'
49
48
  require 'benchmark/ips'
50
49
 
51
- # TODO ok this is interesting and weird
50
+ # TODO: ok this is interesting and weird
52
51
  # basically the earlier I require coverage and
53
52
  # then require files the larger perf impact
54
53
  # this is somewhat expected but can lead to significant perf diffs
@@ -67,6 +66,16 @@ namespace :benchmarks do
67
66
  require File.join(File.dirname(__FILE__), 'dog')
68
67
  end
69
68
 
69
+ def benchmark_redis_store
70
+ redis = if ENV['REDIS_TEST_URL']
71
+ Redis.new(url: ENV['REDIS_TEST_URL'])
72
+ else
73
+ Redis.new
74
+ end
75
+ Coverband::Adapters::RedisStore.new(redis,
76
+ redis_namespace: 'coverband_bench')
77
+ end
78
+
70
79
  desc 'set up coverband tracepoint Redis'
71
80
  task :setup_redis do
72
81
  Coverband.configure do |config|
@@ -76,7 +85,7 @@ namespace :benchmarks do
76
85
  config.logger = $stdout
77
86
  config.collector = 'trace'
78
87
  config.memory_caching = ENV['MEMORY_CACHE'] ? true : false
79
- config.store = Coverband::Adapters::RedisStore.new(Redis.new)
88
+ config.store = benchmark_redis_store
80
89
  end
81
90
  end
82
91
 
@@ -88,7 +97,8 @@ namespace :benchmarks do
88
97
  config.logger = $stdout
89
98
  config.collector = 'trace'
90
99
  config.memory_caching = ENV['MEMORY_CACHE'] ? true : false
91
- config.store = Coverband::Adapters::FileStore.new('/tmp/benchmark_store.json')
100
+ file_path = '/tmp/benchmark_store.json'
101
+ config.store = Coverband::Adapters::FileStore.new(file_path)
92
102
  end
93
103
  end
94
104
 
@@ -104,7 +114,7 @@ namespace :benchmarks do
104
114
  config.logger = $stdout
105
115
  config.collector = 'coverage'
106
116
  config.memory_caching = ENV['MEMORY_CACHE'] ? true : false
107
- config.store = Coverband::Adapters::RedisStore.new(Redis.new)
117
+ config.store = benchmark_redis_store
108
118
  end
109
119
  end
110
120
 
@@ -138,12 +148,12 @@ namespace :benchmarks do
138
148
  10_000.times { Dog.new.bark }
139
149
  end
140
150
 
151
+ # puts "benchmark for: #{Coverband.configuration.inspect}"
152
+ # puts "store: #{Coverband.configuration.store.inspect}"
141
153
  def run_work(hold_work = false)
142
154
  suite = GCSuite.new
143
- #puts "benchmark for: #{Coverband.configuration.inspect}"
144
- #puts "store: #{Coverband.configuration.store.inspect}"
145
155
  Benchmark.ips do |x|
146
- x.config(:time => 12, :warmup => 5, :suite => suite)
156
+ x.config(time: 12, warmup: 5, suite: suite)
147
157
  x.report 'coverband' do
148
158
  Coverband::Collectors::Base.instance.sample do
149
159
  work
@@ -159,6 +169,73 @@ namespace :benchmarks do
159
169
  Coverband::Collectors::Base.instance.reset_instance
160
170
  end
161
171
 
172
+ def fake_line_numbers
173
+ 24.times.each_with_object({}) do |line, line_hash|
174
+ line_hash[(line + 1).to_s] = rand(5)
175
+ end
176
+ end
177
+
178
+ def fake_report
179
+ 2934.times.each_with_object({}) do |file_number, hash|
180
+ hash["file#{file_number + 1}.rb"] = fake_line_numbers
181
+ end
182
+ end
183
+
184
+ def adjust_report(report)
185
+ report.keys.each do |file|
186
+ next unless rand < 0.15
187
+ report[file] = fake_line_numbers
188
+ end
189
+ report
190
+ end
191
+
192
+ def reporting_speed
193
+ report = fake_report
194
+ store = benchmark_redis_store
195
+
196
+ 5.times { store.save_report(report) }
197
+ Benchmark.ips do |x|
198
+ x.config(time: 15, warmup: 5)
199
+ x.report('store_reports') { store.save_report(report) }
200
+ end
201
+ end
202
+
203
+ def reporting_memorycache_speed
204
+ report = fake_report
205
+ redis_store = benchmark_redis_store
206
+ cache_store = Coverband::Adapters::MemoryCacheStore.new(redis_store)
207
+
208
+ 5.times do
209
+ redis_store.save_report(report)
210
+ cache_store.save_report(report)
211
+ adjust_report(report)
212
+ end
213
+ Benchmark.ips do |x|
214
+ x.config(time: 15, warmup: 5)
215
+ x.report('store_redis_reports') do
216
+ redis_store.save_report(report)
217
+ adjust_report(report)
218
+ end
219
+ x.report('store_cache_reports') do
220
+ cache_store.save_report(report)
221
+ adjust_report(report)
222
+ end
223
+ x.compare!
224
+ end
225
+ end
226
+
227
+ desc 'runs benchmarks on reporting large sets of files to redis'
228
+ task redis_reporting: [:setup] do
229
+ puts 'runs benchmarks on reporting large sets of files to redis'
230
+ reporting_speed
231
+ end
232
+
233
+ desc 'benchmarks: reporting large sets of files to redis using memory cache'
234
+ task cache_reporting: [:setup] do
235
+ puts 'benchmarks: reporting large sets of files to redis using memory cache'
236
+ reporting_memorycache_speed
237
+ end
238
+
162
239
  desc 'runs benchmarks on default redis setup'
163
240
  task run_redis: [:setup, :setup_redis] do
164
241
  puts 'Coverband tracepoint configured with default Redis store'
@@ -179,11 +256,13 @@ namespace :benchmarks do
179
256
 
180
257
  desc 'compare Coverband Ruby Coverage with normal Ruby'
181
258
  task :compare_coverage do
182
- puts 'comparing with Coverage loaded and not, this takes some time for output...'
259
+ puts 'comparing Coverage loaded/not, this takes some time for output...'
183
260
  puts `COVERAGE=true rake benchmarks:run_coverage`
184
261
  puts `rake benchmarks:run_coverage`
185
262
  end
186
263
  end
187
264
 
188
265
  desc 'runs benchmarks'
189
- task benchmarks: ['benchmarks:run_file', 'benchmarks:run_redis', 'benchmarks:compare_coverage']
266
+ task benchmarks: ['benchmarks:run_file',
267
+ 'benchmarks:run_redis',
268
+ 'benchmarks:compare_coverage']
@@ -17,13 +17,13 @@ class RedisTest < Test::Unit::TestCase
17
17
 
18
18
  def test_coverage
19
19
  @redis.sadd(BASE_KEY, 'dog.rb')
20
- @store.send(:store_map, "#{BASE_KEY}.dog.rb", example_hash)
21
- expected = { 'dog.rb' => example_hash }
20
+ @store.send(:pipelined_save, combined_report)
21
+ expected = {'dog.rb' => example_hash}
22
22
  assert_equal expected, @store.coverage
23
23
  end
24
24
 
25
25
  def test_covered_lines_for_file
26
- @store.send(:store_map, "#{BASE_KEY}.dog.rb", example_hash)
26
+ @store.send(:pipelined_save, combined_report)
27
27
  assert_equal [["1", "1"], ["2", "2"]], @store.covered_lines_for_file('dog.rb').sort
28
28
  end
29
29
 
@@ -47,6 +47,15 @@ class RedisTest < Test::Unit::TestCase
47
47
 
48
48
  private
49
49
 
50
+ def combined_report
51
+ {
52
+ "#{BASE_KEY}.dog.rb" => {
53
+ new: example_hash,
54
+ existing: {}
55
+ }
56
+ }
57
+ end
58
+
50
59
  def test_data
51
60
  {
52
61
  '/Users/danmayer/projects/cover_band_server/app.rb' => { 54 => 1, 55 => 2 },
@@ -15,6 +15,15 @@ class SimpleCovReportTest < Test::Unit::TestCase
15
15
  {'1' => '1', '2' => '2'}
16
16
  end
17
17
 
18
+ def combined_report
19
+ {
20
+ "#{BASE_KEY}.test/unit/dog.rb" => {
21
+ new: example_hash,
22
+ existing: {}
23
+ }
24
+ }
25
+ end
26
+
18
27
  test 'report data' do
19
28
  Coverband.configure do |config|
20
29
  config.redis = @redis
@@ -25,7 +34,7 @@ class SimpleCovReportTest < Test::Unit::TestCase
25
34
  Coverband::Reporters::ConsoleReport.expects(:current_root).returns('./test/unit')
26
35
 
27
36
  @redis.sadd(BASE_KEY, 'test/unit/dog.rb')
28
- @store.send(:store_map, "#{BASE_KEY}.test/unit/dog.rb", example_hash)
37
+ @store.send(:pipelined_save, combined_report)
29
38
 
30
39
  report = Coverband::Reporters::ConsoleReport.report(@store)
31
40
  expected = {"test/unit/dog.rb"=>[1, 2, nil, nil, nil, nil, nil]}
@@ -15,6 +15,15 @@ class ReportsSimpleCovTest < Test::Unit::TestCase
15
15
  {'1' => '1', '2' => '2'}
16
16
  end
17
17
 
18
+ def combined_report
19
+ {
20
+ "#{BASE_KEY}.test/unit/dog.rb" => {
21
+ new: example_hash,
22
+ existing: {}
23
+ }
24
+ }
25
+ end
26
+
18
27
  test 'generate scov report' do
19
28
  Coverband.configure do |config|
20
29
  config.redis = @redis
@@ -26,7 +35,7 @@ class ReportsSimpleCovTest < Test::Unit::TestCase
26
35
  Coverband.configuration.logger.stubs('info')
27
36
 
28
37
  @redis.sadd(BASE_KEY, 'test/unit/dog.rb')
29
- @store.send(:store_map, "#{BASE_KEY}.test/unit/dog.rb", example_hash)
38
+ @store.send(:pipelined_save, combined_report)
30
39
 
31
40
  SimpleCov.expects(:track_files)
32
41
  SimpleCov.expects(:add_not_loaded_files).returns({})
@@ -48,7 +57,7 @@ class ReportsSimpleCovTest < Test::Unit::TestCase
48
57
  Coverband::Reporters::SimpleCovReport.expects(:current_root).at_least_once.returns('/tmp/root_dir')
49
58
 
50
59
  @redis.sadd(BASE_KEY, 'test/unit/dog.rb')
51
- @store.send(:store_map, "#{BASE_KEY}.test/unit/dog.rb", example_hash)
60
+ @store.send(:pipelined_save, combined_report)
52
61
  SimpleCov.expects(:track_files)
53
62
  SimpleCov.expects(:add_not_loaded_files).returns('fake_file.rb' => [1])
54
63
  SimpleCov::Result.any_instance.expects(:format!)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coverband
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.3.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Mayer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-15 00:00:00.000000000 Z
11
+ date: 2018-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -195,10 +195,6 @@ files:
195
195
  - changes.md
196
196
  - config.ru
197
197
  - coverband.gemspec
198
- - docs/coverband-install-resize.gif
199
- - docs/coverband_details.png
200
- - docs/coverband_index.png
201
- - docs/coverband_install.gif
202
198
  - lib/coverband.rb
203
199
  - lib/coverband/adapters/base.rb
204
200
  - lib/coverband/adapters/file_store.rb
@@ -250,9 +246,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
250
246
  version: '0'
251
247
  required_rubygems_version: !ruby/object:Gem::Requirement
252
248
  requirements:
253
- - - ">="
249
+ - - ">"
254
250
  - !ruby/object:Gem::Version
255
- version: '0'
251
+ version: 1.3.1
256
252
  requirements: []
257
253
  rubyforge_project:
258
254
  rubygems_version: 2.5.1
Binary file
Binary file
Binary file
Binary file