pester 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -0
- data/lib/pester/config.rb +5 -0
- data/lib/pester/environment.rb +17 -0
- data/lib/pester/version.rb +1 -1
- data/lib/pester.rb +22 -2
- data/pester.gemspec +2 -2
- data/spec/environment_spec.rb +45 -0
- data/spec/pester_spec.rb +38 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72934e84c8c0e2fd2f04a00cf0bf813514e22ee6
|
4
|
+
data.tar.gz: 67bdc3fd419f71dd3e5f9e4a49b507eeb97fd083
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2912019dd882c9f0d7f180e8de1c116efcad81af40ddccacdf39c81fc74250cd817f743a402ddb1e3a178da886e50322011d41815021c3ab7551ffd2a5372ade
|
7
|
+
data.tar.gz: 39fc544569277ab0b22972342a480196292155eab48bf4b6c583012608d851fbf69ed3b663099657d6f38dbadfdbc21fe71fadaa3650cdb2c166e83bb7e02fe5
|
data/README.md
CHANGED
@@ -87,6 +87,38 @@ Because it calls `include?`, this also works for regexes:
|
|
87
87
|
|
88
88
|
### Configuration
|
89
89
|
|
90
|
+
#### Environments
|
91
|
+
|
92
|
+
The easiest way to coordinate sets of Pester options across an app is via environments--these are basically option hashes configured in Pester by name:
|
93
|
+
|
94
|
+
Pester.configure do |c|
|
95
|
+
c.environments[:aws] = { max_attempts: 3, delay_interval: 5 }
|
96
|
+
c.environments[:internal] = { max_attempts: 2, delay_interval: 0 }
|
97
|
+
end
|
98
|
+
|
99
|
+
This will create two environments, `aws` and `internal`, which allow you to employ different backoff strategies, depending on the usage context. These are employed simply by calling `Pester.environment_name.retry` (where `retry` can also be another helper method):
|
100
|
+
|
101
|
+
def aws_action
|
102
|
+
Pester.aws.retry do
|
103
|
+
aws_call
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def action
|
108
|
+
Pester.internal.retry do
|
109
|
+
some_other_call
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
Environments can also be merged with retry helper methods:
|
114
|
+
|
115
|
+
Pester.aws.retry # acts different from
|
116
|
+
Pester.aws.retry_with_exponential_backoff
|
117
|
+
|
118
|
+
where the helper method's `Behavior` will take precedence.
|
119
|
+
|
120
|
+
#### Logging
|
121
|
+
|
90
122
|
Pester will write retry and exhaustion information into your logs, by default using a ruby `Logger` to standard out. This can be configured either per-call, or one time per application in your initializer via `Pester#configure`. The following will suppress all logs by using a class that simply does nothing with log data, as found in `spec/`:
|
91
123
|
|
92
124
|
Pester.configure do |c|
|
data/lib/pester/config.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
module Pester
|
2
2
|
class Config
|
3
3
|
class << self
|
4
|
+
attr_reader :environments
|
4
5
|
attr_writer :logger
|
5
6
|
|
6
7
|
def configure
|
7
8
|
yield self
|
8
9
|
end
|
9
10
|
|
11
|
+
def environments
|
12
|
+
@environments ||= {}
|
13
|
+
end
|
14
|
+
|
10
15
|
def logger
|
11
16
|
require 'logger' unless defined? Logger
|
12
17
|
@logger ||= Logger.new(STDOUT)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Pester
|
2
|
+
class Environment
|
3
|
+
attr_accessor :options
|
4
|
+
|
5
|
+
def initialize(opts)
|
6
|
+
@options = opts
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(name, *args, &block)
|
10
|
+
if name.to_s.start_with?('retry') && args.empty?
|
11
|
+
Pester.send(name, @options, &block)
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/pester/version.rb
CHANGED
data/lib/pester.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
require 'pester/behaviors'
|
2
2
|
require 'pester/behaviors/sleep'
|
3
|
+
require 'pester/environment'
|
3
4
|
require 'pester/config'
|
4
5
|
require 'pester/version'
|
5
6
|
|
6
7
|
module Pester
|
7
8
|
def self.configure(&block)
|
8
9
|
Config.configure(&block)
|
10
|
+
unless Config.environments.nil?
|
11
|
+
self.environments = Hash[Config.environments.select { |_, e| e.is_a?(Hash) }.map { |k, e| [k.to_sym, Environment.new(e)] }]
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def self.retry(options = {}, &block)
|
@@ -75,11 +79,27 @@ module Pester
|
|
75
79
|
nil
|
76
80
|
end
|
77
81
|
|
82
|
+
def respond_to?(method_sym)
|
83
|
+
super || Config.environments.key?(method_sym)
|
84
|
+
end
|
85
|
+
|
86
|
+
def method_missing(method_sym)
|
87
|
+
if Config.environments.key?(method_sym)
|
88
|
+
Config.environments[method_sym]
|
89
|
+
else
|
90
|
+
super
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class << self
|
95
|
+
attr_accessor :environments
|
96
|
+
end
|
97
|
+
|
78
98
|
private
|
79
99
|
|
80
100
|
def self.should_retry?(e, opts = {})
|
81
|
-
retry_error_classes
|
82
|
-
retry_error_messages
|
101
|
+
retry_error_classes = opts[:retry_error_classes]
|
102
|
+
retry_error_messages = opts[:retry_error_messages]
|
83
103
|
reraise_error_classes = opts[:reraise_error_classes]
|
84
104
|
|
85
105
|
if retry_error_classes
|
data/pester.gemspec
CHANGED
@@ -18,8 +18,8 @@ EOD
|
|
18
18
|
spec.license = 'MIT'
|
19
19
|
|
20
20
|
spec.files = `git ls-files -z`.split("\x0")
|
21
|
-
spec.executables = spec.files.grep(
|
22
|
-
spec.test_files = spec.files.grep(
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
23
|
spec.require_paths = ['lib']
|
24
24
|
|
25
25
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pester::Environment do
|
4
|
+
let(:options) { {} }
|
5
|
+
let!(:environment) { Pester::Environment.new(options) }
|
6
|
+
|
7
|
+
describe 'Delegation to Pester' do
|
8
|
+
context 'for retry-prefixed methods' do
|
9
|
+
context 'which are supported' do
|
10
|
+
let(:pester) { class_double('Pester').as_stubbed_const }
|
11
|
+
|
12
|
+
context 'without options' do
|
13
|
+
it 'calls Pester#retry without options' do
|
14
|
+
expect(pester).to receive(:send).with(:retry, {})
|
15
|
+
environment.retry {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context 'with options' do
|
19
|
+
let(:options) { { test_opt: 1234 } }
|
20
|
+
|
21
|
+
it 'calls Pester#retry with the given options' do
|
22
|
+
expect(pester).to receive(:send).with(:retry, options)
|
23
|
+
environment.retry {}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'which do not exist' do
|
29
|
+
let(:options) { { test_opt: 1234 } }
|
30
|
+
|
31
|
+
it 'lets Pester raise NoMethodError' do
|
32
|
+
expect { environment.retry_does_not_exist {} }.to raise_error(NoMethodError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'for non-retry-prefixed methods' do
|
38
|
+
let(:pester) { class_double('Pester').as_stubbed_const }
|
39
|
+
|
40
|
+
it 'raises NoMethodError' do
|
41
|
+
expect { environment.something_else {} }.to raise_error(NoMethodError)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/pester_spec.rb
CHANGED
@@ -87,7 +87,7 @@ shared_examples 'raises an error only in the correct cases with a reraise class'
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
describe 'retry_action' do
|
90
|
+
describe '#retry_action' do
|
91
91
|
let(:intended_result) { 1000 }
|
92
92
|
let(:action) { failer.fail(UnmatchedError, 'Dying') }
|
93
93
|
let(:null_logger) { NullLogger.new }
|
@@ -258,7 +258,43 @@ describe 'retry_action' do
|
|
258
258
|
end
|
259
259
|
end
|
260
260
|
|
261
|
-
describe '
|
261
|
+
describe '#environments' do
|
262
|
+
before { Pester.environments = {} }
|
263
|
+
|
264
|
+
context 'when a non-hash environment is configured' do
|
265
|
+
it 'does not add it to the Pester environment list' do
|
266
|
+
Pester.configure do |config|
|
267
|
+
config.environments[:abc] = 1234
|
268
|
+
end
|
269
|
+
|
270
|
+
expect(Pester.environments.count).to eq(0)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'when a non-hash environment is configured' do
|
275
|
+
let(:environment_name) { :abc }
|
276
|
+
let(:options) { { option: 1234 } }
|
277
|
+
|
278
|
+
it 'adds it to the Pester environment list' do
|
279
|
+
Pester.configure do |config|
|
280
|
+
config.environments[environment_name] = options
|
281
|
+
end
|
282
|
+
|
283
|
+
expect(Pester.environments.count).to eq(1)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'contains an Environment with the appropriate options' do
|
287
|
+
Pester.configure do |config|
|
288
|
+
config.environments[environment_name] = options
|
289
|
+
end
|
290
|
+
|
291
|
+
expect(Pester.environments[environment_name].class).to eq(Pester::Environment)
|
292
|
+
expect(Pester.environments[environment_name].options).to eq(options)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe '#logger' do
|
262
298
|
context 'when not otherwise configured' do
|
263
299
|
it 'defaults to the ruby logger' do
|
264
300
|
Pester.configure do |config|
|
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.
|
4
|
+
version: 0.2.0
|
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-04-
|
11
|
+
date: 2015-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -74,8 +74,10 @@ files:
|
|
74
74
|
- lib/pester/behaviors.rb
|
75
75
|
- lib/pester/behaviors/sleep.rb
|
76
76
|
- lib/pester/config.rb
|
77
|
+
- lib/pester/environment.rb
|
77
78
|
- lib/pester/version.rb
|
78
79
|
- pester.gemspec
|
80
|
+
- spec/environment_spec.rb
|
79
81
|
- spec/helpers/null_logger.rb
|
80
82
|
- spec/helpers/scripted_failer.rb
|
81
83
|
- spec/pester_spec.rb
|
@@ -105,6 +107,7 @@ signing_key:
|
|
105
107
|
specification_version: 4
|
106
108
|
summary: Common block-based retry for external calls.
|
107
109
|
test_files:
|
110
|
+
- spec/environment_spec.rb
|
108
111
|
- spec/helpers/null_logger.rb
|
109
112
|
- spec/helpers/scripted_failer.rb
|
110
113
|
- spec/pester_spec.rb
|