honeybadger 1.8.1 → 1.9.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/CHANGELOG.md +14 -0
  2. data/Gemfile.lock +61 -19
  3. data/Guardfile +4 -4
  4. data/MIT-LICENSE +1 -0
  5. data/README.md +2 -2
  6. data/Rakefile +4 -14
  7. data/features/rails.feature +1 -1
  8. data/gemfiles/rack.gemfile.lock +62 -27
  9. data/gemfiles/rails2.3.gemfile.lock +73 -36
  10. data/gemfiles/rails3.0.gemfile.lock +59 -26
  11. data/gemfiles/rails3.1.gemfile.lock +59 -26
  12. data/gemfiles/rails3.2.gemfile.lock +63 -30
  13. data/gemfiles/rails4.gemfile.lock +69 -36
  14. data/gemfiles/rake.gemfile.lock +62 -27
  15. data/gemfiles/sinatra.gemfile.lock +62 -27
  16. data/honeybadger.gemspec +31 -17
  17. data/lib/honeybadger.rb +2 -3
  18. data/lib/honeybadger/array.rb +53 -0
  19. data/lib/honeybadger/configuration.rb +19 -2
  20. data/lib/honeybadger/monitor.rb +16 -0
  21. data/lib/honeybadger/monitor/railtie.rb +52 -0
  22. data/lib/honeybadger/monitor/sender.rb +33 -0
  23. data/lib/honeybadger/monitor/worker.rb +71 -0
  24. data/lib/honeybadger/railtie.rb +10 -0
  25. data/lib/honeybadger/sender.rb +60 -41
  26. data/{test/unit/backtrace_test.rb → spec/honeybadger/backtrace_spec.rb} +69 -71
  27. data/{test/unit/capistrano_test.rb → spec/honeybadger/capistrano_spec.rb} +8 -9
  28. data/{test/unit/configuration_test.rb → spec/honeybadger/configuration_spec.rb} +85 -59
  29. data/spec/honeybadger/logger_spec.rb +65 -0
  30. data/spec/honeybadger/monitor/worker_spec.rb +189 -0
  31. data/{test/unit/notice_test.rb → spec/honeybadger/notice_spec.rb} +169 -185
  32. data/spec/honeybadger/notifier_spec.rb +252 -0
  33. data/spec/honeybadger/rack_spec.rb +84 -0
  34. data/{test/unit/rails/action_controller_catcher_test.rb → spec/honeybadger/rails/action_controller_spec.rb} +65 -57
  35. data/{test/unit/rails_test.rb → spec/honeybadger/rails_spec.rb} +8 -8
  36. data/spec/honeybadger/sender_spec.rb +249 -0
  37. data/spec/honeybadger_tasks_spec.rb +165 -0
  38. data/spec/spec_helper.rb +18 -0
  39. data/spec/support/array_including.rb +31 -0
  40. data/spec/support/backtraced_exception.rb +9 -0
  41. data/spec/support/collected_sender.rb +12 -0
  42. data/spec/support/defines_constants.rb +18 -0
  43. data/{test/test_helper.rb → spec/support/helpers.rb} +8 -61
  44. metadata +93 -45
  45. data/test/unit/honeybadger_tasks_test.rb +0 -167
  46. data/test/unit/logger_test.rb +0 -74
  47. data/test/unit/notifier_test.rb +0 -265
  48. data/test/unit/rack_test.rb +0 -88
  49. data/test/unit/sender_test.rb +0 -290
