pester 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5c9151d53d657939d6506baf8a27e5da2744b3b
4
- data.tar.gz: 251a6215cfe9cd275f37bf7df458561116cb7401
3
+ metadata.gz: c726cd4ef970107604a3cabf1d26ddf04fffbc45
4
+ data.tar.gz: 3579a4065f03f7791720e9d98d0c6bdc5a3c57f7
5
5
  SHA512:
6
- metadata.gz: dd350670630f082f40af4ab8290e7eb5f8a75a2137ca61cacc63c72445c28baad2eda3bc595aec14bb2782bc3ac5778a38c5678661aaec77ab75fe9f1fcb7e9f
7
- data.tar.gz: 4bd76629e817aca9981340564ec5426ab8e6c6619bbe222b6b7b0d33143e587f21c9b49a31d2dbfb87d9a06ac1863dcf192d550860cf7686ba56448dc38041e0
6
+ metadata.gz: 3e6af9161e42c15a613748d81845adfa8d786b4a5309b41163b87c5d42945968e984e66e84a95f9ba141b2a713c1c30f1a2d5c6b8b8648e516fc1cb0931b84d0
7
+ data.tar.gz: a5719117192311422b5bce432f1b53cef9d98f12ef3b4e1df6b244d237709353ce64af6152c015b75910226b010119abadd890cc23a5f15eeebf34c441b0f450
@@ -1,3 +1,3 @@
1
1
  module Pester
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
data/lib/pester.rb CHANGED
@@ -26,6 +26,10 @@ module Pester
26
26
  # Options:
27
27
  # retry_error_classes - A single or array of exceptions to retry on. Thrown exceptions not in this list
28
28
  # (including parent/sub-classes) will be reraised
29
+ # retry_error_messages - A single or array of exception messages to retry on. If only this options is passed,
30
+ # any exception with a message containing one of these strings will be retried. If this
31
+ # option is passed along with retry_error_classes, retry will only happen when both the
32
+ # class and the message match the exception. Strings and regexes are both permitted.
29
33
  # reraise_error_classes - A single or array of exceptions to always re-raiseon. Thrown exceptions not in
30
34
  # this list (including parent/sub-classes) will be retried
31
35
  # max_attempts - Max number of attempts to retry
@@ -33,18 +37,14 @@ module Pester
33
37
  # passed to retry_with_backoff will retry first after 2 seconds, then 4, then 6, et al.
34
38
  # on_retry - A Proc to be called on each successive failure, before the next retry
35
39
  # on_max_attempts_exceeded - A Proc to be called when attempt_num >= max_attempts - 1
36
- # message - String or regex to look for in thrown exception messages. Matches will trigger retry
37
- # logic, non-matches will cause the exception to be reraised
40
+ # logger - Where to log the output
38
41
  #
39
42
  # Usage:
40
- # retry_action do
43
+ # retry_action(retry_error_classes: [Mysql2::Error]) do
41
44
  # puts 'trying to remove a directory'
42
45
  # FileUtils.rm_r(directory)
43
46
  # end
44
- #
45
- # retryable(error_classes: Mysql2::Error, message: /^Lost connection to MySQL server/, max_attempts: 2) do
46
- # ActiveRecord::Base.connection.execute("LONG MYSQL STATEMENT")
47
- # end
47
+
48
48
  def self.retry_action(opts = {}, &block)
49
49
  merge_defaults(opts)
50
50
  if opts[:retry_error_classes] && opts[:reraise_error_classes]
@@ -53,16 +53,10 @@ module Pester
53
53
 
54
54
  opts[:max_attempts].times do |attempt_num|
55
55
  begin
56
- result = yield block
57
- return result
56
+ return yield(block)
58
57
  rescue => e
59
- class_reraise = opts[:retry_error_classes] && !opts[:retry_error_classes].include?(e.class)
60
- reraise_error = opts[:reraise_error_classes] && opts[:reraise_error_classes].include?(e.class)
61
- message_reraise = opts[:message] && !e.message[opts[:message]]
62
-
63
- if class_reraise || message_reraise || reraise_error
64
- match_type = class_reraise ? 'class' : 'message'
65
- opts[:logger].warn("Reraising exception from inside retry_action because provided #{match_type} was not matched.")
58
+ unless should_retry?(e, opts)
59
+ opts[:logger].warn('Reraising exception from inside retry_action.')
66
60
  raise
67
61
  end
68
62
 
@@ -72,6 +66,7 @@ module Pester
72
66
  opts[:logger].warn("Failure encountered: #{e}, backing off and trying again #{attempts_left} more times. Trace: #{trace}")
73
67
  opts[:on_retry].call(attempt_num, opts[:delay_interval])
74
68
  else
69
+ # Careful here because you will get back the return value of the on_max_attempts_exceeded proc!
75
70
  return opts[:on_max_attempts_exceeded].call(opts[:logger], opts[:max_attempts], e)
