coverband-service-client 0.0.8 → 0.0.12.rc.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 +4 -4
- data/Gemfile.lock +3 -3
- data/lib/coverband-service-client.rb +167 -36
- data/lib/coverband/service/client/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b93d9abe50ba1657318562b8fa04b645cfdd2fc22bca0f711cbde57b6d6b3c7
|
4
|
+
data.tar.gz: 1918f4689b50c6bda5b51d2f578b13b4bf439d38fb3510318165152b9093f1d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33c461c2915ef4f9582fd8f87b5b2afa230076f1349e88ef7f66987cb1a8dda25d97c26983421ca52f900c3dd2d48d313e44dd69a8b15984a349dbe3fe4b3fd9
|
7
|
+
data.tar.gz: 0ea1b378ae8044400d50ad33944881d27552b42296cae06ceda360617b30d26a9bb3614e6a81c10b0bd530bcf59ca10ef9be3fba928e4c98b2f22929c21f4a66
|
data/Gemfile.lock
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
coverband-service-client (0.0.
|
4
|
+
coverband-service-client (0.0.12.rc.1)
|
5
5
|
coverband (~> 4.2.4)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
coverband (4.2.
|
10
|
+
coverband (4.2.5)
|
11
11
|
redis
|
12
12
|
minitest (5.14.0)
|
13
13
|
rake (13.0.1)
|
14
|
-
redis (4.1.
|
14
|
+
redis (4.1.4)
|
15
15
|
|
16
16
|
PLATFORMS
|
17
17
|
ruby
|
@@ -1,24 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'socket'
|
2
3
|
|
4
|
+
COVERBAND_ORIGINAL_START = ENV['COVERBAND_DISABLE_AUTO_START']
|
5
|
+
ENV['COVERBAND_DISABLE_AUTO_START'] = 'true'
|
3
6
|
require 'coverband'
|
4
7
|
require 'coverband/service/client/version'
|
5
8
|
require 'securerandom'
|
6
9
|
|
7
|
-
COVERBAND_ENV = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || (defined?(Rails) ? Rails.env : 'unknown')
|
8
|
-
COVERBAND_SERVICE_URL = ENV['COVERBAND_URL'] || 'https://coverband.io'
|
9
|
-
COVERBAND_TIMEOUT = (COVERBAND_ENV == 'development') ? 5 : 1
|
10
|
-
COVERBAND_ENABLE_DEV_MODE = ENV['COVERBAND_ENABLE_DEV_MODE'] || false
|
11
|
-
COVERBAND_ENABLE_TEST_MODE = ENV['COVERBAND_ENABLE_TEST_MODE'] || false
|
12
|
-
COVERBAND_PROCESS_TYPE = ENV['PROCESS_TYPE'] || 'unknown'
|
13
|
-
COVERBAND_REPORT_PERIOD = (ENV['COVERBAND_REPORT_PERIOD'] || 600).to_i
|
14
|
-
|
15
10
|
module Coverband
|
11
|
+
COVERBAND_ENV = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || (defined?(Rails) ? Rails.env : 'unknown')
|
12
|
+
COVERBAND_SERVICE_URL = ENV['COVERBAND_URL'] || 'https://coverband.io'
|
13
|
+
COVERBAND_TIMEOUT = (COVERBAND_ENV == 'development') ? 5 : 2
|
14
|
+
COVERBAND_ENABLE_DEV_MODE = ENV['COVERBAND_ENABLE_DEV_MODE'] || false
|
15
|
+
COVERBAND_ENABLE_TEST_MODE = ENV['COVERBAND_ENABLE_TEST_MODE'] || false
|
16
|
+
COVERBAND_PROCESS_TYPE = ENV['PROCESS_TYPE'] || 'unknown'
|
17
|
+
COVERBAND_REPORT_PERIOD = (ENV['COVERBAND_REPORT_PERIOD'] || 600).to_i
|
18
|
+
|
19
|
+
def self.service_disabled_dev_test_env?
|
20
|
+
(COVERBAND_ENV == 'test' && !COVERBAND_ENABLE_TEST_MODE) ||
|
21
|
+
(COVERBAND_ENV == 'development' && !COVERBAND_ENABLE_DEV_MODE)
|
22
|
+
end
|
16
23
|
|
17
|
-
if
|
18
|
-
COVERBAND_ENV == 'development' && !COVERBAND_ENABLE_DEV_MODE
|
19
|
-
)
|
24
|
+
if service_disabled_dev_test_env?
|
20
25
|
def self.report_coverage
|
21
|
-
# for now disable coverband reporting in test env by default
|
26
|
+
# for now disable coverband reporting in test & dev env by default
|
27
|
+
if Coverband.configuration.verbose
|
28
|
+
puts "Coverband: disabled for #{COVERBAND_ENV}, set COVERBAND_ENABLE_DEV_MODE or COVERBAND_ENABLE_TEST_MODE to enable" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
|
29
|
+
end
|
22
30
|
end
|
23
31
|
end
|
24
32
|
|
@@ -28,16 +36,40 @@ module Coverband
|
|
28
36
|
#
|
29
37
|
# NOTES:
|
30
38
|
# * uses net/http to avoid any dependencies
|
31
|
-
# * currently JSON, but likely better to move to something
|
39
|
+
# * currently JSON, but likely better to move to something faster
|
32
40
|
###
|
33
41
|
class Service < Base
|
34
|
-
attr_reader :coverband_url, :process_type, :runtime_env
|
42
|
+
attr_reader :coverband_url, :process_type, :runtime_env, :hostname, :pid, :stats
|
35
43
|
|
36
44
|
def initialize(coverband_url, opts = {})
|
37
45
|
super()
|
38
46
|
@coverband_url = coverband_url
|
39
|
-
@process_type = opts.fetch(:process_type) { COVERBAND_PROCESS_TYPE }
|
47
|
+
@process_type = opts.fetch(:process_type) { $PROGRAM_NAME&.split('/')&.last || COVERBAND_PROCESS_TYPE }
|
48
|
+
@hostname = opts.fetch(:hostname) { ENV["DYNO"] || Socket.gethostname.force_encoding('utf-8').encode }
|
40
49
|
@runtime_env = opts.fetch(:runtime_env) { COVERBAND_ENV }
|
50
|
+
initialize_stats
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize_stats
|
54
|
+
return unless ENV['COVERBAND_STATS_KEY']
|
55
|
+
return unless defined?(Dogapi::Client)
|
56
|
+
|
57
|
+
@stats = Dogapi::Client.new(ENV['COVERBAND_STATS_KEY'])
|
58
|
+
end
|
59
|
+
|
60
|
+
def report_timing(timing)
|
61
|
+
return unless @stats
|
62
|
+
|
63
|
+
@stats.emit_point(
|
64
|
+
'coverband.save.time',
|
65
|
+
timing,
|
66
|
+
host: hostname,
|
67
|
+
env: runtime_env,
|
68
|
+
client: "coverband_#{self.class.name.split("::").last}")
|
69
|
+
end
|
70
|
+
|
71
|
+
def logger
|
72
|
+
Coverband.configuration.logger
|
41
73
|
end
|
42
74
|
|
43
75
|
def clear!
|
@@ -53,28 +85,35 @@ module Coverband
|
|
53
85
|
0
|
54
86
|
end
|
55
87
|
|
56
|
-
|
88
|
+
def api_key
|
89
|
+
ENV['COVERBAND_API_KEY'] || Coverband.configuration.api_key
|
90
|
+
end
|
91
|
+
|
92
|
+
###
|
93
|
+
# Fetch coverband coverage via the API
|
94
|
+
###
|
57
95
|
def coverage(local_type = nil, opts = {})
|
58
96
|
local_type ||= opts.key?(:override_type) ? opts[:override_type] : type
|
59
|
-
|
60
|
-
|
97
|
+
env_filter = opts.key?(:env_filter) ? opts[:env_filter] : 'production'
|
98
|
+
uri = URI("#{coverband_url}/api/coverage?type=#{local_type}&env_filter=#{env_filter}",)
|
99
|
+
req = Net::HTTP::Get.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => api_key)
|
61
100
|
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
62
101
|
http.request(req)
|
63
102
|
end
|
64
103
|
coverage_data = JSON.parse(res.body)
|
65
|
-
# puts "coverage data: "
|
66
|
-
# puts coverage_data
|
67
104
|
coverage_data
|
68
105
|
rescue StandardError => e
|
69
|
-
|
106
|
+
logger&.error "Coverband: Error while retrieving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
|
70
107
|
end
|
71
108
|
|
72
109
|
def save_report(report)
|
73
|
-
#puts caller.join(',')
|
74
110
|
return if report.empty?
|
75
111
|
|
112
|
+
# We set here vs initialize to avoid setting on the primary process vs child processes
|
113
|
+
@pid ||= ::Process.pid
|
114
|
+
|
76
115
|
# TODO: do we need dup
|
77
|
-
# TODO: remove timestamps, server will track first_seen
|
116
|
+
# TODO: remove upstream timestamps, server will track first_seen
|
78
117
|
Thread.new do
|
79
118
|
data = expand_report(report.dup)
|
80
119
|
full_package = {
|
@@ -83,12 +122,18 @@ module Coverband
|
|
83
122
|
tags: {
|
84
123
|
process_type: process_type,
|
85
124
|
app_loading: type == Coverband::EAGER_TYPE,
|
86
|
-
runtime_env: runtime_env
|
125
|
+
runtime_env: runtime_env,
|
126
|
+
pid: pid,
|
127
|
+
hostname: hostname,
|
87
128
|
},
|
88
129
|
file_coverage: data
|
89
130
|
}
|
90
131
|
}
|
132
|
+
|
133
|
+
starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
91
134
|
save_coverage(full_package)
|
135
|
+
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
136
|
+
report_timing((ending - starting))
|
92
137
|
end&.join
|
93
138
|
end
|
94
139
|
|
@@ -99,12 +144,18 @@ module Coverband
|
|
99
144
|
private
|
100
145
|
|
101
146
|
def save_coverage(data)
|
147
|
+
if api_key.nil?
|
148
|
+
puts "Coverband: Error: no Coverband API key was found!"
|
149
|
+
return
|
150
|
+
end
|
151
|
+
|
102
152
|
uri = URI("#{coverband_url}/api/collector")
|
103
153
|
req = Net::HTTP::Post.new(uri,
|
104
154
|
'Content-Type' => 'application/json',
|
105
|
-
'Coverband-Token' =>
|
106
|
-
# puts "sending #{data}"
|
155
|
+
'Coverband-Token' => api_key)
|
107
156
|
req.body = { remote_uuid: SecureRandom.uuid, data: data }.to_json
|
157
|
+
|
158
|
+
logger&.info "Coverband: saving (#{uri}) #{req.body}" if Coverband.configuration.verbose
|
108
159
|
res = Net::HTTP.start(
|
109
160
|
uri.hostname,
|
110
161
|
uri.port,
|
@@ -116,7 +167,51 @@ module Coverband
|
|
116
167
|
http.request(req)
|
117
168
|
end
|
118
169
|
rescue StandardError => e
|
119
|
-
|
170
|
+
logger&.info "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class PersistentService < Service
|
175
|
+
attr_reader :http, :stats
|
176
|
+
|
177
|
+
def initialize(coverband_url, opts = {})
|
178
|
+
super
|
179
|
+
initiate_http
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def initiate_http
|
185
|
+
@http = Net::HTTP::Persistent.new name: 'coverband_persistent'
|
186
|
+
@http.headers['Content-Type'] = 'application/json'
|
187
|
+
@http.headers['Coverband-Token'] = api_key
|
188
|
+
@http.open_timeout = COVERBAND_TIMEOUT
|
189
|
+
@http.read_timeout = COVERBAND_TIMEOUT
|
190
|
+
@http.ssl_timeout = COVERBAND_TIMEOUT
|
191
|
+
end
|
192
|
+
|
193
|
+
def save_coverage(data)
|
194
|
+
persistent_attempts = 0
|
195
|
+
begin
|
196
|
+
if api_key.nil?
|
197
|
+
puts "Coverband: Error: no Coverband API key was found!"
|
198
|
+
return
|
199
|
+
end
|
200
|
+
|
201
|
+
post_uri = URI("#{coverband_url}/api/collector")
|
202
|
+
post = Net::HTTP::Post.new post_uri.path
|
203
|
+
body = { remote_uuid: SecureRandom.uuid, data: data }.to_json
|
204
|
+
post.body = body
|
205
|
+
logger&.info "Coverband: saving (#{post_uri}) #{body}" if Coverband.configuration.verbose
|
206
|
+
res = http.request post_uri, post
|
207
|
+
rescue Net::HTTP::Persistent::Error => e
|
208
|
+
persistent_attempts += 1
|
209
|
+
http.shutdown
|
210
|
+
initiate_http
|
211
|
+
retry if persistent_attempts < 2
|
212
|
+
end
|
213
|
+
rescue StandardError => e
|
214
|
+
logger&.info "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
|
120
215
|
end
|
121
216
|
end
|
122
217
|
end
|
@@ -150,14 +245,22 @@ module Coverband
|
|
150
245
|
rescue StandardError => e
|
151
246
|
# we don't want to raise errors if Coverband can't reach redis.
|
152
247
|
# This is a nice to have not a bring the system down
|
153
|
-
logger&.error "Coverband: view_tracker failed to store, error #{e.class.name}"
|
248
|
+
logger&.error "Coverband: view_tracker failed to store, error #{e.class.name}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
|
154
249
|
end
|
155
250
|
|
156
251
|
private
|
157
252
|
|
253
|
+
def api_key
|
254
|
+
ENV['COVERBAND_API_KEY'] || Coverband.configuration.api_key
|
255
|
+
end
|
256
|
+
|
257
|
+
def logger
|
258
|
+
Coverband.configuration.logger
|
259
|
+
end
|
260
|
+
|
158
261
|
def save_tracked_views(views:, reported_time:)
|
159
262
|
uri = URI("#{COVERBAND_SERVICE_URL}/api/collector")
|
160
|
-
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' =>
|
263
|
+
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json', 'Coverband-Token' => api_key)
|
161
264
|
data = {
|
162
265
|
collection_type: 'view_tracker_delta',
|
163
266
|
collection_data: {
|
@@ -174,25 +277,53 @@ module Coverband
|
|
174
277
|
http.request(req)
|
175
278
|
end
|
176
279
|
rescue StandardError => e
|
177
|
-
|
280
|
+
logger&.error "Coverband: Error while saving coverage #{e}" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
|
178
281
|
end
|
179
282
|
end
|
180
283
|
end
|
181
284
|
end
|
182
285
|
|
286
|
+
module Coverband
|
287
|
+
class Configuration
|
288
|
+
attr_accessor :api_key
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
ENV['COVERBAND_DISABLE_AUTO_START'] = COVERBAND_ORIGINAL_START
|
183
293
|
Coverband.configure do |config|
|
184
|
-
# Use
|
185
|
-
|
294
|
+
# Use the Service Adapter
|
295
|
+
if defined?(Net::HTTP::Persistent)
|
296
|
+
config.store = Coverband::Adapters::PersistentService.new(Coverband::COVERBAND_SERVICE_URL)
|
297
|
+
else
|
298
|
+
config.store = Coverband::Adapters::Service.new(Coverband::COVERBAND_SERVICE_URL)
|
299
|
+
end
|
186
300
|
|
187
301
|
# default to tracking views true
|
188
|
-
config.track_views = ENV['COVERBAND_DISABLE_VIEW_TRACKER']
|
302
|
+
config.track_views = if ENV['COVERBAND_DISABLE_VIEW_TRACKER']
|
303
|
+
false
|
304
|
+
elsif Coverband.service_disabled_dev_test_env?
|
305
|
+
false
|
306
|
+
else
|
307
|
+
true
|
308
|
+
end
|
189
309
|
|
190
310
|
# report every 10m by default
|
191
|
-
config.background_reporting_sleep_seconds = COVERBAND_ENV == 'production' ? COVERBAND_REPORT_PERIOD : 60
|
311
|
+
config.background_reporting_sleep_seconds = Coverband::COVERBAND_ENV == 'production' ? Coverband::COVERBAND_REPORT_PERIOD : 60
|
192
312
|
# add a wiggle to avoid service stampede
|
193
|
-
config.reporting_wiggle = COVERBAND_ENV == 'production' ? 90 : 6
|
313
|
+
config.reporting_wiggle = Coverband::COVERBAND_ENV == 'production' ? 90 : 6
|
194
314
|
|
195
|
-
if COVERBAND_ENV == 'test'
|
315
|
+
if Coverband::COVERBAND_ENV == 'test'
|
196
316
|
config.background_reporting_enabled = false
|
197
317
|
end
|
198
318
|
end
|
319
|
+
|
320
|
+
# NOTE: it is really hard to bypass / overload our config we should fix this in Coverband
|
321
|
+
# this hopefully detects anyone that has both gems and was trying to configure Coverband themselves.
|
322
|
+
if File.exist?('./config/coverband.rb')
|
323
|
+
puts "Warning: config/coverband.rb found, this overrides coverband service allowing one to setup open source Coverband" if Coverband.configuration.verbose || COVERBAND_ENABLE_DEV_MODE
|
324
|
+
end
|
325
|
+
|
326
|
+
Coverband.configure('./config/coverband_service.rb') if File.exist?('./config/coverband_service.rb')
|
327
|
+
Coverband.start
|
328
|
+
require "coverband/utils/railtie" if defined? ::Rails::Railtie
|
329
|
+
require "coverband/integrations/resque" if defined? ::Resque
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coverband-service-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Mayer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-06-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -106,9 +106,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
106
|
version: '0'
|
107
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - "
|
109
|
+
- - ">"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
111
|
+
version: 1.3.1
|
112
112
|
requirements: []
|
113
113
|
rubygems_version: 3.0.3
|
114
114
|
signing_key:
|