coverband 3.0.0 → 3.0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +2 -1
- data/changes.md +9 -3
- data/coverband.gemspec +10 -4
- data/lib/coverband.rb +4 -1
- 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/test/benchmarks/benchmark.rake +14 -1
- data/test/test_helper.rb +16 -1
- 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/coverband_test.rb +26 -0
- data/test/unit/rack_server_checkout_test.rb +24 -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 +33 -12
- 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: b33132c4d855470c5510444a91b0df3a99ef3ee8
|
4
|
+
data.tar.gz: e9a6c32142c9421251ce7588dcb80a4686c48e45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74411fa1d49db9c7bea3b59e49fcc2432a48650ecfae86c2e09273623c48e148995606ce8bdde73aaa789e8973655394672c01967827e97cd345443cd3a39d2f
|
7
|
+
data.tar.gz: 37dbb381f412f2b11269dbf9550148ab97cd273d60e9afae47ee47772427c0855dd4fe286dce2e9c1e73f686f257a9154f72c928de3ca22cf50008a3c9594ceb
|
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
|
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,8 @@ 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
|
47
49
|
|
48
50
|
### Coverband_jam_session
|
49
51
|
|
@@ -70,8 +72,12 @@ Feature Ideas:
|
|
70
72
|
|
71
73
|
### Coverband 3.0.1
|
72
74
|
|
73
|
-
*
|
74
|
-
|
75
|
+
* update documentation around verification steps (https://github.com/danmayer/coverband/issues/135), thanks @kbaum
|
76
|
+
* resolve coverage drift issue, https://github.com/danmayer/coverband/issues/118, thanks for MD5 hash ideas @dnasseri and @kbaum
|
77
|
+
* first version of background thread coverage reporting https://github.com/danmayer/coverband/pull/138, thanks @kbaum
|
78
|
+
* auto-detection of Rack & Rails thanks @kbaum
|
79
|
+
* improved tests allowing exceptions to raise in tests @kbaum
|
80
|
+
* add support for both aws-sdk 1.x and 2.x thanks @jared
|
75
81
|
|
76
82
|
# Released
|
77
83
|
|
data/coverband.gemspec
CHANGED
@@ -19,22 +19,28 @@ 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
|
+
|
31
36
|
# used for benchmarking and tests
|
32
37
|
spec.add_development_dependency 'classifier-reborn'
|
33
38
|
# add when debugging
|
34
39
|
# require 'byebug'; byebug
|
35
|
-
spec.add_development_dependency 'byebug'
|
40
|
+
spec.add_development_dependency 'pry-byebug'
|
36
41
|
|
37
|
-
#
|
42
|
+
# TODO: make an optional dependency for simplecov reports
|
38
43
|
# also likely should just require simplecov-html not the whole lib
|
44
|
+
# I tried this but it was harder than I thought
|
39
45
|
spec.add_runtime_dependency 'simplecov', '> 0.11.1'
|
40
46
|
end
|
data/lib/coverband.rb
CHANGED
@@ -8,11 +8,13 @@ require 'coverband/configuration'
|
|
8
8
|
require 'coverband/adapters/base'
|
9
9
|
require 'coverband/adapters/redis_store'
|
10
10
|
require 'coverband/adapters/file_store'
|
11
|
-
require 'coverband/utils/
|
11
|
+
require 'coverband/utils/s3_report'
|
12
12
|
require 'coverband/collectors/coverage'
|
13
13
|
require 'coverband/reporters/base'
|
14
14
|
require 'coverband/reporters/simple_cov_report'
|
15
15
|
require 'coverband/reporters/console_report'
|
16
|
+
require 'coverband/integrations/background'
|
17
|
+
require 'coverband/integrations/rack_server_check'
|
16
18
|
require 'coverband/reporters/web'
|
17
19
|
require 'coverband/integrations/middleware'
|
18
20
|
require 'coverband/integrations/background'
|
@@ -44,5 +46,6 @@ module Coverband
|
|
44
46
|
|
45
47
|
def self.start
|
46
48
|
Coverband::Collectors::Coverage.instance
|
49
|
+
Background.start if configuration.background_reporting_enabled && !RackServerCheck.running?
|
47
50
|
end
|
48
51
|
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
|
@@ -71,7 +71,7 @@ module Coverband
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def show
|
74
|
-
html =
|
74
|
+
html = Coverband::Utils::S3Report.instance.retrieve
|
75
75
|
# HACK: the static HTML assets to link to the path where this was mounted
|
76
76
|
html = html.gsub("src='", "src='#{base_path}")
|
77
77
|
html = html.gsub("href='", "href='#{base_path}")
|
@@ -126,30 +126,12 @@ module Coverband
|
|
126
126
|
|
127
127
|
# This method should get the root mounted endpoint
|
128
128
|
# for example if the app is mounted like so:
|
129
|
-
# mount Coverband::
|
129
|
+
# mount Coverband::Web, at: '/coverage'
|
130
130
|
# "/coverage/collect_coverage?" become:
|
131
131
|
# /coverage/
|
132
132
|
def base_path
|
133
133
|
request.path.match("\/.*\/") ? request.path.match("\/.*\/")[0] : '/'
|
134
134
|
end
|
135
|
-
|
136
|
-
def s3
|
137
|
-
begin
|
138
|
-
require 'aws-sdk'
|
139
|
-
rescue StandardError
|
140
|
-
Coverband.configuration.logger.error "coverband requires 'aws-sdk' in order use S3ReportWriter."
|
141
|
-
return
|
142
|
-
end
|
143
|
-
@s3 ||= begin
|
144
|
-
client_options = {
|
145
|
-
region: Coverband.configuration.s3_region,
|
146
|
-
access_key_id: Coverband.configuration.s3_access_key_id,
|
147
|
-
secret_access_key: Coverband.configuration.s3_secret_access_key
|
148
|
-
}
|
149
|
-
client_options = {} if client_options.values.any?(&:nil?)
|
150
|
-
Aws::S3::Client.new(client_options)
|
151
|
-
end
|
152
|
-
end
|
153
135
|
end
|
154
136
|
end
|
155
137
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coverband
|
4
|
+
module Utils
|
5
|
+
###
|
6
|
+
# TODO: this is currently a html report writer
|
7
|
+
# this should support writing coverage the current method should be fine
|
8
|
+
# to write every report to S3 and sum them later or use the 2 pass
|
9
|
+
# method we do for redis if in a background thread
|
10
|
+
###
|
11
|
+
class S3Report
|
12
|
+
def self.instance
|
13
|
+
s3_options = {
|
14
|
+
region: Coverband.configuration.s3_region,
|
15
|
+
access_key_id: Coverband.configuration.s3_access_key_id,
|
16
|
+
secret_access_key: Coverband.configuration.s3_secret_access_key
|
17
|
+
}
|
18
|
+
new(Coverband.configuration.s3_bucket, s3_options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(bucket_name, options = {})
|
22
|
+
@bucket_name = bucket_name
|
23
|
+
@region = options[:region]
|
24
|
+
@access_key_id = options[:access_key_id]
|
25
|
+
@secret_access_key = options[:secret_access_key]
|
26
|
+
begin
|
27
|
+
require 'aws-sdk'
|
28
|
+
rescue StandardError
|
29
|
+
err_msg = 'coverband requires aws-sdk in order use S3Report.'
|
30
|
+
Coverband.configuration.logger.error err_msg
|
31
|
+
return
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def persist!
|
36
|
+
if defined?(Aws)
|
37
|
+
object.put(body: coverage_content)
|
38
|
+
else
|
39
|
+
object.write(coverage_content)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def retrieve
|
44
|
+
if defined?(Aws)
|
45
|
+
s3_client.get_object(bucket: Coverband.configuration.s3_bucket,
|
46
|
+
key: 'coverband/index.html').body.read
|
47
|
+
else
|
48
|
+
object.read
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def coverage_content
|
55
|
+
version = Gem::Specification.find_by_name('simplecov-html').version.version
|
56
|
+
File.read("#{SimpleCov.coverage_dir}/index.html").gsub("./assets/#{version}/", '')
|
57
|
+
rescue StandardError
|
58
|
+
File.read("#{SimpleCov.coverage_dir}/index.html").to_s.gsub('./assets/0.10.1/', '')
|
59
|
+
end
|
60
|
+
|
61
|
+
def object
|
62
|
+
if defined?(Aws)
|
63
|
+
bucket.object('coverband/index.html')
|
64
|
+
else
|
65
|
+
bucket.objects['coverband/index.html']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def client_options
|
70
|
+
{
|
71
|
+
region: @region,
|
72
|
+
access_key_id: @access_key_id,
|
73
|
+
secret_access_key: @secret_access_key
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def s3_client
|
78
|
+
if defined?(Aws)
|
79
|
+
# AWS SDK v2
|
80
|
+
Aws::S3::Client.new(client_options)
|
81
|
+
else
|
82
|
+
# AWS SDK v1
|
83
|
+
AWS::S3::Client.new(client_options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def s3
|
88
|
+
resource_options = { client: s3_client }
|
89
|
+
resource_options = {} if client_options.values.any?(&:nil?)
|
90
|
+
if defined?(Aws)
|
91
|
+
# AWS SDK v2
|
92
|
+
Aws::S3::Resource.new(resource_options)
|
93
|
+
else
|
94
|
+
# AWS SDK v1
|
95
|
+
AWS::S3.new(resource_options)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def bucket
|
100
|
+
if defined?(Aws)
|
101
|
+
s3.bucket(@bucket_name)
|
102
|
+
else
|
103
|
+
s3.buckets[@bucket_name]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/coverband/version.rb
CHANGED
@@ -169,6 +169,18 @@ namespace :benchmarks do
|
|
169
169
|
def reporting_speed
|
170
170
|
report = fake_report
|
171
171
|
store = benchmark_redis_store
|
172
|
+
store.clear!
|
173
|
+
|
174
|
+
###
|
175
|
+
# this is a hack because in the benchmark we don't have real files
|
176
|
+
###
|
177
|
+
def store.file_hash(file)
|
178
|
+
if @file_hash_cache[file]
|
179
|
+
@file_hash_cache[file]
|
180
|
+
else
|
181
|
+
@file_hash_cache[file] = Digest::MD5.file(__FILE__).hexdigest
|
182
|
+
end
|
183
|
+
end
|
172
184
|
|
173
185
|
5.times { store.save_report(report) }
|
174
186
|
Benchmark.ips do |x|
|
@@ -198,7 +210,7 @@ namespace :benchmarks do
|
|
198
210
|
desc 'benchmarks external requests to coverband_demo site'
|
199
211
|
task :coverband_demo do
|
200
212
|
# for local testing
|
201
|
-
# puts `ab -n
|
213
|
+
# puts `ab -n 500 -c 5 "http://127.0.0.1:3000/posts"`
|
202
214
|
puts `ab -n 2000 -c 10 "https://coverband-demo.herokuapp.com/posts"`
|
203
215
|
end
|
204
216
|
|
@@ -206,6 +218,7 @@ namespace :benchmarks do
|
|
206
218
|
task :coverband_demo_graph do
|
207
219
|
# for local testing
|
208
220
|
# puts `ab -n 200 -c 5 "http://127.0.0.1:3000/posts"`
|
221
|
+
#puts `ab -n 500 -c 10 -g tmp/ab_brench.tsv "http://127.0.0.1:3000/posts"`
|
209
222
|
puts `ab -n 2000 -c 10 -g tmp/ab_brench.tsv "https://coverband-demo.herokuapp.com/posts"`
|
210
223
|
puts `test/benchmarks/graph_bench.sh`
|
211
224
|
`open tmp/timeseries.jpg`
|
data/test/test_helper.rb
CHANGED
@@ -7,6 +7,7 @@ require 'mocha/setup'
|
|
7
7
|
require 'ostruct'
|
8
8
|
require 'json'
|
9
9
|
require 'redis'
|
10
|
+
require 'pry-byebug'
|
10
11
|
|
11
12
|
SimpleCov.start do
|
12
13
|
add_filter 'specs/ruby/1.9.1/gems/'
|
@@ -14,10 +15,12 @@ SimpleCov.start do
|
|
14
15
|
add_filter '/config/'
|
15
16
|
end
|
16
17
|
|
17
|
-
TEST_COVERAGE_FILE = '/tmp/fake_file.json'
|
18
|
+
TEST_COVERAGE_FILE = '/tmp/fake_file.json'
|
18
19
|
|
19
20
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
20
21
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
22
|
+
|
23
|
+
Mocha::Configuration.prevent(:stubbing_method_unnecessarily)
|
21
24
|
Mocha::Configuration.prevent(:stubbing_non_existent_method)
|
22
25
|
|
23
26
|
def test(name, &block)
|
@@ -37,6 +40,12 @@ def test(name, &block)
|
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
43
|
+
def mock_file_hash
|
44
|
+
mock_file = mock('mock_file')
|
45
|
+
mock_file.expects(:hexdigest).at_least_once.returns('abcd')
|
46
|
+
Digest::MD5.expects(:file).at_least_once.returns(mock_file)
|
47
|
+
end
|
48
|
+
|
40
49
|
def example_line
|
41
50
|
[0, 1, 2]
|
42
51
|
end
|
@@ -68,3 +77,9 @@ Coverband.configure do |config|
|
|
68
77
|
config.reporter = 'std_out'
|
69
78
|
config.store = Coverband::Adapters::RedisStore.new(Redis.new)
|
70
79
|
end
|
80
|
+
|
81
|
+
Coverband::Configuration.class_eval do
|
82
|
+
def test_env
|
83
|
+
true
|
84
|
+
end
|
85
|
+
end
|
@@ -6,23 +6,44 @@ class AdaptersBaseTest < Test::Unit::TestCase
|
|
6
6
|
def setup
|
7
7
|
@test_file_path = '/tmp/coverband_filestore_test_path.json'
|
8
8
|
@store = Coverband::Adapters::FileStore.new(@test_file_path)
|
9
|
+
mock_file_hash
|
9
10
|
end
|
10
11
|
|
11
12
|
def test_covered_merge
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
old_time = 1541958097
|
14
|
+
current_time = Time.now.to_i
|
15
|
+
old_data = {
|
16
|
+
'first_updated_at' => old_time,
|
17
|
+
'last_updated_at' => current_time,
|
18
|
+
'file_hash' => 'abcd',
|
19
|
+
'data' => [5, 7, nil]
|
20
|
+
}
|
21
|
+
old_report = { '/projects/coverband_demo/config/coverband.rb' => old_data,
|
22
|
+
'/projects/coverband_demo/config/initializers/assets.rb' => old_data,
|
23
|
+
'/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data }
|
24
|
+
new_report = { '/projects/coverband_demo/config/coverband.rb' => [5, 7, nil],
|
25
|
+
'/projects/coverband_demo/config/initializers/filter_logging.rb' => [5, 7, nil],
|
26
|
+
'/projects/coverband_demo/config/initializers/wrap_parameters.rb' => [5, 7, nil],
|
27
|
+
'/projects/coverband_demo/app/controllers/application_controller.rb' => [5, 7, nil] }
|
28
|
+
expected_merge = {
|
29
|
+
'first_updated_at' => old_time,
|
30
|
+
'last_updated_at' => current_time,
|
31
|
+
'file_hash' => 'abcd',
|
32
|
+
'data' => [10, 14, nil]
|
33
|
+
}
|
34
|
+
new_data = {
|
35
|
+
'first_updated_at' => current_time,
|
36
|
+
'last_updated_at' => current_time,
|
37
|
+
'file_hash' => 'abcd',
|
38
|
+
'data' => [5, 7, nil]
|
39
|
+
}
|
19
40
|
expected_result = {
|
20
|
-
'/
|
21
|
-
'/
|
22
|
-
'/
|
23
|
-
'/
|
24
|
-
'/
|
25
|
-
'/
|
41
|
+
'/projects/coverband_demo/app/controllers/application_controller.rb' => new_data,
|
42
|
+
'/projects/coverband_demo/config/coverband.rb' => expected_merge,
|
43
|
+
'/projects/coverband_demo/config/initializers/assets.rb' => old_data,
|
44
|
+
'/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data,
|
45
|
+
'/projects/coverband_demo/config/initializers/filter_logging.rb' => new_data,
|
46
|
+
'/projects/coverband_demo/config/initializers/wrap_parameters.rb' => new_data
|
26
47
|
}
|
27
48
|
assert_equal expected_result, @store.send(:merge_reports, new_report, old_report)
|
28
49
|
end
|
@@ -10,8 +10,8 @@ class AdaptersFileStoreTest < Test::Unit::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_covered_lines_for_file
|
13
|
-
assert_equal @store.covered_lines_for_file('dog.rb')[
|
14
|
-
assert_equal @store.covered_lines_for_file('dog.rb')[
|
13
|
+
assert_equal @store.covered_lines_for_file('dog.rb')[0], 1
|
14
|
+
assert_equal @store.covered_lines_for_file('dog.rb')[1], 2
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_covered_lines_when_null
|
@@ -28,7 +28,8 @@ class AdaptersFileStoreTest < Test::Unit::TestCase
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_save_report
|
31
|
-
|
31
|
+
mock_file_hash
|
32
|
+
@store.send(:save_report, 'cat.rb' => [0, 1])
|
32
33
|
assert_equal @store.covered_lines_for_file('cat.rb')[1], 1
|
33
34
|
end
|
34
35
|
|
@@ -36,7 +37,10 @@ class AdaptersFileStoreTest < Test::Unit::TestCase
|
|
36
37
|
|
37
38
|
def test_data
|
38
39
|
{
|
39
|
-
'dog.rb' => {
|
40
|
+
'dog.rb' => { 'data' => [1, 2, nil],
|
41
|
+
'file_hash' => 'abcd',
|
42
|
+
'first_updated_at' => 1541968729,
|
43
|
+
'last_updated_at' => 1541968729 }
|
40
44
|
}
|
41
45
|
end
|
42
46
|
end
|
@@ -12,27 +12,30 @@ class RedisTest < Test::Unit::TestCase
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_coverage
|
15
|
+
mock_file_hash
|
15
16
|
expected = basic_coverage
|
16
17
|
@store.save_report(expected)
|
17
18
|
assert_equal expected, @store.coverage
|
18
19
|
end
|
19
20
|
|
20
21
|
def test_coverage_increments
|
21
|
-
|
22
|
-
|
22
|
+
mock_file_hash
|
23
|
+
expected = basic_coverage.dup
|
24
|
+
@store.save_report(basic_coverage.dup)
|
23
25
|
assert_equal expected, @store.coverage
|
24
|
-
@store.save_report(
|
26
|
+
@store.save_report(basic_coverage.dup)
|
25
27
|
assert_equal [0, 2, 4], @store.coverage['app_path/dog.rb']
|
26
28
|
end
|
27
29
|
|
28
30
|
def test_covered_lines_for_file
|
31
|
+
mock_file_hash
|
29
32
|
expected = basic_coverage
|
30
33
|
@store.save_report(expected)
|
31
34
|
assert_equal example_line, @store.covered_lines_for_file('app_path/dog.rb')
|
32
35
|
end
|
33
36
|
|
34
37
|
def test_covered_lines_when_null
|
35
|
-
assert_equal
|
38
|
+
assert_equal [], @store.covered_lines_for_file('app_path/dog.rb')
|
36
39
|
end
|
37
40
|
|
38
41
|
def test_clear
|
@@ -42,15 +45,6 @@ class RedisTest < Test::Unit::TestCase
|
|
42
45
|
|
43
46
|
private
|
44
47
|
|
45
|
-
def combined_report
|
46
|
-
{
|
47
|
-
"#{BASE_KEY}.dog.rb" => {
|
48
|
-
new: example_hash,
|
49
|
-
existing: {}
|
50
|
-
}
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
48
|
def test_data
|
55
49
|
{
|
56
50
|
'/Users/danmayer/projects/cover_band_server/app.rb' => { 54 => 1, 55 => 2 },
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class BackgroundTest < Test::Unit::TestCase
|
6
|
+
def test_start
|
7
|
+
Thread.expects(:new).yields
|
8
|
+
Coverband::Background.expects(:loop).yields
|
9
|
+
Coverband::Collectors::Coverage.instance.expects(:report_coverage)
|
10
|
+
Coverband::Background.expects(:sleep).with(30)
|
11
|
+
Coverband::Background.expects(:at_exit).yields
|
12
|
+
Coverband::Collectors::Coverage.instance.expects(:report_coverage)
|
13
|
+
2.times { Coverband::Background.start }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -29,5 +29,29 @@ 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
|
+
test 'report_coverage raises errors in tests' do
|
40
|
+
Coverband.configuration.stubs(:background_reporting_enabled).returns(true)
|
41
|
+
@coverband.reset_instance
|
42
|
+
Coverband::Background.expects(:start).raises("Oh no")
|
43
|
+
assert_raise RuntimeError do
|
44
|
+
@coverband.report_coverage
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
test 'report_coverage does not raise errors in non-test mode' do
|
49
|
+
Coverband.configuration.stubs(:background_reporting_enabled).returns(true)
|
50
|
+
Coverband.configuration.stubs(:test_env).returns(false)
|
51
|
+
@coverband.reset_instance
|
52
|
+
Coverband::Background.expects(:start).raises("Oh no")
|
53
|
+
@coverband.report_coverage
|
54
|
+
end
|
55
|
+
|
32
56
|
end
|
33
57
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class CoverbandTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
test 'Coverband#start kicks off background reporting if enabled and not in rack server' do
|
8
|
+
Coverband.configuration.stubs(:background_reporting_enabled).returns(:true)
|
9
|
+
Coverband::RackServerCheck.expects(:running?).returns(false)
|
10
|
+
Coverband::Background.expects(:start)
|
11
|
+
Coverband.start
|
12
|
+
end
|
13
|
+
|
14
|
+
test 'Coverband#start delays background reporting if enabled and running in a rack server' do
|
15
|
+
Coverband.configuration.stubs(:background_reporting_enabled).returns(true)
|
16
|
+
Coverband::RackServerCheck.expects(:running?).returns(true)
|
17
|
+
Coverband::Background.expects(:start).never
|
18
|
+
Coverband.start
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'Coverband#start does not kick off background reporting if not enabled' do
|
22
|
+
Coverband.configuration.stubs(:background_reporting_enabled).returns(false)
|
23
|
+
Coverband::Background.expects(:start).never
|
24
|
+
::Coverband.start
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class RackServerCheckTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
test 'returns true when running in rack server' do
|
8
|
+
caller_locations = ['blah/lib/rack/server.rb'].map{ |path| OpenStruct.new(path: path, label: 'foo') }
|
9
|
+
Kernel.expects(:caller_locations).returns(caller_locations)
|
10
|
+
assert_true(Coverband::RackServerCheck.running?)
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'returns false when not running in rack server' do
|
14
|
+
caller_locations = ['blah/lib/sidekiq/worker.rb'].map{ |path| OpenStruct.new(path: path, label: 'foo') }
|
15
|
+
Kernel.expects(:caller_locations).returns(caller_locations)
|
16
|
+
assert_false(Coverband::RackServerCheck.running?)
|
17
|
+
end
|
18
|
+
|
19
|
+
test 'returns true if running within a rails server' do
|
20
|
+
caller_locations = [OpenStruct.new(path: '/lib/rails/commands/commands_tasks.rb', label: 'server')]
|
21
|
+
Kernel.expects(:caller_locations).returns(caller_locations)
|
22
|
+
assert_true(Coverband::RackServerCheck.running?)
|
23
|
+
end
|
24
|
+
end
|
@@ -103,8 +103,6 @@ class ReportsBaseTest < Test::Unit::TestCase
|
|
103
103
|
lines_hit = [1, 3, 6]
|
104
104
|
store.stubs(:coverage).returns(key => lines_hit)
|
105
105
|
expected = { key => [1, 3, 6] }
|
106
|
-
File.stubs(:exist?).returns(true)
|
107
|
-
File.stubs(:foreach).returns(['line 1', 'line2', 'line3', 'line4', 'line5', 'line6'])
|
108
106
|
|
109
107
|
assert_equal expected, Coverband::Reporters::Base.send(:get_current_scov_data_imp, store, roots)
|
110
108
|
end
|
@@ -11,15 +11,6 @@ class ReportsSimpleCovTest < Test::Unit::TestCase
|
|
11
11
|
@store.clear!
|
12
12
|
end
|
13
13
|
|
14
|
-
def combined_report
|
15
|
-
{
|
16
|
-
"#{BASE_KEY}.test/unit/dog.rb" => {
|
17
|
-
new: example_hash,
|
18
|
-
existing: {}
|
19
|
-
}
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
14
|
test 'generate scov report' do
|
24
15
|
Coverband.configure do |config|
|
25
16
|
config.reporter = 'scov'
|
@@ -28,13 +19,13 @@ class ReportsSimpleCovTest < Test::Unit::TestCase
|
|
28
19
|
config.ignore = ['notsomething.rb']
|
29
20
|
end
|
30
21
|
Coverband.configuration.logger.stubs('info')
|
22
|
+
mock_file_hash
|
31
23
|
@store.send(:save_report, basic_coverage)
|
32
24
|
|
33
25
|
SimpleCov.expects(:track_files)
|
34
26
|
SimpleCov.expects(:add_not_loaded_files).returns({})
|
35
27
|
SimpleCov::Result.any_instance.expects(:format!)
|
36
28
|
SimpleCov.stubs(:root)
|
37
|
-
|
38
29
|
Coverband::Reporters::SimpleCovReport.report(@store, open_report: false)
|
39
30
|
end
|
40
31
|
end
|
@@ -29,9 +29,7 @@ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.2.0')
|
|
29
29
|
|
30
30
|
test 'renders show content' do
|
31
31
|
Coverband.configuration.s3_bucket = 'coverage-bucket'
|
32
|
-
|
33
|
-
Aws::S3::Client.expects(:new).returns(s3)
|
34
|
-
s3.expects(:get_object).with(bucket: 'coverage-bucket', key: 'coverband/index.html').returns mock('response', body: mock('body', read: 'content'))
|
32
|
+
Coverband::Utils::S3Report.any_instance.expects(:retrieve).returns('content')
|
35
33
|
get '/show'
|
36
34
|
assert last_response.ok?
|
37
35
|
assert_equal 'content', last_response.body
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
2
|
+
require 'aws-sdk'
|
3
|
+
|
4
|
+
module Coverband
|
5
|
+
class S3ReportTest < Test::Unit::TestCase
|
6
|
+
def html_version
|
7
|
+
Gem::Specification.find_by_name('simplecov-html').version.version.to_s
|
8
|
+
rescue StandardError
|
9
|
+
'0.10.1'
|
10
|
+
end
|
11
|
+
|
12
|
+
test 'it writes the coverage report to s3' do
|
13
|
+
if defined?(Aws::S3::Resource)
|
14
|
+
# AWS v2
|
15
|
+
s3 = mock('s3_resource')
|
16
|
+
bucket = mock('bucket')
|
17
|
+
object = mock('object')
|
18
|
+
s3.expects(:bucket).with('coverage-bucket').returns(bucket)
|
19
|
+
bucket.expects(:object).with('coverband/index.html').returns(object)
|
20
|
+
File.expects(:read).at_least(0).returns("content ./assets/#{html_version}/")
|
21
|
+
object.expects(:put).with(body: 'content ')
|
22
|
+
Aws::S3::Resource.expects(:new).returns(s3)
|
23
|
+
else
|
24
|
+
# AWS v1
|
25
|
+
object = mock('object')
|
26
|
+
object.expects(:write).with('content ')
|
27
|
+
bucket = mock('bucket')
|
28
|
+
bucket.expects(:objects).returns('coverband/index.html' => object)
|
29
|
+
local_s3 = mock('s3_resource')
|
30
|
+
local_s3.expects(:buckets).returns('coverage-bucket' => bucket)
|
31
|
+
File.expects(:read).at_least(0).returns("content ./assets/#{html_version}/")
|
32
|
+
AWS::S3::Client.expects(:new).returns(nil)
|
33
|
+
AWS::S3.expects(:new).returns(local_s3)
|
34
|
+
end
|
35
|
+
|
36
|
+
s3_options = {
|
37
|
+
region: 'us-west-1',
|
38
|
+
access_key_id: '',
|
39
|
+
secret_access_key: ''
|
40
|
+
}
|
41
|
+
Coverband::Utils::S3Report.new('coverage-bucket', s3_options).persist!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
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: 3.0.
|
4
|
+
version: 3.0.1.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-11-
|
11
|
+
date: 2018-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: benchmark-ips
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,7 +109,7 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: redis
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - ">="
|
@@ -109,7 +123,7 @@ dependencies:
|
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: test-unit
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - ">="
|
@@ -123,7 +137,7 @@ dependencies:
|
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
140
|
+
name: m
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
143
|
- - ">="
|
@@ -151,7 +165,7 @@ dependencies:
|
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '0'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
|
-
name: byebug
|
168
|
+
name: pry-byebug
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
171
|
- - ">="
|
@@ -204,11 +218,12 @@ files:
|
|
204
218
|
- lib/coverband/configuration.rb
|
205
219
|
- lib/coverband/integrations/background.rb
|
206
220
|
- lib/coverband/integrations/middleware.rb
|
221
|
+
- lib/coverband/integrations/rack_server_check.rb
|
207
222
|
- lib/coverband/reporters/base.rb
|
208
223
|
- lib/coverband/reporters/console_report.rb
|
209
224
|
- lib/coverband/reporters/simple_cov_report.rb
|
210
225
|
- lib/coverband/reporters/web.rb
|
211
|
-
- lib/coverband/utils/
|
226
|
+
- lib/coverband/utils/s3_report.rb
|
212
227
|
- lib/coverband/utils/tasks.rb
|
213
228
|
- lib/coverband/version.rb
|
214
229
|
- test/benchmarks/.gitignore
|
@@ -220,16 +235,19 @@ files:
|
|
220
235
|
- test/unit/adapters_base_test.rb
|
221
236
|
- test/unit/adapters_file_store_test.rb
|
222
237
|
- test/unit/adapters_redis_store_test.rb
|
238
|
+
- test/unit/background_test.rb
|
223
239
|
- test/unit/collectors_coverage_test.rb
|
224
240
|
- test/unit/configuration_test.rb
|
241
|
+
- test/unit/coverband_test.rb
|
225
242
|
- test/unit/dog.rb
|
226
243
|
- test/unit/full_stack_test.rb
|
227
244
|
- test/unit/middleware_test.rb
|
245
|
+
- test/unit/rack_server_checkout_test.rb
|
228
246
|
- test/unit/reports_base_test.rb
|
229
247
|
- test/unit/reports_console_test.rb
|
230
248
|
- test/unit/reports_simple_cov_test.rb
|
231
249
|
- test/unit/reports_web_test.rb
|
232
|
-
- test/unit/
|
250
|
+
- test/unit/utils_s3_report_test.rb
|
233
251
|
homepage: https://github.com/danmayer/coverband
|
234
252
|
licenses:
|
235
253
|
- MIT
|
@@ -245,12 +263,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
245
263
|
version: '0'
|
246
264
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
247
265
|
requirements:
|
248
|
-
- - "
|
266
|
+
- - ">"
|
249
267
|
- !ruby/object:Gem::Version
|
250
|
-
version:
|
268
|
+
version: 1.3.1
|
251
269
|
requirements: []
|
252
270
|
rubyforge_project:
|
253
|
-
rubygems_version: 2.
|
271
|
+
rubygems_version: 2.5.1
|
254
272
|
signing_key:
|
255
273
|
specification_version: 4
|
256
274
|
summary: Rack middleware to help measure production code usage (LOC runtime usage)
|
@@ -264,13 +282,16 @@ test_files:
|
|
264
282
|
- test/unit/adapters_base_test.rb
|
265
283
|
- test/unit/adapters_file_store_test.rb
|
266
284
|
- test/unit/adapters_redis_store_test.rb
|
285
|
+
- test/unit/background_test.rb
|
267
286
|
- test/unit/collectors_coverage_test.rb
|
268
287
|
- test/unit/configuration_test.rb
|
288
|
+
- test/unit/coverband_test.rb
|
269
289
|
- test/unit/dog.rb
|
270
290
|
- test/unit/full_stack_test.rb
|
271
291
|
- test/unit/middleware_test.rb
|
292
|
+
- test/unit/rack_server_checkout_test.rb
|
272
293
|
- test/unit/reports_base_test.rb
|
273
294
|
- test/unit/reports_console_test.rb
|
274
295
|
- test/unit/reports_simple_cov_test.rb
|
275
296
|
- test/unit/reports_web_test.rb
|
276
|
-
- test/unit/
|
297
|
+
- test/unit/utils_s3_report_test.rb
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Coverband
|
4
|
-
module Utils
|
5
|
-
###
|
6
|
-
# TODO: this is currently a html report writer
|
7
|
-
# this should support writing coverage the current method should be fine
|
8
|
-
# to write every report to S3 and sum them later or use the 2 pass
|
9
|
-
# method we do for redis if in a background thread
|
10
|
-
###
|
11
|
-
class S3ReportWriter
|
12
|
-
def initialize(bucket_name, options = {})
|
13
|
-
@bucket_name = bucket_name
|
14
|
-
@region = options[:region]
|
15
|
-
@access_key_id = options[:access_key_id]
|
16
|
-
@secret_access_key = options[:secret_access_key]
|
17
|
-
begin
|
18
|
-
require 'aws-sdk'
|
19
|
-
rescue StandardError
|
20
|
-
err_msg = 'coverband requires aws-sdk in order use S3ReportWriter.'
|
21
|
-
Coverband.configuration.logger.error err_msg
|
22
|
-
return
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def persist!
|
27
|
-
object.put(body: coverage_content)
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def coverage_content
|
33
|
-
version = Gem::Specification.find_by_name('simplecov-html').version.version
|
34
|
-
File.read("#{SimpleCov.coverage_dir}/index.html").gsub("./assets/#{version}/", '')
|
35
|
-
rescue StandardError
|
36
|
-
File.read("#{SimpleCov.coverage_dir}/index.html").to_s.gsub('./assets/0.10.1/', '')
|
37
|
-
end
|
38
|
-
|
39
|
-
def object
|
40
|
-
bucket.object('coverband/index.html')
|
41
|
-
end
|
42
|
-
|
43
|
-
def s3
|
44
|
-
client_options = {
|
45
|
-
region: @region,
|
46
|
-
access_key_id: @access_key_id,
|
47
|
-
secret_access_key: @secret_access_key
|
48
|
-
}
|
49
|
-
resource_options = { client: Aws::S3::Client.new(client_options) }
|
50
|
-
resource_options = {} if client_options.values.any?(&:nil?)
|
51
|
-
Aws::S3::Resource.new(resource_options)
|
52
|
-
end
|
53
|
-
|
54
|
-
def bucket
|
55
|
-
s3.bucket(@bucket_name)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
2
|
-
require 'aws-sdk'
|
3
|
-
|
4
|
-
module Coverband
|
5
|
-
class S3ReportWriterTest < Test::Unit::TestCase
|
6
|
-
def html_version
|
7
|
-
Gem::Specification.find_by_name('simplecov-html').version.version.to_s
|
8
|
-
rescue StandardError
|
9
|
-
'0.10.1'
|
10
|
-
end
|
11
|
-
|
12
|
-
test 'it writes the coverage report to s3' do
|
13
|
-
s3 = mock('s3_resource')
|
14
|
-
bucket = mock('bucket')
|
15
|
-
object = mock('object')
|
16
|
-
s3.expects(:bucket).with('coverage-bucket').returns(bucket)
|
17
|
-
bucket.expects(:object).with('coverband/index.html').returns(object)
|
18
|
-
File.expects(:read).at_least(0).returns("content ./assets/#{html_version}/")
|
19
|
-
object.expects(:put).with(body: 'content ')
|
20
|
-
Aws::S3::Resource.expects(:new).returns(s3)
|
21
|
-
|
22
|
-
s3_writer_options = {
|
23
|
-
region: 'us-west-1',
|
24
|
-
access_key_id: '',
|
25
|
-
secret_access_key: ''
|
26
|
-
}
|
27
|
-
Coverband::Utils::S3ReportWriter.new('coverage-bucket', s3_writer_options).persist!
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|