76
71
  end
77
72
  end
@@ -80,8 +75,29 @@ module Pester
80
75
 
81
76
  private
82
77
 
78
+ def self.should_retry?(e, opts = {})
79
+ retry_error_classes = opts[:retry_error_classes]
80
+ retry_error_messages = opts[:retry_error_messages]
81
+ reraise_error_classes = opts[:reraise_error_classes]
82
+
83
+ if retry_error_classes
84
+ if retry_error_messages
85
+ retry_error_classes.include?(e.class) && retry_error_messages.any? { |m| e.message[m] }
86
+ else
87
+ retry_error_classes.include?(e.class)
88
+ end
89
+ elsif retry_error_messages
90
+ retry_error_messages.any? { |m| e.message[m] }
91
+ elsif reraise_error_classes && reraise_error_classes.include?(e.class)
92
+ false
93
+ else
94
+ true
95
+ end
96
+ end
97
+
83
98
  def self.merge_defaults(opts)
84
99
  opts[:retry_error_classes] = opts[:retry_error_classes] ? Array(opts[:retry_error_classes]) : nil
100
+ opts[:retry_error_messages] = opts[:retry_error_messages] ? Array(opts[:retry_error_messages]) : nil
85
101
  opts[:reraise_error_classes] = opts[:reraise_error_classes] ? Array(opts[:reraise_error_classes]) : nil
86
102
  opts[:max_attempts] ||= 4
87
103
  opts[:delay_interval] ||= 30
data/spec/pester_spec.rb CHANGED
@@ -55,7 +55,6 @@ shared_examples 'raises an error only in the correct cases with a retry class' d
55
55
  let(:actual_error_message) { matching_error_message }
56
56
 
57
57
  it_has_behavior "doesn't raise an error"
58
-
59
58
  it_has_behavior 'returns and succeeds'
60
59
  end
61
60
  end
@@ -66,7 +65,6 @@ shared_examples 'raises an error only in the correct cases with a reraise class'
66
65
  let(:actual_error_message) { non_matching_error_message }
67
66
 
68
67
  it_has_behavior "doesn't raise an error"
69
-
70
68
  it_has_behavior 'returns and succeeds'
71
69
  end
72
70
 
@@ -88,7 +86,6 @@ describe 'retry_action' do
88
86
  let(:options) { { delay_interval: 0, logger: null_logger } }
89
87
 
90
88
  it_has_behavior "doesn't raise an error"
91
-
92
89
  it_has_behavior 'returns and succeeds'
93
90
  end
94
91
 
@@ -97,7 +94,6 @@ describe 'retry_action' do
97
94
  let(:options) { { max_attempts: 3, logger: null_logger } }
98
95
 
99
96
  it_has_behavior "doesn't raise an error"
100
-
101
97
  it_has_behavior 'returns and succeeds'
102
98
  end
103
99
 
@@ -111,17 +107,34 @@ describe 'retry_action' do
111
107
  it_has_behavior 'raises an error'
112
108
  end
113
109
 
114
- context 'with on_max_attempts_exceeded specified (which does not raise)' do
115
- let(:do_nothing_proc) { proc {} }
110
+ context 'with on_max_attempts_exceeded proc specified' do
116
111
  let(:options) do
117
112
  {
118
113
  max_attempts: max_attempts,
119
- on_max_attempts_exceeded: do_nothing_proc,
114
+ on_max_attempts_exceeded: proc_to_call,
120
115
  logger: null_logger
121
116
  }
122
117
  end
123
118
 
124
- it_has_behavior "doesn't raise an error"
119
+ context 'which does not do anything' do
120
+ let(:proc_to_call) { proc {} }
121
+ it_has_behavior "doesn't raise an error"
122
+ end
123
+
124
+ context 'which reraises' do
125
+ let(:proc_to_call) { Behaviors::WarnAndReraise }
126
+ it_has_behavior 'raises an error'
127
+ end
128
+
129
+ context 'which returns a value' do
130
+ let(:return_value) { 'return_value' }
131
+ let(:proc_to_call) { proc { return_value } }
132
+ it_has_behavior "doesn't raise an error"
133
+
134
+ it 'should return the result of the proc' do
135
+ expect(Pester.retry_action(options) { action }).to eq(return_value)
136
+ end
137
+ end
125
138
  end
126
139
  end
127
140
 
@@ -138,7 +151,7 @@ describe 'retry_action' do
138
151
  let(:options) do
139
152
  {
140
153
  retry_error_classes: expected_error_classes,
141
- message: /^Lost connection to MySQL server/,
154
+ retry_error_messages: /^Lost connection to MySQL server/,
142
155
  max_attempts: 10,
143
156
  logger: null_logger
144
157
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pester
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Bollinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-30 00:00:00.000000000 Z
11
+ date: 2015-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler