mobile_metrics 0.0.3 → 0.1.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/Gemfile.lock +3 -3
- data/lib/mobile_metrics.rb +148 -124
- data/lib/mobile_metrics/junit.rb +6 -7
- data/lib/mobile_metrics/version.rb +1 -1
- data/mobile_metrics.gemspec +2 -2
- metadata +8 -10
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71fab7bc92efcbd6f73f826acb238b1f9a8176ce0a25abc5e8e7a0f80772ee7f
|
4
|
+
data.tar.gz: 43d17ec1681e016bcc0123d516497a6754f696d67964908a824f5a2bff71d532
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0f94715c4f0039f8f96780b9c3b85f58806c57acdefb02c2e9b0dbdfab1545e4b4e58677a5763436dac765fbb7eda5ee4b78dda503fe3e0b27b93ccd29ca2e9
|
7
|
+
data.tar.gz: 9a85990eeda3eee10fe92a4b5660697c7b1385749b235a4d99e5af4da718cb94b7a1b5fbfccca1e4272e55d10e0cf307e309d8124d4d1d224cfbd8cf9911a30e
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mobile_metrics (0.0
|
4
|
+
mobile_metrics (0.1.0)
|
5
5
|
ox (~> 2.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
diff-lcs (1.3)
|
11
|
-
ox (2.
|
11
|
+
ox (2.13.4)
|
12
12
|
rake (10.5.0)
|
13
13
|
rspec (3.7.0)
|
14
14
|
rspec-core (~> 3.7.0)
|
@@ -34,4 +34,4 @@ DEPENDENCIES
|
|
34
34
|
rspec (~> 3.0)
|
35
35
|
|
36
36
|
BUNDLED WITH
|
37
|
-
1.
|
37
|
+
1.17.3
|
data/lib/mobile_metrics.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'mobile_metrics/version'
|
2
|
+
require 'mobile_metrics/junit'
|
3
3
|
|
4
4
|
require 'time'
|
5
5
|
require 'json'
|
@@ -8,18 +8,18 @@ require 'fileutils'
|
|
8
8
|
require 'pathname'
|
9
9
|
|
10
10
|
# Metric types
|
11
|
-
METRIC_TIMER = 'x.mobile_metric.timer'
|
12
|
-
METRIC_COUNTER = 'x.mobile_metric.counter'
|
13
|
-
METRIC_RATIO = 'x.mobile_metric.ratio'
|
14
|
-
METRIC_SIZE = 'x.mobile_metric.size'
|
11
|
+
METRIC_TIMER = 'x.mobile_metric.timer'.freeze
|
12
|
+
METRIC_COUNTER = 'x.mobile_metric.counter'.freeze
|
13
|
+
METRIC_RATIO = 'x.mobile_metric.ratio'.freeze
|
14
|
+
METRIC_SIZE = 'x.mobile_metric.size'.freeze
|
15
15
|
|
16
16
|
# Misc Constants
|
17
|
-
UNKNOWN = 'UNKNOWN'
|
18
|
-
LOG_PREFIX = 'CI-METRICS:'
|
19
|
-
LOGGING_DIR = '/tmp/cimetricslogs'
|
20
|
-
UPLOAD_ENV_VAR = 'MOBILE_METRICS_UPLOAD_LOCATION'
|
17
|
+
UNKNOWN = 'UNKNOWN'.freeze
|
18
|
+
LOG_PREFIX = 'CI-METRICS:'.freeze
|
19
|
+
LOGGING_DIR = '/tmp/cimetricslogs'.freeze
|
20
|
+
UPLOAD_ENV_VAR = 'MOBILE_METRICS_UPLOAD_LOCATION'.freeze
|
21
21
|
|
22
|
-
module MobileMetrics
|
22
|
+
module MobileMetrics
|
23
23
|
class Log
|
24
24
|
|
25
25
|
@@in_progress_timers = {}
|
@@ -27,63 +27,63 @@ module MobileMetrics
|
|
27
27
|
@@env_values = nil
|
28
28
|
@@verbose = false
|
29
29
|
@@upload_location = nil
|
30
|
-
|
30
|
+
|
31
31
|
#========================================
|
32
32
|
# Configuration
|
33
33
|
#=========================================
|
34
|
-
|
34
|
+
|
35
35
|
# Named params, with ability to override / leave out stuff we don't care about.
|
36
36
|
def self.set_default_values(
|
37
37
|
# Required params
|
38
38
|
project:,
|
39
39
|
# These params either aren't required, or have sensible defaults.
|
40
|
-
level: "info",
|
41
|
-
platform: "iOS",
|
42
|
-
buildUrl: ENV['BUILD_URL'],
|
43
|
-
gitUrl: ENV['GIT_URL'],
|
44
|
-
gitBranch: ENV['
|
45
|
-
gitSha: ENV['
|
40
|
+
level: "info",
|
41
|
+
platform: "iOS",
|
42
|
+
buildUrl: ENV['BUILD_URL'],
|
43
|
+
gitUrl: ENV['GIT_URL'],
|
44
|
+
gitBranch: ENV['BRANCH'],
|
45
|
+
gitSha: ENV['SHA'],
|
46
46
|
# no sensible defaults for these, we'll strip them later
|
47
|
-
buildType: UNKNOWN,
|
47
|
+
buildType: UNKNOWN,
|
48
48
|
brand: UNKNOWN,
|
49
49
|
# Controls log levels within this class
|
50
50
|
verbose: false,
|
51
51
|
# Upload location for logs
|
52
52
|
upload_location: nil
|
53
|
-
)
|
54
|
-
|
53
|
+
)
|
54
|
+
|
55
55
|
#TODO: May be able to support overridding these at some point in the future.
|
56
56
|
# It won't be threadsafe, but our builds aren't parallelized at the build script level anyway.
|
57
57
|
if @@env_values
|
58
58
|
print 'Can only override default values once! Aborting!'
|
59
59
|
return
|
60
60
|
end
|
61
|
-
|
62
|
-
if project.nil?
|
61
|
+
|
62
|
+
if project.nil?
|
63
63
|
print 'Project value for logging MUST be non-nil, failing build.'
|
64
64
|
exit 14
|
65
65
|
return
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
@@verbose = verbose
|
69
|
-
|
69
|
+
|
70
70
|
# Upload location
|
71
71
|
@@upload_location = (upload_location || ENV[UPLOAD_ENV_VAR])
|
72
|
-
if @@upload_location.nil?
|
72
|
+
if @@upload_location.nil?
|
73
73
|
print 'Upload location value for logging MUST not be nil, exiting.'
|
74
74
|
exit 15
|
75
75
|
return
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
# Create the logging dir + filename
|
79
79
|
FileUtils.mkdir_p(LOGGING_DIR)
|
80
80
|
filename = "metrics_#{project}_#{build_number}.log"
|
81
81
|
@@log_file = Pathname.new(LOGGING_DIR) + filename
|
82
82
|
print @@log_file if @@verbose
|
83
|
-
|
83
|
+
|
84
84
|
# Populate our env values
|
85
85
|
@@env_values = {}
|
86
|
-
|
86
|
+
|
87
87
|
# Required
|
88
88
|
@@env_values[:project] = project
|
89
89
|
# Optional
|
@@ -93,131 +93,155 @@ module MobileMetrics
|
|
93
93
|
@@env_values[:gitBranch] = gitBranch
|
94
94
|
@@env_values[:gitSha] = gitSha
|
95
95
|
@@env_values[:buildUrl] = buildUrl
|
96
|
-
|
96
|
+
|
97
97
|
#TODO: Should any of these be required?
|
98
98
|
@@env_values[:buildType] = buildType if buildType != UNKNOWN
|
99
99
|
@@env_values[:brand] = brand if brand != UNKNOWN
|
100
100
|
end
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
101
|
+
|
102
|
+
# =begin
|
103
|
+
# # Sample timer metric
|
104
|
+
# {
|
105
|
+
# "time": "<yyyy-MM-ddThh:mm:ss[.sss]Z>",
|
106
|
+
# "name": "x.mobile_metric.<metric_type>",
|
107
|
+
# "level": "info",
|
108
|
+
# "data": {
|
109
|
+
# "name": "<metric_name>",
|
110
|
+
# … // additional data per metric type
|
111
|
+
# }
|
112
|
+
# "context": {
|
113
|
+
# "platform": "<ios_or_android>",
|
114
|
+
# "project": "<project_name>",
|
115
|
+
# "gitUrl": "<git_url>",
|
116
|
+
# "gitBranch": "<git_branch>",
|
117
|
+
# "gitSha": "<git_sha>",
|
118
|
+
# "buildType": "<build_type>",
|
119
|
+
# "brand": "<brand>",
|
120
|
+
# "host": "<machine_dns_name_or_device_name>",
|
121
|
+
# "processId": "<process_id_or_build_number>"
|
122
|
+
# }
|
123
|
+
# }
|
124
|
+
# =end
|
125
125
|
|
126
126
|
#=========================================
|
127
127
|
# Public Logging Methods
|
128
128
|
#=========================================
|
129
|
-
|
129
|
+
|
130
130
|
def self.log_ratio_metric(name:, ratio:)
|
131
|
-
overrides = {name: METRIC_RATIO, data: {name: name, ratio: ratio.to_f }}
|
131
|
+
overrides = { name: METRIC_RATIO, data: { name: name, ratio: ratio.to_f } }
|
132
132
|
log_partial_metric(overrides)
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
def self.log_counter_metric(name:, count:)
|
136
|
-
overrides = {name: METRIC_COUNTER, data: {name: name, count: count.to_i }}
|
136
|
+
overrides = { name: METRIC_COUNTER, data: {name: name, count: count.to_i } }
|
137
137
|
log_partial_metric(overrides)
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
140
|
def self.log_size_metric(name:, sizeInBytes:, filename:, artifactUrl:)
|
141
|
-
overrides = {name: METRIC_SIZE, data: {name: name, filename: filename,
|
141
|
+
overrides = { name: METRIC_SIZE, data: { name: name, filename: filename, size: sizeInBytes, artifactUrl: artifactUrl } }
|
142
142
|
log_partial_metric(overrides)
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
|
+
def self.log_timer(name:, delta_in_ms:)
|
146
|
+
overrides = {name: METRIC_TIMER, data: {name: name, duration: delta_in_ms }}
|
147
|
+
log_partial_metric(overrides)
|
148
|
+
end
|
149
|
+
|
145
150
|
def self.start_timer_metric(name:)
|
146
|
-
if @@in_progress_timers.has_key?(name)
|
151
|
+
if @@in_progress_timers.has_key?(name)
|
147
152
|
print "WARNING: #{name} already has a running timer, refusing to start a new timer"
|
148
153
|
return
|
149
154
|
end
|
150
155
|
@@in_progress_timers[name] = monotonic_timestamp
|
151
156
|
end
|
152
|
-
|
157
|
+
|
153
158
|
def self.end_timer_metric(name:)
|
154
159
|
if !@@in_progress_timers.has_key?(name)
|
155
160
|
print "WARNING: #{name} does not have a running timer, the end_timer_metric call has no effect"
|
156
161
|
return
|
157
162
|
end
|
158
|
-
|
163
|
+
|
159
164
|
# Calculate delta
|
160
165
|
start = @@in_progress_timers[name]
|
161
166
|
now = monotonic_timestamp
|
162
167
|
delta_in_ms = ((now - start) * 1000).to_i
|
163
|
-
|
168
|
+
|
164
169
|
# remove existing timer
|
165
170
|
@@in_progress_timers.delete(name)
|
166
|
-
|
171
|
+
|
167
172
|
# log to file
|
168
173
|
overrides = {name: METRIC_TIMER, data: {name: name, duration: delta_in_ms }}
|
169
174
|
log_partial_metric(overrides)
|
170
175
|
end
|
171
|
-
|
176
|
+
|
172
177
|
# Block based timer. This is the recommended way to timer operations.
|
173
|
-
def self.time(name:, &
|
178
|
+
def self.time(name:, &_block)
|
174
179
|
self.start_timer_metric(name: name)
|
175
180
|
yield
|
176
181
|
self.end_timer_metric(name: name)
|
177
182
|
end
|
178
|
-
|
179
|
-
def self.
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
return
|
183
|
+
|
184
|
+
def self.log_unit_test_count_from_file(junit_file:, fail_build_on_file_not_found: false)
|
185
|
+
if !File.exist?(junit_file)
|
186
|
+
print "WARN: JUnit file #{junit_file} does not exist on disk"
|
187
|
+
exit 16 if fail_build_on_file_not_found
|
188
|
+
return if !fail_build_on_file_not_found
|
184
189
|
end
|
185
|
-
|
190
|
+
|
191
|
+
parser = MobileMetrics::JunitParser.new
|
192
|
+
parser.parse(junit_file)
|
193
|
+
unit_test_count = parser.tests.count
|
194
|
+
|
195
|
+
# Only log values > 0 to avoid any parser issues.
|
196
|
+
if unit_test_count == 0
|
197
|
+
print 'WARN: Parsed unit test count is zero, avoiding logging.'
|
198
|
+
else
|
199
|
+
self.log_counter_metric(name: 'unit_tests_count', count: unit_test_count)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def self.upload_logs
|
204
|
+
# Already called upload logs before, second time is a no-op
|
205
|
+
if @@log_file.nil? || !@@log_file.file?
|
206
|
+
print 'WARN: Log file is empty or doesn\'t exist. Was upload_logs called previously?'
|
207
|
+
return
|
208
|
+
end
|
209
|
+
|
186
210
|
# Skip uploads for local dev machines
|
187
|
-
if !should_upload_logs
|
211
|
+
if !should_upload_logs
|
188
212
|
print 'Detected local machine, refusing to upload build metrics. Removing intermediate log file'
|
189
|
-
remove_log_file
|
213
|
+
remove_log_file
|
190
214
|
return
|
191
215
|
end
|
192
|
-
|
216
|
+
|
193
217
|
# Warn for any open timers
|
194
|
-
if @@in_progress_timers.size > 0
|
195
|
-
@@in_progress_timers.each { |k,
|
218
|
+
if @@in_progress_timers.size > 0
|
219
|
+
@@in_progress_timers.each { |k, _v|
|
196
220
|
print "WARN: Timer not closed when upload_logs was called: #{k}"
|
197
221
|
}
|
198
222
|
end
|
199
|
-
|
200
|
-
# Upload
|
201
|
-
upload_log_file
|
202
|
-
|
223
|
+
|
224
|
+
# Upload
|
225
|
+
upload_log_file
|
226
|
+
|
203
227
|
# Remove log file
|
204
|
-
remove_log_file
|
228
|
+
remove_log_file
|
205
229
|
end
|
206
|
-
|
207
|
-
def self.log_file
|
230
|
+
|
231
|
+
def self.log_file
|
208
232
|
@@log_file
|
209
233
|
end
|
210
|
-
|
211
|
-
def self.upload_location
|
234
|
+
|
235
|
+
def self.upload_location
|
212
236
|
@@upload_location
|
213
237
|
end
|
214
|
-
|
238
|
+
|
215
239
|
# Tears down logging instance, removes any intermediate log files.
|
216
240
|
# Does not finalize or upload any in-progress logs.
|
217
241
|
# To use the logger again, you'll have to call set_default_values before any other methods.
|
218
|
-
def self.reset
|
219
|
-
if @@log_file
|
220
|
-
remove_log_file
|
242
|
+
def self.reset
|
243
|
+
if @@log_file
|
244
|
+
remove_log_file
|
221
245
|
end
|
222
246
|
@@log_file = nil
|
223
247
|
@@env_values = nil
|
@@ -225,15 +249,15 @@ module MobileMetrics
|
|
225
249
|
@@verbose = false
|
226
250
|
@@upload_location = nil
|
227
251
|
end
|
228
|
-
|
229
|
-
def self.remove_all_log_files
|
230
|
-
FileUtils.rm_rf(LOGGING_DIR)
|
252
|
+
|
253
|
+
def self.remove_all_log_files
|
254
|
+
FileUtils.rm_rf(LOGGING_DIR)
|
231
255
|
end
|
232
|
-
|
256
|
+
|
233
257
|
private
|
234
258
|
|
235
259
|
# Creates a stubbed metric with common fields
|
236
|
-
def self.default_metric
|
260
|
+
def self.default_metric
|
237
261
|
if !@@env_values
|
238
262
|
print 'default_metric called before env_values initialized, aborting!'
|
239
263
|
exit 12
|
@@ -251,25 +275,26 @@ module MobileMetrics
|
|
251
275
|
buildUrl: @@env_values[:buildUrl],
|
252
276
|
host: hostname(),
|
253
277
|
processId: build_number()
|
254
|
-
}.select { |k,v| !v.nil? }
|
278
|
+
}.select { |k,v| !v.nil? }
|
255
279
|
{time: timestamp(), level:@@env_values[:level], context: context}
|
256
280
|
end
|
257
|
-
|
281
|
+
|
258
282
|
def self.append_to_log(value)
|
259
283
|
# Create the log file if it doesn't exist
|
260
284
|
if !@@log_file.file?
|
261
|
-
FileUtils.touch(@@log_file)
|
285
|
+
FileUtils.touch(@@log_file)
|
262
286
|
end
|
263
287
|
File.open(@@log_file, 'a+') { |f| f.puts(value + "\n") }
|
264
288
|
end
|
265
|
-
|
266
|
-
def self.remove_log_file
|
289
|
+
|
290
|
+
def self.remove_log_file
|
267
291
|
FileUtils.rm_rf(@@log_file)
|
268
292
|
end
|
269
|
-
|
270
|
-
def self.upload_log_file
|
293
|
+
|
294
|
+
def self.upload_log_file
|
271
295
|
destination = @@upload_location + "metrics_#{@@env_values[:project]}_#{build_number}.log"
|
272
|
-
|
296
|
+
verbose_flag = @@verbose ? '-v' : ''
|
297
|
+
command = "scp #{verbose_flag} -o StrictHostKeyChecking=no #{@@log_file} #{destination}"
|
273
298
|
# This feels icky
|
274
299
|
print `#{command}`
|
275
300
|
end
|
@@ -278,17 +303,17 @@ module MobileMetrics
|
|
278
303
|
# Note: This format doesn't currently add milliseconds.
|
279
304
|
# Example: "2018-03-27T21:12:21Z"
|
280
305
|
# Note: DO NOT use this for benchmarking / measuring timers, see monotonic_timestamp instead.
|
281
|
-
def self.timestamp
|
306
|
+
def self.timestamp
|
282
307
|
Time.now.utc.iso8601.to_s
|
283
308
|
end
|
284
|
-
|
309
|
+
|
285
310
|
# Returns a floating point monotonic timestamp suitable for timers
|
286
311
|
# Monotonic means we won't ever go back for things like leap seconds
|
287
312
|
# Unit is a floating point in seconds.
|
288
|
-
def self.monotonic_timestamp
|
313
|
+
def self.monotonic_timestamp
|
289
314
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
290
315
|
end
|
291
|
-
|
316
|
+
|
292
317
|
# Each metric should call this method.
|
293
318
|
# This method handles merging the metric hash with the default hash,
|
294
319
|
# Generates the JSON with the keys in the right order, then appends to the log.
|
@@ -299,40 +324,39 @@ module MobileMetrics
|
|
299
324
|
metric = ordered_hash.to_json
|
300
325
|
append_to_log(metric)
|
301
326
|
end
|
302
|
-
|
327
|
+
|
303
328
|
# Util method for merging the default hash values and overrides recursively as we want them
|
304
329
|
def self.merge_hashes(default, overrides)
|
305
|
-
default.merge(overrides) { |key, oldval, newval|
|
306
|
-
if key == :data || key == :
|
330
|
+
default.merge(overrides) { |key, oldval, newval|
|
331
|
+
if key == :data || key == :context
|
307
332
|
oldval.merge(newval)
|
308
333
|
else
|
309
334
|
newval
|
310
335
|
end
|
311
336
|
}
|
312
337
|
end
|
313
|
-
|
338
|
+
|
314
339
|
# Returns the host name of the machine we are currently running on
|
315
|
-
def self.hostname
|
340
|
+
def self.hostname
|
316
341
|
ENV['NODE_NAME'] || 'local-dev'
|
317
342
|
end
|
318
|
-
|
319
|
-
def self.build_number
|
343
|
+
|
344
|
+
def self.build_number
|
320
345
|
ENV['BUILD_NUMBER']
|
321
346
|
end
|
322
|
-
|
347
|
+
|
323
348
|
# This method checks against a bunch of default environment variables available through DOTCI
|
324
349
|
# The intent is never to upload timing logs from a local machine, so we make it unlikely that these
|
325
350
|
# env variables are present on a dev's local machine
|
326
|
-
def self.should_upload_logs
|
351
|
+
def self.should_upload_logs
|
327
352
|
have_workspace = ENV['WORKSPACE'] && !ENV['WORKSPACE'].empty?
|
328
353
|
have_build_number = ENV['BUILD_NUMBER'] && !ENV['BUILD_NUMBER'].empty?
|
329
354
|
have_jenkins_url = ENV['JENKINS_URL'] && !ENV['JENKINS_URL'].empty?
|
330
|
-
|
331
|
-
have_workspace && have_build_number && have_jenkins_url && have_ci_var
|
355
|
+
have_workspace && have_build_number && have_jenkins_url
|
332
356
|
end
|
333
|
-
|
357
|
+
|
334
358
|
def self.print(val)
|
335
359
|
puts("#{LOG_PREFIX} #{val}")
|
336
360
|
end
|
337
361
|
end
|
338
|
-
end
|
362
|
+
end
|
data/lib/mobile_metrics/junit.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
|
2
2
|
module MobileMetrics
|
3
|
-
|
4
3
|
# Adapted from: https://github.com/orta/danger-junit/blob/master/lib/junit/plugin.rb
|
5
4
|
class JunitParser
|
6
5
|
# All the tests for introspection
|
@@ -55,23 +54,23 @@ module MobileMetrics
|
|
55
54
|
failed_suites = suite_root.nodes.select { |suite| suite[:failures].to_i > 0 || suite[:errors].to_i > 0 }
|
56
55
|
failed_tests = failed_suites.map(&:nodes).flatten.select { |node| node.kind_of?(Ox::Element) && node.value == 'testcase' }
|
57
56
|
|
58
|
-
@failures = failed_tests.select do |test|
|
57
|
+
@failures = failed_tests.select do |test|
|
59
58
|
test.nodes.count > 0
|
60
59
|
end.select do |test|
|
61
60
|
node = test.nodes.first
|
62
61
|
node.kind_of?(Ox::Element) && node.value == 'failure'
|
63
62
|
end
|
64
63
|
|
65
|
-
@errors = failed_tests.select do |test|
|
64
|
+
@errors = failed_tests.select do |test|
|
66
65
|
test.nodes.count > 0
|
67
|
-
end.select do |test|
|
66
|
+
end.select do |test|
|
68
67
|
node = test.nodes.first
|
69
68
|
node.kind_of?(Ox::Element) && node.value == 'error'
|
70
69
|
end
|
71
70
|
|
72
|
-
@skipped = tests.select do |test|
|
71
|
+
@skipped = tests.select do |test|
|
73
72
|
test.nodes.count > 0
|
74
|
-
end.select do |test|
|
73
|
+
end.select do |test|
|
75
74
|
node = test.nodes.first
|
76
75
|
node.kind_of?(Ox::Element) && node.value == 'skipped'
|
77
76
|
end
|
@@ -79,4 +78,4 @@ module MobileMetrics
|
|
79
78
|
@passes = tests - @failures - @errors - @skipped
|
80
79
|
end
|
81
80
|
end
|
82
|
-
end
|
81
|
+
end
|
data/mobile_metrics.gemspec
CHANGED
@@ -13,12 +13,12 @@ Gem::Specification.new do |spec|
|
|
13
13
|
# spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
-
|
16
|
+
f.match(%r{^(test|spec|features|README|scripts)/}) || f.match(%r{^(.ci|README.md)})
|
17
17
|
end
|
18
18
|
spec.bindir = "exe"
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
|
-
|
21
|
+
|
22
22
|
spec.add_runtime_dependency 'ox', '~> 2.0'
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.16"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mobile_metrics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dbeard
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ox
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
|
-
description:
|
69
|
+
description:
|
70
70
|
email:
|
71
71
|
- dbeard@groupon.com
|
72
72
|
executables: []
|
@@ -75,7 +75,6 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- ".gitignore"
|
77
77
|
- ".rspec"
|
78
|
-
- ".travis.yml"
|
79
78
|
- Gemfile
|
80
79
|
- Gemfile.lock
|
81
80
|
- Rakefile
|
@@ -85,10 +84,10 @@ files:
|
|
85
84
|
- lib/mobile_metrics/junit.rb
|
86
85
|
- lib/mobile_metrics/version.rb
|
87
86
|
- mobile_metrics.gemspec
|
88
|
-
homepage:
|
87
|
+
homepage:
|
89
88
|
licenses: []
|
90
89
|
metadata: {}
|
91
|
-
post_install_message:
|
90
|
+
post_install_message:
|
92
91
|
rdoc_options: []
|
93
92
|
require_paths:
|
94
93
|
- lib
|
@@ -103,9 +102,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
102
|
- !ruby/object:Gem::Version
|
104
103
|
version: '0'
|
105
104
|
requirements: []
|
106
|
-
|
107
|
-
|
108
|
-
signing_key:
|
105
|
+
rubygems_version: 3.0.3
|
106
|
+
signing_key:
|
109
107
|
specification_version: 4
|
110
108
|
summary: Mobile logging format library
|
111
109
|
test_files: []
|