right_support 2.11.3 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -0
  3. data/VERSION +1 -1
  4. data/lib/right_support/notifiers/airbrake.rb +194 -0
  5. data/lib/right_support/notifiers/base.rb +73 -0
  6. data/lib/right_support/notifiers/blacklisters/base.rb +48 -0
  7. data/lib/right_support/notifiers/blacklisters/canonical.rb +60 -0
  8. data/lib/right_support/notifiers/blacklisters/regular_expression.rb +86 -0
  9. data/{features/support/file_utils_bundler_mixin.rb → lib/right_support/notifiers/blacklisters/simple.rb} +21 -20
  10. data/lib/right_support/notifiers/blacklisters/snake_case.rb +60 -0
  11. data/lib/right_support/notifiers/blacklisters/wildcard.rb +65 -0
  12. data/lib/right_support/notifiers/blacklisters.rb +34 -0
  13. data/lib/right_support/notifiers/logger.rb +94 -0
  14. data/lib/right_support/notifiers/notification.rb +57 -0
  15. data/lib/right_support/notifiers/utilities/backtrace_decoder.rb +234 -0
  16. data/lib/right_support/notifiers/utilities.rb +29 -0
  17. data/lib/right_support/notifiers.rb +32 -0
  18. data/lib/right_support/rack/request_logger.rb +13 -9
  19. data/lib/right_support.rb +1 -0
  20. data/right_support.gemspec +19 -70
  21. metadata +17 -69
  22. data/.coveralls.yml +0 -2
  23. data/.rspec +0 -3
  24. data/.simplecov +0 -6
  25. data/.travis.yml +0 -13
  26. data/Gemfile +0 -51
  27. data/Gemfile.lock +0 -153
  28. data/features/balancer_error_handling.feature +0 -34
  29. data/features/balancer_health_check.feature +0 -33
  30. data/features/hash_tools.feature +0 -27
  31. data/features/http_client_timeout.feature +0 -19
  32. data/features/serialization.feature +0 -113
  33. data/features/step_definitions/hash_tools_steps.rb +0 -41
  34. data/features/step_definitions/http_client_steps.rb +0 -27
  35. data/features/step_definitions/request_balancer_steps.rb +0 -93
  36. data/features/step_definitions/ruby_steps.rb +0 -176
  37. data/features/step_definitions/serialization_steps.rb +0 -133
  38. data/features/step_definitions/server_steps.rb +0 -134
  39. data/features/support/env.rb +0 -148
  40. data/right_support.rconf +0 -9
  41. data/spec/config/feature_set_spec.rb +0 -83
  42. data/spec/crypto/signed_hash_spec.rb +0 -73
  43. data/spec/data/hash_tools_spec.rb +0 -602
  44. data/spec/data/mash_spec.rb +0 -313
  45. data/spec/data/token_spec.rb +0 -21
  46. data/spec/data/uuid_spec.rb +0 -45
  47. data/spec/db/cassandra_model_part1_spec.rb +0 -84
  48. data/spec/db/cassandra_model_part2_spec.rb +0 -73
  49. data/spec/db/cassandra_model_spec.rb +0 -375
  50. data/spec/fixtures/encrypted_priv_rsa.pem +0 -30
  51. data/spec/fixtures/good_priv_dsa.pem +0 -12
  52. data/spec/fixtures/good_priv_rsa.pem +0 -15
  53. data/spec/fixtures/good_pub_dsa.ssh +0 -1
  54. data/spec/fixtures/good_pub_rsa.pem +0 -5
  55. data/spec/fixtures/good_pub_rsa.ssh +0 -1
  56. data/spec/log/exception_logger_spec.rb +0 -76
  57. data/spec/log/filter_logger_spec.rb +0 -66
  58. data/spec/log/mixin_spec.rb +0 -141
  59. data/spec/log/multiplexer_spec.rb +0 -54
  60. data/spec/log/null_logger_spec.rb +0 -36
  61. data/spec/log/step_level_logger_spec.rb +0 -49
  62. data/spec/log/system_logger_spec.rb +0 -172
  63. data/spec/net/address_helper_spec.rb +0 -57
  64. data/spec/net/dns_spec.rb +0 -187
  65. data/spec/net/http_client_spec.rb +0 -181
  66. data/spec/net/lb/health_check_spec.rb +0 -417
  67. data/spec/net/lb/round_robin_spec.rb +0 -15
  68. data/spec/net/lb/sticky_spec.rb +0 -92
  69. data/spec/net/request_balancer_spec.rb +0 -690
  70. data/spec/net/s3_helper_spec.rb +0 -160
  71. data/spec/net/ssl_spec.rb +0 -42
  72. data/spec/net/string_encoder_spec.rb +0 -58
  73. data/spec/rack/log_setter_spec.rb +0 -5
  74. data/spec/rack/request_logger_spec.rb +0 -225
  75. data/spec/rack/request_tracker_spec.rb +0 -115
  76. data/spec/rack/runtime_spec.rb +0 -49
  77. data/spec/ruby/easy_singleton_spec.rb +0 -72
  78. data/spec/ruby/object_extensions_spec.rb +0 -27
  79. data/spec/ruby/string_extensions_spec.rb +0 -98
  80. data/spec/spec_helper.rb +0 -188
  81. data/spec/stats/activity_spec.rb +0 -425
  82. data/spec/stats/exceptions_spec.rb +0 -247
  83. data/spec/stats/helpers_spec.rb +0 -685
  84. data/spec/validation/openssl_spec.rb +0 -37
  85. data/spec/validation/ssh_spec.rb +0 -39
