service_downtime_simulator 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +16 -0
- data/.gitignore +58 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +51 -0
- data/Makefile +15 -0
- data/README.md +89 -0
- data/lib/service_downtime_simulator/config.rb +91 -0
- data/lib/service_downtime_simulator/middleware.rb +22 -0
- data/lib/service_downtime_simulator/modes/base.rb +37 -0
- data/lib/service_downtime_simulator/modes/hard_down.rb +11 -0
- data/lib/service_downtime_simulator/modes/intermittently_down.rb +21 -0
- data/lib/service_downtime_simulator/modes/successful_but_gibberish.rb +19 -0
- data/lib/service_downtime_simulator/modes/timing_out.rb +20 -0
- data/lib/service_downtime_simulator/modes.rb +22 -0
- data/lib/service_downtime_simulator.rb +12 -0
- data/service_downtime_simulator.gemspec +23 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b251f2b6694651096a5ae0ca961b6011625f7de5fd454760f6806457c745d813
|
4
|
+
data.tar.gz: 1e62307f82e95f9eb3017f06f8a5c89974992625aa9fabde4bd25a4aed2455d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: df90f8ca05da0c71e34d2eb8427301d128a13f3049f6628039d2a3df08421843073cef6382b2b553e7090bada1f112782e997453a03d9af0b713c302bd9b41e2
|
7
|
+
data.tar.gz: 0eed6fcb9ab37f11ea39270b28ada5ceb772d944b2a5bed7448ddc2748a8ad6b8833c6ff1400979f16590237dfdc4d3cef5efe4de3c6b663cbde5aca30ccce12
|
data/.gitignore
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Created by https://www.gitignore.io/api/ruby
|
2
|
+
|
3
|
+
### Ruby ###
|
4
|
+
*.gem
|
5
|
+
*.rbc
|
6
|
+
/.config
|
7
|
+
/coverage/
|
8
|
+
/InstalledFiles
|
9
|
+
/pkg/
|
10
|
+
/spec/reports/
|
11
|
+
/spec/examples.txt
|
12
|
+
/test/tmp/
|
13
|
+
/test/version_tmp/
|
14
|
+
/tmp/
|
15
|
+
|
16
|
+
# Used by dotenv library to load environment variables.
|
17
|
+
# .env
|
18
|
+
|
19
|
+
## Specific to RubyMotion:
|
20
|
+
.dat*
|
21
|
+
.repl_history
|
22
|
+
build/
|
23
|
+
*.bridgesupport
|
24
|
+
build-iPhoneOS/
|
25
|
+
build-iPhoneSimulator/
|
26
|
+
|
27
|
+
## Specific to RubyMotion (use of CocoaPods):
|
28
|
+
#
|
29
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
30
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
31
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
32
|
+
#
|
33
|
+
# vendor/Pods/
|
34
|
+
|
35
|
+
## Documentation cache and generated files:
|
36
|
+
/.yardoc/
|
37
|
+
/_yardoc/
|
38
|
+
/doc/
|
39
|
+
/rdoc/
|
40
|
+
|
41
|
+
## Environment normalization:
|
42
|
+
/.bundle/
|
43
|
+
/vendor/bundle
|
44
|
+
/lib/bundler/man/
|
45
|
+
|
46
|
+
# for a library or gem, you might want to ignore these files since the code is
|
47
|
+
# intended to run in multiple environments; otherwise, check them in:
|
48
|
+
# Gemfile.lock
|
49
|
+
# .ruby-version
|
50
|
+
# .ruby-gemset
|
51
|
+
|
52
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
53
|
+
.rvmrc
|
54
|
+
|
55
|
+
|
56
|
+
# End of https://www.gitignore.io/api/ruby
|
57
|
+
|
58
|
+
.rspec_status
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# 80 char line length is not enough chars. 120 is better. We're not working on 1024x768 CRTs.
|
2
|
+
Metrics/LineLength:
|
3
|
+
Max: 120
|
4
|
+
|
5
|
+
# Documentation is for nerds.
|
6
|
+
Style/Documentation:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
# I like my code verbose and spaced out.
|
10
|
+
Metrics/MethodLength:
|
11
|
+
Max: 20
|
12
|
+
|
13
|
+
# Because RSpec tests are block-centric, this is an insane linter to run on them.
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Exclude:
|
16
|
+
- spec/**/*
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
service_downtime_simulator (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.0)
|
10
|
+
diff-lcs (1.3)
|
11
|
+
jaro_winkler (1.5.1)
|
12
|
+
parallel (1.12.1)
|
13
|
+
parser (2.5.1.2)
|
14
|
+
ast (~> 2.4.0)
|
15
|
+
powerpack (0.1.2)
|
16
|
+
rainbow (3.0.0)
|
17
|
+
rspec (3.8.0)
|
18
|
+
rspec-core (~> 3.8.0)
|
19
|
+
rspec-expectations (~> 3.8.0)
|
20
|
+
rspec-mocks (~> 3.8.0)
|
21
|
+
rspec-core (3.8.0)
|
22
|
+
rspec-support (~> 3.8.0)
|
23
|
+
rspec-expectations (3.8.1)
|
24
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
+
rspec-support (~> 3.8.0)
|
26
|
+
rspec-mocks (3.8.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.8.0)
|
29
|
+
rspec-support (3.8.0)
|
30
|
+
rubocop (0.59.1)
|
31
|
+
jaro_winkler (~> 1.5.1)
|
32
|
+
parallel (~> 1.10)
|
33
|
+
parser (>= 2.5, != 2.5.1.1)
|
34
|
+
powerpack (~> 0.1)
|
35
|
+
rainbow (>= 2.2.2, < 4.0)
|
36
|
+
ruby-progressbar (~> 1.7)
|
37
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
38
|
+
ruby-progressbar (1.10.0)
|
39
|
+
unicode-display_width (1.4.0)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
bundler (~> 1.16)
|
46
|
+
rspec (~> 3.0)
|
47
|
+
rubocop
|
48
|
+
service_downtime_simulator!
|
49
|
+
|
50
|
+
BUNDLED WITH
|
51
|
+
1.16.1
|
data/Makefile
ADDED
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# Service Downtime Simulator
|
2
|
+
|
3
|
+
[![CircleCI](https://circleci.com/gh/deliveroo/service_downtime_simulator/tree/master.svg?style=svg&circle-token=d66bc2c0246da5cdf4eeaeb6c9f7b10bcd74bb7b)](https://circleci.com/gh/deliveroo/service_downtime_simulator/tree/master)
|
4
|
+
|
5
|
+
This is a piece of Rack middleware that simulates failures you would want to tolerate in upstream services.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
### Rails
|
10
|
+
|
11
|
+
Add the following in `application.rb`:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
config.middleware.use(
|
15
|
+
ServiceDowntimeSimulator::Middleware,
|
16
|
+
config # See below for info about how to configure this
|
17
|
+
)
|
18
|
+
```
|
19
|
+
|
20
|
+
### Other Rack-based applications
|
21
|
+
|
22
|
+
Instructions TBC.
|
23
|
+
|
24
|
+
## Configuration
|
25
|
+
|
26
|
+
The middleware takes a `config` argument in the form of a hash. Said hash should have the following shape:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
{
|
30
|
+
enabled: Boolean,
|
31
|
+
mode: Symbol,
|
32
|
+
excluded_paths: Array<String>,
|
33
|
+
logger: Logger?
|
34
|
+
}
|
35
|
+
```
|
36
|
+
|
37
|
+
Here's what you can supply for each of those options:
|
38
|
+
|
39
|
+
- **enabled** (`Boolean`)
|
40
|
+
- `true` will enable simulation of failures (assuming you supply a valid `mode`, see below)
|
41
|
+
- `false` will disable simulation and your application will function as normal
|
42
|
+
- **mode** (`Symbol`)
|
43
|
+
- `:hard_down` will cause all requests to return a 500 error
|
44
|
+
- `:intermittently_down` will cause 50% of requests to return a 500 error
|
45
|
+
- `:successful_but_gibberish` will return a 200, but with a response body that is not machine readable
|
46
|
+
- `:timing_out` will wait for 15 seconds on each request, and then return a 503
|
47
|
+
- **excluded_paths** (`Array<String>`)
|
48
|
+
- You can supply a list of paths that you don't want to be affected by the simulation here (e.g. `['/foobar']`)
|
49
|
+
- The most common thing you're going to want to include here is your service's health check endpoint, as if it is returning a 5xx thanks to this middleware your application will not deploy
|
50
|
+
- **logger** (`Logger?`)
|
51
|
+
- If supplied, useful debug information will be sent here
|
52
|
+
|
53
|
+
In order for the middleware to kick in, `enabled` must be explicitly set to `true` and `mode` must be a valid option. Unless both are explicitly supplied, the underlying application will continue to function as normal.
|
54
|
+
|
55
|
+
### Examples
|
56
|
+
|
57
|
+
Here's a couple of example configurations:
|
58
|
+
|
59
|
+
#### Hard-coded Hard Down
|
60
|
+
|
61
|
+
This example will always return a 500 for all requests.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
config.middleware.use(
|
65
|
+
ServiceDowntimeSimulator::Middleware,
|
66
|
+
{
|
67
|
+
enabled: true,
|
68
|
+
mode: :hard_down,
|
69
|
+
excluded_paths: ['/health'],
|
70
|
+
logger: Rails.logger
|
71
|
+
}
|
72
|
+
)
|
73
|
+
```
|
74
|
+
|
75
|
+
#### Environment-variable Controlled Simulation
|
76
|
+
|
77
|
+
This is a more practical example, allowing failure simulation to happen based on environment variables. It requires an environment variable with a specific value to enable the failure simulation, and also requires a mode to be provided. If either are missing, the app continues as normal. You can also use this pattern for feature flagging. Probably.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
config.middleware.use(
|
81
|
+
ServiceDowntimeSimulator::Middleware,
|
82
|
+
{
|
83
|
+
enabled: ENV['FAILURE_SIMULATION_ENABLED'] == 'I_UNDERSTAND_THE_CONSEQUENCES_OF_THIS',
|
84
|
+
mode: ENV['FAILURE_SIMULATION_MODE'],
|
85
|
+
excluded_paths: ['/health'],
|
86
|
+
logger: Rails.logger
|
87
|
+
}
|
88
|
+
)
|
89
|
+
```
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module ServiceDowntimeSimulator
|
2
|
+
class Config
|
3
|
+
WonkyInputError = Class.new(StandardError)
|
4
|
+
|
5
|
+
OPTIONS = %i[
|
6
|
+
enabled
|
7
|
+
mode
|
8
|
+
logger
|
9
|
+
excluded_paths
|
10
|
+
].freeze
|
11
|
+
|
12
|
+
attr_reader :logger
|
13
|
+
|
14
|
+
def self.for(config)
|
15
|
+
return config if config.is_a?(self)
|
16
|
+
|
17
|
+
new(config)
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(config_hash)
|
21
|
+
raise WonkyInputError unless config_hash.is_a?(Hash)
|
22
|
+
|
23
|
+
config_hash.each do |key, value|
|
24
|
+
instance_variable_set("@#{key}", value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def activated?
|
29
|
+
enabled == true && !mode.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
def enabled
|
33
|
+
@enabled == true
|
34
|
+
end
|
35
|
+
|
36
|
+
def mode
|
37
|
+
if @mode.nil?
|
38
|
+
moan(:mode, 'No mode provided')
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
|
42
|
+
unless @mode.is_a?(Symbol)
|
43
|
+
moan(:mode, 'Mode must be a symbol')
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
|
47
|
+
unless ServiceDowntimeSimulator::Modes.exists?(@mode)
|
48
|
+
moan(:mode, "Unknown mode #{@mode}")
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
|
52
|
+
@mode
|
53
|
+
end
|
54
|
+
|
55
|
+
def mode_klass
|
56
|
+
ServiceDowntimeSimulator::Modes.for(mode)
|
57
|
+
end
|
58
|
+
|
59
|
+
def excluded_paths
|
60
|
+
if @excluded_paths.nil?
|
61
|
+
moan(:excluded_paths, 'No excluded paths set. What about your health check endpoint?')
|
62
|
+
return []
|
63
|
+
end
|
64
|
+
|
65
|
+
unless @excluded_paths.is_a?(Array)
|
66
|
+
moan(:excluded_paths, 'Excluded paths must ba an array of paths')
|
67
|
+
return []
|
68
|
+
end
|
69
|
+
|
70
|
+
# Detect if any elements are not a string
|
71
|
+
if @excluded_paths.any? { |el| !el.is_a?(String) }
|
72
|
+
moan(:excluded_paths, 'Excluded paths includes non-string value')
|
73
|
+
return []
|
74
|
+
end
|
75
|
+
|
76
|
+
@excluded_paths
|
77
|
+
end
|
78
|
+
|
79
|
+
def path_excluded?(path)
|
80
|
+
excluded_paths.include?(path)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def moan(option, message)
|
86
|
+
return unless logger.respond_to?(:error)
|
87
|
+
|
88
|
+
logger.error("[SDS] Issue with #{option}: #{message}. Will not activate unless fixed.")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ServiceDowntimeSimulator
|
2
|
+
class Middleware
|
3
|
+
def initialize(app, config)
|
4
|
+
@app = app
|
5
|
+
@config = ServiceDowntimeSimulator::Config.for(config)
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
return app.call(env) if bypass?(env)
|
10
|
+
|
11
|
+
config.mode_klass.new(app).call(env)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :app, :config
|
17
|
+
|
18
|
+
def bypass?(env)
|
19
|
+
!config.activated? || config.path_excluded?(env['PATH_INFO'])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ServiceDowntimeSimulator
|
2
|
+
module Modes
|
3
|
+
class Base
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
@env = env
|
10
|
+
|
11
|
+
[status, headers, body]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def headers
|
17
|
+
{
|
18
|
+
'X-SDS-Mode' => identifier
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def body
|
23
|
+
"Simulated Response (#{identifier})"
|
24
|
+
end
|
25
|
+
|
26
|
+
def status
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def identifier
|
31
|
+
self.class.name
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :app, :env
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ServiceDowntimeSimulator
|
2
|
+
module Modes
|
3
|
+
class IntermittentlyDown < Base
|
4
|
+
def call(env)
|
5
|
+
return app.call(env) unless knackered?
|
6
|
+
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def status
|
13
|
+
500
|
14
|
+
end
|
15
|
+
|
16
|
+
def knackered?
|
17
|
+
[true, false].sample
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ServiceDowntimeSimulator
|
2
|
+
module Modes
|
3
|
+
class SuccessfulButGibberish < Base
|
4
|
+
private
|
5
|
+
|
6
|
+
def status
|
7
|
+
200
|
8
|
+
end
|
9
|
+
|
10
|
+
def body
|
11
|
+
cheeseboard.shuffle.join(' ')
|
12
|
+
end
|
13
|
+
|
14
|
+
def cheeseboard
|
15
|
+
%w[stilton caerphilly cheddar gloucester wensleydale brie] * 10
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ServiceDowntimeSimulator
|
2
|
+
module Modes
|
3
|
+
NotFound = Class.new(StandardError)
|
4
|
+
|
5
|
+
AVAILABLE = {
|
6
|
+
hard_down: ServiceDowntimeSimulator::Modes::HardDown,
|
7
|
+
intermittently_down: ServiceDowntimeSimulator::Modes::IntermittentlyDown,
|
8
|
+
successful_but_gibberish: ServiceDowntimeSimulator::Modes::SuccessfulButGibberish,
|
9
|
+
timing_out: ServiceDowntimeSimulator::Modes::TimingOut
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
def self.for(id)
|
13
|
+
raise NotFound unless exists?(id)
|
14
|
+
|
15
|
+
AVAILABLE[id]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.exists?(id)
|
19
|
+
AVAILABLE.key?(id)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ServiceDowntimeSimulator
|
2
|
+
VERSION = '0.1.0'.freeze
|
3
|
+
end
|
4
|
+
|
5
|
+
require_relative 'service_downtime_simulator/config'
|
6
|
+
require_relative 'service_downtime_simulator/middleware'
|
7
|
+
require_relative 'service_downtime_simulator/modes/base'
|
8
|
+
require_relative 'service_downtime_simulator/modes/hard_down'
|
9
|
+
require_relative 'service_downtime_simulator/modes/intermittently_down'
|
10
|
+
require_relative 'service_downtime_simulator/modes/successful_but_gibberish'
|
11
|
+
require_relative 'service_downtime_simulator/modes/timing_out'
|
12
|
+
require_relative 'service_downtime_simulator/modes'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'service_downtime_simulator'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'service_downtime_simulator'
|
7
|
+
spec.version = ServiceDowntimeSimulator::VERSION
|
8
|
+
spec.authors = ['Josh McMillan']
|
9
|
+
spec.email = ['joshua.mcmillan@deliveroo.co.uk']
|
10
|
+
|
11
|
+
spec.summary = "Want to know what it's like to have me in your dev team? This gem is for you!"
|
12
|
+
spec.homepage = 'https://github.com/deliveroo/service_downtime_simulator'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
21
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
22
|
+
spec.add_development_dependency 'rubocop'
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: service_downtime_simulator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh McMillan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- joshua.mcmillan@deliveroo.co.uk
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".circleci/config.yml"
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".rubocop.yml"
|
66
|
+
- Gemfile
|
67
|
+
- Gemfile.lock
|
68
|
+
- Makefile
|
69
|
+
- README.md
|
70
|
+
- lib/service_downtime_simulator.rb
|
71
|
+
- lib/service_downtime_simulator/config.rb
|
72
|
+
- lib/service_downtime_simulator/middleware.rb
|
73
|
+
- lib/service_downtime_simulator/modes.rb
|
74
|
+
- lib/service_downtime_simulator/modes/base.rb
|
75
|
+
- lib/service_downtime_simulator/modes/hard_down.rb
|
76
|
+
- lib/service_downtime_simulator/modes/intermittently_down.rb
|
77
|
+
- lib/service_downtime_simulator/modes/successful_but_gibberish.rb
|
78
|
+
- lib/service_downtime_simulator/modes/timing_out.rb
|
79
|
+
- service_downtime_simulator.gemspec
|
80
|
+
homepage: https://github.com/deliveroo/service_downtime_simulator
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.7.6
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Want to know what it's like to have me in your dev team? This gem is for
|
104
|
+
you!
|
105
|
+
test_files: []
|