right_support 2.6.17 → 2.7.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.
- data/.rspec +4 -0
- data/CHANGELOG.rdoc +37 -0
- data/Gemfile +29 -0
- data/Gemfile.lock +111 -0
- data/README.rdoc +2 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/features/balancer_error_handling.feature +34 -0
- data/features/balancer_health_check.feature +33 -0
- data/features/continuous_integration.feature +51 -0
- data/features/continuous_integration_cucumber.feature +28 -0
- data/features/continuous_integration_rspec1.feature +28 -0
- data/features/continuous_integration_rspec2.feature +28 -0
- data/features/http_client_timeout.feature +19 -0
- data/features/serialization.feature +95 -0
- data/features/step_definitions/http_client_steps.rb +27 -0
- data/features/step_definitions/request_balancer_steps.rb +93 -0
- data/features/step_definitions/ruby_steps.rb +176 -0
- data/features/step_definitions/serialization_steps.rb +96 -0
- data/features/step_definitions/server_steps.rb +134 -0
- data/features/support/env.rb +138 -0
- data/features/support/file_utils_bundler_mixin.rb +45 -0
- data/lib/right_support/ci/java_cucumber_formatter.rb +22 -8
- data/lib/right_support/ci/java_spec_formatter.rb +26 -8
- data/lib/right_support/ci/rake_task.rb +3 -0
- data/lib/right_support/ci.rb +24 -0
- data/lib/right_support/crypto/signed_hash.rb +22 -0
- data/lib/right_support/data/serializer.rb +24 -2
- data/lib/right_support/net/address_helper.rb +20 -8
- data/lib/right_support/net/dns.rb +20 -8
- data/lib/right_support/net/http_client.rb +22 -0
- data/lib/right_support/net/request_balancer.rb +27 -21
- data/lib/right_support/net/s3_helper.rb +20 -8
- data/lib/right_support/net/ssl/open_ssl_patch.rb +22 -0
- data/lib/right_support/net/ssl.rb +20 -8
- data/lib/right_support/ruby/easy_singleton.rb +22 -0
- data/lib/right_support/ruby/object_extensions.rb +22 -0
- data/lib/right_support/ruby/string_extensions.rb +1 -1
- data/lib/right_support.rb +13 -10
- data/right_support.gemspec +180 -18
- data/right_support.rconf +8 -0
- data/spec/config/feature_set_spec.rb +83 -0
- data/spec/crypto/signed_hash_spec.rb +60 -0
- data/spec/data/hash_tools_spec.rb +471 -0
- data/spec/data/uuid_spec.rb +45 -0
- data/spec/db/cassandra_model_part1_spec.rb +84 -0
- data/spec/db/cassandra_model_part2_spec.rb +73 -0
- data/spec/db/cassandra_model_spec.rb +359 -0
- data/spec/fixtures/encrypted_priv_rsa.pem +30 -0
- data/spec/fixtures/good_priv_dsa.pem +12 -0
- data/spec/fixtures/good_priv_rsa.pem +15 -0
- data/spec/fixtures/good_pub_dsa.ssh +1 -0
- data/spec/fixtures/good_pub_rsa.pem +5 -0
- data/spec/fixtures/good_pub_rsa.ssh +1 -0
- data/spec/log/exception_logger_spec.rb +76 -0
- data/spec/log/filter_logger_spec.rb +8 -0
- data/spec/log/mixin_spec.rb +62 -0
- data/spec/log/multiplexer_spec.rb +54 -0
- data/spec/log/null_logger_spec.rb +36 -0
- data/spec/log/system_logger_spec.rb +92 -0
- data/spec/net/address_helper_spec.rb +57 -0
- data/spec/net/balancing/health_check_spec.rb +382 -0
- data/spec/net/balancing/round_robin_spec.rb +15 -0
- data/spec/net/balancing/sticky_policy_spec.rb +92 -0
- data/spec/net/dns_spec.rb +152 -0
- data/spec/net/http_client_spec.rb +171 -0
- data/spec/net/request_balancer_spec.rb +579 -0
- data/spec/net/s3_helper_spec.rb +160 -0
- data/spec/net/ssl_spec.rb +42 -0
- data/spec/net/string_encoder_spec.rb +58 -0
- data/spec/rack/log_setter_spec.rb +5 -0
- data/spec/rack/request_logger_spec.rb +68 -0
- data/spec/rack/request_tracker_spec.rb +5 -0
- data/spec/ruby/easy_singleton_spec.rb +72 -0
- data/spec/ruby/object_extensions_spec.rb +27 -0
- data/spec/ruby/string_extensions_spec.rb +98 -0
- data/spec/spec_helper.rb +181 -0
- data/spec/stats/activity_spec.rb +193 -0
- data/spec/stats/exceptions_spec.rb +123 -0
- data/spec/stats/helpers_spec.rb +603 -0
- data/spec/validation/openssl_spec.rb +37 -0
- data/spec/validation/ssh_spec.rb +39 -0
- metadata +218 -19
data/.rspec
ADDED
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
== 2.0
|
2
|
+
|
3
|
+
=== Interface-breaking changes
|
4
|
+
|
5
|
+
* Changed some of the more esoteric options of RequestBalancer
|
6
|
+
* Removed TagLogger and CustomLogger middlwares
|
7
|
+
* Renamed Balancing module to LB
|
8
|
+
* Renamed StickyPolicy class to Sticky
|
9
|
+
* Removed Object#if_require_succeeds(&block); too dangerous -- use
|
10
|
+
Object#require_succeeds instead!
|
11
|
+
|
12
|
+
=== New functionality
|
13
|
+
|
14
|
+
* Several new Rack middlewares for request logging & tracking
|
15
|
+
* Statistics gathering, string extensions,
|
16
|
+
* HTTPClient methods can accept query-strings (:query) and/or request body
|
17
|
+
(:payload)
|
18
|
+
|
19
|
+
== 1.0
|
20
|
+
|
21
|
+
=== Interface-breaking changes
|
22
|
+
|
23
|
+
* Moved logging classes (FilterLogger, SystemLogger, TagLogger) into RightSupport::Log namespace
|
24
|
+
* Moved CassandraModel into RightSupport::DB
|
25
|
+
* Removed RightSupport::REST module entirely. Replaced by RightSupport::Net::HTTPClient class.
|
26
|
+
|
27
|
+
=== New functionality
|
28
|
+
|
29
|
+
* RequestBalancer now capable of using multiple policies for endpoint selection.
|
30
|
+
Default is RoundRobin (previously the only option); now you can choose HealthCheck
|
31
|
+
in addition. See rdoc for more info.
|
32
|
+
* RequestBalancer can accept a logger as a class attribute. If supplied, any failed requests
|
33
|
+
will be logged with the error severity, including detailed information about exception type,
|
34
|
+
retryability, etc.
|
35
|
+
* HTTPClient object is a thin wrapper around RestClient that adds some default timeouts.
|
36
|
+
It's appropriate for low-latency REST requests to nearby services; by tweaking the
|
37
|
+
defaults, you can use it for various other scenarios.
|
data/Gemfile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Gems that RightSupport can optionally make use of, but which it does
|
4
|
+
# not require to be installed. These would be "optional dependencies"
|
5
|
+
# if gemspecs allowed for them.
|
6
|
+
group :optional do
|
7
|
+
gem "net-ssh", "~> 2.0"
|
8
|
+
gem "rest-client", "~> 1.6"
|
9
|
+
gem "addressable", "~> 2.2.7"
|
10
|
+
gem "uuidtools", "~> 2.0", :require => nil
|
11
|
+
gem "simple_uuid", "~> 0.2", :require => nil
|
12
|
+
gem "uuid", "~> 2.3", :require => nil
|
13
|
+
gem "yajl-ruby", "~> 1.1"
|
14
|
+
end
|
15
|
+
|
16
|
+
# Gems used during test and development of RightSupport.
|
17
|
+
group :development do
|
18
|
+
gem "rake", "~> 0.9"
|
19
|
+
gem "jeweler", "~> 1.8.3"
|
20
|
+
gem "right_develop", "~> 1.0",
|
21
|
+
:git => "git@github.com:rightscale/right_develop.git",
|
22
|
+
:branch => "master"
|
23
|
+
gem "ruby-debug", ">= 0.10", :platforms => :ruby_18
|
24
|
+
gem "ruby-debug19", ">= 0.11.6", :platforms => :ruby_19
|
25
|
+
gem "rdoc", ">= 2.4.2"
|
26
|
+
gem "flexmock", "~> 0.8"
|
27
|
+
gem "syntax", "~> 1.0.0" #rspec will syntax-highlight code snippets if this gem is available
|
28
|
+
gem "nokogiri", "~> 1.5"
|
29
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git@github.com:rightscale/right_develop.git
|
3
|
+
revision: baabb68c392e1afdbff7d6cc21d87f9b1cdb2db6
|
4
|
+
branch: master
|
5
|
+
specs:
|
6
|
+
right_develop (1.1.0)
|
7
|
+
actionpack (>= 2.3.0, < 4.0)
|
8
|
+
builder (~> 3.0)
|
9
|
+
cucumber (~> 1.0)
|
10
|
+
rake (>= 0.8.7, < 0.10)
|
11
|
+
right_support (~> 2.0)
|
12
|
+
rspec (>= 1.3, < 3.0)
|
13
|
+
trollop (~> 1.0)
|
14
|
+
|
15
|
+
GEM
|
16
|
+
remote: http://rubygems.org/
|
17
|
+
specs:
|
18
|
+
actionpack (2.3.18)
|
19
|
+
activesupport (= 2.3.18)
|
20
|
+
rack (~> 1.1.0)
|
21
|
+
activesupport (2.3.18)
|
22
|
+
addressable (2.2.8)
|
23
|
+
archive-tar-minitar (0.5.2)
|
24
|
+
builder (3.2.0)
|
25
|
+
columnize (0.3.6)
|
26
|
+
cucumber (1.2.5)
|
27
|
+
builder (>= 2.1.2)
|
28
|
+
diff-lcs (>= 1.1.3)
|
29
|
+
gherkin (~> 2.11.7)
|
30
|
+
multi_json (~> 1.3)
|
31
|
+
diff-lcs (1.2.2)
|
32
|
+
flexmock (0.9.0)
|
33
|
+
gherkin (2.11.8)
|
34
|
+
multi_json (~> 1.3)
|
35
|
+
git (1.2.5)
|
36
|
+
jeweler (1.8.4)
|
37
|
+
bundler (~> 1.0)
|
38
|
+
git (>= 1.2.5)
|
39
|
+
rake
|
40
|
+
rdoc
|
41
|
+
json (1.7.7)
|
42
|
+
linecache (0.46)
|
43
|
+
rbx-require-relative (> 0.0.4)
|
44
|
+
linecache19 (0.5.12)
|
45
|
+
ruby_core_source (>= 0.1.4)
|
46
|
+
macaddr (1.6.1)
|
47
|
+
systemu (~> 2.5.0)
|
48
|
+
mime-types (1.22)
|
49
|
+
multi_json (1.7.2)
|
50
|
+
net-ssh (2.6.6)
|
51
|
+
nokogiri (1.5.9)
|
52
|
+
rack (1.1.6)
|
53
|
+
rake (0.9.6)
|
54
|
+
rbx-require-relative (0.0.9)
|
55
|
+
rdoc (4.0.1)
|
56
|
+
json (~> 1.4)
|
57
|
+
rest-client (1.6.7)
|
58
|
+
mime-types (>= 1.16)
|
59
|
+
right_support (2.6.17)
|
60
|
+
rspec (2.13.0)
|
61
|
+
rspec-core (~> 2.13.0)
|
62
|
+
rspec-expectations (~> 2.13.0)
|
63
|
+
rspec-mocks (~> 2.13.0)
|
64
|
+
rspec-core (2.13.1)
|
65
|
+
rspec-expectations (2.13.0)
|
66
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
67
|
+
rspec-mocks (2.13.1)
|
68
|
+
ruby-debug (0.10.4)
|
69
|
+
columnize (>= 0.1)
|
70
|
+
ruby-debug-base (~> 0.10.4.0)
|
71
|
+
ruby-debug-base (0.10.4)
|
72
|
+
linecache (>= 0.3)
|
73
|
+
ruby-debug-base19 (0.11.25)
|
74
|
+
columnize (>= 0.3.1)
|
75
|
+
linecache19 (>= 0.5.11)
|
76
|
+
ruby_core_source (>= 0.1.4)
|
77
|
+
ruby-debug19 (0.11.6)
|
78
|
+
columnize (>= 0.3.1)
|
79
|
+
linecache19 (>= 0.5.11)
|
80
|
+
ruby-debug-base19 (>= 0.11.19)
|
81
|
+
ruby_core_source (0.1.5)
|
82
|
+
archive-tar-minitar (>= 0.5.2)
|
83
|
+
simple_uuid (0.3.0)
|
84
|
+
syntax (1.0.0)
|
85
|
+
systemu (2.5.2)
|
86
|
+
trollop (1.16.2)
|
87
|
+
uuid (2.3.7)
|
88
|
+
macaddr (~> 1.0)
|
89
|
+
uuidtools (2.1.3)
|
90
|
+
yajl-ruby (1.1.0)
|
91
|
+
|
92
|
+
PLATFORMS
|
93
|
+
ruby
|
94
|
+
|
95
|
+
DEPENDENCIES
|
96
|
+
addressable (~> 2.2.7)
|
97
|
+
flexmock (~> 0.8)
|
98
|
+
jeweler (~> 1.8.3)
|
99
|
+
net-ssh (~> 2.0)
|
100
|
+
nokogiri (~> 1.5)
|
101
|
+
rake (~> 0.9)
|
102
|
+
rdoc (>= 2.4.2)
|
103
|
+
rest-client (~> 1.6)
|
104
|
+
right_develop (~> 1.0)!
|
105
|
+
ruby-debug (>= 0.10)
|
106
|
+
ruby-debug19 (>= 0.11.6)
|
107
|
+
simple_uuid (~> 0.2)
|
108
|
+
syntax (~> 1.0.0)
|
109
|
+
uuid (~> 2.3)
|
110
|
+
uuidtools (~> 2.0)
|
111
|
+
yajl-ruby (~> 1.1)
|
data/README.rdoc
CHANGED
data/Rakefile
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require 'rake'
|
6
|
+
require 'rdoc/task'
|
7
|
+
require 'rubygems/package_task'
|
8
|
+
|
9
|
+
require 'rake/clean'
|
10
|
+
require 'rspec/core/rake_task'
|
11
|
+
require 'cucumber/rake/task'
|
12
|
+
|
13
|
+
require 'right_develop/ci/rake_task'
|
14
|
+
|
15
|
+
# But, we have a very special need, because OUR Cucumbers need to run with a pristine
|
16
|
+
# environment that isn't polluted by RVM or RubyGems or anyone else, in order to validate
|
17
|
+
# that RightSupport's CI harness doesn't break your app if those gems are unavailable.
|
18
|
+
# Thus when our own Rake task runs spec or cucumber as a subprocess, we need to give it
|
19
|
+
# a pristine non-bundled environment, so it can use Bundler.with_clean_env to launch
|
20
|
+
# subprocesses.
|
21
|
+
require File.expand_path('../features/support/file_utils_bundler_mixin', __FILE__)
|
22
|
+
|
23
|
+
desc "Run unit tests"
|
24
|
+
task :default => :spec
|
25
|
+
|
26
|
+
desc "Run unit tests"
|
27
|
+
RSpec::Core::RakeTask.new do |t|
|
28
|
+
t.pattern = Dir['**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Run functional tests"
|
32
|
+
Cucumber::Rake::Task.new do |t|
|
33
|
+
t.cucumber_opts = %w{--color --format pretty}
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'Generate documentation for the right_support gem.'
|
37
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
38
|
+
rdoc.rdoc_dir = 'doc'
|
39
|
+
rdoc.title = 'RightSupport'
|
40
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
41
|
+
rdoc.rdoc_files.include('README.rdoc')
|
42
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
43
|
+
rdoc.rdoc_files.exclude('features/**/*')
|
44
|
+
rdoc.rdoc_files.exclude('spec/**/*')
|
45
|
+
end
|
46
|
+
|
47
|
+
require 'jeweler'
|
48
|
+
Jeweler::Tasks.new do |gem|
|
49
|
+
# gem is a Gem::Specification; see http://docs.rubygems.org/read/chapter/20 for more options
|
50
|
+
gem.name = "right_support"
|
51
|
+
gem.homepage = "https://github.com/rightscale/right_support"
|
52
|
+
gem.license = "MIT"
|
53
|
+
gem.summary = %Q{Reusable foundation code.}
|
54
|
+
gem.description = %Q{A toolkit of useful, reusable foundation code created by RightScale.}
|
55
|
+
gem.email = "support@rightscale.com"
|
56
|
+
gem.authors = ['Tony Spataro', 'Sergey Sergyenko', 'Ryan Williamson', 'Lee Kirchhoff', 'Alexey Karpik', 'Scott Messier']
|
57
|
+
end
|
58
|
+
Jeweler::RubygemsDotOrgTasks.new
|
59
|
+
|
60
|
+
CLEAN.include('pkg')
|
61
|
+
|
62
|
+
RightDevelop::CI::RakeTask.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.0
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Feature: request balancer error handling
|
2
|
+
In order to enhance app availability and development velocity
|
3
|
+
RequestBalancer should consider certain errors as fatal by default
|
4
|
+
So careless developers do not cause unexpected behavior when failures occur
|
5
|
+
|
6
|
+
Scenario: well-behaved servers
|
7
|
+
Given 5 servers that respond with 200
|
8
|
+
When a client makes a load-balanced request to '/'
|
9
|
+
Then the request should complete
|
10
|
+
And the request should be attempted once
|
11
|
+
|
12
|
+
Scenario: resource not found
|
13
|
+
Given 4 servers that respond with 404
|
14
|
+
When a client makes a load-balanced request to '/'
|
15
|
+
Then the request should raise ResourceNotFound
|
16
|
+
And the request should be attempted once
|
17
|
+
|
18
|
+
Scenario: client-side error
|
19
|
+
Given a server that responds with 200
|
20
|
+
When a client makes a buggy load-balanced request to '/'
|
21
|
+
Then the request should raise ArgumentError
|
22
|
+
And the request should be attempted once
|
23
|
+
|
24
|
+
Scenario: socket open timeout
|
25
|
+
Given 2 blackholed servers
|
26
|
+
When a client makes a load-balanced request to '/'
|
27
|
+
Then the request should be attempted 2 times
|
28
|
+
And the request should raise NoResult
|
29
|
+
|
30
|
+
Scenario: HTTP request timeout
|
31
|
+
Given 2 overloaded servers
|
32
|
+
When a client makes a load-balanced request to '/'
|
33
|
+
Then the request should be attempted 2 times
|
34
|
+
And the request should raise NoResult
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: request balancer health check
|
2
|
+
In order to enhance system availability for customers
|
3
|
+
RightSupport should track endpoint health when making load-balanced REST requests
|
4
|
+
So apps do not become hung during network failures
|
5
|
+
|
6
|
+
Scenario: mixed servers (overloaded, blackholed) using health check
|
7
|
+
Given 4 overloaded servers
|
8
|
+
And 4 blackholed servers
|
9
|
+
And HealthCheck balancing policy
|
10
|
+
When a client makes a load-balanced request to '/' with timeout 1 and open_timeout 2
|
11
|
+
Then the request should raise in less than 12 seconds
|
12
|
+
|
13
|
+
Scenario: mixed servers (well-behaved, blackholed) using health check
|
14
|
+
Given 4 servers that respond with 200
|
15
|
+
And 4 blackholed servers
|
16
|
+
And HealthCheck balancing policy
|
17
|
+
When a client makes a load-balanced request to '/' with timeout 1 and open_timeout 2
|
18
|
+
Then the request should complete in less than 8 seconds
|
19
|
+
|
20
|
+
Scenario: mixed servers (overloaded, well-behaved, blackholed) using health check
|
21
|
+
Given 1 overloaded server
|
22
|
+
And 1 server that responds with 200
|
23
|
+
And 1 blackholed server
|
24
|
+
And HealthCheck balancing policy
|
25
|
+
When a client makes a load-balanced request to '/' with timeout 1 and open_timeout 2
|
26
|
+
Then the request should complete in less than 3 seconds
|
27
|
+
|
28
|
+
Scenario: mixed servers (condition commented by Tony https://rightscale.acunote.com/projects/2091/tasks/23987#comments) using health check
|
29
|
+
Given 3 overloaded servers
|
30
|
+
And 1 server that responds with 200
|
31
|
+
And HealthCheck balancing policy
|
32
|
+
When a client makes a load-balanced request to '/' with timeout 1 and open_timeout 2
|
33
|
+
Then the request should complete in less than 3 seconds
|
@@ -0,0 +1,51 @@
|
|
1
|
+
Feature: continuous integration disabled
|
2
|
+
In order to let minimize runtime dependencies
|
3
|
+
RightSupport's Rake CI harness should gracefully handle missing gems
|
4
|
+
So it runs predictably and reliably in production
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a Ruby application
|
8
|
+
And a Gemfile
|
9
|
+
And a gem dependency on 'rake ~> 0.9'
|
10
|
+
|
11
|
+
Scenario: all gems unavailable
|
12
|
+
Given the Rakefile contains a RightSupport::CI::RakeTask
|
13
|
+
When I install the bundle
|
14
|
+
And I rake '-T'
|
15
|
+
Then the output should not contain 'ci:cucumber'
|
16
|
+
And the output should not contain 'ci:spec'
|
17
|
+
|
18
|
+
Scenario: conditional availability of ci:cucumber
|
19
|
+
Given a gem dependency on 'rspec ~> 1.0'
|
20
|
+
And a gem dependency on 'builder ~> 3.0'
|
21
|
+
And the Rakefile contains a RightSupport::CI::RakeTask
|
22
|
+
When I install the bundle
|
23
|
+
And I rake '-T'
|
24
|
+
Then the output should contain 'ci:spec'
|
25
|
+
And the output should not contain 'ci:cucumber'
|
26
|
+
|
27
|
+
Scenario: conditional availability of ci:rspec
|
28
|
+
Given a gem dependency on 'cucumber ~> 1.0'
|
29
|
+
And the Rakefile contains a RightSupport::CI::RakeTask
|
30
|
+
When I install the bundle
|
31
|
+
And I rake '-T'
|
32
|
+
Then the output should contain 'ci:cucumber'
|
33
|
+
And the output should not contain 'ci:spec'
|
34
|
+
|
35
|
+
Scenario: list Rake tasks
|
36
|
+
Given a gem dependency on 'rspec ~> 2.0'
|
37
|
+
And a gem dependency on 'cucumber ~> 1.0'
|
38
|
+
And the Rakefile contains a RightSupport::CI::RakeTask
|
39
|
+
When I install the bundle
|
40
|
+
And I rake '-T'
|
41
|
+
And the output should contain 'ci:cucumber'
|
42
|
+
And the output should contain 'ci:spec'
|
43
|
+
|
44
|
+
Scenario: override namespace
|
45
|
+
Given a gem dependency on 'rspec ~> 2.0'
|
46
|
+
And a gem dependency on 'cucumber ~> 1.0'
|
47
|
+
And the Rakefile contains a RightSupport::CI::RakeTask with parameter ':funkalicious'
|
48
|
+
When I install the bundle
|
49
|
+
And I rake '-T'
|
50
|
+
Then the output should contain 'funkalicious:cucumber'
|
51
|
+
Then the output should contain 'funkalicious:spec'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: continuous integration of Cucumber features
|
2
|
+
In order to facilitate TDD and enhance code quality
|
3
|
+
RightSupport should provide CI tasks with Cucumber with JUnit XML output
|
4
|
+
So any Ruby project can have a beautiful, info-rich Jenkins project
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a Ruby application
|
8
|
+
And a Gemfile
|
9
|
+
And a gem dependency on 'rake ~> 0.9'
|
10
|
+
And a gem dependency on 'builder ~> 3.0'
|
11
|
+
And a gem dependency on 'cucumber ~> 1.0'
|
12
|
+
And the Rakefile contains a RightSupport::CI::RakeTask
|
13
|
+
|
14
|
+
Scenario: passing Cucumber features
|
15
|
+
Given a trivial Cucumber feature
|
16
|
+
When I install the bundle
|
17
|
+
And I rake 'ci:cucumber'
|
18
|
+
Then the command should succeed
|
19
|
+
And the output should contain '** Execute ci:cucumber'
|
20
|
+
And the directory 'measurement/cucumber' should contain files
|
21
|
+
|
22
|
+
Scenario: failing Cucumber features
|
23
|
+
Given a trivial failing Cucumber feature
|
24
|
+
When I install the bundle
|
25
|
+
And I rake 'ci:cucumber'
|
26
|
+
Then the command should fail
|
27
|
+
And the output should contain '** Execute ci:cucumber'
|
28
|
+
And the directory 'measurement/cucumber' should contain files
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: continuous integration of RSpec 1.x specs
|
2
|
+
In order to facilitate TDD and enhance code quality
|
3
|
+
RightSupport should provide a Rake CI harness with JUnit XML output
|
4
|
+
So any Ruby project can have a beautiful, info-rich Jenkins project
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a Ruby application
|
8
|
+
And a Gemfile
|
9
|
+
And a gem dependency on 'rake ~> 0.9'
|
10
|
+
And a gem dependency on 'rspec ~> 1.0'
|
11
|
+
And a gem dependency on 'builder ~> 3.0'
|
12
|
+
And the Rakefile contains a RightSupport::CI::RakeTask
|
13
|
+
|
14
|
+
Scenario: passing RSpec 1.x examples
|
15
|
+
Given a trivial RSpec spec
|
16
|
+
When I install the bundle
|
17
|
+
And I rake 'ci:spec'
|
18
|
+
Then the command should succeed
|
19
|
+
And the file 'measurement/rspec/rspec.xml' should mention 2 passing test cases
|
20
|
+
And the file 'measurement/rspec/rspec.xml' should mention 0 failing test cases
|
21
|
+
|
22
|
+
Scenario: failing RSpec 1.x examples
|
23
|
+
Given a trivial failing RSpec spec
|
24
|
+
When I install the bundle
|
25
|
+
And I rake 'ci:spec'
|
26
|
+
Then the command should fail
|
27
|
+
And the file 'measurement/rspec/rspec.xml' should mention 2 passing test cases
|
28
|
+
And the file 'measurement/rspec/rspec.xml' should mention 1 failing test case
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: continuous integration of RSpec 2.x specs
|
2
|
+
In order to facilitate TDD and enhance code quality
|
3
|
+
RightSupport should provide a Rake CI harness with JUnit XML output
|
4
|
+
So any Ruby project can have a beautiful, info-rich Jenkins project
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a Ruby application
|
8
|
+
And a Gemfile
|
9
|
+
And a gem dependency on 'rake ~> 0.9'
|
10
|
+
And a gem dependency on 'rspec ~> 2.0'
|
11
|
+
And a gem dependency on 'builder ~> 3.0'
|
12
|
+
And the Rakefile contains a RightSupport::CI::RakeTask
|
13
|
+
|
14
|
+
Scenario: passing examples
|
15
|
+
And a trivial RSpec spec
|
16
|
+
When I install the bundle
|
17
|
+
And I rake 'ci:spec'
|
18
|
+
Then the command should succeed
|
19
|
+
And the file 'measurement/rspec/rspec.xml' should mention 2 passing test cases
|
20
|
+
And the file 'measurement/rspec/rspec.xml' should mention 0 failing test cases
|
21
|
+
|
22
|
+
Scenario: failing examples
|
23
|
+
And a trivial failing RSpec spec
|
24
|
+
When I install the bundle
|
25
|
+
And I rake 'ci:spec'
|
26
|
+
Then the command should fail
|
27
|
+
And the file 'measurement/rspec/rspec.xml' should mention 2 passing test cases
|
28
|
+
And the file 'measurement/rspec/rspec.xml' should mention 1 failing test case
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: HTTP client request timeout
|
2
|
+
In order to enhance system availability for customers
|
3
|
+
RightSupport should provide robust REST query interfaces
|
4
|
+
So apps do not become hung during network failures
|
5
|
+
|
6
|
+
Scenario: well-behaved server
|
7
|
+
Given a server that responds with 200
|
8
|
+
When a client makes a request to '/' with timeout 1 and open_timeout 2
|
9
|
+
Then the request should complete in less than 3 seconds
|
10
|
+
|
11
|
+
Scenario: overloaded server
|
12
|
+
Given an overloaded server
|
13
|
+
When a client makes a request to '/' with timeout 1 and open_timeout 2
|
14
|
+
Then the request should raise in less than 3 seconds
|
15
|
+
|
16
|
+
Scenario: blackholed servers
|
17
|
+
Given a blackholed server
|
18
|
+
When a client makes a load-balanced request to '/' with timeout 1 and open_timeout 2
|
19
|
+
Then the request should raise in less than 3 seconds
|
@@ -0,0 +1,95 @@
|
|
1
|
+
Feature: JSON serialization
|
2
|
+
In order to facilitate Ruby apps' use of external JSON data stores
|
3
|
+
RightSupport should cleanly serialize arbitrary Ruby objects to JSON without data loss or semantic ambiguity
|
4
|
+
So app code can be idiomatic and focus on the business problem, not the encoding details
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a serializer named 'RightSupport::Data::Serializer'
|
8
|
+
And a stateful Ruby class named 'GotState'
|
9
|
+
|
10
|
+
Scenario Outline: Ruby types with a native JSON representation
|
11
|
+
When I serialize the Ruby value: <ruby>
|
12
|
+
Then the serialized value should be: <json>
|
13
|
+
And the serialized value should round-trip cleanly
|
14
|
+
|
15
|
+
Examples:
|
16
|
+
| ruby | json |
|
17
|
+
| true | true |
|
18
|
+
| false | false |
|
19
|
+
| nil | null |
|
20
|
+
| 0 | 0 |
|
21
|
+
| 42 | 42 |
|
22
|
+
| -32 | -32 |
|
23
|
+
| 3.1415926535 | 3.1415926535 |
|
24
|
+
| 0xFFFFFFFFFFFFFFFFFFFFFFFF | 79228162514264337593543950335 |
|
25
|
+
| "hello, world!" | "hello, world!" |
|
26
|
+
| [0,true,nil,['a',false]] | [0,true,null,["a",false]] |
|
27
|
+
| {"one"=>2} | {"one":2} |
|
28
|
+
| {"hash"=>{"lucky"=>777,"seq"=>[2,3]}} | {"hash":{"lucky":777,"seq":[2,3]}} |
|
29
|
+
|
30
|
+
Scenario: complex Ruby structures with a native JSON representation
|
31
|
+
When I serialize a complex random data structure
|
32
|
+
Then the serialized value should round-trip cleanly
|
33
|
+
|
34
|
+
Scenario Outline: object-escaped Symbol
|
35
|
+
When I serialize the Ruby value: <ruby>
|
36
|
+
Then the serialized value should be: <json>
|
37
|
+
And the serialized value should round-trip cleanly
|
38
|
+
|
39
|
+
Examples:
|
40
|
+
| ruby | json |
|
41
|
+
| :my_symbol | ":my_symbol" |
|
42
|
+
| :'weird symbol' | ":weird symbol" |
|
43
|
+
|
44
|
+
Scenario Outline: object-escaped Time
|
45
|
+
When I serialize the Ruby value: <ruby>
|
46
|
+
Then the serialized value should be: <json>
|
47
|
+
And the serialized value should round-trip cleanly
|
48
|
+
|
49
|
+
Examples:
|
50
|
+
| ruby | json |
|
51
|
+
| Time.at(1234567890) | "2009-02-13T23:31:30Z" |
|
52
|
+
| Time.at(1234567890).utc | "2009-02-13T23:31:30Z" |
|
53
|
+
|
54
|
+
Scenario Outline: object-escaped String
|
55
|
+
When I serialize the Ruby value: <ruby>
|
56
|
+
Then the serialized value should be: <json>
|
57
|
+
And the serialized value should round-trip cleanly
|
58
|
+
|
59
|
+
Examples:
|
60
|
+
| ruby | json |
|
61
|
+
| ":not_a_symbol" | {"_ruby_class":"String","value":":not_a_symbol"} |
|
62
|
+
|
63
|
+
Scenario Outline: Ruby Class and Module types
|
64
|
+
|
65
|
+
Scenario Outline: Ruby Class and Module types
|
66
|
+
When I serialize the Ruby value: <ruby>
|
67
|
+
Then the serialized value should be a JSON object
|
68
|
+
And the serialized value should round-trip cleanly
|
69
|
+
|
70
|
+
Examples:
|
71
|
+
| ruby |
|
72
|
+
| String |
|
73
|
+
| RightSupport::Ruby::EasySingleton |
|
74
|
+
| RightSupport::Net::HTTPClient |
|
75
|
+
| Hash |
|
76
|
+
| Kernel |
|
77
|
+
|
78
|
+
Scenario Outline: arbitrary Ruby objects
|
79
|
+
When I serialize the Ruby value: <ruby>
|
80
|
+
Then the serialized value should be a JSON object
|
81
|
+
And the serialized value should have a suitable _ruby_class
|
82
|
+
|
83
|
+
Examples:
|
84
|
+
| ruby |
|
85
|
+
| RightSupport::Crypto::SignedHash.new() |
|
86
|
+
| GotState.new |
|
87
|
+
|
88
|
+
Scenario: arbitrary Ruby object round-trip, happy path
|
89
|
+
When I serialize the Ruby value: GotState.new
|
90
|
+
Then the serialized value should round-trip cleanly
|
91
|
+
|
92
|
+
Scenario: arbitrary Ruby object round-trip, sad path
|
93
|
+
When I serialize the Ruby value: GotState.new
|
94
|
+
And an eldritch force deletes a key from the serialized value
|
95
|
+
And the serialized value should fail to round-trip
|
@@ -0,0 +1,27 @@
|
|
1
|
+
When /^a client makes a (buggy )?request to '(.*)'$/ do |buggy, path|
|
2
|
+
t = RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:timeout]
|
3
|
+
o = RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:open_timeout]
|
4
|
+
When "a client makes a #{buggy}request to '#{path}' with timeout #{t} and open_timeout #{o}"
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
When /^a client makes a (buggy )?request to '(.*)' with timeout (\d+) and open_timeout (\d+)$/ do |buggy, path, timeout, open_timeout|
|
9
|
+
buggy = !(buggy.nil? || buggy.empty?)
|
10
|
+
|
11
|
+
@mock_servers.should_not be_nil
|
12
|
+
@mock_servers.size.should == 1
|
13
|
+
|
14
|
+
timeout = timeout.to_i
|
15
|
+
open_timeout = open_timeout.to_i
|
16
|
+
url = @mock_servers.first.url
|
17
|
+
|
18
|
+
@http_client = RightSupport::Net::HTTPClient.new(:timeout=>timeout, :open_timeout=>open_timeout)
|
19
|
+
@request_t0 = Time.now
|
20
|
+
begin
|
21
|
+
raise ArgumentError, "Fall down go boom!" if buggy
|
22
|
+
@http_client.get("#{url}#{path}", {:timeout => timeout, :open_timeout => open_timeout})
|
23
|
+
rescue Exception => e
|
24
|
+
@request_error = e
|
25
|
+
end
|
26
|
+
@request_t1 = Time.now
|
27
|
+
end
|