chillout 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+
3
+ class DispatcherTest < ChilloutTestCase
4
+
5
+ def test_error_dispatch
6
+ exception = build_exception(NameError)
7
+ env = {
8
+ "HTTP_USER_AGENT" => "Mozzila/4.0",
9
+ "rack.session" => {}
10
+ }
11
+ error = Chillout::Error.new(exception, env)
12
+
13
+ filter = mock("Filter")
14
+ filter.expects(:deliver_error?).with(error).returns(true)
15
+
16
+ server_side = mock("ServerSide")
17
+ server_side.expects(:send_error).with(error)
18
+
19
+ dispatcher = Chillout::Dispatcher.new(filter, server_side)
20
+ dispatcher.dispatch_error(error)
21
+ end
22
+
23
+ def test_ignored_error_dispatch
24
+ exception = build_exception(NameError)
25
+ env = {
26
+ "HTTP_USER_AGENT" => "Mozzila/4.0",
27
+ "rack.session" => {}
28
+ }
29
+ error = Chillout::Error.new(exception, env)
30
+
31
+ filter = mock("Filter")
32
+ filter.expects(:deliver_error?).with(error).returns(false)
33
+
34
+ server_side = mock("ServerSide")
35
+
36
+ dispatcher = Chillout::Dispatcher.new(filter, server_side)
37
+ dispatcher.dispatch_error(error)
38
+ end
39
+
40
+ def test_send_error_ignore_not_sent_exception
41
+ server_side = stub()
42
+ server_side.stubs(:send_error).raises(Chillout::HttpClient::NotSent.new(:http_error))
43
+
44
+ dispatcher = Chillout::Dispatcher.new(mock, server_side)
45
+
46
+ assert_nil dispatcher.send_error(:error)
47
+ end
48
+
49
+ def test_send_creations
50
+ filter = mock("Filter")
51
+
52
+ server_side = mock("ServerSide")
53
+ server_side.expects(:send_creations).with(:creations)
54
+
55
+ dispatcher = Chillout::Dispatcher.new(filter, server_side)
56
+ dispatcher.send_creations(:creations)
57
+ end
58
+
59
+ def test_send_creations_ignore_not_sent_exception
60
+ server_side = stub()
61
+ server_side.stubs(:send_creations).raises(Chillout::HttpClient::NotSent.new(:http_error))
62
+
63
+ dispatcher = Chillout::Dispatcher.new(mock, server_side)
64
+
65
+ assert_nil dispatcher.send_creations(:creations)
66
+ end
67
+
68
+ end
@@ -0,0 +1,115 @@
1
+ require 'test_helper'
2
+
3
+ class ErrorTest < ChilloutTestCase
4
+
5
+ def setup
6
+ @exception = build_exception(ArgumentError)
7
+ @env = { 'charset' => 'utf-8' }
8
+ @error = Chillout::Error.new(@exception, @env)
9
+ end
10
+
11
+ def test_exception_class
12
+ assert_equal "ArgumentError", @error.exception_class
13
+ end
14
+
15
+ def test_backtrace
16
+ assert_kind_of Array, @error.backtrace
17
+ end
18
+
19
+ def test_file
20
+ file = File.expand_path('../test_helper.rb', __FILE__)
21
+ assert_equal file, @error.file
22
+ end
23
+
24
+ context "controller is not given" do
25
+
26
+ def test_controller_name
27
+ assert_nil @error.controller_name
28
+ end
29
+
30
+ def test_controller_action
31
+ assert_nil @error.controller_action
32
+ end
33
+
34
+ end
35
+
36
+ context "controller is given" do
37
+
38
+ setup do
39
+ @controller = mock("controller")
40
+ @env['action_controller.instance'] = @controller
41
+ end
42
+
43
+ def test_controller_action_when_controller_is_set
44
+ @controller.expects(:action_name).returns("index")
45
+ assert_equal "index", @error.controller_action
46
+ end
47
+
48
+ def test_controller_name_when_controller_is_set
49
+ @controller.expects(:controller_name).returns("ApplicationController")
50
+ assert_equal "ApplicationController", @error.controller_name
51
+ end
52
+
53
+ end
54
+
55
+ context "current user is not given" do
56
+
57
+ def test_current_user_id
58
+ assert_nil @error.current_user_id
59
+ end
60
+
61
+ def test_current_user_email
62
+ assert_nil @error.current_user_email
63
+ end
64
+
65
+ def test_current_user_full_name
66
+ assert_nil @error.current_user_full_name
67
+ end
68
+
69
+ end
70
+
71
+ context "current user is given" do
72
+
73
+ setup do
74
+ @user = mock("user")
75
+ @env['current_user'] = @user
76
+ end
77
+
78
+ def test_current_user_id
79
+ @user.expects(:id).returns(123)
80
+ assert_equal 123, @error.current_user_id
81
+ end
82
+
83
+ def test_current_user_email
84
+ @user.expects(:email).returns("john@example.net")
85
+ assert_equal "john@example.net", @error.current_user_email
86
+ end
87
+
88
+ def test_current_user_full_name
89
+ @user.expects(:full_name).returns("john doe")
90
+ assert_equal "john doe", @error.current_user_full_name
91
+ end
92
+ end
93
+
94
+ context "current user is given but does not respond to expected methods" do
95
+
96
+ setup do
97
+ @user = mock("user")
98
+ @env['current_user'] = @user
99
+ end
100
+
101
+ def test_current_user_id
102
+ assert_nil @error.current_user_id
103
+ end
104
+
105
+ def test_current_user_email
106
+ assert_nil @error.current_user_email
107
+ end
108
+
109
+ def test_current_user_full_name
110
+ assert_nil @error.current_user_full_name
111
+ end
112
+
113
+ end
114
+
115
+ end
@@ -0,0 +1,190 @@
1
+ require 'test_helper'
2
+ require 'chillout/event_data_builder'
3
+ require 'chillout/creations_container'
4
+
5
+ module Chillout
6
+ class EventDataBuilderTest < ChilloutTestCase
7
+ setup do
8
+ @shell_env = { 'PATH' => '/bin:/usr/bin' }
9
+ @api_key = "s3cr3t"
10
+
11
+ @config = Config.new(@api_key)
12
+ @config.shell_environment = @shell_env
13
+ @config.platform = "rails"
14
+ @config.environment = "development"
15
+ @config.notifier_name = "chillout"
16
+ @config.version = "0.1"
17
+ @config.notifier_url = "http://github.com/arkency/chillout"
18
+
19
+ @timestamp = Time.now.iso8601
20
+ end
21
+
22
+ context "build from error" do
23
+ setup do
24
+ @event_data_builder = EventDataBuilder.new(@config)
25
+
26
+ @controller = mock("Controller")
27
+ @controller.stubs(:controller_name).returns("UsersController")
28
+ @controller.stubs(:action_name).returns("index")
29
+
30
+ @current_user = mock("User")
31
+ @current_user.stubs(:id).returns(123)
32
+ @current_user.stubs(:email).returns("john@example.com")
33
+ @current_user.stubs(:full_name).returns("john doe")
34
+
35
+ @exception = build_exception(NameError, "FooBar does not exists")
36
+ @env = {
37
+ 'HTTP_USER_AGENT' => 'Mozilla/4.0',
38
+ 'action_controller.instance' => @controller,
39
+ 'current_user' => @current_user
40
+ }
41
+ @error = Chillout::Error.new(@exception, @env)
42
+ @event_data = @event_data_builder.build_from_error(@error, @timestamp)
43
+ end
44
+
45
+ def test_event_type
46
+ assert_param :event, 'exception'
47
+ end
48
+
49
+ def test_timestamp
50
+ assert_param :timestamp, @timestamp
51
+ end
52
+
53
+ def test_exception_class
54
+ assert_content :class, 'NameError'
55
+ end
56
+
57
+ def test_exception_message
58
+ assert_content :message, 'FooBar does not exists'
59
+ end
60
+
61
+ def test_backtrace
62
+ assert_content :backtrace, @exception.backtrace
63
+ end
64
+
65
+ def test_file
66
+ assert_content :file, @error.file
67
+ end
68
+
69
+ def test_environment
70
+ assert_content :environment, "development"
71
+ end
72
+
73
+ def test_platform
74
+ assert_context :platform, "rails"
75
+ end
76
+
77
+ def test_controller
78
+ assert_context :controller, "UsersController"
79
+ end
80
+
81
+ def test_action
82
+ assert_context :controller, "UsersController"
83
+ end
84
+
85
+ def test_current_user_id
86
+ assert_current_user :id, 123
87
+ end
88
+
89
+ def test_current_user_email
90
+ assert_current_user :email, "john@example.com"
91
+ end
92
+
93
+ def test_current_user_full_name
94
+ assert_current_user :full_name, "john doe"
95
+ end
96
+
97
+ def test_rack_environment
98
+ expected_value = Hash[@env.collect { |k,v| [k, v.to_s] }]
99
+ assert_content :rack_environment, expected_value
100
+ end
101
+
102
+ def test_shell_environment
103
+ assert_content :shell_environment, @shell_env
104
+ end
105
+
106
+ def test_notifier_name
107
+ assert_notifier :name, "chillout"
108
+ end
109
+
110
+ def test_notifier_version
111
+ assert_notifier :version, "0.1"
112
+ end
113
+
114
+ def test_notifier_url
115
+ assert_notifier :url, "http://github.com/arkency/chillout"
116
+ end
117
+ end
118
+
119
+ context "build from creations container" do
120
+ setup do
121
+ @creations_container = CreationsContainer.new
122
+ 5.times { @creations_container.increment!("User") }
123
+ 3.times { @creations_container.increment!("Cart") }
124
+ 8.times { @creations_container.increment!("CartItem") }
125
+
126
+ @event_data_builder = EventDataBuilder.new(@config)
127
+ @event_data = @event_data_builder.build_from_creations_container(@creations_container, @timestamp)
128
+ end
129
+
130
+ def test_metric_type
131
+ assert_param :metric, "creations"
132
+ end
133
+
134
+ def test_timestamp
135
+ assert_param :timestamp, @timestamp
136
+ end
137
+
138
+ def test_each_counter
139
+ assert_creations :User, 5
140
+ assert_creations :Cart, 3
141
+ assert_creations :CartItem, 8
142
+ end
143
+
144
+ def test_environment
145
+ assert_content :environment, "development"
146
+ end
147
+
148
+ def test_notifier_name
149
+ assert_notifier :name, "chillout"
150
+ end
151
+
152
+ def test_notifier_version
153
+ assert_notifier :version, "0.1"
154
+ end
155
+
156
+ def test_notifier_url
157
+ assert_notifier :url, "http://github.com/arkency/chillout"
158
+ end
159
+ end
160
+
161
+ private
162
+ def event_data
163
+ @event_data
164
+ end
165
+
166
+ def assert_param(key, value)
167
+ assert_equal value, event_data[key]
168
+ end
169
+
170
+ def assert_content(key, value)
171
+ assert_equal value, event_data[:content][key]
172
+ end
173
+
174
+ def assert_context(key, value)
175
+ assert_equal value, event_data[:content][:context][key]
176
+ end
177
+
178
+ def assert_creations(key, value)
179
+ assert_equal value, event_data[:content][:creations][key]
180
+ end
181
+
182
+ def assert_current_user(key, value)
183
+ assert_equal value, event_data[:content][:context][:current_user][key]
184
+ end
185
+
186
+ def assert_notifier(key, value)
187
+ assert_equal value, event_data[:notifier][key]
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ module Chillout
4
+ class HttpClientTest < ChilloutTestCase
5
+ def test_post_raises_not_sent_exception_when_get_any_error
6
+ logger = stub(error: nil)
7
+ http_client = HttpClient.new(:wrong_config, logger)
8
+ assert_raises HttpClient::NotSent do
9
+ http_client.post("/events", {fake_data: "client"})
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+ require 'chillout/creations_container'
3
+
4
+ module Chillout
5
+ class CreationsMonitorRackTest < ChilloutTestCase
6
+ include Rack::Test::Methods
7
+
8
+ def setup
9
+ api_key = "xyz123"
10
+ stub_api_request(api_key, "metrics")
11
+ @config = Chillout::Config.new(api_key)
12
+ @config.ssl = false
13
+ @client = Chillout::Client.new(@config)
14
+ end
15
+
16
+ def app
17
+ client = @client
18
+ deepest_level = lambda do |env|
19
+ Thread.current[:creations] = CreationsContainer.new
20
+ 2.times { Thread.current[:creations].increment!("User") }
21
+ 3.times { Thread.current[:creations].increment!("Cart") }
22
+ [200, env, ['hello']]
23
+ end
24
+ Rack::Builder.new do
25
+ use Middleware::CreationsMonitor, client
26
+ run(deepest_level)
27
+ end
28
+ end
29
+
30
+ def test_creations_values
31
+ get "/"
32
+ assert_equal 2, request_body["content"]["creations"]["User"]
33
+ assert_equal 3, request_body["content"]["creations"]["Cart"]
34
+ end
35
+
36
+ private
37
+ def request_body
38
+ assert_request_body("metrics") { |body| return body }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptionMonitorRackTest < ChilloutTestCase
4
+ include Rack::Test::Methods
5
+
6
+ def setup
7
+ api_key = "xyz123"
8
+ stub_api_request(api_key, "events")
9
+ @config = Chillout::Config.new(api_key)
10
+ @config.ssl = false
11
+ @client = Chillout::Client.new(@config)
12
+ end
13
+
14
+ def app
15
+ client = @client # Only local variable can be passed to the block below
16
+ Rack::Builder.new do
17
+ use Chillout::Middleware::ExceptionMonitor, client
18
+ run(lambda { |env| raise ChilloutTestException.new("Something went wrong") })
19
+ end
20
+ end
21
+
22
+ def test_exception_class
23
+ trigger_error
24
+ assert_equal "ChilloutTestException", request_body["content"]["class"]
25
+ end
26
+
27
+ def test_exception_message
28
+ trigger_error
29
+ assert_equal "Something went wrong", request_body["content"]["message"]
30
+ end
31
+
32
+ def test_rack_environment
33
+ trigger_error
34
+ assert_request_body "events" do |body|
35
+ assert_equal last_request.env.keys, body["content"]["rack_environment"].keys
36
+ end
37
+ end
38
+
39
+ private
40
+ def trigger_error
41
+ begin
42
+ get "/"
43
+ rescue ChilloutTestException
44
+ end
45
+ end
46
+
47
+ def request_body
48
+ assert_request_body("events"){ |body| return body }
49
+ end
50
+
51
+ end
@@ -0,0 +1,66 @@
1
+ require 'test_helper'
2
+ require 'webmock/minitest'
3
+
4
+ class StandaloneClientTest < ChilloutTestCase
5
+
6
+ def setup
7
+ api_key = "xyz123"
8
+ stub_api_request(api_key, "events")
9
+ config = Chillout::Config.new(api_key)
10
+ config.ssl = false
11
+ @client = Chillout::Client.new(config)
12
+ @error = build_error(NameError, "FooBar is not defined")
13
+ end
14
+
15
+ def test_request_headers_contain_content_type
16
+ send_error
17
+ assert_request_headers 'events', 'Content-Type' => 'application/vnd.chillout.v1+json'
18
+ end
19
+
20
+ def test_request_body_contains_exception_class
21
+ send_error
22
+ assert_equal "NameError", request_body["content"]["class"]
23
+ end
24
+
25
+ def test_request_body_contains_exception_message
26
+ send_error
27
+ assert_equal "FooBar is not defined", request_body["content"]["message"]
28
+ end
29
+
30
+ def test_request_body_contains_event_type
31
+ send_error
32
+ assert_equal "exception", request_body["event"]
33
+ end
34
+
35
+ def test_request_body_contains_shell_environment
36
+ send_error
37
+ assert_equal ENV.to_hash, request_body["content"]["shell_environment"]
38
+ end
39
+
40
+ def test_request_body_contains_notifier_name
41
+ send_error
42
+ assert_equal "Chillout", request_body["notifier"]["name"]
43
+ end
44
+
45
+ def test_request_body_contains_notifier_version
46
+ send_error
47
+ assert_equal Chillout::VERSION, request_body["notifier"]["version"]
48
+ end
49
+
50
+ def test_allows_to_send_exceptions
51
+ exception = build_exception(ArgumentError, "wrong number of arguments")
52
+ @client.send_exception(exception)
53
+ assert_equal "ArgumentError", request_body["content"]["class"]
54
+ assert_equal "wrong number of arguments", request_body["content"]["message"]
55
+ end
56
+
57
+ private
58
+ def send_error
59
+ @client.send_error(@error)
60
+ end
61
+
62
+ def request_body
63
+ assert_request_body("events") { |body| return body }
64
+ end
65
+
66
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ module Chillout
4
+ module Middleware
5
+ class CreationsMonitorTest < ChilloutTestCase
6
+ setup do
7
+ @env = { 'HOST' => 'example.net' }
8
+ @client = mock()
9
+ end
10
+
11
+ context "for call with model creation" do
12
+ setup do
13
+ @app = lambda do |env|
14
+ Thread.current[:creations] = :creations
15
+ [200, env, ['hello']]
16
+ end
17
+ @middleware = CreationsMonitor.new(@app, @client)
18
+ end
19
+
20
+ def test_behaves_like_rack_middleware
21
+ @client.stubs(:send_creations)
22
+ response = @middleware.call(@env)
23
+
24
+ assert_equal [200, @env, ['hello']], response
25
+ end
26
+
27
+ def test_dispatch_creations_from_thread_current
28
+ @client.expects(:send_creations).with(:creations)
29
+
30
+ @middleware.call(@env)
31
+ end
32
+ end
33
+
34
+ context "for call without model creation" do
35
+ setup do
36
+ @app = lambda do |env|
37
+ [200, env, ['hello']]
38
+ end
39
+ @middleware = CreationsMonitor.new(@app, @client)
40
+ end
41
+
42
+ def test_behaves_like_rack_middleware
43
+ response = @middleware.call(@env)
44
+
45
+ assert_equal [200, @env, ['hello']], response
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,54 @@
1
+ require 'test_helper'
2
+
3
+ module Chillout
4
+ module Middleware
5
+ class ExceptionMonitorTest < ChilloutTestCase
6
+
7
+ class DummyError < StandardError; end
8
+
9
+ def test_behaves_like_rack_middleware
10
+ env = { 'HOST' => 'example.net' }
11
+ app = lambda { |env| [200, env, ['hello']] }
12
+ middleware = ExceptionMonitor.new(app, mock)
13
+
14
+ response = middleware.call(env)
15
+
16
+ assert_equal [200, env, ['hello']], response
17
+ end
18
+
19
+ def test_exception_is_raised
20
+ exception = build_exception(DummyError)
21
+ env = { 'HOST' => 'example.net' }
22
+ app = lambda do |env|
23
+ raise exception
24
+ end
25
+ dispatcher = mock("Dispatcher")
26
+ dispatcher.expects(:dispatch_error).with do |error|
27
+ error.exception == exception && error.environment == env
28
+ end
29
+
30
+ middleware = ExceptionMonitor.new(app, dispatcher)
31
+ assert_raises DummyError do
32
+ middleware.call(env)
33
+ end
34
+ end
35
+
36
+ def test_exception_is_found_in_rack_environment
37
+ exception = build_exception(DummyError)
38
+ env = { 'HOST' => 'example.net' }
39
+ app = lambda do |env|
40
+ env['rack.exception'] = exception
41
+ [200, env, ['hello']]
42
+ end
43
+ dispatcher = mock("Dispatcher")
44
+ dispatcher.expects(:dispatch_error).with do |error|
45
+ error.exception == exception && error.environment == env
46
+ end
47
+
48
+ middleware = ExceptionMonitor.new(app, dispatcher)
49
+ middleware.call(env)
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ module Chillout
4
+ class PrefixedLoggerTest < ChilloutTestCase
5
+ def test_error_message_is_prefixed
6
+ output = StringIO.new
7
+ logger = Logger.new(output)
8
+ prefixed_logger = PrefixedLogger.new("[Chillout]", logger)
9
+ prefixed_logger.error "Someone is wrong on the internet"
10
+ assert_includes output.string, "[Chillout] Someone is wrong on the internet"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+ require 'time'
3
+
4
+ class ServerSideTest < ChilloutTestCase
5
+
6
+ def setup
7
+ @event_data_builder = mock("EventDataBuilder")
8
+ @http_client = mock("HttpClient")
9
+ @server_side = Chillout::ServerSide.new(@event_data_builder, @http_client)
10
+ end
11
+
12
+ def test_send_error_use_event_data_builder
13
+ @event_data_builder.expects(:build_from_error).with(:error, anything).returns(:event_data_from_builder)
14
+ @http_client.stubs(:post)
15
+ @server_side.send_error(:error)
16
+ end
17
+
18
+ def test_send_error_use_http_client
19
+ @event_data_builder.stubs(:build_from_error).returns(:event_data_from_builder)
20
+ @http_client.expects(:post).with('/events', :event_data_from_builder)
21
+ @server_side.send_error(:error)
22
+ end
23
+
24
+ def test_send_creations_use_event_data_builder
25
+ @event_data_builder.expects(:build_from_creations_container).with(:creations_container, anything).returns(:event_data_from_builder)
26
+ @http_client.stubs(:post)
27
+ @server_side.send_creations(:creations_container)
28
+ end
29
+
30
+ def test_send_creations_use_http_client
31
+ @event_data_builder.stubs(:build_from_creations_container).returns(:event_data_from_builder)
32
+ @http_client.expects(:post).with('/metrics', :event_data_from_builder)
33
+ @server_side.send_creations(:creations_container)
34
+ end
35
+ end