govdelivery-proctor 1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +34 -0
- data/README.md +93 -0
- data/Rakefile +8 -0
- data/lib/govdelivery-proctor.rb +6 -0
- data/lib/govdelivery/proctor/base.rb +109 -0
- data/lib/govdelivery/proctor/version.rb +5 -0
- data/proctor.gemspec +24 -0
- data/test/test_helper.rb +8 -0
- data/test/test_proctor.rb +101 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bce8d79f6531e5607f2cc402de70da89aa6c961a
|
4
|
+
data.tar.gz: cc01c5f9d058db7f0aacff5ecffa1141417dac37
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1047b2266805be8100f8d365a36952e4a91afb18dac09a15a84c9563094971fbf3ace15ff6b5a0823aa0340c62eaf72a0f98f180e2c91392f016d3258e40cdd6
|
7
|
+
data.tar.gz: 75b16d48140304a9cab0cf1343b2f153cda23bd7ca0ee77a02ecd5d901fade3c8b3ba8be2269aae0ca67aba32400bf5247f255c70d8b1ae2ef8c267946f1391f
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Change Log
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
|
+
|
5
|
+
[How to use a CHANGELOG](http://keepachangelog.com/)
|
6
|
+
## [1.3.0]
|
7
|
+
### Added
|
8
|
+
- Say hello to steady_check which sleeps for the increment passed to it
|
9
|
+
### Fixed
|
10
|
+
- accelerating_check algorithm was messed up, so now using `log` to better approximate reverse of backoff_check
|
11
|
+
## [1.2.1]
|
12
|
+
### Fixed
|
13
|
+
- backoff_check and accelerating_check now reset the logger when finished.
|
14
|
+
- Corrected README documentation about accelerating_check
|
15
|
+
## [1.2.0]
|
16
|
+
### Added
|
17
|
+
- reverse backoff added for situations when the likelihood of the condition being true increases over time
|
18
|
+
## [1.1.1]
|
19
|
+
### Fixed
|
20
|
+
- Removed references to the `colored` gem, which was never required, or that useful
|
21
|
+
## [1.1.0]
|
22
|
+
### Updated
|
23
|
+
- backoff_check to only log out on failure.
|
24
|
+
## [1.0.0] - 2016-03-21
|
25
|
+
### Added
|
26
|
+
- backoff_check, log, and suppress class methods on GovDelivery::Proctor
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
govdelivery-proctor (1.2.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
byebug (9.0.5)
|
10
|
+
coderay (1.1.1)
|
11
|
+
method_source (0.8.2)
|
12
|
+
power_assert (0.3.0)
|
13
|
+
pry (0.10.4)
|
14
|
+
coderay (~> 1.1.0)
|
15
|
+
method_source (~> 0.8.1)
|
16
|
+
slop (~> 3.4)
|
17
|
+
pry-byebug (3.4.0)
|
18
|
+
byebug (~> 9.0)
|
19
|
+
pry (~> 0.10)
|
20
|
+
slop (3.6.0)
|
21
|
+
test-unit (3.2.1)
|
22
|
+
power_assert
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
bundler (~> 1.7)
|
29
|
+
govdelivery-proctor!
|
30
|
+
pry-byebug (~> 3.4)
|
31
|
+
test-unit
|
32
|
+
|
33
|
+
BUNDLED WITH
|
34
|
+
1.13.6
|
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
Proctor
|
2
|
+
===========
|
3
|
+
|
4
|
+
Classes and functions to support feature testing.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'govdelivery-proctor'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install govdelivery-proctor
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Include it: `require 'govdelivery-proctor'`
|
25
|
+
|
26
|
+
### backoff_check
|
27
|
+
|
28
|
+
`GovDelivery::Proctor.backoff_check` will run a provided block, over and over
|
29
|
+
with longer and longer waits between runs, until the provided block either
|
30
|
+
returns a truthy value or exceeds a provided max time to wait. At the end
|
31
|
+
of each unsuccessful run - a run that does not return a truthy value - a
|
32
|
+
message will be written to the log based on the provided message string.
|
33
|
+
|
34
|
+
```
|
35
|
+
tomorrow = Time.new.day + 1.day
|
36
|
+
GovDelivery::Proctor.backoff_check(24.hours, "Waiting for tomorrow") do
|
37
|
+
Time.new.day == tomorrow
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
### accelerating_check
|
42
|
+
|
43
|
+
`GovDelivery::Proctor.accelerating_check` will run a provided block, over and over
|
44
|
+
with shorter and shorter waits between runs, until the provided block either
|
45
|
+
returns a truthy value or exceeds a provided max time to wait. At the end
|
46
|
+
of each unsuccessful run - a run that does not return a truthy value - a
|
47
|
+
message will be written to the log based on the provided message string.
|
48
|
+
|
49
|
+
### steady_check
|
50
|
+
|
51
|
+
`GovDelivery::Proctor.steady_check` will run a provided block, over and over
|
52
|
+
with the specified wait between every run, until the provided block either
|
53
|
+
returns a truthy value or exceeds a provided max time to wait. At the end
|
54
|
+
of each unsuccessful run - a run that does not return a truthy value - a
|
55
|
+
message will be written to the log based on the provided message string.
|
56
|
+
|
57
|
+
### log
|
58
|
+
|
59
|
+
Returns a logger object for logging/outputing. By default, this logger object
|
60
|
+
will print to `STDOUT` and have a level of `INFO`. These can be set via the
|
61
|
+
environment variables `TEST_LOG_FILE` and `TEST_LOG_LEVEL` respectively.
|
62
|
+
|
63
|
+
```
|
64
|
+
GovDelivery::Proctor.log.info('Nothing is real') unless 1 == 1
|
65
|
+
```
|
66
|
+
|
67
|
+
### suppress
|
68
|
+
|
69
|
+
Runs a provided block and ignores if a specified exception is thrown.
|
70
|
+
|
71
|
+
```
|
72
|
+
GovDelivery::Proctor.suppress(ZeroDivisionError) do
|
73
|
+
1/0
|
74
|
+
puts 'Nothing wrong here'
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
## Development
|
79
|
+
### Get Dev Dependencies
|
80
|
+
|
81
|
+
$ bundle install
|
82
|
+
|
83
|
+
### Build
|
84
|
+
|
85
|
+
$ gem build proctor.gemspec
|
86
|
+
|
87
|
+
### Install locally
|
88
|
+
|
89
|
+
$ gem install govdelivery-proctor-1.2.0.gem
|
90
|
+
|
91
|
+
### Test
|
92
|
+
|
93
|
+
$ rake test
|
data/Rakefile
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
module GovDelivery::Proctor
|
2
|
+
class CheckTimeExceeded < StandardError; end
|
3
|
+
|
4
|
+
def self.backoff_check(limit, desc = 'Backoff check', inc = 1)
|
5
|
+
raise 'Check requires a block' unless block_given?
|
6
|
+
check(limit, 'backoff', desc, inc) do
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Sometimes you want to reverse backoff because as time
|
12
|
+
# passes it is more likely your condition is true
|
13
|
+
def self.accelerating_check(limit, desc = 'Backon check', inc = 1)
|
14
|
+
raise 'Check requires a block' unless block_given?
|
15
|
+
check(limit, 'accelerate', desc, inc) do
|
16
|
+
yield
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.steady_check(limit, desc = 'Steady check', inc = 1)
|
21
|
+
raise 'Check requires a block' unless block_given?
|
22
|
+
check(limit, 'steady', desc, inc) do
|
23
|
+
yield
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# if backoff, double the wait time each time
|
28
|
+
# if accelerating, ramp up after long pause
|
29
|
+
# if steady, just keep it steady
|
30
|
+
def self.sleep_time(check_type, limit, increment, iteration)
|
31
|
+
case check_type
|
32
|
+
when 'steady'
|
33
|
+
increment
|
34
|
+
when 'backoff'
|
35
|
+
(2**iteration) * increment
|
36
|
+
when 'accelerate'
|
37
|
+
val = Math.log(limit, iteration + 1)
|
38
|
+
val = val.to_f.infinite? ? limit / increment : val
|
39
|
+
val = val.to_f.nan? ? 1 : val.round
|
40
|
+
[increment, val * increment].max
|
41
|
+
else
|
42
|
+
raise "Check type #{check_type} invalid: choose backon, accelerate or steady."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.check(limit, check_type, desc, inc)
|
47
|
+
setup
|
48
|
+
|
49
|
+
slept_time = 0
|
50
|
+
x = 0
|
51
|
+
response = nil
|
52
|
+
Kernel.loop do
|
53
|
+
sleep_time = sleep_time(check_type, limit, inc, ++x)
|
54
|
+
sleep(sleep_time)
|
55
|
+
slept_time += sleep_time
|
56
|
+
response = yield
|
57
|
+
break if response
|
58
|
+
if slept_time >= limit
|
59
|
+
fail_message = "#{desc} has taken too long. Have waited #{slept_time} seconds\nlog: #{@backBuffer.string}"
|
60
|
+
raise CheckTimeExceeded, fail_message
|
61
|
+
end
|
62
|
+
# We're doing this twice, once for standard out so you can see it's still
|
63
|
+
# working, and then again inside the logged output if it fails.
|
64
|
+
|
65
|
+
getStandardLogger.info("Still waiting while #{desc}, current time=#{slept_time}")
|
66
|
+
log.info("Still waiting while #{desc}, current time=#{slept_time}")
|
67
|
+
end
|
68
|
+
teardown
|
69
|
+
response
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.log
|
73
|
+
getStandardLogger
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.suppress(*exception_classes)
|
77
|
+
yield
|
78
|
+
rescue *exception_classes
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.getStandardLogger
|
82
|
+
@log ||= begin
|
83
|
+
logger = Logger.new(ENV['TEST_LOG_FILE'] || STDOUT)
|
84
|
+
logger.level = Logger.const_get(ENV['TEST_LOG_LEVEL'] || 'INFO')
|
85
|
+
logger
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.setup
|
90
|
+
@backBuffer = StringIO.new
|
91
|
+
@backLog = Logger.new @backBuffer
|
92
|
+
|
93
|
+
# We're re-defining log in here so that we can log meaningful information
|
94
|
+
# out during the backoff check, but only for failed runs.
|
95
|
+
def self.log
|
96
|
+
@backLog
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.teardown
|
101
|
+
# We have to re-define log back to it's original implementation
|
102
|
+
# so that we get normal logging after we're out of the backoff check.
|
103
|
+
def self.log
|
104
|
+
getStandardLogger
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private_class_method :getStandardLogger, :setup, :teardown
|
109
|
+
end
|
data/proctor.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'govdelivery/proctor/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'govdelivery-proctor'
|
8
|
+
spec.version = GovDelivery::Proctor::VERSION
|
9
|
+
spec.authors = ['Bill Bushey']
|
10
|
+
spec.email = ['bill.bushey@govdelivery.com']
|
11
|
+
spec.summary = 'Classes and functions to support feature testing.'
|
12
|
+
spec.description = 'Classes and functions to support feature testing.'
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'test-unit'
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
23
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.4'
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module GovDelivery::Proctor
|
4
|
+
require 'logger'
|
5
|
+
end
|
6
|
+
|
7
|
+
class TestProctor < Test::Unit::TestCase
|
8
|
+
def test_sleep_time_steady
|
9
|
+
assert_equal 30, GovDelivery::Proctor.sleep_time('steady', 600, 30, 5)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_sleep_time_backoff_iteration_one
|
13
|
+
assert_equal 60, GovDelivery::Proctor.sleep_time('backoff', 600, 30, 1)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_sleep_time_backoff_iteration_four
|
17
|
+
assert_equal 480, GovDelivery::Proctor.sleep_time('backoff', 600, 30, 4)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_sleep_time_accelerate_iteration_default_to_minimum
|
21
|
+
assert_equal 10, GovDelivery::Proctor.sleep_time('accelerate', 1, 10, 2)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_sleep_time_accelerate_iteration_one
|
25
|
+
assert_equal 90, GovDelivery::Proctor.sleep_time('accelerate', 600, 10, 1)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_sleep_time_accelerate_iteration_four
|
29
|
+
assert_equal 40, GovDelivery::Proctor.sleep_time('accelerate', 600, 10, 4)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_sleep_time_accelerate_iteration_four_lower_sleep
|
33
|
+
assert_equal 4, GovDelivery::Proctor.sleep_time('accelerate', 600, 1, 4)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_backoff_check_condition_true
|
37
|
+
GovDelivery::Proctor.backoff_check 2 do
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_accelerating_check_condition_true
|
43
|
+
GovDelivery::Proctor.accelerating_check 2 do
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_steady_check_condition_true
|
49
|
+
GovDelivery::Proctor.steady_check 2 do
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_backoff_check_condition_false
|
55
|
+
ex = assert_raises GovDelivery::Proctor::CheckTimeExceeded do
|
56
|
+
GovDelivery::Proctor.backoff_check 1 do
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
assert_equal "Backoff check has taken too long. Have waited 1 seconds\nlog: ", ex.message
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_accelerating_check_condition_false
|
64
|
+
ex = assert_raises GovDelivery::Proctor::CheckTimeExceeded do
|
65
|
+
GovDelivery::Proctor.accelerating_check 1 do
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
assert_equal "Backon check has taken too long. Have waited 1 seconds\nlog: ", ex.message
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_steady_check_condition_false
|
73
|
+
ex = assert_raises GovDelivery::Proctor::CheckTimeExceeded do
|
74
|
+
GovDelivery::Proctor.steady_check 1 do
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
assert_equal "Steady check has taken too long. Have waited 1 seconds\nlog: ", ex.message
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_backoff_check_requires_block
|
82
|
+
ex = assert_raises RuntimeError do
|
83
|
+
GovDelivery::Proctor.backoff_check 1
|
84
|
+
end
|
85
|
+
assert_equal 'Check requires a block', ex.message
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_accelerating_check_requires_block
|
89
|
+
ex = assert_raises RuntimeError do
|
90
|
+
GovDelivery::Proctor.accelerating_check 1
|
91
|
+
end
|
92
|
+
assert_equal 'Check requires a block', ex.message
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_steady_check_requires_block
|
96
|
+
ex = assert_raises RuntimeError do
|
97
|
+
GovDelivery::Proctor.steady_check 1
|
98
|
+
end
|
99
|
+
assert_equal 'Check requires a block', ex.message
|
100
|
+
end
|
101
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: govdelivery-proctor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.3'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bill Bushey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: test-unit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
description: Classes and functions to support feature testing.
|
56
|
+
email:
|
57
|
+
- bill.bushey@govdelivery.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- CHANGELOG.md
|
64
|
+
- Gemfile
|
65
|
+
- Gemfile.lock
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/govdelivery-proctor.rb
|
69
|
+
- lib/govdelivery/proctor/base.rb
|
70
|
+
- lib/govdelivery/proctor/version.rb
|
71
|
+
- proctor.gemspec
|
72
|
+
- test/test_helper.rb
|
73
|
+
- test/test_proctor.rb
|
74
|
+
homepage: ''
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 2.5.1
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Classes and functions to support feature testing.
|
98
|
+
test_files:
|
99
|
+
- test/test_helper.rb
|
100
|
+
- test/test_proctor.rb
|