opbeat 0.9.1 → 0.9.2

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.
@@ -0,0 +1,50 @@
1
+ require File::expand_path('../../spec_helper', __FILE__)
2
+ require 'opbeat'
3
+
4
+ describe Opbeat::Configuration do
5
+ before do
6
+ # Make sure we reset the env in case something leaks in
7
+ ENV.delete('OPBEAT_ORGANIZATION_ID')
8
+ ENV.delete('OPBEAT_APP_ID')
9
+ ENV.delete('OPBEAT_SECRET_TOKEN')
10
+ end
11
+
12
+ shared_examples 'a complete configuration' do
13
+ it 'should have a server' do
14
+ expect(subject[:server]).to eq('http://opbeat.localdomain/opbeat')
15
+ end
16
+
17
+ it 'should have an secret token' do
18
+ expect(subject[:secret_token]).to eq('67890')
19
+ end
20
+
21
+ it 'should have an organization ID' do
22
+ expect(subject[:organization_id]).to eq('42')
23
+ end
24
+
25
+ it 'should have an app ID' do
26
+ expect(subject[:app_id]).to eq('43')
27
+ end
28
+ end
29
+
30
+ context 'being initialized with options' do
31
+ before do
32
+ subject.server = 'http://opbeat.localdomain/opbeat'
33
+ subject.secret_token = '67890'
34
+ subject.organization_id = '42'
35
+ subject.app_id = '43'
36
+ end
37
+ it_should_behave_like 'a complete configuration'
38
+ end
39
+
40
+ context 'being initialized with an environment variable' do
41
+ subject do
42
+ ENV['OPBEAT_ORGANIZATION_ID'] = '42'
43
+ ENV['OPBEAT_APP_ID'] = '43'
44
+ ENV['OPBEAT_SECRET_TOKEN'] = '67890'
45
+ ENV['OPBEAT_SERVER'] = 'http://opbeat.localdomain/opbeat'
46
+ Opbeat::Configuration.new
47
+ end
48
+ it_should_behave_like 'a complete configuration'
49
+ end
50
+ end
@@ -0,0 +1,130 @@
1
+ require File::expand_path('../../spec_helper', __FILE__)
2
+ require 'opbeat'
3
+
4
+ describe Opbeat::Event do
5
+ describe '.capture_message' do
6
+ let(:message) { 'This is a message' }
7
+ let(:hash) { Opbeat::Event.capture_message(message).to_hash }
8
+
9
+ context 'for a Message' do
10
+ it 'returns an event' do
11
+ expect(Opbeat::Event.capture_message(message)).to be_a(Opbeat::Event)
12
+ end
13
+
14
+ it "sets the message to the value passed" do
15
+ expect(hash['message']).to eq(message)
16
+ end
17
+
18
+ it 'has level ERROR' do
19
+ expect(hash['level']).to eq('error')
20
+ end
21
+ end
22
+ end
23
+
24
+ describe '.capture_exception' do
25
+ let(:message) { 'This is a message' }
26
+ let(:exception) { Exception.new(message) }
27
+ let(:hash) { Opbeat::Event.capture_exception(exception).to_hash }
28
+
29
+ context 'for an Exception' do
30
+ it 'returns an event' do
31
+ expect(Opbeat::Event.capture_exception(exception)).to be_a(Opbeat::Event)
32
+ end
33
+
34
+ it "sets the message to the exception's message and type" do
35
+ expect(hash['message']).to eq("Exception: #{message}")
36
+ end
37
+
38
+ it 'has level ERROR' do
39
+ expect(hash['level']).to eq('error')
40
+ end
41
+
42
+ it 'uses the exception class name as the exception type' do
43
+ expect(hash['exception']['type']).to eq('Exception')
44
+ end
45
+
46
+ it 'uses the exception message as the exception value' do
47
+ expect(hash['exception']['value']).to eq(message)
48
+ end
49
+
50
+ it 'does not belong to a module' do
51
+ expect(hash['exception']['module']).to eq('')
52
+ end
53
+ end
54
+
55
+ context 'for a nested exception type' do
56
+ module Opbeat::Test
57
+ class Exception < Exception; end
58
+ end
59
+ let(:exception) { Opbeat::Test::Exception.new(message) }
60
+
61
+ it 'sends the module name as part of the exception info' do
62
+ expect(hash['exception']['module']).to eq('Opbeat::Test')
63
+ end
64
+ end
65
+
66
+ context 'for a Opbeat::Error' do
67
+ let(:exception) { Opbeat::Error.new }
68
+ it 'does not create an event' do
69
+ expect(Opbeat::Event.capture_exception(exception)).to be_nil
70
+ end
71
+ end
72
+
73
+ context 'when the exception has a backtrace' do
74
+ let(:exception) do
75
+ e = Exception.new(message)
76
+ allow(e).to receive(:backtrace).and_return([
77
+ "/path/to/some/file:22:in `function_name'",
78
+ "/some/other/path:1412:in `other_function'",
79
+ ])
80
+ e
81
+ end
82
+
83
+ it 'parses the backtrace' do
84
+ expect(hash['stacktrace']['frames'].length).to eq(2)
85
+ expect(hash['stacktrace']['frames'][0]['lineno']).to eq(1412)
86
+ expect(hash['stacktrace']['frames'][0]['function']).to eq('other_function')
87
+ expect(hash['stacktrace']['frames'][0]['filename']).to eq('/some/other/path')
88
+
89
+ expect(hash['stacktrace']['frames'][1]['lineno']).to eq(22)
90
+ expect(hash['stacktrace']['frames'][1]['function']).to eq('function_name')
91
+ expect(hash['stacktrace']['frames'][1]['filename']).to eq('/path/to/some/file')
92
+ end
93
+
94
+ it "sets the culprit" do
95
+ expect(hash['culprit']).to eq("/some/other/path in other_function")
96
+ end
97
+
98
+ context 'when a path in the stack trace is on the laod path' do
99
+ before do
100
+ $LOAD_PATH << '/some'
101
+ end
102
+
103
+ after do
104
+ $LOAD_PATH.delete('/some')
105
+ end
106
+
107
+ it 'strips prefixes in the load path from frame filenames' do
108
+ expect(hash['stacktrace']['frames'][0]['filename']).to eq('other/path')
109
+ end
110
+ end
111
+ end
112
+
113
+ context 'when there is user context' do
114
+ it 'sends the context and is_authenticated' do
115
+ Opbeat::Event.set_context(:user => {:id => 99})
116
+ hash = Opbeat::Event.capture_exception(exception).to_hash
117
+ expect(hash['user']).to eq({:id => 99, :is_authenticated => true})
118
+ end
119
+ end
120
+
121
+ context 'when there is extra context' do
122
+ it 'sends the context and is_authenticated' do
123
+ extra_context = {:jobid => 99}
124
+ Opbeat::Event.set_context(:extra => extra_context)
125
+ hash = Opbeat::Event.capture_exception(exception).to_hash
126
+ expect(hash['extra']).to eq(extra_context)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,38 @@
1
+ require File::expand_path('../../../spec_helper', __FILE__)
2
+ require 'time'
3
+ require 'delayed_job'
4
+ require 'opbeat/integrations/delayed_job'
5
+
6
+ # turtles, all the way down
7
+ # trying too hard
8
+ require 'active_support/core_ext/time/calculations.rb'
9
+ load File.join(
10
+ Gem::Specification.find_by_name("delayed_job").gem_dir,
11
+ "spec", "delayed", "backend", "test.rb"
12
+ )
13
+
14
+
15
+ class Bomb
16
+ def blow_up ex
17
+ raise ex
18
+ end
19
+ end
20
+
21
+
22
+ Delayed::Worker.backend = Delayed::Backend::Test::Job
23
+
24
+ describe Delayed::Plugins::Opbeat do
25
+ it 'should call Opbeat::captureException on erronous jobs' do
26
+ test_exception = Exception.new("Test exception")
27
+ expect(Opbeat).to receive(:captureException).with(test_exception)
28
+
29
+ # Queue
30
+ bomb = Bomb.new
31
+ bomb.delay.blow_up test_exception
32
+
33
+ expect {
34
+ Delayed::Worker.new.work_off.should == [0, 1]
35
+ }.to raise_error(Exception)
36
+ end
37
+ end
38
+
@@ -0,0 +1,55 @@
1
+ require File::expand_path('../../spec_helper', __FILE__)
2
+ require 'opbeat'
3
+
4
+ describe Opbeat::Logger do
5
+ context 'without a backend logger' do
6
+ before do
7
+ allow(Opbeat.configuration).to receive(:logger) { nil }
8
+ end
9
+
10
+ it 'should not error' do
11
+ subject.fatal 'fatalmsg'
12
+ subject.error 'errormsg'
13
+ subject.warn 'warnmsg'
14
+ subject.info 'infomsg'
15
+ subject.debug 'debugmsg'
16
+ end
17
+ end
18
+
19
+ context 'with a backend logger' do
20
+ before do
21
+ @logger = double('logger')
22
+ allow(Opbeat.configuration).to receive(:logger) { @logger }
23
+ end
24
+
25
+ it 'should log fatal messages' do
26
+ expect(@logger).to receive(:fatal).with('** [Opbeat] fatalmsg')
27
+ subject.fatal 'fatalmsg'
28
+ end
29
+
30
+ it 'should log error messages' do
31
+ expect(@logger).to receive(:error).with('** [Opbeat] errormsg')
32
+ subject.error 'errormsg'
33
+ end
34
+
35
+ it 'should log warning messages' do
36
+ expect(@logger).to receive(:warn).with('** [Opbeat] warnmsg')
37
+ subject.warn 'warnmsg'
38
+ end
39
+
40
+ it 'should log info messages' do
41
+ expect(@logger).to receive(:info).with('** [Opbeat] infomsg')
42
+ subject.info 'infomsg'
43
+ end
44
+
45
+ it 'should log debug messages' do
46
+ expect(@logger).to receive(:debug).with('** [Opbeat] debugmsg')
47
+ subject.debug 'debugmsg'
48
+ end
49
+
50
+ it 'should log messages from blocks' do
51
+ expect(@logger).to receive(:info).with('** [Opbeat] infoblock')
52
+ subject.info { 'infoblock' }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,39 @@
1
+ require File::expand_path('../../spec_helper', __FILE__)
2
+ require 'opbeat'
3
+
4
+ describe Opbeat do
5
+ before do
6
+ @send = double("send")
7
+ @event = double("event")
8
+ allow(Opbeat).to receive(:send) { @send }
9
+ allow(Opbeat::Event).to receive(:capture_message) { @event }
10
+ allow(Opbeat::Event).to receive(:capture_exception) { @event }
11
+ end
12
+
13
+ it 'captureMessage should send result of Event.capture_message' do
14
+ message = "Test message"
15
+ expect(Opbeat::Event).to receive(:capture_message).with(message, {})
16
+ expect(Opbeat).to receive(:send).with(@event)
17
+
18
+ Opbeat.captureMessage(message)
19
+ end
20
+
21
+ it 'captureMessage with options should send result of Event.capture_message' do
22
+ message = "Test message"
23
+ options = {:extra => {:hello => "world"}}
24
+ expect(Opbeat::Event).to receive(:capture_message).with(message, options)
25
+ expect(Opbeat).to receive(:send).with(@event)
26
+
27
+ Opbeat.captureMessage(message, options)
28
+ end
29
+
30
+ it 'captureException should send result of Event.capture_exception' do
31
+ exception = build_exception()
32
+
33
+ expect(Opbeat::Event).to receive(:capture_exception).with(exception, {})
34
+ expect(Opbeat).to receive(:send).with(@event)
35
+
36
+ Opbeat.captureException(exception)
37
+ end
38
+
39
+ end
@@ -0,0 +1,117 @@
1
+ require File::expand_path('../../spec_helper', __FILE__)
2
+
3
+ require 'opbeat'
4
+ require 'opbeat/interfaces'
5
+
6
+ class User
7
+ attr_accessor :id, :email, :username
8
+ end
9
+
10
+
11
+ class TestController
12
+ def current_user
13
+ test_user = User.new
14
+ test_user.id = 99
15
+ test_user.email = "ron@opbeat.com"
16
+ test_user.username = "roncohen"
17
+
18
+ return test_user
19
+ end
20
+
21
+ def custom_user
22
+ test_user = User.new
23
+ test_user.id = 999
24
+ test_user.email = "custom@opbeat.com"
25
+ test_user.username = "custom"
26
+
27
+ return test_user
28
+ end
29
+ end
30
+
31
+
32
+
33
+ describe Opbeat::Rack do
34
+ before do
35
+ @send = double("send")
36
+ @event = double("event")
37
+ allow(Opbeat).to receive(:send) { @send }
38
+ allow(Opbeat::Event).to receive(:capture_rack_exception) { @event }
39
+ end
40
+
41
+ it 'should capture exceptions' do
42
+ exception = build_exception()
43
+ env = {}
44
+
45
+ expect(Opbeat::Event).to receive(:capture_rack_exception).with(exception, env)
46
+ expect(Opbeat).to receive(:send).with(@event)
47
+
48
+ app = lambda do |e|
49
+ raise exception
50
+ end
51
+
52
+ stack = Opbeat::Rack.new(app)
53
+ expect(lambda {stack.call(env)}).to raise_error(exception)
54
+ end
55
+
56
+ it 'should capture rack.exception' do
57
+ exception = build_exception()
58
+ env = {}
59
+
60
+ expect(Opbeat::Event).to receive(:capture_rack_exception).with(exception, env)
61
+ expect(Opbeat).to receive(:send).with(@event)
62
+
63
+ app = lambda do |e|
64
+ e['rack.exception'] = exception
65
+ [200, {}, ['okay']]
66
+ end
67
+
68
+ stack = Opbeat::Rack.new(app)
69
+
70
+ stack.call(env)
71
+ end
72
+ end
73
+
74
+
75
+ describe Opbeat::Rack do
76
+ before do
77
+ @exception = build_exception()
78
+ @env = {
79
+ 'action_controller.instance' => TestController.new
80
+ }
81
+ allow(Opbeat::HttpInterface).to receive(:new) { Opbeat::Interface.new }
82
+ end
83
+
84
+ it 'should extract user info' do
85
+ expected_user = TestController.new.current_user
86
+
87
+ Opbeat::Event.capture_rack_exception(@exception, @env) do |event|
88
+ user = event.to_hash['user']
89
+ expect(user[:id]).to eq(expected_user.id)
90
+ expect(user[:email]).to eq(expected_user.email)
91
+ expect(user[:username]).to eq(expected_user.username)
92
+ expect(user[:is_authenticated]).to eq(true)
93
+ end
94
+ end
95
+
96
+ it 'should handle custom user method' do
97
+ Opbeat.configuration.user_controller_method = :custom_user
98
+ expected_user = TestController.new.custom_user
99
+
100
+ Opbeat::Event.capture_rack_exception(@exception, @env) do |event|
101
+ user = event.to_hash['user']
102
+ expect(user[:id]).to eq(expected_user.id)
103
+ expect(user[:email]).to eq(expected_user.email)
104
+ expect(user[:username]).to eq(expected_user.username)
105
+ expect(user[:is_authenticated]).to eq(true)
106
+ end
107
+ end
108
+
109
+ it 'should handle missing user method' do
110
+ Opbeat.configuration.user_controller_method = :missing_user_method
111
+ expected_user = TestController.new.custom_user
112
+
113
+ Opbeat::Event.capture_rack_exception(@exception, @env) do |event|
114
+ expect(event.user).to eq(nil)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,42 @@
1
+ require File::expand_path('../../spec_helper', __FILE__)
2
+ require 'opbeat/processors/sanitizedata'
3
+
4
+ describe Opbeat::Processor::SanitizeData do
5
+ before do
6
+ @client = double("client")
7
+ @processor = Opbeat::Processor::SanitizeData.new(@client)
8
+ end
9
+
10
+ it 'should filter http data' do
11
+ data = {
12
+ 'http' => {
13
+ 'data' => {
14
+ 'foo' => 'bar',
15
+ 'password' => 'hello',
16
+ 'the_secret' => 'hello',
17
+ 'a_password_here' => 'hello',
18
+ 'mypasswd' => 'hello',
19
+ }
20
+ }
21
+ }
22
+
23
+ result = @processor.process(data)
24
+
25
+ vars = result["http"]["data"]
26
+ expect(vars["foo"]).to eq("bar")
27
+ expect(vars["password"]).to eq(Opbeat::Processor::SanitizeData::MASK)
28
+ expect(vars["the_secret"]).to eq(Opbeat::Processor::SanitizeData::MASK)
29
+ expect(vars["a_password_here"]).to eq(Opbeat::Processor::SanitizeData::MASK)
30
+ expect(vars["mypasswd"]).to eq(Opbeat::Processor::SanitizeData::MASK)
31
+ end
32
+
33
+ it 'should filter credit card values' do
34
+ data = {
35
+ 'ccnumba' => '4242424242424242'
36
+ }
37
+
38
+ result = @processor.process(data)
39
+ expect(result["ccnumba"]).to eq(Opbeat::Processor::SanitizeData::MASK)
40
+ end
41
+
42
+ end
@@ -0,0 +1,10 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ def build_exception()
5
+ begin
6
+ 1 / 0
7
+ rescue ZeroDivisionError => exception
8
+ return exception
9
+ end
10
+ end