quarantine 2.1.3 → 2.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/quarantine.rb +0 -17
- data/lib/quarantine/databases/google_sheets.rb +11 -3
- data/lib/quarantine/rspec_adapter.rb +53 -22
- data/lib/quarantine/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c846ed3cf614eecefab5610bfb5d693444099fe90b6b429e4c697c16a014e21b
|
4
|
+
data.tar.gz: 5d17a24b4735f4c34af2d0902c0e3a7199750ce592694b5f9fe375928ada9d03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb20ce19d6581b4836486176a080a6204a66f93d609e2b76a5d7bb91886b97e07466026fe45d0d7d4c16b8d2f072212a4ff982f42c40a55d68f42413276a92c4
|
7
|
+
data.tar.gz: bc093985a12b77f636d577b3fed3ab783f5fe206350a759a796097eee93976f42cb2fa199101a853f81d729aa109cce612f6deb4ba75748779281086e2591bca
|
data/lib/quarantine.rb
CHANGED
@@ -9,23 +9,6 @@ require 'quarantine/databases/base'
|
|
9
9
|
require 'quarantine/databases/dynamo_db'
|
10
10
|
require 'quarantine/databases/google_sheets'
|
11
11
|
|
12
|
-
module RSpec
|
13
|
-
module Core
|
14
|
-
class Example
|
15
|
-
extend T::Sig
|
16
|
-
|
17
|
-
# The implementation of clear_exception in rspec-retry doesn't work
|
18
|
-
# for examples that use `it_behaves_like`, so we implement our own version that
|
19
|
-
# clear the exception field recursively.
|
20
|
-
sig { void }
|
21
|
-
def clear_exception!
|
22
|
-
@exception = T.let(nil, T.untyped)
|
23
|
-
T.unsafe(self).example.clear_exception! if defined?(example)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
12
|
class Quarantine
|
30
13
|
extend T::Sig
|
31
14
|
|
@@ -41,7 +41,13 @@ class Quarantine
|
|
41
41
|
indexes = Hash[parsed_rows.each_with_index.map { |item, idx| [item['id'], idx] }]
|
42
42
|
|
43
43
|
items.each do |item|
|
44
|
-
cells = headers.map
|
44
|
+
cells = headers.map do |header|
|
45
|
+
match = header.match(/^(extra_)?(.+)/)
|
46
|
+
extra, name = match[1..]
|
47
|
+
puts "header: #{header}, extra: #{extra}, name: #{name}"
|
48
|
+
value = extra ? item['extra_attributes'][name.to_sym] : item[name]
|
49
|
+
value.to_s
|
50
|
+
end
|
45
51
|
row_idx = indexes[item['id']]
|
46
52
|
if row_idx
|
47
53
|
# Overwrite existing row
|
@@ -104,8 +110,10 @@ class Quarantine
|
|
104
110
|
hash_row = Hash[headers.zip(row)]
|
105
111
|
# TODO: use Google Sheets developer metadata to store type information
|
106
112
|
unless hash_row['id'].empty?
|
107
|
-
|
108
|
-
|
113
|
+
extra_values, base_values = hash_row.partition{|k, v| k.start_with?('extra_')}
|
114
|
+
base_hash = Hash[base_values]
|
115
|
+
base_hash['extra_attributes'] = Hash[extra_values]
|
116
|
+
base_hash
|
109
117
|
end
|
110
118
|
end.compact
|
111
119
|
end
|
@@ -1,5 +1,22 @@
|
|
1
1
|
# typed: strict
|
2
2
|
|
3
|
+
module RSpec
|
4
|
+
module Core
|
5
|
+
class Example
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
# The implementation of clear_exception in rspec-retry doesn't work
|
9
|
+
# for examples that use `it_behaves_like`, so we implement our own version that
|
10
|
+
# clear the exception field recursively.
|
11
|
+
sig { void }
|
12
|
+
def clear_exception!
|
13
|
+
@exception = T.let(nil, T.untyped)
|
14
|
+
T.unsafe(self).example.clear_exception! if defined?(example)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
3
20
|
class Quarantine
|
4
21
|
module RSpecAdapter
|
5
22
|
extend T::Sig
|
@@ -52,33 +69,47 @@ class Quarantine
|
|
52
69
|
end
|
53
70
|
end
|
54
71
|
|
72
|
+
sig { params(example: RSpec::Core::Example).returns(T.nilable([Symbol, T::Boolean])) }
|
73
|
+
def self.final_status(example)
|
74
|
+
metadata = example.metadata
|
75
|
+
|
76
|
+
# The user may define their own after hook that marks an example as flaky in its metadata.
|
77
|
+
previously_quarantined = Quarantine::RSpecAdapter.quarantine.test_quarantined?(example) || metadata[:flaky]
|
78
|
+
|
79
|
+
if example.exception
|
80
|
+
# The example failed _this try_.
|
81
|
+
if metadata[:retry_attempts] + 1 == metadata[:retry]
|
82
|
+
# The example failed all its retries - if it's already quarantined, keep it that way;
|
83
|
+
# otherwise, mark it as failing.
|
84
|
+
if RSpec.configuration.skip_quarantined_tests && previously_quarantined
|
85
|
+
return [:quarantined, false]
|
86
|
+
else
|
87
|
+
return [:failing, false]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
# The example failed, but it's not the final retry yet, so return nil.
|
91
|
+
return nil
|
92
|
+
elsif metadata[:retry_attempts] > 0
|
93
|
+
# The example passed this time, but failed one or more times before - the definition of a flaky test.
|
94
|
+
return [:quarantined, false]
|
95
|
+
elsif previously_quarantined
|
96
|
+
# The example passed the first time, but it's already marked quarantined, so keep it that way.
|
97
|
+
return [:quarantined, true]
|
98
|
+
else
|
99
|
+
return [:passing, true]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
55
103
|
# Purpose: binds quarantine to record test statuses
|
56
104
|
sig { void }
|
57
105
|
def self.bind_on_test
|
58
106
|
::RSpec.configure do |config|
|
59
107
|
config.after(:each) do |example|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
if example.exception
|
66
|
-
if metadata[:retry_attempts] + 1 == metadata[:retry]
|
67
|
-
# will record the failed test if it's final retry from the rspec-retry gem
|
68
|
-
if RSpec.configuration.skip_quarantined_tests && quarantined
|
69
|
-
example.clear_exception!
|
70
|
-
Quarantine::RSpecAdapter.quarantine.on_test(example, :quarantined, passed: false)
|
71
|
-
else
|
72
|
-
Quarantine::RSpecAdapter.quarantine.on_test(example, :failing, passed: false)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
elsif metadata[:retry_attempts] > 0
|
76
|
-
# will record the flaky test if it failed the first run but passed a subsequent run
|
77
|
-
Quarantine::RSpecAdapter.quarantine.on_test(example, :quarantined, passed: false)
|
78
|
-
elsif quarantined
|
79
|
-
Quarantine::RSpecAdapter.quarantine.on_test(example, :quarantined, passed: true)
|
80
|
-
else
|
81
|
-
Quarantine::RSpecAdapter.quarantine.on_test(example, :passing, passed: true)
|
108
|
+
result = Quarantine::RSpecAdapter.final_status(example)
|
109
|
+
if result
|
110
|
+
status, passed = result
|
111
|
+
example.clear_exception! if status == :quarantined && !passed
|
112
|
+
Quarantine::RSpecAdapter.quarantine.on_test(example, status, passed: passed)
|
82
113
|
end
|
83
114
|
end
|
84
115
|
end
|
data/lib/quarantine/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quarantine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Flexport Engineering, Eric Zhu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|