right_support 2.6.17 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.rspec +4 -0
  2. data/CHANGELOG.rdoc +37 -0
  3. data/Gemfile +29 -0
  4. data/Gemfile.lock +111 -0
  5. data/README.rdoc +2 -0
  6. data/Rakefile +62 -0
  7. data/VERSION +1 -0
  8. data/features/balancer_error_handling.feature +34 -0
  9. data/features/balancer_health_check.feature +33 -0
  10. data/features/continuous_integration.feature +51 -0
  11. data/features/continuous_integration_cucumber.feature +28 -0
  12. data/features/continuous_integration_rspec1.feature +28 -0
  13. data/features/continuous_integration_rspec2.feature +28 -0
  14. data/features/http_client_timeout.feature +19 -0
  15. data/features/serialization.feature +95 -0
  16. data/features/step_definitions/http_client_steps.rb +27 -0
  17. data/features/step_definitions/request_balancer_steps.rb +93 -0
  18. data/features/step_definitions/ruby_steps.rb +176 -0
  19. data/features/step_definitions/serialization_steps.rb +96 -0
  20. data/features/step_definitions/server_steps.rb +134 -0
  21. data/features/support/env.rb +138 -0
  22. data/features/support/file_utils_bundler_mixin.rb +45 -0
  23. data/lib/right_support/ci/java_cucumber_formatter.rb +22 -8
  24. data/lib/right_support/ci/java_spec_formatter.rb +26 -8
  25. data/lib/right_support/ci/rake_task.rb +3 -0
  26. data/lib/right_support/ci.rb +24 -0
  27. data/lib/right_support/crypto/signed_hash.rb +22 -0
  28. data/lib/right_support/data/serializer.rb +24 -2
  29. data/lib/right_support/net/address_helper.rb +20 -8
  30. data/lib/right_support/net/dns.rb +20 -8
  31. data/lib/right_support/net/http_client.rb +22 -0
  32. data/lib/right_support/net/request_balancer.rb +27 -21
  33. data/lib/right_support/net/s3_helper.rb +20 -8
  34. data/lib/right_support/net/ssl/open_ssl_patch.rb +22 -0
  35. data/lib/right_support/net/ssl.rb +20 -8
  36. data/lib/right_support/ruby/easy_singleton.rb +22 -0
  37. data/lib/right_support/ruby/object_extensions.rb +22 -0
  38. data/lib/right_support/ruby/string_extensions.rb +1 -1
  39. data/lib/right_support.rb +13 -10
  40. data/right_support.gemspec +180 -18
  41. data/right_support.rconf +8 -0
  42. data/spec/config/feature_set_spec.rb +83 -0
  43. data/spec/crypto/signed_hash_spec.rb +60 -0
  44. data/spec/data/hash_tools_spec.rb +471 -0
  45. data/spec/data/uuid_spec.rb +45 -0
  46. data/spec/db/cassandra_model_part1_spec.rb +84 -0
  47. data/spec/db/cassandra_model_part2_spec.rb +73 -0
  48. data/spec/db/cassandra_model_spec.rb +359 -0
  49. data/spec/fixtures/encrypted_priv_rsa.pem +30 -0
  50. data/spec/fixtures/good_priv_dsa.pem +12 -0
  51. data/spec/fixtures/good_priv_rsa.pem +15 -0
  52. data/spec/fixtures/good_pub_dsa.ssh +1 -0
  53. data/spec/fixtures/good_pub_rsa.pem +5 -0
  54. data/spec/fixtures/good_pub_rsa.ssh +1 -0
  55. data/spec/log/exception_logger_spec.rb +76 -0
  56. data/spec/log/filter_logger_spec.rb +8 -0
  57. data/spec/log/mixin_spec.rb +62 -0
  58. data/spec/log/multiplexer_spec.rb +54 -0
  59. data/spec/log/null_logger_spec.rb +36 -0
  60. data/spec/log/system_logger_spec.rb +92 -0
  61. data/spec/net/address_helper_spec.rb +57 -0
  62. data/spec/net/balancing/health_check_spec.rb +382 -0
  63. data/spec/net/balancing/round_robin_spec.rb +15 -0
  64. data/spec/net/balancing/sticky_policy_spec.rb +92 -0
  65. data/spec/net/dns_spec.rb +152 -0
  66. data/spec/net/http_client_spec.rb +171 -0
  67. data/spec/net/request_balancer_spec.rb +579 -0
  68. data/spec/net/s3_helper_spec.rb +160 -0
  69. data/spec/net/ssl_spec.rb +42 -0
  70. data/spec/net/string_encoder_spec.rb +58 -0
  71. data/spec/rack/log_setter_spec.rb +5 -0
  72. data/spec/rack/request_logger_spec.rb +68 -0
  73. data/spec/rack/request_tracker_spec.rb +5 -0
  74. data/spec/ruby/easy_singleton_spec.rb +72 -0
  75. data/spec/ruby/object_extensions_spec.rb +27 -0
  76. data/spec/ruby/string_extensions_spec.rb +98 -0
  77. data/spec/spec_helper.rb +181 -0
  78. data/spec/stats/activity_spec.rb +193 -0
  79. data/spec/stats/exceptions_spec.rb +123 -0
  80. data/spec/stats/helpers_spec.rb +603 -0
  81. data/spec/validation/openssl_spec.rb +37 -0
  82. data/spec/validation/ssh_spec.rb +39 -0
  83. metadata +218 -19
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format=nested
3
+ --backtrace
4
+ --debugger
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
@@ -1,5 +1,7 @@
1
1
  RightSupport is a library of reusable, unit- and functional-tested Ruby code that RightScale has found broadly useful.
2
2
 
3
+ Maintained by the RightScale Teal Team
4
+
3
5
  == What Does It Do?
4
6
 
5
7
  === Logging
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