aranea 0.0.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.rspec +3 -0
- data/.rubocop.yml +21 -0
- data/.travis.yml +26 -0
- data/CHANGELOG.md +17 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +19 -0
- data/README.md +124 -0
- data/aranea.gemspec +38 -0
- data/lib/aranea/failure_repository.rb +28 -33
- data/lib/aranea/faraday/aranea_middleware.rb +2 -8
- data/lib/aranea/rack/aranea_middleware.rb +31 -22
- data/lib/aranea/version.rb +3 -3
- data/lib/aranea.rb +13 -2
- metadata +66 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1f95355bc1bd064c5a8a08ff5ba13f5632c908ad3b69d2cfecf463eb86487060
|
4
|
+
data.tar.gz: 5478f42f5772e7dac1e0271a7a885e0721f4f773ff34b796fc4192571071bf65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ce5e10dd7cd3406bef5f0dc18c63bbe22d04bfad828380e46b9b65eab1c464ecaa77f38f73a97ba54c6f5202ebd39cc00f8c4c6b36b76f6e4619614d893792f
|
7
|
+
data.tar.gz: f610b53334f72d814fadd75c15450ad2237aac20a7e9849fb373ab5418386cd1778f61b3f156dd43362b58507d3ff7d3be849ad036750f3f1731f9e512a596f2
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-mdsol: rubocop.yml
|
3
|
+
|
4
|
+
require:
|
5
|
+
- rubocop-performance
|
6
|
+
|
7
|
+
Gemspec/RequireMFA:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Layout/ArgumentAlignment:
|
11
|
+
EnforcedStyle: with_fixed_indentation
|
12
|
+
|
13
|
+
Layout/FirstHashElementIndentation:
|
14
|
+
EnforcedStyle: consistent
|
15
|
+
|
16
|
+
Style/FrozenStringLiteralComment:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Style/StringLiterals:
|
20
|
+
Enabled: true
|
21
|
+
EnforcedStyle: double_quotes
|
data/.travis.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
dist: focal
|
2
|
+
language: ruby
|
3
|
+
cache: bundler
|
4
|
+
|
5
|
+
rvm:
|
6
|
+
- 2.5
|
7
|
+
- 2.6
|
8
|
+
- 2.7
|
9
|
+
- 3.0
|
10
|
+
- 3.1
|
11
|
+
|
12
|
+
before_install:
|
13
|
+
- gem update --system --force -N > /dev/null && echo "Rubygems version $(gem --version)" && bundle --version
|
14
|
+
|
15
|
+
install: BUNDLE_JOBS=4 bundle install
|
16
|
+
|
17
|
+
script:
|
18
|
+
- bundle exec rubocop
|
19
|
+
- bundle exec rspec
|
20
|
+
|
21
|
+
deploy:
|
22
|
+
edge: true # opt in to dpl v2
|
23
|
+
provider: rubygems
|
24
|
+
on:
|
25
|
+
tags: true
|
26
|
+
condition: $TRAVIS_RUBY_VERSION == 3.1
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# 0.2.0
|
2
|
+
- Allow Faraday 2.x.
|
3
|
+
|
4
|
+
# 0.1.0
|
5
|
+
- Require Ruby 2.5 and up.
|
6
|
+
- Require ActiveSupport 4.2 and up.
|
7
|
+
- Allow Faraday 1.x.
|
8
|
+
- Refresh code/specs and publish to rubygems.org.
|
9
|
+
|
10
|
+
# 0.0.3
|
11
|
+
- Added ability to specify the response body and response headers.
|
12
|
+
|
13
|
+
# 0.0.2
|
14
|
+
- Ability to raise Faraday::SSLError.
|
15
|
+
|
16
|
+
# 0.0.1
|
17
|
+
- Initial release.
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2015-2021 Medidata Solutions Worldwide
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# Aranea
|
2
|
+
|
3
|
+
Aranea is a gem to use in fault-tolerance testing. It simulates a remote dependency failing, so that you can see how your project reacts.
|
4
|
+
|
5
|
+
In Dungeons and Dragons, an Aranea is a giant spider that will ambush a group of adventurers using its illusion powers, then immobilize the strongest member, forcing the others to battle without a key ally.
|
6
|
+
|
7
|
+
Aranea currently only works with Faraday clients.
|
8
|
+
|
9
|
+
## Activating Aranea in a Deployed Rails or Rack Application
|
10
|
+
|
11
|
+
If Aranea has already been set up and configured to run in your testing environment, you can switch it on via a POST request to `/disable`. For example, in your shell, you could write
|
12
|
+
|
13
|
+
```sh
|
14
|
+
curl -d "" https://myapp-sandbox.example.com/disable?dependency=google
|
15
|
+
```
|
16
|
+
|
17
|
+
Your app should return the message "For the next 5 minutes, all requests to urls containing 'google' will 500". You can then see how your app would behave if google were down, without the bother of having to actually DOS google.
|
18
|
+
|
19
|
+
You must specify a dependency. If you want *all* external requests to fail, set `dependency=.`. Any regular expression syntax will work, so if you want a subset of dependencies to fail, use a pipe-delimited list (`dependency=google|yahoo`).
|
20
|
+
|
21
|
+
You can override the duration of the test by specifying `minutes=` with a number from 1 to 60.
|
22
|
+
|
23
|
+
You can optionally specify the response body by setting `response=` and also the response header by setting `header=`. The endpoint to create a stubbed response uses query parameters, so your `response` and `header` fields must be URL encoded. For example, to return a response `{ "errors": "test_error" }`, you must send `response=%7B%20%22errors%22%3A%20%22test_error%22%20%7D`.
|
24
|
+
|
25
|
+
You can also override the simulated response code, if your app is meant to handle different failures differently. `?dependency=google&failure=404` will simulate a 404 (Not Found) response instead of a 500 (Internal Server Error). `?dependency=google&failure=timeout` will pretend the server never responded at all (although it will raise an error instantly; the illusion is not perfect).
|
26
|
+
|
27
|
+
### Sample calls and their effects
|
28
|
+
|
29
|
+
```
|
30
|
+
https://myapp-sandbox.example.com/disable?dependency=google
|
31
|
+
```
|
32
|
+
For the next 5 minutes, all requests to urls containing 'google' will 500.
|
33
|
+
|
34
|
+
---
|
35
|
+
|
36
|
+
```
|
37
|
+
https://myapp-sandbox.example.com/disable?dependency=.&failure=403
|
38
|
+
```
|
39
|
+
For the next 5 minutes, all external requests will 403.
|
40
|
+
|
41
|
+
---
|
42
|
+
|
43
|
+
```
|
44
|
+
https://myapp-sandbox.example.com/disable?dependency=sheep&failure=ssl_error
|
45
|
+
```
|
46
|
+
For the next 5 minutes, all external requests to urls containing `sheep` will raise a Faraday::SSLError.
|
47
|
+
|
48
|
+
---
|
49
|
+
|
50
|
+
```
|
51
|
+
https://myapp-sandbox.example.com/disable?dependency=google|yahoo&minutes=10
|
52
|
+
```
|
53
|
+
For the next 10 minutes, all requests to urls containing 'google' and/or 'yahoo' will 500.
|
54
|
+
|
55
|
+
---
|
56
|
+
|
57
|
+
```
|
58
|
+
https://myapp-sandbox.example.com/disable?dependency=google|yahoo&minutes=10&failure=timeout
|
59
|
+
```
|
60
|
+
For the next 10 minutes, all requests to urls containing 'google' and/or 'yahoo' will raise a Timeout error.
|
61
|
+
|
62
|
+
---
|
63
|
+
|
64
|
+
```
|
65
|
+
https://myapp-sandbox.example.com/disable?dependency=google|yahoo&minutes=10&failure=timeout&response=%7B%20%22errors%22%3A%20%22test_error%22%20%7D
|
66
|
+
```
|
67
|
+
Similar to the above example, except all external requests that match will now return `{ "errors": "test_error" }`.
|
68
|
+
|
69
|
+
---
|
70
|
+
|
71
|
+
```
|
72
|
+
https://myapp-sandbox.example.com/disable?dependency=google|yahoo&minutes=10&failure=timeout&response=%7B%20%22errors%22%3A%20%22test_error%22%20%7D&headers=%7B%20%22Content-Type%22%3A%20%22application%2Fjson%22%20%7D
|
73
|
+
```
|
74
|
+
Similar to the above example, except all external requests that match will now return `{ "errors": "test_error" }`, and will return the header `{ "Content-Type": "application/json" }`
|
75
|
+
|
76
|
+
## Activating Aranea Programmatically
|
77
|
+
|
78
|
+
From inside your application, you can run
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
Aranea::Failure.create(
|
82
|
+
pattern: /google/,
|
83
|
+
minutes: 5,
|
84
|
+
failure: 503,
|
85
|
+
response_hash: { "errors": "test_error" },
|
86
|
+
response_headers_hash: { "Content-Type": "application/json" }
|
87
|
+
)
|
88
|
+
```
|
89
|
+
|
90
|
+
All parameters are required in this form. They may alternatively be provided as strings ('google','5').
|
91
|
+
|
92
|
+
## Adding Aranea To Your Project
|
93
|
+
|
94
|
+
In your Gemfile:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
gem "aranea", "~> 0.1"
|
98
|
+
```
|
99
|
+
|
100
|
+
In your Faraday middleware stack (wherever and however you configure it):
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
use Aranea::Faraday::FailureSimulator
|
104
|
+
```
|
105
|
+
|
106
|
+
Similarly, in your Rack middleware stack:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
if ENV['USE_ARANEA']
|
110
|
+
use Aranea::Rack::FailureCreator
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
You'll want to ensure that Aranea (or at minimum the Rack middleware) is not active in production!
|
115
|
+
|
116
|
+
## Caveats and Limitations
|
117
|
+
|
118
|
+
Aranea needs to be included manually into every Faraday stack you have. If you miss one, or if you have a gem that makes http requests without using Faraday, your fault-tolerance test may falsely pass. Pull requests are welcome for compatibility with other http clients (aws-sdk is on the wishlist).
|
119
|
+
|
120
|
+
Failures are not necessarily shared between processes. Aranea will use `Rails.cache` if it exists and is available when it starts up, so if `Rails.cache` is shared between processes, a POST that hits one app worker will disable requests from all of them. But if you're not using Rails, your cache is in-memory, your cache is a file cache and your workers can be on different servers, or something else goes wrong, then some requests are likely to get through. In particular, jobs executed in the background may not hit the failure, even if they execute within the specified time frame.
|
121
|
+
|
122
|
+
## Owners
|
123
|
+
|
124
|
+
Aranea is (c) Medidata Solutions Worldwide and owned by whoever committed to it most recently. Original concept by Matthew Szenher.
|
data/aranea.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/aranea/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "aranea"
|
7
|
+
s.version = Aranea::VERSION
|
8
|
+
s.authors = ["Aaron Weiner", "Matthew Szenher"]
|
9
|
+
s.email = s.authors.map { |name| name.sub(/(.).* (.*)/, '\1\2@mdsol.com') }
|
10
|
+
s.homepage = "https://github.com/mdsol/aranea"
|
11
|
+
s.summary = "Middleware for fault tolerance testing"
|
12
|
+
s.description = "Rack and Faraday middleware to temporarily disable connections to external dependencies"
|
13
|
+
s.license = "MIT"
|
14
|
+
|
15
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
16
|
+
|
17
|
+
s.metadata["homepage_uri"] = s.homepage
|
18
|
+
s.metadata["source_code_uri"] = s.homepage
|
19
|
+
s.metadata["changelog_uri"] = "#{s.homepage}/blob/master/CHANGELOG.md"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
s.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
|
28
|
+
s.add_dependency "activesupport", ">= 4.2"
|
29
|
+
s.add_dependency "faraday", ">= 0.9", "< 3.0"
|
30
|
+
s.add_dependency "rack"
|
31
|
+
|
32
|
+
s.add_development_dependency "pry-byebug"
|
33
|
+
s.add_development_dependency "rails"
|
34
|
+
s.add_development_dependency "rspec"
|
35
|
+
s.add_development_dependency "rubocop", "= 1.26.1"
|
36
|
+
s.add_development_dependency "rubocop-mdsol", "~> 0.1"
|
37
|
+
s.add_development_dependency "rubocop-performance", "= 1.13.3"
|
38
|
+
end
|
@@ -1,31 +1,27 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
module Aranea
|
4
|
-
|
5
|
-
#
|
4
|
+
# TODO: Look into moving whitelisting of consumer hostnames to here and allowing it to be configurable
|
5
|
+
# via the consuming application
|
6
6
|
|
7
7
|
class Failure
|
8
|
-
|
9
8
|
class << self
|
10
|
-
|
11
9
|
def current
|
12
10
|
retrieve_failure || NullFailure.new
|
13
11
|
end
|
14
12
|
|
15
13
|
def create(params)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
14
|
+
failure = retrieve_failure
|
15
|
+
raise FailureFailure, "A failure is already in progress (#{failure})." if failure
|
16
|
+
|
17
|
+
failure = new(params)
|
18
|
+
Repository.store(failure, params[:minutes].minutes)
|
19
|
+
failure
|
23
20
|
end
|
24
21
|
|
25
22
|
def retrieve_failure
|
26
23
|
Repository.get
|
27
24
|
end
|
28
|
-
|
29
25
|
end
|
30
26
|
|
31
27
|
attr_accessor :expiration_date
|
@@ -33,34 +29,39 @@ module Aranea
|
|
33
29
|
def initialize(params)
|
34
30
|
@pattern = Regexp.new(params[:pattern])
|
35
31
|
@response = params[:failure]
|
32
|
+
@response_hash = params[:response_hash] || {}
|
33
|
+
@response_headers_hash = params[:response_headers_hash] || {}
|
36
34
|
end
|
37
35
|
|
38
|
-
def should_fail?(request_env,
|
36
|
+
def should_fail?(request_env, _app)
|
39
37
|
@pattern.match(request_env[:url].to_s)
|
40
38
|
end
|
41
39
|
|
42
40
|
def respond!
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
case @response
|
42
|
+
when "timeout"
|
43
|
+
raise ::Faraday::TimeoutError, "Fake failure from Aranea"
|
44
|
+
when "ssl_error"
|
45
|
+
raise ::Faraday::SSLError, "Fake failure from Aranea"
|
47
46
|
else
|
48
|
-
::Faraday::Response.new(
|
47
|
+
::Faraday::Response.new(
|
48
|
+
status: @response.to_i,
|
49
|
+
body: @response_hash.to_json,
|
50
|
+
response_headers: @response_headers_hash
|
51
|
+
)
|
49
52
|
end
|
50
53
|
end
|
51
54
|
|
52
55
|
def to_s
|
53
|
-
"Failure on #{@pattern.inspect} ending at approximately
|
56
|
+
"Failure on #{@pattern.inspect} ending at approximately #{@expiration_date}"
|
54
57
|
end
|
55
58
|
|
56
|
-
#TODO: Actually implement Repository pattern, dependency injection and all.
|
59
|
+
# TODO: Actually implement Repository pattern, dependency injection and all.
|
57
60
|
# As is we only support sharing between multiple instances if Rails.cache exists and does
|
58
61
|
class Repository
|
59
|
-
|
60
|
-
KEY = 'aranea_current_failure'
|
62
|
+
KEY = "aranea_current_failure"
|
61
63
|
|
62
64
|
class << self
|
63
|
-
|
64
65
|
def store(failure, lifespan)
|
65
66
|
failure.expiration_date = Time.now + lifespan
|
66
67
|
cache.write(KEY, failure, expires_in: lifespan)
|
@@ -83,22 +84,16 @@ module Aranea
|
|
83
84
|
end
|
84
85
|
|
85
86
|
def memory_store
|
86
|
-
require
|
87
|
+
require "active_support/cache"
|
87
88
|
ActiveSupport::Cache::MemoryStore.new
|
88
89
|
end
|
89
|
-
|
90
90
|
end
|
91
|
-
|
92
91
|
end
|
93
|
-
|
94
92
|
end
|
95
93
|
|
96
94
|
class NullFailure
|
97
|
-
|
98
|
-
def should_fail?(request_env, app)
|
95
|
+
def should_fail?(_request_env, _app)
|
99
96
|
false
|
100
97
|
end
|
101
|
-
|
102
98
|
end
|
103
|
-
|
104
99
|
end
|
@@ -1,30 +1,24 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Aranea
|
4
4
|
module Faraday
|
5
|
-
|
6
5
|
class FailureSimulator
|
7
|
-
|
8
6
|
def initialize(app, config = {})
|
9
7
|
@app = app
|
10
8
|
@config = config
|
11
9
|
end
|
12
10
|
|
13
11
|
def call(request_env)
|
14
|
-
|
15
12
|
current_failure = Failure.current
|
16
13
|
|
17
14
|
if current_failure.should_fail?(request_env, @app)
|
18
|
-
#TODO: injectable logger
|
15
|
+
# TODO: injectable logger
|
19
16
|
puts "Aranea: simulating a failed call on #{request_env}"
|
20
17
|
current_failure.respond!
|
21
18
|
else
|
22
19
|
@app.call(request_env)
|
23
20
|
end
|
24
|
-
|
25
21
|
end
|
26
|
-
|
27
22
|
end
|
28
|
-
|
29
23
|
end
|
30
24
|
end
|
@@ -1,16 +1,12 @@
|
|
1
|
-
|
2
|
-
require 'rack'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Aranea
|
5
|
-
|
6
4
|
FailureFailure = Class.new(RuntimeError)
|
7
5
|
|
8
|
-
ALLOWED_MINUTES = 1..60
|
6
|
+
ALLOWED_MINUTES = (1..60).freeze
|
9
7
|
|
10
8
|
module Rack
|
11
|
-
|
12
9
|
class FailureCreator
|
13
|
-
|
14
10
|
def initialize(app, config = {})
|
15
11
|
@app = app
|
16
12
|
@config = config
|
@@ -19,11 +15,11 @@ module Aranea
|
|
19
15
|
def call(env)
|
20
16
|
if failure_creation_request?(env)
|
21
17
|
response = begin
|
22
|
-
[create_failure(::Rack::Utils.parse_query(env[
|
18
|
+
[create_failure(::Rack::Utils.parse_query(env["QUERY_STRING"])), 201, {}]
|
23
19
|
rescue FailureFailure => e
|
24
20
|
[e.message, 422, {}]
|
25
|
-
rescue
|
26
|
-
[
|
21
|
+
rescue => e
|
22
|
+
[e.message, 500, {}]
|
27
23
|
end
|
28
24
|
::Rack::Response.new(*response).finish
|
29
25
|
else
|
@@ -31,37 +27,50 @@ module Aranea
|
|
31
27
|
end
|
32
28
|
end
|
33
29
|
|
34
|
-
|
30
|
+
protected
|
35
31
|
|
36
32
|
def failure_creation_request?(env)
|
37
|
-
env[
|
33
|
+
env["REQUEST_METHOD"] == "POST" && env["PATH_INFO"] == "/disable"
|
38
34
|
end
|
39
35
|
|
40
36
|
def create_failure(options)
|
41
|
-
dependency = options.fetch(
|
42
|
-
|
43
|
-
|
37
|
+
dependency = options.fetch("dependency") do
|
38
|
+
raise FailureFailure, "Please provide a dependency to simulate failing"
|
39
|
+
end
|
40
|
+
minutes = options.fetch("minutes", 5)
|
41
|
+
failure = options.fetch("failure", "500")
|
42
|
+
response = options.fetch("response", "{}") # Expect URI encoded
|
43
|
+
headers = options.fetch("headers", "{}")
|
44
44
|
|
45
|
-
|
45
|
+
# These will emit a parsing error if the response/headers URI encoded string is malformed.
|
46
|
+
response_hash = JSON.parse(CGI.unescape(response)).to_hash
|
47
|
+
response_headers_hash = JSON.parse(CGI.unescape(headers)).to_hash
|
48
|
+
|
49
|
+
unless /\A((4|5)\d\d|timeout|ssl_error)\Z/i.match?(failure)
|
46
50
|
raise FailureFailure, "failure should be a 4xx or 5xx status code, timeout, or ssl_error; got #{failure}"
|
47
51
|
end
|
48
52
|
|
49
53
|
unless ALLOWED_MINUTES.cover?(minutes.to_i)
|
50
|
-
raise FailureFailure,
|
54
|
+
raise FailureFailure,
|
55
|
+
"minutes should be an integer from #{ALLOWED_MINUTES.begin} to #{ALLOWED_MINUTES.end}, got #{minutes}"
|
51
56
|
end
|
52
57
|
|
53
|
-
Failure.create(
|
58
|
+
Failure.create(
|
59
|
+
pattern: dependency,
|
60
|
+
minutes: minutes.to_i,
|
61
|
+
failure: failure,
|
62
|
+
response_hash: response_hash,
|
63
|
+
response_headers_hash: response_headers_hash
|
64
|
+
)
|
54
65
|
|
55
|
-
result = "For the next #{minutes} minutes, all requests to urls containing '#{dependency}'
|
66
|
+
result = "For the next #{minutes} minutes, all requests to urls containing '#{dependency}' " \
|
67
|
+
"will #{failure.downcase}"
|
56
68
|
|
57
|
-
#TODO: injectable logger
|
69
|
+
# TODO: injectable logger
|
58
70
|
puts "Aranea: #{result}"
|
59
71
|
|
60
72
|
result
|
61
|
-
|
62
73
|
end
|
63
|
-
|
64
74
|
end
|
65
|
-
|
66
75
|
end
|
67
76
|
end
|
data/lib/aranea/version.rb
CHANGED
data/lib/aranea.rb
CHANGED
@@ -1,2 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support"
|
4
|
+
require "active_support/cache"
|
5
|
+
require "active_support/core_ext/numeric/time"
|
6
|
+
require "active_support/notifications"
|
7
|
+
require "faraday"
|
8
|
+
require "json"
|
9
|
+
require "rack"
|
10
|
+
|
11
|
+
require "aranea/failure_repository"
|
12
|
+
require "aranea/rack/aranea_middleware"
|
13
|
+
require "aranea/faraday/aranea_middleware"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aranea
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Weiner
|
@@ -9,22 +9,42 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-04-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '4.2'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '4.2'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: faraday
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
17
31
|
requirements:
|
18
32
|
- - ">="
|
19
33
|
- !ruby/object:Gem::Version
|
20
|
-
version: '0'
|
34
|
+
version: '0.9'
|
35
|
+
- - "<"
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '3.0'
|
21
38
|
type: :runtime
|
22
39
|
prerelease: false
|
23
40
|
version_requirements: !ruby/object:Gem::Requirement
|
24
41
|
requirements:
|
25
42
|
- - ">="
|
26
43
|
- !ruby/object:Gem::Version
|
27
|
-
version: '0'
|
44
|
+
version: '0.9'
|
45
|
+
- - "<"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
28
48
|
- !ruby/object:Gem::Dependency
|
29
49
|
name: rack
|
30
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -40,13 +60,13 @@ dependencies:
|
|
40
60
|
- !ruby/object:Gem::Version
|
41
61
|
version: '0'
|
42
62
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
63
|
+
name: pry-byebug
|
44
64
|
requirement: !ruby/object:Gem::Requirement
|
45
65
|
requirements:
|
46
66
|
- - ">="
|
47
67
|
- !ruby/object:Gem::Version
|
48
68
|
version: '0'
|
49
|
-
type: :
|
69
|
+
type: :development
|
50
70
|
prerelease: false
|
51
71
|
version_requirements: !ruby/object:Gem::Requirement
|
52
72
|
requirements:
|
@@ -82,33 +102,47 @@ dependencies:
|
|
82
102
|
- !ruby/object:Gem::Version
|
83
103
|
version: '0'
|
84
104
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
105
|
+
name: rubocop
|
86
106
|
requirement: !ruby/object:Gem::Requirement
|
87
107
|
requirements:
|
88
|
-
- -
|
108
|
+
- - '='
|
89
109
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
110
|
+
version: 1.26.1
|
91
111
|
type: :development
|
92
112
|
prerelease: false
|
93
113
|
version_requirements: !ruby/object:Gem::Requirement
|
94
114
|
requirements:
|
95
|
-
- -
|
115
|
+
- - '='
|
96
116
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
117
|
+
version: 1.26.1
|
98
118
|
- !ruby/object:Gem::Dependency
|
99
|
-
name:
|
119
|
+
name: rubocop-mdsol
|
100
120
|
requirement: !ruby/object:Gem::Requirement
|
101
121
|
requirements:
|
102
|
-
- - "
|
122
|
+
- - "~>"
|
103
123
|
- !ruby/object:Gem::Version
|
104
|
-
version: '0'
|
124
|
+
version: '0.1'
|
105
125
|
type: :development
|
106
126
|
prerelease: false
|
107
127
|
version_requirements: !ruby/object:Gem::Requirement
|
108
128
|
requirements:
|
109
|
-
- - "
|
129
|
+
- - "~>"
|
110
130
|
- !ruby/object:Gem::Version
|
111
|
-
version: '0'
|
131
|
+
version: '0.1'
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
name: rubocop-performance
|
134
|
+
requirement: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.13.3
|
139
|
+
type: :development
|
140
|
+
prerelease: false
|
141
|
+
version_requirements: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 1.13.3
|
112
146
|
description: Rack and Faraday middleware to temporarily disable connections to external
|
113
147
|
dependencies
|
114
148
|
email:
|
@@ -118,6 +152,15 @@ executables: []
|
|
118
152
|
extensions: []
|
119
153
|
extra_rdoc_files: []
|
120
154
|
files:
|
155
|
+
- ".gitignore"
|
156
|
+
- ".rspec"
|
157
|
+
- ".rubocop.yml"
|
158
|
+
- ".travis.yml"
|
159
|
+
- CHANGELOG.md
|
160
|
+
- Gemfile
|
161
|
+
- MIT-LICENSE
|
162
|
+
- README.md
|
163
|
+
- aranea.gemspec
|
121
164
|
- lib/aranea.rb
|
122
165
|
- lib/aranea/failure_repository.rb
|
123
166
|
- lib/aranea/faraday/aranea_middleware.rb
|
@@ -126,7 +169,10 @@ files:
|
|
126
169
|
homepage: https://github.com/mdsol/aranea
|
127
170
|
licenses:
|
128
171
|
- MIT
|
129
|
-
metadata:
|
172
|
+
metadata:
|
173
|
+
homepage_uri: https://github.com/mdsol/aranea
|
174
|
+
source_code_uri: https://github.com/mdsol/aranea
|
175
|
+
changelog_uri: https://github.com/mdsol/aranea/blob/master/CHANGELOG.md
|
130
176
|
post_install_message:
|
131
177
|
rdoc_options: []
|
132
178
|
require_paths:
|
@@ -135,15 +181,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
181
|
requirements:
|
136
182
|
- - ">="
|
137
183
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
184
|
+
version: 2.5.0
|
139
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
186
|
requirements:
|
141
187
|
- - ">="
|
142
188
|
- !ruby/object:Gem::Version
|
143
|
-
version:
|
189
|
+
version: '0'
|
144
190
|
requirements: []
|
145
|
-
|
146
|
-
rubygems_version: 2.6.12
|
191
|
+
rubygems_version: 3.1.2
|
147
192
|
signing_key:
|
148
193
|
specification_version: 4
|
149
194
|
summary: Middleware for fault tolerance testing
|