govdelivery-proctor 1.3

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 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
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
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,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc 'Run tests'
8
+ task default: :test
@@ -0,0 +1,6 @@
1
+ module GovDelivery
2
+ module Proctor #:nodoc:
3
+ end
4
+ end
5
+
6
+ require 'govdelivery/proctor/base'
@@ -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
@@ -0,0 +1,5 @@
1
+ module GovDelivery
2
+ module Proctor
3
+ VERSION = "1.3"
4
+ end
5
+ 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
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH << File.expand_path("../lib/govdelivery/proctor", __FILE__)
2
+ require 'bundler/setup'
3
+ Bundler.require :default, :test
4
+
5
+ require 'test/unit'
6
+ require 'govdelivery-proctor'
7
+ require 'pry-byebug'
8
+ require 'logger'
@@ -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