@@ -1,88 +0,0 @@
1
- require 'test_helper'
2
-
3
- class RackTest < Test::Unit::TestCase
4
- should "call the upstream app with the environment" do
5
- environment = { 'key' => 'value' }
6
- app = lambda { |env| ['response', {}, env] }
7
- stack = Honeybadger::Rack.new(app)
8
-
9
- response = stack.call(environment)
10
-
11
- assert_equal ['response', {}, environment], response
12
- end
13
-
14
- should "deliver an exception raised while calling an upstream app" do
15
- Honeybadger.stubs(:notify_or_ignore)
16
-
17
- exception = build_exception
18
- environment = { 'key' => 'value' }
19
- app = lambda do |env|
20
- raise exception
21
- end
22
-
23
- begin
24
- stack = Honeybadger::Rack.new(app)
25
- stack.call(environment)
26
- rescue Exception => raised
27
- assert_equal exception, raised
28
- else
29
- flunk "Didn't raise an exception"
30
- end
31
-
32
- assert_received(Honeybadger, :notify_or_ignore) do |expect|
33
- expect.with(exception, :rack_env => environment)
34
- end
35
- end
36
-
37
- should "deliver an exception in rack.exception" do
38
- Honeybadger.stubs(:notify_or_ignore)
39
- exception = build_exception
40
- environment = { 'key' => 'value' }
41
-
42
- response = [200, {}, ['okay']]
43
- app = lambda do |env|
44
- env['rack.exception'] = exception
45
- response
46
- end
47
- stack = Honeybadger::Rack.new(app)
48
-
49
- actual_response = stack.call(environment)
50
-
51
- assert_equal response, actual_response
52
- assert_received(Honeybadger, :notify_or_ignore) do |expect|
53
- expect.with(exception, :rack_env => environment)
54
- end
55
- end
56
-
57
- should "deliver an exception in sinatra.error" do
58
- Honeybadger.stubs(:notify_or_ignore)
59
- exception = build_exception
60
- environment = { 'key' => 'value' }
61
-
62
- response = [200, {}, ['okay']]
63
- app = lambda do |env|
64
- env['sinatra.error'] = exception
65
- response
66
- end
67
- stack = Honeybadger::Rack.new(app)
68
-
69
- actual_response = stack.call(environment)
70
-
71
- assert_equal response, actual_response
72
- assert_received(Honeybadger, :notify_or_ignore) do |expect|
73
- expect.with(exception, :rack_env => environment)
74
- end
75
- end
76
-
77
- should "clear context after app is called" do
78
- Honeybadger.context( :foo => :bar )
79
- assert_equal({ :foo => :bar }, Thread.current[:honeybadger_context])
80
-
81
- app = lambda { |env| ['response', {}, env] }
82
- stack = Honeybadger::Rack.new(app)
83
-
84
- response = stack.call({})
85
-
86
- assert_equal nil, Thread.current[:honeybadger_context]
87
- end
88
- end
@@ -1,290 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SenderTest < Test::Unit::TestCase
4
- def setup
5
- reset_config
6
- end
7
-
8
- def build_sender(opts = {})
9
- Honeybadger.configure do |conf|
10
- opts.each {|opt, value| conf.send(:"#{opt}=", value) }
11
- end
12
- end
13
-
14
- def send_exception(args = {})
15
- notice = args.delete(:notice) || build_notice_data
16
- sender = args.delete(:sender) || build_sender(args)
17
- sender.send_to_honeybadger(notice)
18
- end
19
-
20
- def stub_http(options = {})
21
- response = options[:response] || Net::HTTPSuccess.new('1.2', '200', 'OK')
22
- response.stubs(:body => options[:body] || '{"id":"1234"}')
23
- http = stub(:post => response,
24
- :read_timeout= => nil,
25
- :open_timeout= => nil,
26
- :ca_file= => nil,
27
- :verify_mode= => nil,
28
- :use_ssl= => nil)
29
- Net::HTTP.stubs(:new => http)
30
- http
31
- end
32
-
33
- should "post to Honeybadger when using an HTTP proxy" do
34
- response = stub(:body => 'body')
35
- http = stub(:post => response,
36
- :read_timeout= => nil,
37
- :open_timeout= => nil,
38
- :use_ssl= => nil,
39
- :ca_file= => nil,
40
- :verify_mode= => nil)
41
- proxy = stub(:new => http)
42
- Net::HTTP.stubs(:Proxy => proxy)
43
-
44
- url = "http://api.honeybadger.io:80#{Honeybadger::Sender::NOTICES_URI}"
45
- uri = URI.parse(url)
46
-
47
- proxy_host = 'some.host'
48
- proxy_port = 88
49
- proxy_user = 'login'
50
- proxy_pass = 'passwd'
51
-
52
- send_exception(:proxy_host => proxy_host,
53
- :proxy_port => proxy_port,
54
- :proxy_user => proxy_user,
55
- :proxy_pass => proxy_pass)
56
- assert_received(http, :post) do |expect|
57
- expect.with(uri.path, anything, Honeybadger::HEADERS.merge({ 'X-API-Key' => 'abc123'}))
58
- end
59
- assert_received(Net::HTTP, :Proxy) do |expect|
60
- expect.with(proxy_host, proxy_port, proxy_user, proxy_pass)
61
- end
62
- end
63
-
64
- should "return the created group's id on successful posting" do
65
- http = stub_http(:body => '{"id":"3799307"}')
66
- assert_equal "3799307", send_exception(:secure => false)
67
- end
68
-
69
- should "return nil on failed posting" do
70
- http = stub_http(:response => Net::HTTPServerError.new('1.2', '500', 'Internal Error'))
71
- assert_equal nil, send_exception(:secure => false)
72
- end
73
-
74
- should "log missing API key and return nil" do
75
- sender = build_sender({ :api_key => nil })
76
- sender.expects(:log).with(:error, includes('API key'))
77
- assert_equal nil, send_exception(:sender => sender, :secure => false)
78
- end
79
-
80
- should "should log success" do
81
- http = stub_http
82
- sender = build_sender
83
- sender.expects(:log).with(:debug, includes('Success'), kind_of(Net::HTTPSuccess), kind_of(String))
84
- send_exception(:sender => sender, :secure => false)
85
- end
86
-
87
- should "should log failure" do
88
- http = stub_http(:response => Net::HTTPServerError.new('1.2', '500', 'Internal Error'))
89
- sender = build_sender
90
- sender.expects(:log).with(:error, includes('Failure'), kind_of(Net::HTTPServerError), kind_of(String))
91
- send_exception(:sender => sender, :secure => false)
92
- end
93
-
94
- context "when encountering exceptions: " do
95
- context "HTTP connection setup problems" do
96
- should "not be rescued" do
97
- proxy = stub()
98
- proxy.stubs(:new).raises(NoMemoryError)
99
- Net::HTTP.stubs(:Proxy => proxy)
100
-
101
- assert_raise NoMemoryError do
102
- build_sender.send(:setup_http_connection)
103
- end
104
- end
105
-
106
- should "be logged" do
107
- proxy = stub()
108
- proxy.stubs(:new).raises(RuntimeError)
109
- Net::HTTP.stubs(:Proxy => proxy)
110
-
111
- sender = build_sender
112
- sender.expects(:log).with(:error, includes('Failure initializing the HTTP connection'))
113
-
114
- assert_raise RuntimeError do
115
- sender.send(:setup_http_connection)
116
- end
117
-
118
- end
119
- end
120
-
121
- context "unexpected exception sending problems" do
122
- should "be logged" do
123
- sender = build_sender
124
- sender.stubs(:setup_http_connection).raises(RuntimeError.new)
125
-
126
- sender.expects(:log).with(:error, includes('Error'))
127
- sender.send_to_honeybadger("stuff")
128
- end
129
-
130
- should "return nil no matter what" do
131
- sender = build_sender
132
- sender.stubs(:setup_http_connection).raises(LocalJumpError)
133
-
134
- assert_nothing_thrown do
135
- assert_nil sender.send_to_honeybadger("stuff")
136
- end
137
- end
138
- end
139
-
140
- should "return nil on failed posting" do
141
- http = stub_http
142
- http.stubs(:post).raises(Errno::ECONNREFUSED)
143
- assert_equal nil, send_exception(:secure => false)
144
- end
145
-
146
- should "not fail when posting and a timeout exception occurs" do
147
- http = stub_http
148
- http.stubs(:post).raises(TimeoutError)
149
- assert_nothing_thrown do
150
- send_exception(:secure => false)
151
- end
152
- end
153
-
154
- should "not fail when posting and a connection refused exception occurs" do
155
- http = stub_http
156
- http.stubs(:post).raises(Errno::ECONNREFUSED)
157
- assert_nothing_thrown do
158
- send_exception(:secure => false)
159
- end
160
- end
161
-
162
- should "not fail when posting any http exception occurs" do
163
- http = stub_http
164
- Honeybadger::Sender::HTTP_ERRORS.each do |error|
165
- http.stubs(:post).raises(error)
166
- assert_nothing_thrown do
167
- send_exception(:secure => false)
168
- end
169
- end
170
- end
171
- end
172
-
173
- context "SSL" do
174
- should "post to the right url for non-ssl" do
175
- http = stub_http
176
- url = "http://api.honeybadger.io:80#{Honeybadger::Sender::NOTICES_URI}"
177
- uri = URI.parse(url)
178
- send_exception(:secure => false)
179
- assert_received(http, :post) {|expect| expect.with(uri.path, anything, Honeybadger::HEADERS.merge({ 'X-API-Key' => 'abc123'})) }
180
- end
181
-
182
- should "post to the right path for ssl" do
183
- http = stub_http
184
- send_exception(:secure => true)
185
- assert_received(http, :post) {|expect| expect.with(Honeybadger::Sender::NOTICES_URI, anything, Honeybadger::HEADERS.merge({ 'X-API-Key' => 'abc123'})) }
186
- end
187
-
188
- should "verify the SSL peer when the use_ssl option is set to true" do
189
- url = "https://api.honeybadger.io#{Honeybadger::Sender::NOTICES_URI}"
190
- uri = URI.parse(url)
191
-
192
- real_http = Net::HTTP.new(uri.host, uri.port)
193
- real_http.stubs(:post => nil)
194
- proxy = stub(:new => real_http)
195
- Net::HTTP.stubs(:Proxy => proxy)
196
- File.stubs(:exist?).with(OpenSSL::X509::DEFAULT_CERT_FILE).returns(false)
197
-
198
- send_exception(:secure => true)
199
- assert(real_http.use_ssl?)
200
- assert_equal(OpenSSL::SSL::VERIFY_PEER, real_http.verify_mode)
201
- assert_equal(Honeybadger.configuration.local_cert_path, real_http.ca_file)
202
- end
203
-
204
- should "use the default DEFAULT_CERT_FILE if asked to" do
205
- File.expects(:exist?).with(OpenSSL::X509::DEFAULT_CERT_FILE).returns(true)
206
-
207
- Honeybadger.configure do |config|
208
- config.secure = true
209
- config.use_system_ssl_cert_chain = true
210
- end
211
-
212
- sender = Honeybadger::Sender.new(Honeybadger.configuration)
213
-
214
- assert(sender.use_system_ssl_cert_chain?)
215
-
216
- http = sender.send(:setup_http_connection)
217
- assert_not_equal http.ca_file, Honeybadger.configuration.local_cert_path
218
- end
219
-
220
- should "verify the connection when the use_ssl option is set (VERIFY_PEER)" do
221
- sender = build_sender(:secure => true)
222
- http = sender.send(:setup_http_connection)
223
- assert_equal(OpenSSL::SSL::VERIFY_PEER, http.verify_mode)
224
- end
225
-
226
- should "use the default cert (OpenSSL::X509::DEFAULT_CERT_FILE) only if explicitly told to" do
227
- sender = build_sender(:secure => true)
228
- http = sender.send(:setup_http_connection)
229
-
230
- assert_equal(Honeybadger.configuration.local_cert_path, http.ca_file)
231
-
232
- File.stubs(:exist?).with(OpenSSL::X509::DEFAULT_CERT_FILE).returns(true)
233
- sender = build_sender(:secure => true, :use_system_ssl_cert_chain => true)
234
- http = sender.send(:setup_http_connection)
235
-
236
- assert_not_equal(Honeybadger.configuration.local_cert_path, http.ca_file)
237
- assert_equal(OpenSSL::X509::DEFAULT_CERT_FILE, http.ca_file)
238
- end
239
-
240
- should "connect to the right port for ssl" do
241
- stub_http
242
- send_exception(:secure => true)
243
- assert_received(Net::HTTP, :new) {|expect| expect.with("api.honeybadger.io", 443) }
244
- end
245
-
246
- should "connect to the right port for non-ssl" do
247
- stub_http
248
- send_exception(:secure => false)
249
- assert_received(Net::HTTP, :new) {|expect| expect.with("api.honeybadger.io", 80) }
250
- end
251
-
252
- should "use ssl if secure" do
253
- stub_http
254
- send_exception(:secure => true, :host => 'example.org')
255
- assert_received(Net::HTTP, :new) {|expect| expect.with('example.org', 443) }
256
- end
257
-
258
- should "not use ssl if not secure" do
259
- stub_http
260
- send_exception(:secure => false, :host => 'example.org')
261
- assert_received(Net::HTTP, :new) {|expect| expect.with('example.org', 80) }
262
- end
263
- end
264
-
265
- context "network timeouts" do
266
- should "default the open timeout to 2 seconds" do
267
- http = stub_http
268
- send_exception
269
- assert_received(http, :open_timeout=) {|expect| expect.with(2) }
270
- end
271
-
272
- should "default the read timeout to 5 seconds" do
273
- http = stub_http
274
- send_exception
275
- assert_received(http, :read_timeout=) {|expect| expect.with(5) }
276
- end
277
-
278
- should "allow override of the open timeout" do
279
- http = stub_http
280
- send_exception(:http_open_timeout => 4)
281
- assert_received(http, :open_timeout=) {|expect| expect.with(4) }
282
- end
283
-
284
- should "allow override of the read timeout" do
285
- http = stub_http
286
- send_exception(:http_read_timeout => 10)
287
- assert_received(http, :read_timeout=) {|expect| expect.with(10) }
288
- end
289
- end
290
- end