chillout 0.2.0

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,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