brine-dsl 0.9.0 → 0.10.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 +1 -1
- data/Rakefile +1 -1
- data/brine-dsl.gemspec +1 -2
- data/lib/brine/cleaning_up.rb +120 -0
- data/lib/brine/client_building.rb +123 -0
- data/lib/brine/coercing.rb +91 -0
- data/lib/brine/hooks.rb +8 -1
- data/lib/brine/mustache_expanding.rb +51 -0
- data/lib/brine/performing.rb +159 -0
- data/lib/brine/requesting.rb +171 -0
- data/lib/brine/rest_steps.rb +1 -1
- data/lib/brine/selecting.rb +166 -0
- data/lib/brine/step_definitions/assertions.rb +15 -15
- data/lib/brine/step_definitions/assignment.rb +5 -4
- data/lib/brine/step_definitions/cleanup.rb +2 -2
- data/lib/brine/step_definitions/perform.rb +16 -0
- data/lib/brine/step_definitions/request_construction.rb +12 -8
- data/lib/brine/step_definitions/selection.rb +24 -12
- data/lib/brine/test_steps.rb +20 -0
- data/lib/brine/transforms.rb +12 -4
- data/lib/brine/type_checking.rb +88 -0
- data/lib/brine/util.rb +1 -0
- data/lib/brine.rb +13 -20
- metadata +12 -9
- data/lib/brine/cleaner_upper.rb +0 -101
- data/lib/brine/coercer.rb +0 -68
- data/lib/brine/mustache_binder.rb +0 -25
- data/lib/brine/requester.rb +0 -161
- data/lib/brine/selector.rb +0 -66
- data/lib/brine/type_checks.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 690350fecddec6e5978bcb684189f2ac742a7918
|
4
|
+
data.tar.gz: 6a37f34f8424ac9422517f3cc0282cb8eb5b321d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41b4ddf87394b647485b3ae8f77c517742661330583650eebf980e52050b2b8878f6d27c150613682e4da04b3ad0c109c62d97018a36effcb698e4f5bda3caae
|
7
|
+
data.tar.gz: 786aa5afef5cca973ac32c12b5fac728810da1d1eeface795254ac9d61f2b1f14b6fb4978c7f14463616f7342f45e30aabe02b566e32af09b64e9e2687a9e326
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
data/brine-dsl.gemspec
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
raise 'VERSION must be specified in environment' unless ENV['VERSION']
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'brine-dsl'
|
5
|
-
s.version = '
|
6
|
-
# s.version = ENV['VERSION']
|
5
|
+
s.version = ENV['VERSION'][1..-1]
|
7
6
|
s.platform = Gem::Platform::RUBY
|
8
7
|
s.authors = ["Matt Whipple"]
|
9
8
|
s.email = ["mwhipple@brightcove.com"]
|
@@ -0,0 +1,120 @@
|
|
1
|
+
##
|
2
|
+
# @file cleaning_up.rb
|
3
|
+
# Clean up resources created during test run.
|
4
|
+
#
|
5
|
+
# Will issue DELETE call for all tracked URLs which will normally be triggered
|
6
|
+
# in a hook.
|
7
|
+
#
|
8
|
+
# The present approach for this is to explicitly track created resources to
|
9
|
+
# which DELETE calls will be sent. Cleaning up of resources will be given some
|
10
|
+
# further attention in the future, but this functionality should be preserved.
|
11
|
+
##
|
12
|
+
|
13
|
+
module Brine
|
14
|
+
|
15
|
+
##
|
16
|
+
# A module providing resource cleanup.
|
17
|
+
#
|
18
|
+
# Exposes methods to keep a stack of DeleteCommands corresponding to each
|
19
|
+
# created resource which are then popped and invoked to perform the cleanup.
|
20
|
+
#
|
21
|
+
# LIFO behavior is adopted as it is more likely to preserve integrity,
|
22
|
+
# such as removing children added to parents or similar dependencies.
|
23
|
+
##
|
24
|
+
module CleaningUp
|
25
|
+
|
26
|
+
##
|
27
|
+
# A command object for the delete which will be executed as part of cleaning up.
|
28
|
+
#
|
29
|
+
# The command will be retried a specified number of times if an unsuccessful status code is received.
|
30
|
+
##
|
31
|
+
class DeleteCommand
|
32
|
+
|
33
|
+
##
|
34
|
+
# Construct a command with the required paramters to perform the delete.
|
35
|
+
#
|
36
|
+
# @param [Faraday::Connection, #delete] client The Faraday client which will send the delete message.
|
37
|
+
# @param [String] path The path of the resource to be deleted.
|
38
|
+
# @param [Array<Integer>] oks The response status codes which will be considered successful.
|
39
|
+
# @param [Integer] attempts The number of times this command should be tried.
|
40
|
+
##
|
41
|
+
def initialize(client, path, oks: [200,204], attempts: 3)
|
42
|
+
@client = client
|
43
|
+
@path = path
|
44
|
+
@oks = oks
|
45
|
+
@attempts = attempts
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Issue the delete based on the parameters provided during construction.
|
50
|
+
#
|
51
|
+
# @return [Boolean] true if a successful response is obtained, otherwise false.
|
52
|
+
##
|
53
|
+
def cleanup
|
54
|
+
for _ in 1..@attempts
|
55
|
+
begin
|
56
|
+
resp=@client.delete(@path)
|
57
|
+
return true if @oks.include?(resp.status)
|
58
|
+
rescue ex
|
59
|
+
STDERR.puts "WARNING: #{ex}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
STDERR.puts "ERROR: Could not DELETE #{@path}"
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Set the Faraday HTTP client object used to issue DELETE calls.
|
69
|
+
#
|
70
|
+
# The client provided will be subsequently used to create DeleteCommands.
|
71
|
+
# This can be called multiple times where each DeleteCommand will use the
|
72
|
+
# most recently set value. In most use cases this will also be the client
|
73
|
+
# used to issue the creation requests and could therefore be passed to this
|
74
|
+
# method prior to use.
|
75
|
+
#
|
76
|
+
# @param [Faraday::Connection, #delete] client The client to use to DELETE subsequently tracked resources.
|
77
|
+
##
|
78
|
+
def set_cleaning_client(client)
|
79
|
+
@client = client
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Record resource to be later cleaned (pushes a DeleteCommand).
|
84
|
+
#
|
85
|
+
# @param [String] path The path for the created resource; will be issued a DELETE.
|
86
|
+
##
|
87
|
+
def track_created_resource(path)
|
88
|
+
cleanup_commands << DeleteCommand.new(@client, path)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Clean recorded resources (normally after a test run).
|
93
|
+
#
|
94
|
+
# @return [Boolean] true if all commands succeeded successfully, otherwise false.
|
95
|
+
##
|
96
|
+
def cleanup_created_resources
|
97
|
+
# Avoid the use of any short circuiting folds.
|
98
|
+
cleanup_commands.reverse.inject(true) { |accum, x| accum && x.cleanup }
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
##
|
104
|
+
# The array which serves as the stack of DeleteCommands.
|
105
|
+
#
|
106
|
+
# Provides the property mixed in by the module.
|
107
|
+
#
|
108
|
+
# @return [Array<DeleteCommand>]
|
109
|
+
##
|
110
|
+
def cleanup_commands
|
111
|
+
@cleanup_commands ||= []
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Mix the CleaningUp module functionality into the main Brine module.
|
118
|
+
##
|
119
|
+
include CleaningUp
|
120
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
##
|
2
|
+
# @file client_building.rb
|
3
|
+
# Construction of a Faraday connection.
|
4
|
+
##
|
5
|
+
|
6
|
+
module Brine
|
7
|
+
|
8
|
+
##
|
9
|
+
# Supports construction of a Faraday connection with some common middleware.
|
10
|
+
##
|
11
|
+
module ClientBuilding
|
12
|
+
require 'oauth2'
|
13
|
+
|
14
|
+
##
|
15
|
+
# Parameter object used to configure OAuth2 middleware
|
16
|
+
#
|
17
|
+
# This is essentially a thin wrapper around `https://github.com/oauth-xx/oauth2`
|
18
|
+
# to provide a mini-DSL and to facilitate the middleware configuration.
|
19
|
+
##
|
20
|
+
class OAuth2Params
|
21
|
+
|
22
|
+
##
|
23
|
+
# A token which has been retrieved from the authorization server.
|
24
|
+
##
|
25
|
+
attr_accessor :token
|
26
|
+
|
27
|
+
##
|
28
|
+
# The type of OAuth2 token which will be retrieved.
|
29
|
+
#
|
30
|
+
# Currently only `bearer` is supported.
|
31
|
+
##
|
32
|
+
attr_accessor :token_type
|
33
|
+
|
34
|
+
##
|
35
|
+
# Instantiate a new object with default attributes.
|
36
|
+
##
|
37
|
+
def initialize
|
38
|
+
@token_type = 'bearer'
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Fetch an OAuth2 token based on configuration and store as `token`.
|
43
|
+
#
|
44
|
+
# The parameters are forwarded to OAuth2::Client.new which is used to
|
45
|
+
# retrieve the token.
|
46
|
+
#
|
47
|
+
# @param [String] id The login id to send to request authorization.
|
48
|
+
# @param [String] secret The secret to send to request authorization.
|
49
|
+
# @param [Hash] opts Options with which to create a client,
|
50
|
+
# see `https://github.com/oauth-xx/oauth2/blob/master/lib/oauth2/client.rb` for full details,
|
51
|
+
# common options will be duplicated here.
|
52
|
+
# @option opts [String] :site The OAuth2 authorization server from which to request a token.
|
53
|
+
# @option opts [String] :token_url The absolute or relative path to the Token endpoint on the authorization server.
|
54
|
+
# @option opts [Hash] :ssl SSL options to pass through to the transport client,
|
55
|
+
# `{verify: false}` may be useful for self-signed certificates.
|
56
|
+
##
|
57
|
+
def fetch_from(id, secret, opts)
|
58
|
+
@token = OAuth2::Client.new(id, secret, opts)
|
59
|
+
.client_credentials.get_token.token
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Acquire an OAuth2 token within provided configuration block.
|
65
|
+
#
|
66
|
+
# @param [Block] Logic to execute with an OAuth2Params receiver;
|
67
|
+
# this will normally involve an OAuth2Params#fetch_from call.
|
68
|
+
##
|
69
|
+
def use_oauth2_token(&block)
|
70
|
+
@oauth2 = OAuth2Params.new
|
71
|
+
@oauth2.instance_eval(&block)
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# The handlers/middleware that will be wired while constructing a client.
|
76
|
+
#
|
77
|
+
# This is represented as list of functions so that it can be more easily customized for
|
78
|
+
# unexpected use cases.
|
79
|
+
# It should likely be broken up a bit more sensibly and more useful insertion commands added...
|
80
|
+
# but it's likely enough of a power feature and platform specific to leave pretty raw.
|
81
|
+
##
|
82
|
+
def connection_handlers
|
83
|
+
@connection_handlers ||= [
|
84
|
+
proc do |conn|
|
85
|
+
conn.request :json
|
86
|
+
if @oauth2
|
87
|
+
conn.request :oauth2, @oauth2.token, :token_type => @oauth2.token_type
|
88
|
+
end
|
89
|
+
end,
|
90
|
+
proc do |conn|
|
91
|
+
if @logging
|
92
|
+
conn.response :logger, nil, :bodies => (@logging.casecmp('DEBUG') == 0)
|
93
|
+
end
|
94
|
+
conn.response :json, :content_type => /\bjson$/
|
95
|
+
end,
|
96
|
+
proc{|conn| conn.adapter Faraday.default_adapter }
|
97
|
+
]
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Construct a new client to send requests to `host`.
|
102
|
+
#
|
103
|
+
# Will configure the client using `#connection_handlers`.
|
104
|
+
#
|
105
|
+
# @param [String] host The hostname to which this client will send requests.
|
106
|
+
# @param [String] logging Indicate the desired logging level for this client.
|
107
|
+
# @return [Faraday::Connection] The configured client connection.
|
108
|
+
##
|
109
|
+
def client_for_host(host, logging: ENV['BRINE_LOG_HTTP'])
|
110
|
+
@logging = logging
|
111
|
+
Faraday.new(host) do |conn|
|
112
|
+
connection_handlers.each{|h| h.call(conn) }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Mix the ClientBuilding module functionality into the main Brine module.
|
120
|
+
##
|
121
|
+
include ClientBuilding
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
##
|
2
|
+
# @file coering.rb
|
3
|
+
# Type coercion to support assertions.
|
4
|
+
##
|
5
|
+
|
6
|
+
module Brine
|
7
|
+
|
8
|
+
##
|
9
|
+
# A module which allows mixing in Corcer behavior.
|
10
|
+
##
|
11
|
+
module Coercing
|
12
|
+
|
13
|
+
##
|
14
|
+
# Coerces the types of provided objects to support desired assertions.
|
15
|
+
#
|
16
|
+
# Coercion is used to support handling richer data types in Brine without
|
17
|
+
# introducing noisy type information to the language.
|
18
|
+
# Argument Transforms can be used to convert input provided directly
|
19
|
+
# to a Brine step, however data extracted from JSON will by default be
|
20
|
+
# limited to the small amount of JSON supported data types. As normally
|
21
|
+
# the data extracted from JSON will only be directly present on one side
|
22
|
+
# of the assertion (most likely the left), the simpler JSON data types can
|
23
|
+
# be coerced to a richer type based on the right hand side.
|
24
|
+
#
|
25
|
+
# A standard example (and that which is defined at the moment here) is date/time
|
26
|
+
# values. When testing an API that returns such values it is likely desirable to
|
27
|
+
# perform assertions with proper date/time semantics, and the coercer allows
|
28
|
+
# such assertions against a value retrieved out of a JSON structure.
|
29
|
+
#
|
30
|
+
# The combination of Argument Transforms and the Coercer can also effectively
|
31
|
+
# allow for user defined types to seemlessly exist within the Brine tests.
|
32
|
+
# The date/time implementation is an example of this.
|
33
|
+
#
|
34
|
+
# Implementation (Most of the non-implementation info should later be moved).
|
35
|
+
# ---
|
36
|
+
# Internally the Coercer is a wrapper around a map of coercion functions
|
37
|
+
# where the keys are the pairs of classes for the operands and the
|
38
|
+
# values are the functions which accept a pair of instances (ostensibly) of the
|
39
|
+
# classes and return a pair of transformed values. The default coercion function
|
40
|
+
# returns the inputs unmodified (a nop), so any pair of classes which does not
|
41
|
+
# have a key will pass through unchanged.
|
42
|
+
#
|
43
|
+
# Note that this relies solely on the hash lookup and does not attempt any kind
|
44
|
+
# of inheritance lookup or similar. The current thinking is that there should be
|
45
|
+
# few expected types and lineage could be covered through explicit keys so the
|
46
|
+
# simple, dumb approach is likely sufficient.
|
47
|
+
##
|
48
|
+
class Coercer
|
49
|
+
|
50
|
+
##
|
51
|
+
# Instantiate a new Coercer.
|
52
|
+
#
|
53
|
+
# Initialize the standard map of coercion functions.
|
54
|
+
##
|
55
|
+
def initialize
|
56
|
+
@map = Hash.new(->(lhs, rhs){[lhs, rhs]})
|
57
|
+
@map[[String, Time]] = ->(lhs, rhs){[Time.parse(lhs), rhs]}
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Coerce the provided inputs as needed.
|
62
|
+
#
|
63
|
+
# Looks up and invokes the associated coercion function.
|
64
|
+
#
|
65
|
+
# @param [Object] first The first operand.
|
66
|
+
# @param [Object] second The second operand.
|
67
|
+
# @return [Array] A pair of the potentially coerced [first, second] values.
|
68
|
+
##
|
69
|
+
def coerce(first, second)
|
70
|
+
@map[[first.class, second.class]].call(first, second)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# The coercer instance mixed in as a property.
|
76
|
+
#
|
77
|
+
# Will instantiate a Coercer if needed on first access.
|
78
|
+
#
|
79
|
+
# @return [Coercer] The object which will be used to handle coercions.
|
80
|
+
##
|
81
|
+
def coercer
|
82
|
+
@coercer ||= Coercer.new
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Include the Coercing module functionality into the main Brine module.
|
89
|
+
##
|
90
|
+
include Coercing
|
91
|
+
end
|
data/lib/brine/hooks.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
##
|
2
|
+
# @file mustache_expanding.rb
|
3
|
+
# Support for expanding Mustache templates with a defined binding.
|
4
|
+
##
|
5
|
+
|
6
|
+
module Brine
|
7
|
+
|
8
|
+
##
|
9
|
+
# Provides a binding environment and template expansion that uses that environment.
|
10
|
+
##
|
11
|
+
module MustacheExpanding
|
12
|
+
require 'mustache'
|
13
|
+
|
14
|
+
##
|
15
|
+
# Mutable hash which serves as binding environment.
|
16
|
+
#
|
17
|
+
# @return [Hash<String, Object>] The active binding environment.
|
18
|
+
##
|
19
|
+
def binding
|
20
|
+
@binding ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Assign `value' to `key' within binding,
|
25
|
+
#
|
26
|
+
# @param [String] key The key in the binding to which `value` will be assigned.
|
27
|
+
# @param [Object] value The value to assign to ``key` within the binding.
|
28
|
+
##
|
29
|
+
def bind(key, value)
|
30
|
+
STDERR.puts "Assigning #{value} to #{key}" if ENV['BRINE_LOG_BINDING']
|
31
|
+
binding[key] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Expanded Mustache template using binding environment.
|
36
|
+
# Mustache in...no Mustache out.
|
37
|
+
#
|
38
|
+
# @param [String] template Template content to expand with binding.
|
39
|
+
# @return [String] The contents of `template` with any expansions done using `binding`.
|
40
|
+
##
|
41
|
+
def shave_value(template)
|
42
|
+
Mustache.render(template, binding)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Include the MustacheExpanding module functionality into the main Brine module.
|
49
|
+
##
|
50
|
+
include MustacheExpanding
|
51
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
##
|
2
|
+
# @file performing.rb
|
3
|
+
# Performing of of potentially deferred actions.
|
4
|
+
##
|
5
|
+
|
6
|
+
module Brine
|
7
|
+
|
8
|
+
##
|
9
|
+
# A module supporting either immediate or defered evaluation of logic.
|
10
|
+
##
|
11
|
+
module Performing
|
12
|
+
|
13
|
+
##
|
14
|
+
# A passthrough performer which immediately invokes provided actions.
|
15
|
+
#
|
16
|
+
# This has no instance state and therefore a Flyweight could be used,
|
17
|
+
# but too few instances are expected to warrant even the minor divergence.
|
18
|
+
##
|
19
|
+
class ImmediatePerformer
|
20
|
+
|
21
|
+
##
|
22
|
+
# Perform the provided actions immediately.
|
23
|
+
#
|
24
|
+
# @param [Proc] A thunk of actions to be performed.
|
25
|
+
##
|
26
|
+
def perform(actions)
|
27
|
+
actions.call
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# A Peformer which collects rather than evaluating actions.
|
33
|
+
##
|
34
|
+
class CollectingPerformer
|
35
|
+
|
36
|
+
##
|
37
|
+
# Construct an instance with an empty collection of actions.
|
38
|
+
##
|
39
|
+
def initialize
|
40
|
+
@actions = []
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Collect provided actions for later evaluation.
|
45
|
+
#
|
46
|
+
# @param [Proc] A thunk of actions to be performed.
|
47
|
+
##
|
48
|
+
def perform(actions)
|
49
|
+
@actions << actions
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Evaluate the collected actions in sequence.
|
54
|
+
##
|
55
|
+
def evaluate
|
56
|
+
@actions.each { |it| it.call }
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# The currently active Performer instance exposed as a property.
|
63
|
+
#
|
64
|
+
# The default implementation will be wired as needed upon first access.
|
65
|
+
#
|
66
|
+
# @return [Performer, #perform] The Performer to which actions will be sent.
|
67
|
+
##
|
68
|
+
def performer
|
69
|
+
@performer || reset_performer
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Reset the Performer instance to the default implementation.
|
74
|
+
#
|
75
|
+
# @return [Performer, #perform] The default implementation which will now be the `performer`.
|
76
|
+
##
|
77
|
+
def reset_performer
|
78
|
+
@performer = ImmediatePerformer.new
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# Pass the actions to the current Performer instance.
|
83
|
+
#
|
84
|
+
# @param [Proc] The thunk of the actions to be performed.
|
85
|
+
##
|
86
|
+
def perform(&actions)
|
87
|
+
performer.perform(actions)
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Begin collecting, rather than immediately performing, actions.
|
92
|
+
##
|
93
|
+
def collect_actions
|
94
|
+
@performer = CollectingPerformer.new
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# The number of seconds between polling attempts.
|
99
|
+
#
|
100
|
+
# Can be provided by the `BRINE_POLL_INTERVAL_SECONDS` environment variable.
|
101
|
+
# Defaults to `0.5`.
|
102
|
+
#
|
103
|
+
# @return [Number] The number of seconds to sleep between poll attempts.
|
104
|
+
##
|
105
|
+
def poll_interval_seconds
|
106
|
+
ENV['BRINE_POLL_INTERVAL_SECONDS'] || 0.25
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Retry the provided block for the specified period.
|
111
|
+
#
|
112
|
+
# If the provided block is evaluated successfully the result
|
113
|
+
# will be returned, if any exception is thrown it will be
|
114
|
+
# retried until the period elapses.
|
115
|
+
#
|
116
|
+
# @param [Number] seconds The period (in seconds) during which the block will be retried.
|
117
|
+
# @param [Number] interval How long to sleep between polling attempts, defaults to `#poll_interval_seconds`.
|
118
|
+
# @param [Block] The logic to retry within the defined period.
|
119
|
+
# @return [Object] The result of the block if successfully evaluated.
|
120
|
+
# @throws [Exception] The most recent exception thrown from the block if never successfully evaluated.
|
121
|
+
##
|
122
|
+
def poll_for(seconds, interval=poll_interval_seconds)
|
123
|
+
failure = nil
|
124
|
+
quit = Time.now + seconds
|
125
|
+
while (Time.now < quit)
|
126
|
+
begin
|
127
|
+
return yield
|
128
|
+
rescue Exception => ex
|
129
|
+
failure = ex
|
130
|
+
sleep interval
|
131
|
+
end
|
132
|
+
end
|
133
|
+
raise failure
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# The duration in seconds for the given handle.
|
138
|
+
#
|
139
|
+
# Currently this only supports values provided through environment variables
|
140
|
+
# of the format BRINE_DURATION_SECONDS_{handle}.
|
141
|
+
#
|
142
|
+
# @param[String] duration The handle/name of the duration whose length should be returned.
|
143
|
+
# @return [Number] The number of seconds to poll for the requested duration.
|
144
|
+
##
|
145
|
+
def retrieve_duration(duration)
|
146
|
+
if ENV["BRINE_DURATION_SECONDS_#{duration}"]
|
147
|
+
ENV["BRINE_DURATION_SECONDS_#{duration}"].to_f
|
148
|
+
else
|
149
|
+
STDERR.puts("Duration #{duration} not defined")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
# Mix the Performing module functionality into the main Brine module.
|
157
|
+
##
|
158
|
+
include Performing
|
159
|
+
end
|