peastash 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +129 -0
- data/README.md +183 -0
- data/Rakefile +17 -0
- data/lib/peastash/middleware.rb +37 -0
- data/lib/peastash/outputs/io.rb +21 -0
- data/lib/peastash/rails_ext/railtie.rb +30 -0
- data/lib/peastash/rails_ext/watch.rb +15 -0
- data/lib/peastash/rails_ext.rb +2 -0
- data/lib/peastash/version.rb +3 -0
- data/lib/peastash.rb +120 -0
- data/peastash.gemspec +31 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/welcome_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +28 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +34 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +40 -0
- data/spec/dummy/config/environments/test_with_specific_position.rb +41 -0
- data/spec/dummy/config/environments/test_without_buchestache.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/peastash/middleware_spec.rb +144 -0
- data/spec/peastash/rails_ext/railtie_spec.rb +92 -0
- data/spec/peastash/rails_ext/watch_spec.rb +24 -0
- data/spec/peastash_spec.rb +213 -0
- data/spec/spec_helper.rb +31 -0
- metadata +289 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'peastash/middleware'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
describe Peastash::Middleware do
|
6
|
+
before do
|
7
|
+
Peastash.any_instance.stub(:enabled?) { true }
|
8
|
+
end
|
9
|
+
let(:app) { ->(env) { [200, {}, "app"] } }
|
10
|
+
let(:before_block) { ->(env, response) {} }
|
11
|
+
let(:after_block) { ->(env, response) {} }
|
12
|
+
|
13
|
+
let(:middleware) do
|
14
|
+
Peastash::Middleware.new(app, before_block, after_block)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "Rack middleware" do
|
18
|
+
it "wraps the call to the next middleware in a Peastash block" do
|
19
|
+
expect(Peastash.with_instance).to receive(:log)
|
20
|
+
middleware.call env_for('/')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "doesn't interrupt the middleware chain" do
|
24
|
+
expect(app).to receive(:call).and_call_original
|
25
|
+
middleware.call env_for('/')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "calls whatever block is given to the middleware" do
|
29
|
+
before_block = ->(env, response) { Peastash.with_instance.store[:before_block] = true }
|
30
|
+
after_block = ->(env, response) { Peastash.with_instance.store[:after_block] = true }
|
31
|
+
|
32
|
+
middleware = Peastash::Middleware.new(app, before_block, after_block)
|
33
|
+
code, env = middleware.call env_for('/')
|
34
|
+
expect(Peastash.with_instance.store[:before_block]).to be true
|
35
|
+
expect(Peastash.with_instance.store[:after_block]).to be true
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'storing data in the custom block' do
|
39
|
+
before :each do
|
40
|
+
block = ->(env, response) {
|
41
|
+
request = Rack::Request.new(env)
|
42
|
+
Peastash.with_instance.store[:path] = request.path
|
43
|
+
}
|
44
|
+
@middleware = Peastash::Middleware.new(app, block)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "can store arbitrary data in the Peastash store" do
|
48
|
+
@middleware.call env_for('/')
|
49
|
+
expect(Peastash.with_instance.store[:path]).to eq('/')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'uses the stored data to build the event' do
|
53
|
+
expect(LogStash::Event).to receive(:new).with({
|
54
|
+
'@source' => Peastash::STORE_NAME,
|
55
|
+
'@fields' => { path: '/', duration: 0, status: 200, ip: nil },
|
56
|
+
'@tags' => []
|
57
|
+
})
|
58
|
+
Timecop.freeze { @middleware.call env_for('/') }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'storing data in the rack app' do
|
63
|
+
before :each do
|
64
|
+
app = ->(env) do
|
65
|
+
request = Rack::Request.new(env)
|
66
|
+
Peastash.with_instance.store[:scheme] = request.scheme
|
67
|
+
[200, {}, "app"]
|
68
|
+
end
|
69
|
+
@middleware = Peastash::Middleware.new(app, before_block)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "can store arbitrary data in the Peastash store" do
|
73
|
+
@middleware.call env_for('/')
|
74
|
+
expect(Peastash.with_instance.store[:scheme]).to eq('http')
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'uses the stored data to build the event' do
|
78
|
+
expect(LogStash::Event).to receive(:new).with({
|
79
|
+
'@source' => Peastash::STORE_NAME,
|
80
|
+
'@fields' => { scheme: 'http', duration: 0, status: 200, ip: nil },
|
81
|
+
'@tags' => []
|
82
|
+
})
|
83
|
+
Timecop.freeze { @middleware.call env_for('/') }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'without a custom block' do
|
88
|
+
it "doesn't try to call the block" do
|
89
|
+
@middleware = Peastash::Middleware.new(app)
|
90
|
+
expect {
|
91
|
+
@middleware.call env_for('/')
|
92
|
+
}.to_not raise_error
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'persistence between before/after block' do
|
97
|
+
it "saves instance variables between before/after block" do
|
98
|
+
before_block = ->(env, request) { @foo = 'foo' }
|
99
|
+
after_block = ->(env, request) { Peastash.with_instance.store[:foo] = @foo }
|
100
|
+
@middleware = Peastash::Middleware.new(app, before_block, after_block)
|
101
|
+
|
102
|
+
expect(LogStash::Event).to receive(:new).with({
|
103
|
+
'@source' => Peastash::STORE_NAME,
|
104
|
+
'@fields' => { duration: 0, status: 200, foo: 'foo', ip: nil },
|
105
|
+
'@tags' => [],
|
106
|
+
})
|
107
|
+
Timecop.freeze { @middleware.call env_for('/') }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "exception in before / after block" do
|
112
|
+
before :each do
|
113
|
+
Peastash.safe!
|
114
|
+
before_block = ->(env, request) { 1 / 0 }
|
115
|
+
after_block = ->(env, request) { unknown_method }
|
116
|
+
@middleware = Peastash::Middleware.new(app, before_block, after_block)
|
117
|
+
STDERR.stub(:puts)
|
118
|
+
end
|
119
|
+
after(:each) { STDERR.unstub(:puts) }
|
120
|
+
|
121
|
+
it "doesn't interrupt the middleware flow, logging should be transparent" do
|
122
|
+
expect {
|
123
|
+
@middleware.call env_for('/')
|
124
|
+
}.to_not raise_error
|
125
|
+
end
|
126
|
+
|
127
|
+
it "puts the error to STDERR for easy debugging" do
|
128
|
+
expect(STDERR).to receive(:puts).twice
|
129
|
+
@middleware.call env_for('/')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "doesn't catch exception in the app" do
|
134
|
+
Peastash.safe!
|
135
|
+
app = ->(env) { raise }
|
136
|
+
@middleware = Peastash::Middleware.new(app)
|
137
|
+
expect {
|
138
|
+
@middleware.call env_for('/')
|
139
|
+
}.to raise_error
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rails'
|
3
|
+
require 'peastash/rails_ext'
|
4
|
+
require 'simplecov'
|
5
|
+
|
6
|
+
describe Peastash::Railtie do
|
7
|
+
context 'not configured' do
|
8
|
+
it "doesn't add the middleware by default" do
|
9
|
+
run_with_env 'test_without_peastash' do
|
10
|
+
expect(Rails.application.middleware).to_not include(Peastash::Middleware)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't add the subscriber" do
|
15
|
+
run_with_env 'test_without_peastash' do
|
16
|
+
Peastash.with_instance.store.clear
|
17
|
+
ActiveSupport::Notifications.instrument('process_action.action_controller', db_runtime: 1)
|
18
|
+
expect(Peastash.with_instance.store).to_not include(db: 1)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'correctly configured' do
|
24
|
+
context 'with specific conf' do
|
25
|
+
it 'places the middleware before the configured middleware if specified' do
|
26
|
+
run_with_env 'test_with_specific_position' do
|
27
|
+
cookies_index = -1
|
28
|
+
Rails.application.middleware.each_with_index { |middleware, index| cookies_index = index if middleware == ActionDispatch::Cookies }
|
29
|
+
expect(Rails.application.middleware[cookies_index - 1]).to eq(Peastash::Middleware)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with regular conf' do
|
35
|
+
before :all do
|
36
|
+
ENV['RAILS_ENV'] = 'test'
|
37
|
+
require 'dummy/config/environment'
|
38
|
+
end
|
39
|
+
|
40
|
+
before(:each) { Peastash.with_instance.store.clear }
|
41
|
+
|
42
|
+
context 'middleware' do
|
43
|
+
it "adds the middleware" do
|
44
|
+
expect(Rails.application.middleware).to include(Peastash::Middleware)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'adds the middleware before ActionDispatch::ShowExceptions by default' do
|
48
|
+
show_exceptions_index = -1
|
49
|
+
Rails.application.middleware.each_with_index { |middleware, index| show_exceptions_index = index if middleware == ActionDispatch::ShowExceptions }
|
50
|
+
expect(Rails.application.middleware[show_exceptions_index - 1]).to eq(Peastash::Middleware)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
it "adds a subscriber on 'process_action.action_controller' to gather metrics about the request" do
|
56
|
+
ActiveSupport::Notifications.instrument('process_action.action_controller', db_runtime: 1)
|
57
|
+
expect(Peastash.with_instance.store).to include(db: 1)
|
58
|
+
end
|
59
|
+
|
60
|
+
context "params logging" do
|
61
|
+
it "doesn't log the parameters if log_parameters isn't true" do
|
62
|
+
Peastash.with_instance.configuration[:log_parameters] = false
|
63
|
+
Rails.application.call env_for('/')
|
64
|
+
expect(Peastash.with_instance.store.keys).to_not include(:params)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "logs the parameters if log_parameters is true" do
|
68
|
+
Peastash.with_instance.configuration[:log_parameters] = true
|
69
|
+
Rails.application.call env_for('/')
|
70
|
+
expect(Peastash.with_instance.store.keys).to include(:params)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "doesn't log filtered parameters in clear text" do
|
74
|
+
Peastash.with_instance.configuration[:log_parameters] = true
|
75
|
+
Rails.application.call env_for('/?password=foo')
|
76
|
+
expect(Peastash.with_instance.store[:params]["password"]).to eq("[FILTERED]")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def run_with_env(env = 'test')
|
84
|
+
# Can't run those tests on jruby... yet
|
85
|
+
return if RUBY_PLATFORM == 'java'
|
86
|
+
fork do
|
87
|
+
SimpleCov.running = false
|
88
|
+
ENV['RAILS_ENV'] = env
|
89
|
+
require 'dummy/config/environment'
|
90
|
+
yield
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'peastash/rails_ext/watch'
|
3
|
+
|
4
|
+
describe "Peastash::Watch" do
|
5
|
+
it "adds the #watch method to Peastash" do
|
6
|
+
expect(Peastash.with_instance).to respond_to(:watch)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#watch" do
|
10
|
+
it "can subscribe to any notification" do
|
11
|
+
@dummy = Object.new.stub(:foo)
|
12
|
+
@subscriber = Peastash.with_instance.watch('foo.bar') { @dummy.foo }
|
13
|
+
expect(@dummy).to receive(:foo)
|
14
|
+
ActiveSupport::Notifications.instrument('foo.bar')
|
15
|
+
ActiveSupport::Notifications.unsubscribe(@subscriber)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is provided with a handy named store" do
|
19
|
+
Peastash.with_instance.watch('foo.bar') { |*event, store| store[:foo] = 'bar' }
|
20
|
+
@subscriber = ActiveSupport::Notifications.instrument('foo.bar')
|
21
|
+
expect(Peastash.with_instance.store['foo.bar']).to eq(foo: 'bar')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Peastash do
|
4
|
+
|
5
|
+
after(:each) { unconfigure_foostash! }
|
6
|
+
|
7
|
+
describe 'enabled' do
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
Peastash.any_instance.stub(:enabled?) { true }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "scoped instances" do
|
14
|
+
it 'always return the same instance for the same name' do
|
15
|
+
expect(Peastash.with_instance(:foo)).to be(Peastash.with_instance(:foo))
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns different instances for different names' do
|
19
|
+
expect(Peastash.with_instance(:bar)).to_not be(Peastash.with_instance(:foo))
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'uses `global` as the default instance name' do
|
23
|
+
expect(Peastash.with_instance(:global)).to be(Peastash.with_instance)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'inherits its configuration for the `global` conf' do
|
27
|
+
Peastash.with_instance(:global).configure!({source: :foo})
|
28
|
+
expect(Peastash.with_instance(:bar).configuration[:source]).to be(:foo)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#configure!" do
|
33
|
+
it 'allows setting tags to be added to every event' do
|
34
|
+
tags = ['foo', 'bar']
|
35
|
+
Peastash.with_instance.configure!(tags: tags)
|
36
|
+
expect(LogStash::Event).to receive(:new).with({
|
37
|
+
'@source' => Peastash::STORE_NAME,
|
38
|
+
'@fields' => {},
|
39
|
+
'@tags' => tags
|
40
|
+
})
|
41
|
+
Peastash.with_instance.log {}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can customize the source" do
|
45
|
+
Peastash.with_instance.configure!(source: 'foo')
|
46
|
+
expect(LogStash::Event).to receive(:new).with({
|
47
|
+
'@source' => 'foo',
|
48
|
+
'@fields' => {},
|
49
|
+
'@tags' => []
|
50
|
+
})
|
51
|
+
Peastash.with_instance.log {}
|
52
|
+
end
|
53
|
+
|
54
|
+
it "can customize the store name" do
|
55
|
+
Peastash.with_instance.configure!(store_name: :foo)
|
56
|
+
Peastash.with_instance.store[:bar] = 'bar'
|
57
|
+
expect(Thread.current[:global].keys).to include(:foo)
|
58
|
+
expect(Thread.current[:global][:foo]).to eq(bar: 'bar')
|
59
|
+
end
|
60
|
+
|
61
|
+
context "dump if empty?" do
|
62
|
+
it "can prevent logging if nothing is stored" do
|
63
|
+
Peastash.with_instance.configure!(dump_if_empty: false)
|
64
|
+
expect(Peastash.with_instance.instance_variable_get(:@output)).to_not receive(:dump)
|
65
|
+
Peastash.with_instance.log {}
|
66
|
+
end
|
67
|
+
|
68
|
+
it "doesn't prevent logging if set to true" do
|
69
|
+
Peastash.with_instance.configure!(dump_if_empty: true)
|
70
|
+
expect(Peastash.with_instance.instance_variable_get(:@output)).to receive(:dump)
|
71
|
+
Peastash.with_instance.log {}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#log" do
|
77
|
+
context "Peastash not configured" do
|
78
|
+
it "calls #configure! beforehand" do
|
79
|
+
expect(Peastash.with_instance).to receive(:configure!).once.and_call_original
|
80
|
+
Peastash.with_instance.log {}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "Peastash already configured" do
|
85
|
+
before { Peastash.with_instance.configure! }
|
86
|
+
|
87
|
+
it "doesn't call #configure!" do
|
88
|
+
expect(Peastash).to_not receive(:configure!)
|
89
|
+
Peastash.with_instance.log {}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "sends the event to the output" do
|
94
|
+
Peastash.with_instance.configure!
|
95
|
+
expect(Peastash.with_instance.instance_variable_get(:@output)).to receive(:dump)
|
96
|
+
Peastash.with_instance.log {}
|
97
|
+
end
|
98
|
+
|
99
|
+
it "clears the store beforehand" do
|
100
|
+
Peastash.with_instance.configure!
|
101
|
+
Peastash.with_instance.store[:foo] = 'bar'
|
102
|
+
Peastash.with_instance.log {}
|
103
|
+
expect(Peastash.with_instance.store.keys).to_not include(:foo)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "aggregates everything in the store and dumps it" do
|
107
|
+
Peastash.with_instance.configure!
|
108
|
+
Peastash.with_instance.log do
|
109
|
+
Peastash.with_instance.store[:foo] = ['foo']
|
110
|
+
Peastash.with_instance.store[:foo] << 'bar'
|
111
|
+
end
|
112
|
+
expect(Peastash.with_instance.store[:foo]).to eq(['foo', 'bar'])
|
113
|
+
end
|
114
|
+
|
115
|
+
it "merges the tags from the parameters with the base tags" do
|
116
|
+
base_tags = %w(foo bar)
|
117
|
+
tags = %w(baz)
|
118
|
+
Peastash.with_instance.configure!(tags: base_tags)
|
119
|
+
expect(LogStash::Event).to receive(:new).with({
|
120
|
+
'@source' => Peastash::STORE_NAME,
|
121
|
+
'@fields' => {},
|
122
|
+
'@tags' => base_tags + tags
|
123
|
+
})
|
124
|
+
Peastash.with_instance.log(tags) {}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe ".safely" do
|
129
|
+
context "when safe" do
|
130
|
+
before { Peastash.safe! }
|
131
|
+
|
132
|
+
it 'rescues errors silently' do
|
133
|
+
expect {
|
134
|
+
Peastash.safely { 1 / 0 }
|
135
|
+
}.not_to raise_error
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'returns value returned from the block' do
|
139
|
+
expect(Peastash.safely { "test" }).to eq("test")
|
140
|
+
end
|
141
|
+
|
142
|
+
it "puts the error to STDERR for easy debugging" do
|
143
|
+
expect(STDERR).to receive(:puts)
|
144
|
+
Peastash.safely { 1 / 0 }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "when unsafe" do
|
149
|
+
before { Peastash.unsafe! }
|
150
|
+
|
151
|
+
it 'doesn\'t rescue errors silently' do
|
152
|
+
expect {
|
153
|
+
Peastash.safely { 1 / 0 }
|
154
|
+
}.to raise_error(ZeroDivisionError)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "puts the error to STDERR for easy debugging" do
|
158
|
+
expect(STDERR).to receive(:puts)
|
159
|
+
|
160
|
+
expect {
|
161
|
+
Peastash.safely { 1 / 0 }
|
162
|
+
}.to raise_error(ZeroDivisionError)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "#tags" do
|
168
|
+
it "calls configure beforehand if instance isn't configured" do
|
169
|
+
expect(Peastash.with_instance).to receive(:configure!).and_call_original
|
170
|
+
Peastash.with_instance.tags << 'foo'
|
171
|
+
end
|
172
|
+
|
173
|
+
it "makes it possible to add tags from within the #log block" do
|
174
|
+
base_tags = %w(foo bar)
|
175
|
+
tags = %w(baz)
|
176
|
+
additional_tags = %w(qux)
|
177
|
+
Peastash.with_instance.configure!(tags: base_tags)
|
178
|
+
expect(LogStash::Event).to receive(:new).with({
|
179
|
+
'@source' => Peastash::STORE_NAME,
|
180
|
+
'@fields' => {},
|
181
|
+
'@tags' => base_tags + tags + additional_tags
|
182
|
+
})
|
183
|
+
Peastash.with_instance.log(tags) { Peastash.with_instance.tags.concat(additional_tags) }
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
describe 'disabled' do
|
190
|
+
|
191
|
+
it "can process the called stuff in the #log block" do
|
192
|
+
expect {
|
193
|
+
Peastash.with_instance.log do
|
194
|
+
raise
|
195
|
+
end
|
196
|
+
}.to raise_error
|
197
|
+
end
|
198
|
+
|
199
|
+
it "can process the called stuff in the #log block" do
|
200
|
+
expect { |b|
|
201
|
+
Peastash.with_instance.log(&b)
|
202
|
+
}.to yield_with_args(Peastash.with_instance)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "can process the called stuff for custom instance in the #log block" do
|
206
|
+
expect { |b|
|
207
|
+
Peastash.with_instance(:worker).log(&b)
|
208
|
+
}.to yield_with_args(Peastash.with_instance(:worker))
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
# ENV['RACK_ENV'] = 'test'
|
4
|
+
# ENV['RAILS_ENV'] = 'test'
|
5
|
+
|
6
|
+
require 'timecop'
|
7
|
+
require 'simplecov'
|
8
|
+
require 'rack/test'
|
9
|
+
|
10
|
+
require 'peastash'
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.include Rack::Test::Methods
|
14
|
+
config.before(:all) do
|
15
|
+
# Muting the output from the logger
|
16
|
+
Peastash::Outputs::IO.class_variable_set(:@@default_io, File.open(File::NULL, File::WRONLY))
|
17
|
+
end
|
18
|
+
|
19
|
+
config.before(:each) do
|
20
|
+
# For the errors to be raised
|
21
|
+
Peastash.unsafe!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def unconfigure_foostash!
|
26
|
+
Peastash.class_variable_set(:@@instance_cache, ThreadSafe::Cache.new)
|
27
|
+
end
|
28
|
+
|
29
|
+
def env_for(url, opts={})
|
30
|
+
Rack::MockRequest.env_for(url, opts)
|
31
|
+
end
|