@@ -1,160 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe RightSupport::Net::S3Helper do
4
-
5
- def digest
6
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, passphrase, @valid_params[:data])
7
- end
8
-
9
- def ciphertext
10
- "\203\346\271\273\323\377r\246\002\204\231\374h\327!\323"
11
- end
12
-
13
- def passphrase
14
- "#{@valid_params[:key]}:key"
15
- end
16
-
17
- before(:each) do
18
- @valid_params = { :key => "foo", :data => "bar" }
19
-
20
- # Mock right_aws config & objects with reasonable default behavior
21
- @s3_config = {'creds' =>
22
- {'aws_access_key_id' => 'knock_knock',
23
- 'aws_secret_access_key' => 'open_sesame'},
24
- 'bucket_name' => 'my_own_personal_bucket',
25
- 'master_secret' => 'if i told you i would have to kill you'}
26
- @s3_class = flexmock("s3")
27
- @s3_object = flexmock("s3_object")
28
- @s3_bucket = flexmock("s3_bucket")
29
- @s3_class.should_receive(:new).with(String, String, Hash).and_return(@s3_object)
30
- @s3_object.should_receive(:bucket).with('my_own_personal_bucket').and_return(@s3_bucket).by_default
31
- @s3_bucket.should_receive(:key).and_return(@s3_object).by_default
32
- @s3_bucket.should_receive(:put).with(String, String, Hash).and_return(true).by_default
33
-
34
- @s3_object.should_receive(:meta_headers).and_return({"digest" => digest})
35
- @s3_object.should_receive(:data).and_return(ciphertext)
36
-
37
- flexmock(RightSupport::Net::S3Helper).should_receive(:s3_enabled?).and_return(:true)
38
- flexmock(RightSupport::Net::S3Helper).should_receive(:master_secret).and_return('key')
39
-
40
- @encrypt = flexmock("encrypt")
41
- @encrypt.should_receive(:encrypt).with(String, String, Hash).and_return(ciphertext)
42
- @encrypt.should_receive(:encrypt).with(Hash).and_return(ciphertext)
43
- @encrypt.should_receive(:decrypt).with(Hash).and_return(@valid_params[:data])
44
- end
45
-
46
- context :init do
47
- context "when all params are valid" do
48
- it "succeeds" do
49
- RightSupport::Net::S3Helper.init(@s3_config, @s3_class, @encrypt).should be_true
50
- end
51
- end
52
-
53
- context "when bucket does not exist" do
54
- before(:each) do
55
- @bad_s3_config = @s3_config.clone
56
- @bad_s3_config['bucket_name'] = "supercallifragilisticexpialidocious"
57
- @s3_object.should_receive(:bucket).with("supercallifragilisticexpialidocious").and_return(nil)
58
- end
59
-
60
- it "raises BucketNotFound" do
61
- lambda {
62
- RightSupport::Net::S3Helper.init(@bad_s3_config, @s3_class, @encrypt)
63
- }.should raise_error(RightSupport::Net::S3Helper::BucketNotFound)
64
- end
65
- end
66
- end
67
-
68
- context :get do
69
- before(:each) do
70
- RightSupport::Net::S3Helper.init(@s3_config, @s3_class, @encrypt)
71
- end
72
-
73
- context "with valid params" do
74
- it 'returns plaintext' do
75
- RightSupport::Net::S3Helper.get(@valid_params[:key]).should be_eql(@valid_params[:data])
76
- end
77
- end
78
- end
79
-
80
- context :post do
81
- before(:each) do
82
- RightSupport::Net::S3Helper.init(@s3_config, @s3_class, @encrypt)
83
- end
84
-
85
- context "with valid params" do
86
- it 'encrypts and saves data' do
87
- @s3_bucket.should_receive(:put).with(@valid_params[:key], ciphertext, {"digest" => digest}).and_return(true)
88
- RightSupport::Net::S3Helper.post(@valid_params[:key], @valid_params[:data]).should be_true
89
- end
90
- end
91
- end
92
-
93
- context :health_check do
94
- before(:each) do
95
- RightSupport::Net::S3Helper.init(@s3_config, @s3_class, @encrypt)
96
- end
97
-
98
- context 'with invalid configuration' do
99
- before :each do
100
- flexmock(RightSupport::Net::S3Helper).should_receive(:config).and_return({'creds' => {'aws_access_key_id' => '@@AWS_ACCESS_KEY_ID@@', 'aws_secret_access_key' => '@@AWS_SECRET_ACCESS_KEY@@'}, 'bucket_name' => '@@s3_bucket_NAME@@', 'master_secret' => '@@MASTER_SECRET@@'})
101
- end
102
-
103
- it 'return error' do
104
- RightSupport::Net::S3Helper.health_check.class.should == String
105
- end
106
- end
107
-
108
- context 'with valid configuration but invalid s3 connection credentials' do
109
- before :each do
110
- flexmock(RightSupport::Net::S3Helper).should_receive(:config).and_return({'creds' => {'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY'}, 'bucket_name' => 'BUCKET_NAME', 'master_secret' => 'MASTER_SECRET'})
111
- end
112
-
113
- it 'returns error ' do
114
- RightSupport::Net::S3Helper.health_check.class.should == String
115
- end
116
- end
117
-
118
- context 'with valid configuration and s3 connection' do
119
- before :each do
120
- flexmock(RightSupport::Net::S3Helper).should_receive(:config).and_return({'creds' => {'aws_access_key_id' => 'dsfgdsfgdsfgdsfg', 'aws_secret_access_key' => 'sdghdhsdg'}, 'bucket_name' => 'dshdshdfgh', 'master_secret' => 'dshdshg'})
121
- flexmock(RightSupport::Net::S3Helper).should_receive(:post).with('ping', 'heath check').and_return(true)
122
- flexmock(RightSupport::Net::S3Helper).should_receive(:get).with('ping').and_return('heath check')
123
- end
124
-
125
- it 'returns ok' do
126
- RightSupport::Net::S3Helper.health_check.should == true
127
- end
128
- end
129
- end
130
-
131
- context 'test/development environment' do
132
-
133
- before :each do
134
- @key1 = 'aws_access_key_id'
135
- @key2 = 'aws_secret_access_key'
136
- @opt_with_no_subdomains = {:no_subdomains => true}
137
- @opt_without_subdoamins = {}
138
- @config = {}
139
- @config["creds"] = {}
140
- @config["creds"]["aws_access_key_id"] = @key1
141
- @config["creds"]["aws_secret_access_key"] = @key2
142
- @s3_class = flexmock('Rightscale::S3')
143
- flexmock(RightSupport::Net::S3Helper).should_receive(:bucket).and_return(true)
144
- end
145
-
146
- it 'works ok with :no_subdomains' do
147
- @s3_class.should_receive(:new).with(@key1, @key2, @opt_with_no_subdomains)
148
- RightSupport::Net::S3Helper.init(@config, @s3_class, @s3_class, :no_subdomains => true)
149
- RightSupport::Net::S3Helper.s3
150
- end
151
-
152
- it 'works ok without subdomains' do
153
- @s3_class.should_receive(:new).with(@key1, @key2, @opt_without_subdoamins)
154
- RightSupport::Net::S3Helper.init(@config, @s3_class, @s3_class)
155
- RightSupport::Net::S3Helper.s3
156
- end
157
-
158
- end
159
-
160
- end
data/spec/net/ssl_spec.rb DELETED
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RightSupport::Net::SSL do
4
- PATCH = RightSupport::Net::SSL::OpenSSLPatch
5
-
6
- context :with_expected_hostname do
7
- before(:all) do
8
- PATCH.enable!
9
- end
10
-
11
- it 'works' do
12
- OpenSSL::SSL.should respond_to(:verify_certificate_identity_without_hack)
13
- PATCH.enabled?.should be_true
14
-
15
- cert = flexmock('SSL certificate')
16
-
17
- flexmock(OpenSSL::SSL).
18
- should_receive(:verify_certificate_identity_without_hack).
19
- with(cert, 'reposeX.rightscale.com').and_return(true)
20
- RightSupport::Net::SSL.with_expected_hostname('reposeX.rightscale.com') do
21
- OpenSSL::SSL.verify_certificate_identity(cert, '1.2.3.4').should be_true
22
- end
23
- end
24
-
25
- context 'with disabled monkey-patch' do
26
- before(:all) do
27
- PATCH.disable!
28
- end
29
- it 'does not work' do
30
- PATCH.enabled?.should be_false
31
- cert = flexmock('SSL certificate')
32
- flexmock(OpenSSL::SSL).
33
- should_receive(:verify_certificate_identity_without_hack).
34
- with(cert, '1.2.3.4').and_return(false)
35
-
36
- RightSupport::Net::SSL.with_expected_hostname('reposeX.rightscale.com') do
37
- OpenSSL::SSL.verify_certificate_identity(cert, '1.2.3.4').should be_false
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,58 +0,0 @@
1
- require 'spec_helper'
2
- require 'cgi'
3
-
4
- describe RightSupport::Net::StringEncoder do
5
- #Alias for brevity's sake
6
- ENCODINGS = RightSupport::Net::StringEncoder::ENCODINGS
7
-
8
- before(:all) do
9
- #Generate some random binary test vectors with varying
10
- #lengths, 2-1024 bytes
11
- @strings = []
12
- (1..10).each do |i|
13
- s = ''
14
- i.times { s << rand(256) }
15
-
16
- if RUBY_VERSION >= '1.9'
17
- @strings << s.force_encoding(Encoding::ASCII_8BIT)
18
- else
19
- @strings << s
20
- end
21
- end
22
- end
23
-
24
- context :initialize do
25
- it 'accepts a glob of encodings' do
26
- obj = RightSupport::Net::StringEncoder.new(:base64, :url)
27
- obj.decode(obj.encode('moo')).should == 'moo'
28
- end
29
-
30
- it 'accepts an Array of encodings' do
31
- obj = RightSupport::Net::StringEncoder.new([:base64, :url])
32
- obj.decode(obj.encode('moo')).should == 'moo'
33
- end
34
-
35
- context 'when unknown encodings are specified' do
36
- it 'raises ArgumentError' do
37
- lambda do
38
- RightSupport::Net::StringEncoder.new(:xyzzy, :foobar)
39
- end.should raise_error(ArgumentError)
40
- end
41
- end
42
- end
43
-
44
- #Ensure that encodings are symmetrical and commutative by testing round-trip
45
- #for all combinations.
46
- (1..ENCODINGS.length).each do |n|
47
- context "when using any #{n} encoding#{n > 1 ? 's' : ''}" do
48
- ENCODINGS.combination(n).each do |list|
49
- it "round-trips #{list.join(', ')}" do
50
- obj = RightSupport::Net::StringEncoder.new(*list)
51
- @strings.each do |str|
52
- obj.decode(obj.encode(str)).should == str
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,5 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RightSupport::Rack::LogSetter do
4
- it 'has test coverage'
5
- end
@@ -1,225 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RightSupport::Rack::RequestLogger do
4
- class OhNoes < Exception; end
5
-
6
- before(:each) do
7
- @app = flexmock('Rack app')
8
- @app.should_receive(:call).and_return([200, {}, 'body']).by_default
9
- @logger = mock_logger
10
- @env = {'rack.logger' => @logger}
11
- @options = {}
12
- end
13
-
14
- subject { described_class.new(@app, @options) }
15
-
16
- context :initialize do
17
- context 'without :logger option' do
18
- it 'uses rack.logger' do
19
- @logger.should_receive(:info).at_least.once
20
- subject.call(@env).should == [200, {}, 'body']
21
- end
22
- end
23
-
24
- context 'with :logger option' do
25
- it 'uses given logger' do
26
- @env = {'rack.logger' => flexmock('overridden')}
27
- @options[:logger] = @logger
28
- @logger.should_receive(:info).at_least.once
29
- subject.call(@env).should == [200, {}, 'body']
30
- end
31
- end
32
-
33
- context 'with :normalize_40x option' do
34
- it 'omits some 40x details and disables global session Set-Cookie fields' do
35
- @options[:normalize_40x] = true
36
- @app = flexmock('Rack app')
37
- body = 'insecure information'
38
- headers = { 'TooMuch' => 'info', 'Content-Type' => 'text/plain', 'Content-Length' => body.bytesize.to_s }
39
- iterative = [nil, headers, body]
40
- @app.should_receive(:call).and_return(iterative)
41
-
42
- # note that sending 'X-Debug' header should have no effect on a
43
- # normalized 40x response
44
- @env.merge!(described_class::DEBUG_MODE_HTTP_HEADER => 'true')
45
- (400..499).each do |code|
46
- iterative[0] = code
47
- if described_class::NORMALIZE_40X.include?(code)
48
- env = @env.dup
49
- subject.call(env).should == [code, { 'Content-Length' => '0'}, []]
50
- env.should == @env.merge(
51
- 'global_session.req.renew' => false,
52
- 'global_session.req.update' => false,
53
- described_class::DEBUG_MODE_ENV_KEY => false)
54
- else
55
- subject.call(@env).should == iterative
56
- end
57
- end
58
- end
59
- end
60
-
61
- context 'with :normalize_40x_set_cookie option' do
62
- it 'disables global session Set-Cookie fields' do
63
- @options[:normalize_40x_set_cookie] = true
64
- @app = flexmock('Rack app')
65
- body = 'whatever'
66
- headers = { 'Content-Type' => 'text/plain', 'Content-Length' => body.bytesize.to_s }
67
- iterative = [nil, headers, body]
68
- @app.should_receive(:call).and_return(iterative)
69
-
70
- (400..499).each do |code|
71
- iterative[0] = code
72
- if described_class::NORMALIZE_40X.include?(code)
73
- env = @env.dup
74
- subject.call(env).should == iterative
75
- env.should == @env.merge(
76
- 'global_session.req.renew' => false,
77
- 'global_session.req.update' => false)
78
- else
79
- subject.call(@env).should == iterative
80
- end
81
- end
82
- end
83
- end
84
- end
85
-
86
- context :call do
87
- context 'when the app raises an exception' do
88
- before(:each) do
89
- @app.should_receive(:call).and_raise(OhNoes)
90
- end
91
-
92
- it 'logs the exception' do
93
- @logger.should_receive(:error).at_least.once
94
- lambda {
95
- subject.call(@env)
96
- }.should raise_error
97
- end
98
- end
99
-
100
- context 'when Sinatra stores an exception' do
101
- before(:each) do
102
- @app.should_receive(:call).and_return([500, {}, 'body'])
103
- @env['sinatra.error'] = OhNoes.new
104
- end
105
-
106
- it 'logs the exception' do
107
- @logger.should_receive(:info)
108
- @logger.should_receive(:error).at_least.once
109
- subject.call(@env)
110
- end
111
-
112
- it 'skips logging the exception when already handled' do
113
- @logger.should_receive(:info)
114
- @logger.should_receive(:error).never
115
- @env['sinatra.error.handled'] = true
116
- subject.call(@env)
117
- end
118
- end
119
-
120
- context 'given limiting options' do
121
- before(:each) do
122
- @options = {:except => [/bar/]}
123
- @env.merge!('PATH_INFO' => '/foo/bar')
124
- subject = described_class.new(@app, @options)
125
- @logger.should_receive(:level).and_return(Logger::INFO).by_default
126
- end
127
-
128
- it 'limits if logger in debug mode' do
129
- @logger.should_receive(:level).and_return(Logger::DEBUG)
130
- @logger.should_receive(:info).never
131
- subject.call(@env)
132
- end
133
-
134
- it 'does not limit if HTTP_X_DEBUG set' do
135
- @logger.should_receive(:info).at_least.once
136
- subject.call(@env.merge('HTTP_X_DEBUG' => true))
137
- end
138
-
139
- it 'does not log for paths matching :except option' do
140
- @logger.should_receive(:info).never
141
- subject.call(@env)
142
- end
143
-
144
- it 'does log for paths matching :only option' do
145
- @options = {:only => [/bar/]}
146
- subject = described_class.new(@app, @options)
147
- @logger.should_receive(:info)
148
- subject.call(@env)
149
- end
150
-
151
- it 'sets rack.logging.enabled in Rack environment' do
152
- @logger.should_receive(:info).at_least.once
153
- @env.merge!('PATH_INFO' => '/my/app')
154
- subject.call(@env)
155
- @env['rack.logging.enabled'].should be_true
156
- end
157
- end
158
-
159
- context 'when logging the query string' do
160
- before(:each) do
161
- @options = {}
162
- @env.merge!('PATH_INFO' => '/my/app', 'QUERY_STRING' => 'foo=bar')
163
- subject = described_class.new(@app, @options)
164
- end
165
-
166
- it 'does not log the query string by default' do
167
- @logger.should_receive(:info).with(FlexMock.on { |arg| arg.should =~ /\/my\/app\?\.{3}/ } )
168
- subject.send(:log_request_begin, @logger, @env)
169
- end
170
-
171
- context 'when the include_query_string option is true' do
172
- it 'logs the query string' do
173
- @options[:include_query_string] = true
174
- subject = described_class.new(@app, @options)
175
- @logger.should_receive(:info).with(FlexMock.on { |arg| arg.should =~ /\/my\/app\?foo%3Dbar/ } )
176
- subject.send(:log_request_begin, @logger, @env)
177
- end
178
- end
179
-
180
- context 'when the include_query_string option is false' do
181
- it 'does not log the query string' do
182
- @options[:include_query_string] = false
183
- subject = described_class.new(@app, @options)
184
- @logger.should_receive(:info).with(FlexMock.on { |arg| arg.should =~ /\/my\/app\?\.{3}/ } )
185
- subject.send(:log_request_begin, @logger, @env)
186
- end
187
- end
188
- end
189
-
190
- context 'Shard ID logging' do
191
- before(:each) do
192
- @logger = mock_logger
193
- end
194
-
195
- it 'logs X-Shard header if it is present' do
196
- @env['HTTP_X_SHARD'] = '9'
197
- @logger.should_receive(:info).with(FlexMock.on { |arg| arg.should =~ /Shard: 9$/ } )
198
- subject.send(:log_request_begin, @logger, @env)
199
- end
200
-
201
- it 'logs "default" if X-Shard header is absent' do
202
- @logger.should_receive(:info).with(FlexMock.on { |arg| arg.should =~ /Shard: default$/ } )
203
- subject.send(:log_request_begin, @logger, @env)
204
- end
205
- end
206
-
207
- context 'request ID logging' do
208
- before(:each) do
209
- @logger = mock_logger
210
- @env['rack.request_uuid'] = 'some-uuid'
211
- end
212
-
213
- it 'tags the Started line' do
214
- @logger.should_receive(:info).with(FlexMock.on { |arg| arg.should =~ /^\[some\-uuid\] Started / } )
215
- subject.send(:log_request_begin, @logger, @env)
216
- end
217
-
218
- it 'tags the Completed line' do
219
- @logger.should_receive(:info).with(FlexMock.on { |arg| arg.should =~ /^\[some\-uuid\] Completed / } )
220
- subject.send(:log_request_end, @logger, @env, 200, {}, '', Time.now)
221
- end
222
- end
223
-
224
- end
225
- end
@@ -1,115 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe RightSupport::Rack::RequestTracker do
4
-
5
- let(:app) { flexmock('next middleware or rack app') }
6
-
7
- let(:generator) { described_class::Generator }
8
- let(:generated_request_uuid) { 'generated-uuid' }
9
- let(:request_uuid) { 'given-uuid' }
10
-
11
- subject { described_class.new(app) }
12
-
13
- context :call do
14
- context 'when ID is missing from request headers' do
15
- it 'generates a new request ID and responds as UUID for legacy reasons' do
16
- flexmock(generator).
17
- should_receive(:generate).
18
- and_return(generated_request_uuid).
19
- once
20
- original_env = {}
21
- expected_env = original_env.merge(described_class::REQUEST_UUID_ENV_NAME => generated_request_uuid)
22
- app.should_receive(:call).with(expected_env).and_return([200, {}, 'body']).once
23
-
24
- actual = subject.call(original_env)
25
-
26
- expected_headers = { described_class::REQUEST_UUID_HEADER => generated_request_uuid }
27
- actual[1].should == expected_headers
28
- end
29
- end
30
-
31
- context 'when ID sent with request' do
32
- it 'passes incoming request ID and responds as ID' do
33
- flexmock(generator).should_receive(:generate).never
34
- original_env = { described_class::HTTP_REQUEST_ID_HEADER => request_uuid }
35
- expected_env = original_env.merge(described_class::REQUEST_UUID_ENV_NAME => request_uuid)
36
- app.should_receive(:call).with(expected_env).and_return([200, {}, 'body']).once
37
-
38
- actual = subject.call(original_env)
39
-
40
- expected_headers = { described_class::REQUEST_ID_HEADER => request_uuid }
41
- actual[1].should == expected_headers
42
- end
43
- end
44
-
45
- context 'when UUID sent with request' do
46
- it 'passes incoming request UUID and responds as UUID' do
47
- flexmock(generator).should_receive(:generate).never
48
- original_env = { described_class::HTTP_REQUEST_UUID_HEADER => request_uuid }
49
- expected_env = original_env.merge(described_class::REQUEST_UUID_ENV_NAME => request_uuid)
50
- app.should_receive(:call).with(expected_env).and_return([200, {}, 'body']).once
51
-
52
- actual = subject.call(original_env)
53
-
54
- expected_headers = { described_class::REQUEST_UUID_HEADER => request_uuid }
55
- actual[1].should == expected_headers
56
- end
57
- end
58
-
59
- context 'when lineage sent with request' do
60
- it 'passes all UUIDs in header under length limit' do
61
- uuids = []
62
- 3.times do
63
- uuids << ::RightSupport::Data::UUID.generate
64
- end
65
- lineage_uuid = uuids.join(described_class::UUID_SEPARATOR)
66
- flexmock(generator).should_receive(:generate).never
67
- original_env = { described_class::REQUEST_LINEAGE_UUID_HEADER => lineage_uuid }
68
- expected_env = original_env.merge(described_class::REQUEST_UUID_ENV_NAME => lineage_uuid)
69
- app.should_receive(:call).with(expected_env).and_return([200, {}, 'body']).once
70
-
71
- actual = subject.call(original_env)
72
-
73
- expected_headers = { described_class::REQUEST_UUID_HEADER => lineage_uuid }
74
- actual[1].should == expected_headers
75
- end
76
- end
77
-
78
- context 'when sent ID exceeds length limit' do
79
- it 'passes truncated request ID' do
80
- flexmock(generator).should_receive(:generate).never
81
- too_long_id = 'x' * 1024
82
- truncated_id = 'x' * described_class::MAX_REQUEST_UUID_LENGTH
83
- original_env = { described_class::HTTP_REQUEST_ID_HEADER => too_long_id }
84
- expected_env = original_env.merge(described_class::REQUEST_UUID_ENV_NAME => truncated_id)
85
- app.should_receive(:call).with(expected_env).and_return([200, {}, 'body']).once
86
-
87
- actual = subject.call(original_env)
88
-
89
- expected_headers = { described_class::REQUEST_ID_HEADER => truncated_id }
90
- actual[1].should == expected_headers
91
- end
92
- end
93
-
94
- end
95
-
96
- context :copy_request_uuid do
97
- it 'does nothing when request UUID is missing' do
98
- described_class.copy_request_uuid(nil, nil).should be_empty
99
- end
100
-
101
- it 'copies request UUID to target hash when present' do
102
- env = {
103
- described_class::REQUEST_UUID_ENV_NAME => request_uuid,
104
- 'other' => 'stuff'
105
- }
106
- other_headers = { 'Foo' => 'bar' }
107
- expected = {
108
- described_class::REQUEST_ID_HEADER => request_uuid
109
- }.merge(other_headers)
110
- actual = described_class.copy_request_uuid(env, other_headers)
111
- actual.should == expected
112
- end
113
- end
114
-
115
- end
@@ -1,49 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class FasterApp
4
- def self.call(env)
5
- sleep 0.05; [200, {}, "50ms"]
6
- end
7
- end
8
-
9
- class SlowerApp
10
- def self.call(env)
11
- sleep 0.2; [200, {}, "200ms"]
12
- end
13
- end
14
-
15
- describe RightSupport::Rack::Runtime do
16
- before(:each) do
17
- @app = flexmock('Rack app')
18
- @app.should_receive(:call).and_return([200, {}, 'body']).by_default
19
- @env = {'rack.logger' => @logger}
20
- @middleware = RightSupport::Rack::Runtime.new(@app)
21
- end
22
-
23
- context :call do
24
- it 'sets an X-Runtime header in response' do
25
- @middleware.call(@env).should == [200, {"X-Runtime"=>"0"}, 'body']
26
- end
27
-
28
- it 'sets a correct X-Runtime value for 50 ms app' do
29
- faster = RightSupport::Rack::Runtime.new(FasterApp)
30
- result = faster.call(@env)
31
- result[1].keys.should == ['X-Runtime']
32
- result[1]['X-Runtime'].to_i.should >= 50
33
- result[1]['X-Runtime'].to_i.should < 70
34
- end
35
-
36
- it 'sets a correct X-Runtime value for 200 ms app' do
37
- slower = RightSupport::Rack::Runtime.new(SlowerApp)
38
- result = slower.call(@env)
39
- result[1].keys.should == ['X-Runtime']
40
- result[1]['X-Runtime'].to_i.should >= 200
41
- result[1]['X-Runtime'].to_i.should < 270
42
- end
43
-
44
- it 'allows appending custom name to X-Runtime header' do
45
- customized = RightSupport::Rack::Runtime.new(@app, "Test")
46
- customized.call(@env).should == [200, {"X-Runtime-Test"=>"0"}, 'body']
47
- end
48
- end
49
- end