cucumber-formatter 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/cucumber_formatter.rb +34 -30
- data/lib/database.rb +28 -0
- data/lib/failure_rate_module.rb +141 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51da32d4f5d9326a9f967539d43582d890e46d9e
|
4
|
+
data.tar.gz: 14dd80718d3103a9efd448eb7ad48555cecc19b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0171ed75b8a7d99d24dd7728475cbe556b7b1acb48faca98ccef33363ac7713db304491b1fce3ec0415449ef32026504fbd16ab01ad7b84d9dcc7568a8a09587
|
7
|
+
data.tar.gz: 2c0c252a8f1adaccf9a0be0f35a900161504122cd2e5802a8782a38c244fb541053ffd71440377cd686aa94154e8a90d8f112ec82abfb430e919e725fce12831
|
data/lib/cucumber_formatter.rb
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
=end
|
1
|
+
# Copyright (c) 2015, Salesforce.com, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation and/or
|
12
|
+
# other materials provided with the distribution.
|
13
|
+
|
14
|
+
# * Neither the name of Salesforce.com nor the names of its contributors may be
|
15
|
+
# used to endorse or promote products derived from this software without specific
|
16
|
+
# prior written permission.
|
17
|
+
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
21
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
22
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
23
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
24
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
25
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
26
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
27
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
28
|
|
31
29
|
require_relative 'database.rb'
|
30
|
+
require_relative 'failure_rate_module.rb'
|
32
31
|
|
33
32
|
class CucumberFormatter
|
33
|
+
include FailureRateModule
|
34
34
|
|
35
35
|
def initialize(step_mother, io, options)
|
36
36
|
puts "Initializing CucumberMetrics ...\n\n\n"
|
@@ -102,6 +102,11 @@ class CucumberFormatter
|
|
102
102
|
@db_avail = false
|
103
103
|
end
|
104
104
|
|
105
|
+
#update failure rate if configured
|
106
|
+
if OpenStruct.new(YAML.load_file(METRICS_CONFIG_FILE)).failure_rate
|
107
|
+
check_past_failures(@scenario.title)
|
108
|
+
end
|
109
|
+
|
105
110
|
if scenario.failed?
|
106
111
|
begin
|
107
112
|
save_links(scenario) if @db_avail
|
@@ -129,7 +134,6 @@ class CucumberFormatter
|
|
129
134
|
private
|
130
135
|
|
131
136
|
def save_str_start_time
|
132
|
-
###############
|
133
137
|
@scenario_time_start = Time.now
|
134
138
|
|
135
139
|
@start_time = Time.now
|
data/lib/database.rb
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
# Copyright (c) 2015, Salesforce.com, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation and/or
|
12
|
+
# other materials provided with the distribution.
|
13
|
+
|
14
|
+
# * Neither the name of Salesforce.com nor the names of its contributors may be
|
15
|
+
# used to endorse or promote products derived from this software without specific
|
16
|
+
# prior written permission.
|
17
|
+
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
21
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
22
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
23
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
24
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
25
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
26
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
27
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
|
1
29
|
require 'mysql2'
|
2
30
|
|
3
31
|
class Database
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# Copyright (c) 2015, Salesforce.com, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation and/or
|
12
|
+
# other materials provided with the distribution.
|
13
|
+
|
14
|
+
# * Neither the name of Salesforce.com nor the names of its contributors may be
|
15
|
+
# used to endorse or promote products derived from this software without specific
|
16
|
+
# prior written permission.
|
17
|
+
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
21
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
22
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
23
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
24
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
25
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
26
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
27
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
|
29
|
+
module FailureRateModule
|
30
|
+
|
31
|
+
### calculate and save the failure rate for scenarios
|
32
|
+
def check_past_failures(scenario)
|
33
|
+
# load the failure rate config settings
|
34
|
+
config = OpenStruct.new(YAML.load_file(METRICS_CONFIG_FILE)).failure_rate
|
35
|
+
machines = Array.new
|
36
|
+
|
37
|
+
# only useful if the regex is in the config file
|
38
|
+
unless config == nil || config['machines_regex'] == nil || !config['machines_regex'].is_a?(Array)
|
39
|
+
config['machines_regex'].each do |r|
|
40
|
+
machines << r.gsub('/', '')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
machines.uniq!
|
44
|
+
|
45
|
+
scenario = scenario.strip[0..255].gsub('\'', '')
|
46
|
+
period = parse_time_period(config['time_period'])
|
47
|
+
|
48
|
+
sql = "SELECT s.id, COUNT(*) as count FROM scenarios s
|
49
|
+
LEFT JOIN scenario_test_runs str ON str.scenario_id = s.id
|
50
|
+
WHERE s.scenario_name like \'#{scenario}\'
|
51
|
+
AND test_run_at > DATE_SUB(NOW(), INTERVAL #{period.upcase})"
|
52
|
+
|
53
|
+
# find the machines used to calculate failure rate
|
54
|
+
# if not configured, will not add to query
|
55
|
+
machines.each_with_index do |reg, i|
|
56
|
+
if i == 0
|
57
|
+
sql += " AND (machine_name RLIKE '#{reg}' "
|
58
|
+
else
|
59
|
+
sql += "OR machine_name RLIKE '#{reg}' "
|
60
|
+
end
|
61
|
+
sql += ") " if i == machines.size - 1
|
62
|
+
end
|
63
|
+
|
64
|
+
scenario_id = 0
|
65
|
+
all_tests = 0
|
66
|
+
failed_tests = 0
|
67
|
+
|
68
|
+
Database.query(sql).each do |r|
|
69
|
+
all_tests = r["count"]
|
70
|
+
scenario_id = r["id"]
|
71
|
+
end
|
72
|
+
|
73
|
+
# this is required if the query above returns a count of 0; we still want
|
74
|
+
# to update the failure rate, but we need the scenario ID to do so
|
75
|
+
if scenario_id == 0 || scenario_id == nil
|
76
|
+
scenario_sql = "SELECT id FROM scenarios WHERE scenario_name like '#{scenario}'"
|
77
|
+
Database.query(scenario_sql).each do |r|
|
78
|
+
scenario_id = r["id"]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
sql = sql + " AND (passed is NULL OR passed = 0)"
|
83
|
+
|
84
|
+
Database.query(sql).each do |r|
|
85
|
+
failed_tests = r["count"]
|
86
|
+
end
|
87
|
+
|
88
|
+
# prevents divide by zero errors when no test runs in db
|
89
|
+
ratio = all_tests > 0 ? failed_tests.fdiv(all_tests) : 0
|
90
|
+
# get threshold from config settings and make sure it's less than 1
|
91
|
+
threshold = config['threshold']
|
92
|
+
if threshold == nil || !threshold.is_a?(Float) || threshold >= 1
|
93
|
+
threshold = 0.05
|
94
|
+
end
|
95
|
+
|
96
|
+
readable_period = period.split(' ')
|
97
|
+
if readable_period[0].to_i != 1
|
98
|
+
readable_period[1] += "s"
|
99
|
+
end
|
100
|
+
|
101
|
+
body_text = "\n#{(ratio * 100).round}% of the test runs for \"#{scenario}\"
|
102
|
+
have failed in the past #{readable_period.join(' ').downcase}. You'd better get some eyes on it.\n\n"
|
103
|
+
|
104
|
+
if ratio > threshold
|
105
|
+
puts body_text
|
106
|
+
end
|
107
|
+
|
108
|
+
# update the scenarios table with the failure rate
|
109
|
+
insert_sql = "UPDATE scenarios SET failure_rate = #{ratio * 100} WHERE id = #{scenario_id}"
|
110
|
+
Database.query(insert_sql)
|
111
|
+
end
|
112
|
+
|
113
|
+
# basically, we need a format MySQL will recognize. That means an integer
|
114
|
+
# followed by a specific interval type. It is currently restricted to days,
|
115
|
+
# weeks, months, quarters, and years. See the MySQL developers site:
|
116
|
+
# https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
|
117
|
+
# Override valid_times and default_time_period to change the defaults
|
118
|
+
def parse_time_period(period)
|
119
|
+
if period == nil || !period.is_a?(String)
|
120
|
+
default_time_period
|
121
|
+
else
|
122
|
+
period = period.gsub('.', '').split(' ')
|
123
|
+
if period.size != 2 || period[0] == nil || period[1] == nil
|
124
|
+
default_time_period
|
125
|
+
elsif valid_times.include?(period[1].upcase) && period[0].strip =~ /\d+/
|
126
|
+
period.join(' ')
|
127
|
+
else
|
128
|
+
default_time_period
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def valid_times
|
134
|
+
%w(DAY WEEK MONTH QUARTER YEAR)
|
135
|
+
end
|
136
|
+
|
137
|
+
def default_time_period
|
138
|
+
"1 WEEK"
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-formatter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Hartill
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mysql2
|
@@ -32,6 +32,7 @@ extra_rdoc_files: []
|
|
32
32
|
files:
|
33
33
|
- lib/cucumber_formatter.rb
|
34
34
|
- lib/database.rb
|
35
|
+
- lib/failure_rate_module.rb
|
35
36
|
homepage: https://github.com/SalesforceEng/cucumber-metrics
|
36
37
|
licenses:
|
37
38
|
- BSD 3-clause
|