roqua-support 0.4.4 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/roqua/probes/base_probe.rb +3 -0
- data/lib/roqua/responders/api_errors_responder.rb +12 -1
- data/lib/roqua/support/errors.rb +3 -3
- data/lib/roqua-support/version.rb +1 -1
- data/roqua-support.gemspec +3 -3
- metadata +8 -76
- data/.gitignore +0 -20
- data/.gitlab-ci.yml +0 -32
- data/.rspec +0 -1
- data/.rubocop.yml +0 -2
- data/.travis.yml +0 -6
- data/Appraisals +0 -15
- data/Gemfile +0 -21
- data/Gemfile.lock +0 -213
- data/Guardfile +0 -8
- data/circle.yml +0 -13
- data/gemfiles/rails52.gemfile +0 -24
- data/gemfiles/rails60.gemfile +0 -23
- data/gemfiles/rails61.gemfile +0 -23
- data/spec/internal/config/balancer_state +0 -1
- data/spec/internal/config/routes.rb +0 -3
- data/spec/roqua/core_ext/active_interaction/date_time_as_unix_extension_spec.rb +0 -51
- data/spec/roqua/core_ext/active_interaction/duration_filter_spec.rb +0 -90
- data/spec/roqua/core_ext/active_interaction/rails_intrumentation_spec.rb +0 -20
- data/spec/roqua/core_ext/activerecord/uniq_find_or_create_spec.rb +0 -77
- data/spec/roqua/core_ext/delayed_job/activity_monitoring_spec.rb +0 -75
- data/spec/roqua/core_ext/enumerable/sort_by_alphanum_spec.rb +0 -33
- data/spec/roqua/core_ext/fabrication/singleton_spec.rb +0 -23
- data/spec/roqua/logging/roqua_logging_railtie_spec.rb +0 -48
- data/spec/roqua/probes/delayed_job_probe_spec.rb +0 -56
- data/spec/roqua/probes/monitoring_probe_spec.rb +0 -69
- data/spec/roqua/responders/active_interaction_aware_responder_spec.rb +0 -54
- data/spec/roqua/responders/api_errors_responder_spec.rb +0 -34
- data/spec/roqua/scheduling/scheduler_spec.rb +0 -114
- data/spec/roqua/status_checks/check_db_connection_spec.rb +0 -12
- data/spec/roqua/status_checks/check_load_balancer_member_spec.rb +0 -22
- data/spec/roqua/status_checks/status_controller_spec.rb +0 -63
- data/spec/roqua/support/errors_spec.rb +0 -168
- data/spec/roqua/support/helpers_spec.rb +0 -50
- data/spec/roqua/support/logwrapper_spec.rb +0 -69
- data/spec/roqua/support/request_logger_spec.rb +0 -148
- data/spec/roqua/support/stats_spec.rb +0 -18
- data/spec/roqua/support_spec.rb +0 -19
- data/spec/roqua/type/stripped_string_spec.rb +0 -34
- data/spec/roqua/validators/subset_validator_spec.rb +0 -39
- data/spec/spec_helper.rb +0 -39
- data/styleguide/ruby/rubocop.yml +0 -219
@@ -1,114 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'timecop'
|
3
|
-
|
4
|
-
describe Roqua::Scheduling::Scheduler do
|
5
|
-
before do
|
6
|
-
Timecop.freeze
|
7
|
-
Roqua::Scheduling::CronJob.delete_all
|
8
|
-
end
|
9
|
-
|
10
|
-
after { Timecop.return }
|
11
|
-
|
12
|
-
subject { described_class.new }
|
13
|
-
|
14
|
-
def setup_daily_and_hourly_schedule
|
15
|
-
Roqua::Scheduling::Schedule.setup do |cron|
|
16
|
-
cron.add_task 'hourly', next_run_at: Roqua::Scheduling::Schedule::BEGINNING_OF_EVERY_HOUR do
|
17
|
-
end
|
18
|
-
|
19
|
-
cron.add_task 'daily', next_run_at: Roqua::Scheduling::Schedule::BEGINNING_OF_EVERY_DAY do
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def setup_hourly_schedule
|
25
|
-
Roqua::Scheduling::Schedule.setup do |cron|
|
26
|
-
cron.add_task 'hourly', next_run_at: Roqua::Scheduling::Schedule::BEGINNING_OF_EVERY_HOUR do
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'creates the correct table rows' do
|
32
|
-
expect { setup_daily_and_hourly_schedule }
|
33
|
-
.to change { Roqua::Scheduling::CronJob.all.pluck(:name, :next_run_at, :completed_at) }
|
34
|
-
.from(
|
35
|
-
[]
|
36
|
-
)
|
37
|
-
.to(
|
38
|
-
[
|
39
|
-
['hourly', Time.now.beginning_of_hour + 1.hour, nil],
|
40
|
-
['daily', Time.now.beginning_of_day + 1.day, nil]
|
41
|
-
]
|
42
|
-
)
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'removes unused table rows' do
|
46
|
-
setup_daily_and_hourly_schedule
|
47
|
-
|
48
|
-
expect { setup_hourly_schedule }
|
49
|
-
.to change { Roqua::Scheduling::CronJob.all.pluck(:name).sort }
|
50
|
-
.from(['daily', 'hourly']).to(['hourly'])
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'generates a database specific advisory lock name' do
|
54
|
-
# expect(ActiveRecord::Base.connection_config[:database]).to eql(':memory:')
|
55
|
-
expect(subject.advisory_lock_name).to eql ':memory:_cron_lock'
|
56
|
-
end
|
57
|
-
|
58
|
-
describe 'with a run_at in the future' do
|
59
|
-
before do
|
60
|
-
Roqua::Scheduling::Schedule.setup do |cron|
|
61
|
-
cron.add_task 'hourly', next_run_at: proc { 1.minute.from_now } do
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'the task will not be run' do
|
67
|
-
expect(subject.schedule.tasks['hourly']).to_not receive(:run)
|
68
|
-
subject.ping
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe 'callbacks' do
|
73
|
-
let(:callback_spy) { spy(:callback) }
|
74
|
-
|
75
|
-
before do
|
76
|
-
Roqua::Scheduling::Schedule.setup do |cron|
|
77
|
-
cron.add_task 'hourly', next_run_at: proc { 1.minute.ago } do
|
78
|
-
callback_spy.execute
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'get executed' do
|
84
|
-
expect(callback_spy).to receive(:execute)
|
85
|
-
subject.ping
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'counts task calls' do
|
89
|
-
expect(Appsignal).to receive(:increment_counter).with('scheduler.completed', 1)
|
90
|
-
expect(Appsignal).to receive(:increment_counter).with('scheduler.run_task.completed', 1, task_name: 'hourly')
|
91
|
-
subject.ping
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe 'when running multiple times' do
|
96
|
-
before do
|
97
|
-
Timecop.freeze(60.seconds.ago)
|
98
|
-
|
99
|
-
Roqua::Scheduling::Schedule.setup do |cron|
|
100
|
-
cron.add_task 'task', next_run_at: proc { 30.seconds.from_now } do
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
let(:schedule) { Roqua::Scheduling::Schedule.current_schedule }
|
106
|
-
|
107
|
-
it 'the task is only called once' do
|
108
|
-
expect(schedule.tasks['task']).to receive(:run).once
|
109
|
-
|
110
|
-
Timecop.return
|
111
|
-
3.times { Roqua::Scheduling::Scheduler.new.ping }
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Roqua::StatusChecks::CheckDbConnection' do
|
4
|
-
it 'returns true when there is a db connection' do
|
5
|
-
expect(Roqua::StatusChecks::CheckDbConnection.connected?).to be_truthy
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'returns false when there is no db configured' do
|
9
|
-
allow(ActiveRecord::Base).to receive_message_chain(:connection, :active?).and_return(false)
|
10
|
-
expect(Roqua::StatusChecks::CheckDbConnection.connected?).to be_falsey
|
11
|
-
end
|
12
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Roqua::StatusChecks::CheckLoadBalancerMember' do
|
4
|
-
it 'returns true when the status file contains on' do
|
5
|
-
allow(File).to receive(:read).and_return('on')
|
6
|
-
|
7
|
-
expect(Roqua::StatusChecks::CheckLoadBalancerMember.balancer_member?('foo/bar')).to be_truthy
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'returns false when the status file does not contain off' do
|
11
|
-
allow(File).to receive(:read).and_return('off')
|
12
|
-
|
13
|
-
expect(Roqua::StatusChecks::CheckLoadBalancerMember.balancer_member?('foo/bar')).to be_falsey
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'raises InvalidStatus error when the status file contains something else' do
|
17
|
-
allow(File).to receive(:read).and_return('foo')
|
18
|
-
|
19
|
-
expect { Roqua::StatusChecks::CheckLoadBalancerMember.balancer_member?('foo/bar') }
|
20
|
-
.to raise_error(Roqua::StatusChecks::CheckLoadBalancerMember::InvalidStatus, 'Invalid state: foo')
|
21
|
-
end
|
22
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Roqua::StatusChecks::StatusController, type: :controller do
|
4
|
-
context 'visiting the status page while balancer member and database is up' do
|
5
|
-
it 'returns the correct status' do
|
6
|
-
allow(Roqua::StatusChecks::CheckLoadBalancerMember).to receive(:balancer_member?).and_return(true)
|
7
|
-
allow(Roqua::StatusChecks::CheckDbConnection).to receive(:connected?).and_return(true)
|
8
|
-
|
9
|
-
get :balancer_status
|
10
|
-
|
11
|
-
expect(response.status).to eq(200)
|
12
|
-
expect(response.body).to eq("{\"status\":\"ok\",\"member\":true}")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'visiting the status page while not balancer member and database is up' do
|
17
|
-
it 'returns the correct status' do
|
18
|
-
allow(Roqua::StatusChecks::CheckLoadBalancerMember).to receive(:balancer_member?).and_return(false)
|
19
|
-
allow(Roqua::StatusChecks::CheckDbConnection).to receive(:connected?).and_return(true)
|
20
|
-
|
21
|
-
get :balancer_status
|
22
|
-
|
23
|
-
expect(response.status).to eq(503)
|
24
|
-
expect(response.body).to eq("{\"status\":\"ok\",\"member\":false}")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'visiting the status page while balancer member and database is down' do
|
29
|
-
it 'returns the correct status' do
|
30
|
-
allow(Roqua::StatusChecks::CheckLoadBalancerMember).to receive(:balancer_member?).and_return(true)
|
31
|
-
allow(Roqua::StatusChecks::CheckDbConnection).to receive(:connected?).and_return(false)
|
32
|
-
|
33
|
-
get :balancer_status
|
34
|
-
|
35
|
-
expect(response.status).to eq(503)
|
36
|
-
expect(response.body).to eq("{\"status\":\"error\",\"member\":true}")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'visiting the status page while not balancer member and database is down' do
|
41
|
-
it 'returns the correct status' do
|
42
|
-
allow(Roqua::StatusChecks::CheckLoadBalancerMember).to receive(:balancer_member?).and_return(false)
|
43
|
-
allow(Roqua::StatusChecks::CheckDbConnection).to receive(:connected?).and_return(false)
|
44
|
-
|
45
|
-
get :balancer_status
|
46
|
-
|
47
|
-
expect(response.status).to eq(503)
|
48
|
-
expect(response.body).to eq("{\"status\":\"error\",\"member\":false}")
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'visiting the status page while balancer_state is on nor off' do
|
53
|
-
it 'returns the correct status' do
|
54
|
-
allow(Roqua::StatusChecks::CheckLoadBalancerMember).to receive(:balancer_member?)
|
55
|
-
.and_raise(Roqua::StatusChecks::CheckLoadBalancerMember::InvalidStatus)
|
56
|
-
|
57
|
-
get :balancer_status
|
58
|
-
|
59
|
-
expect(response.status).to eq(500)
|
60
|
-
expect(response.body).to eq("{\"status\":\"unknown status\"}")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,168 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'roqua/support/errors'
|
3
|
-
require 'appsignal'
|
4
|
-
|
5
|
-
describe 'Error reporting' do
|
6
|
-
let(:exception) do
|
7
|
-
Exception.new('exception_message').tap do |exception|
|
8
|
-
exception.set_backtrace ['back', 'trace', 'lines']
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:logstream) { StringIO.new }
|
13
|
-
let(:logger) { Logger.new(logstream) }
|
14
|
-
let(:logwrapper) { Roqua::LogWrapper.new(logger) }
|
15
|
-
|
16
|
-
before do
|
17
|
-
Rails.env = 'foo' # in test we don't log
|
18
|
-
Roqua.logger = logwrapper
|
19
|
-
end
|
20
|
-
|
21
|
-
context 'when the Roqua logger is defined' do
|
22
|
-
it 'supports default extra params' do
|
23
|
-
allow(Roqua::Support::Errors).to receive(:extra_parameters).and_return(organization: 'some_org')
|
24
|
-
expect(Roqua.logger).to receive(:error).with('roqua.exception',
|
25
|
-
class_name: 'Exception',
|
26
|
-
message: 'exception_message',
|
27
|
-
backtrace: ['back', 'trace', 'lines'],
|
28
|
-
parameters: {organization: 'some_org'})
|
29
|
-
Roqua::Support::Errors.report exception
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'sends notifications to the eventlog' do
|
33
|
-
expect(Roqua.logger).to receive(:error).with('roqua.exception',
|
34
|
-
class_name: 'Exception',
|
35
|
-
message: 'exception_message',
|
36
|
-
backtrace: ['back', 'trace', 'lines'],
|
37
|
-
parameters: {})
|
38
|
-
Roqua::Support::Errors.report exception
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'skips the backtrace when the skip_backtrace flag is set' do
|
42
|
-
expect(Roqua.logger).to receive(:error).with('roqua.exception',
|
43
|
-
class_name: 'Exception',
|
44
|
-
message: 'exception_message',
|
45
|
-
parameters: {})
|
46
|
-
Roqua::Support::Errors.report exception, skip_backtrace: true
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'can add extra parameters by calling add_parameters' do
|
50
|
-
expect(Roqua.logger).to receive(:error).with \
|
51
|
-
'roqua.exception', class_name: 'RuntimeError',
|
52
|
-
message: 'exception_message',
|
53
|
-
parameters: {more: 'params',
|
54
|
-
even_more: 'params'}
|
55
|
-
begin
|
56
|
-
begin
|
57
|
-
begin
|
58
|
-
fail 'exception_message'
|
59
|
-
rescue
|
60
|
-
Roqua::Support::Errors.add_parameters(more: 'params')
|
61
|
-
raise
|
62
|
-
end
|
63
|
-
rescue
|
64
|
-
Roqua::Support::Errors.add_parameters(even_more: 'params')
|
65
|
-
raise
|
66
|
-
end
|
67
|
-
rescue => e
|
68
|
-
Roqua::Support::Errors.report e, skip_backtrace: true
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'will not fail when called outside of rescue or when passed the wrong format to add_parameters' do
|
73
|
-
expect(Roqua.logger).to receive(:error).with \
|
74
|
-
'roqua.exception', class_name: 'RuntimeError',
|
75
|
-
message: 'exception_message',
|
76
|
-
parameters: {}
|
77
|
-
|
78
|
-
begin
|
79
|
-
Roqua::Support::Errors.add_parameters('just a string')
|
80
|
-
begin
|
81
|
-
fail 'exception_message'
|
82
|
-
rescue
|
83
|
-
Roqua::Support::Errors.add_parameters('just a string')
|
84
|
-
raise
|
85
|
-
end
|
86
|
-
rescue => e
|
87
|
-
Roqua::Support::Errors.report e, skip_backtrace: true
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'when Appsignal is loaded' do
|
93
|
-
let(:agent) { double("agent") }
|
94
|
-
let(:transaction) { double("transaction") }
|
95
|
-
|
96
|
-
before do
|
97
|
-
Appsignal.config = Appsignal::Config.new(Dir.pwd, "test")
|
98
|
-
allow(Appsignal).to receive(:active?).and_return(true)
|
99
|
-
allow(Appsignal).to receive(:agent).and_return(agent)
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'it will send an error' do
|
103
|
-
expect(Appsignal).to receive(:send_error)
|
104
|
-
Roqua::Support::Errors.report exception
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'defaults to a background job' do
|
108
|
-
transaction = Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::FRONTEND, nil)
|
109
|
-
expect(Appsignal).to receive(:send_error).with(exception).and_yield(transaction)
|
110
|
-
Roqua::Support::Errors.report exception
|
111
|
-
expect(transaction.namespace).to eq Appsignal::Transaction::BACKGROUND_JOB
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'it will send an error under the provided category' do
|
115
|
-
transaction = Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::FRONTEND, nil)
|
116
|
-
expect(Appsignal)
|
117
|
-
.to receive(:send_error)
|
118
|
-
.with(exception).and_yield(transaction)
|
119
|
-
|
120
|
-
Roqua::Support::Errors.report exception, a: 'b', namespace: :web
|
121
|
-
expect(transaction.namespace).to eq Appsignal::Transaction::HTTP_REQUEST
|
122
|
-
expect(transaction.tags).to eq a: 'b'
|
123
|
-
end
|
124
|
-
|
125
|
-
describe 'when a current transaction is present' do
|
126
|
-
let(:current_transaction) do
|
127
|
-
Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, nil)
|
128
|
-
end
|
129
|
-
|
130
|
-
before do
|
131
|
-
expect(Appsignal::Transaction).to receive(:current).at_least(:once).and_return(current_transaction)
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'sets the correct properties if a current transaction is present' do
|
135
|
-
expect(current_transaction).to receive(:set_tags).with(a: 'b').and_call_original
|
136
|
-
expect(current_transaction).to receive(:add_exception).with(exception).and_call_original
|
137
|
-
|
138
|
-
Roqua::Support::Errors.report exception, a: 'b', namespace: :web
|
139
|
-
end
|
140
|
-
|
141
|
-
describe "if the current transaction isn't a http request" do
|
142
|
-
let(:current_transaction) do
|
143
|
-
Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::BACKGROUND_JOB, nil)
|
144
|
-
end
|
145
|
-
|
146
|
-
it "will not set the properties if the current transaction isn't a http request" do
|
147
|
-
expect(current_transaction).to_not receive(:set_tags)
|
148
|
-
expect(current_transaction).to_not receive(:add_exception)
|
149
|
-
|
150
|
-
Roqua::Support::Errors.report exception, a: 'b', namespace: :web
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
context '.appsignal_namespace_for_category' do
|
157
|
-
it 'returns the correct string based on the category' do
|
158
|
-
expect(Roqua::Support::Errors.appsignal_namespace_for_category(:background))
|
159
|
-
.to eql(Appsignal::Transaction::BACKGROUND_JOB)
|
160
|
-
|
161
|
-
expect(Roqua::Support::Errors.appsignal_namespace_for_category(:web))
|
162
|
-
.to eql(Appsignal::Transaction::HTTP_REQUEST)
|
163
|
-
|
164
|
-
expect(Roqua::Support::Errors.appsignal_namespace_for_category(''))
|
165
|
-
.to eql(Appsignal::Transaction::BLANK)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'roqua/support/instrumentation'
|
2
|
-
|
3
|
-
describe 'Helper methods' do
|
4
|
-
describe '#with_instrumentation' do
|
5
|
-
include Roqua::Support::Instrumentation
|
6
|
-
|
7
|
-
let(:logger) { double("Logger", info: nil, error: nil) }
|
8
|
-
let(:stats) { double("Stats", submit: nil) }
|
9
|
-
|
10
|
-
before do
|
11
|
-
allow(Roqua).to receive(:logger).and_return(logger)
|
12
|
-
allow(Roqua).to receive(:stats).and_return(stats)
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'when the block returns a value' do
|
16
|
-
it 'logs the start and finish lifecycle of a block' do
|
17
|
-
expect(logger).to receive(:info).with('testevent:started', {extra: "params"}).ordered
|
18
|
-
expect(logger).to receive(:info).with('testevent:finished', hash_including({extra: "params"})).ordered
|
19
|
-
expect(stats).to receive(:submit).with('testevent.finished', 1)
|
20
|
-
expect(stats).to receive(:submit).with('testevent.duration', an_instance_of(Float))
|
21
|
-
|
22
|
-
with_instrumentation('testevent', extra: 'params') { 1 + 1 }
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'returns the value returned by the block' do
|
26
|
-
expect(with_instrumentation('testevent') { 1 + 1 }).to eq 2
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'when an exception happens during the block' do
|
31
|
-
it 'logs the start and failure of a block if it raises' do
|
32
|
-
expect(logger).to receive(:info).with('testevent:started', instance_of(Hash)).ordered
|
33
|
-
expect(logger).to receive(:error).with('testevent:failed', instance_of(Hash)).ordered
|
34
|
-
expect(stats).to receive(:submit).with('testevent.failed', 1)
|
35
|
-
|
36
|
-
with_instrumentation 'testevent' do
|
37
|
-
raise StandardError, "Foo"
|
38
|
-
end rescue nil
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'reraises the exception' do
|
42
|
-
expect {
|
43
|
-
with_instrumentation 'testevent' do
|
44
|
-
raise "Foo"
|
45
|
-
end
|
46
|
-
}.to raise_error('Foo')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'roqua/support/log_wrapper'
|
2
|
-
require 'logger'
|
3
|
-
require 'stringio'
|
4
|
-
|
5
|
-
module Roqua
|
6
|
-
describe LogWrapper do
|
7
|
-
before { allow(Roqua).to receive(:appname).and_return('roqua-support-testsuite') }
|
8
|
-
|
9
|
-
let(:logstream) { StringIO.new }
|
10
|
-
let(:logger) { Logger.new(logstream) }
|
11
|
-
let(:logwrapper) { LogWrapper.new(logger) }
|
12
|
-
|
13
|
-
def log
|
14
|
-
logstream.string
|
15
|
-
end
|
16
|
-
|
17
|
-
describe '#add' do
|
18
|
-
it 'writes event name to log' do
|
19
|
-
logwrapper.add :info, "testevent"
|
20
|
-
expect(log).to include("testevent {}\n")
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'writes given parameters as json hash' do
|
24
|
-
logwrapper.add :info, "testevent", extra: 'params', go: 'here'
|
25
|
-
expect(log).to include('testevent {"extra":"params","go":"here"}' + "\n")
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'escapes newline characters in params' do
|
29
|
-
logwrapper.add :info, "testevent", param: "this\nshould not have newlines"
|
30
|
-
expect(log).to include('testevent {"param":"this\nshould not have newlines"')
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe '#lifecycle' do
|
35
|
-
it 'logs the start and finish lifecycle of a block' do
|
36
|
-
logwrapper.lifecycle 'testevent', extra: 'params' do
|
37
|
-
1 + 1
|
38
|
-
end
|
39
|
-
expect(log).to include('testevent:started {"extra":"params"}')
|
40
|
-
expect(log).to match(/testevent:finished.*"extra":"params"/)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'logs the duration of the block with the finished event' do
|
44
|
-
logwrapper.lifecycle('testevent') { 1 + 1 }
|
45
|
-
expect(log).to match(/testevent:finished.*"duration":/)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'returns the value returned by the block' do
|
49
|
-
expect(logwrapper.lifecycle('testevent') { 1 + 1 }).to eq 2
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'logs the start and failure of a block if it raises' do
|
53
|
-
logwrapper.lifecycle 'testevent' do
|
54
|
-
raise StandardError, "Foo"
|
55
|
-
end rescue nil
|
56
|
-
expect(log).to include('testevent:started')
|
57
|
-
expect(log).to include('testevent:failed {"exception":"StandardError","message":"Foo"}')
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'reraises the exception' do
|
61
|
-
expect {
|
62
|
-
logwrapper.lifecycle 'testevent' do
|
63
|
-
raise "Foo"
|
64
|
-
end
|
65
|
-
}.to raise_error('Foo')
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,148 +0,0 @@
|
|
1
|
-
require 'roqua/support/log_wrapper'
|
2
|
-
require 'roqua/support/request_logger'
|
3
|
-
require 'active_support/notifications'
|
4
|
-
require 'active_support/core_ext/string'
|
5
|
-
|
6
|
-
describe Roqua::Support::RequestLogger do
|
7
|
-
let(:logstream) { StringIO.new }
|
8
|
-
let(:logger) { Logger.new(logstream) }
|
9
|
-
let(:logwrapper) { Roqua::LogWrapper.new(logger) }
|
10
|
-
|
11
|
-
# before { Roqua.stub(logger: logwrapper) }
|
12
|
-
before { allow(Roqua).to receive(:logger).and_return(logwrapper) }
|
13
|
-
|
14
|
-
def log
|
15
|
-
logstream.string
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:subscriber) { Roqua::Support::RequestLogger.new }
|
19
|
-
|
20
|
-
context 'when processing a request' do
|
21
|
-
let(:event) do
|
22
|
-
ActiveSupport::Notifications::Event.new('process_action.action_controller',
|
23
|
-
Time.new(2013, 02, 28, 12, 34, 56),
|
24
|
-
Time.new(2013, 02, 28, 12, 34, 57), 2,
|
25
|
-
status: 200, format: 'application/json', method: 'GET', path: '/home?foo=bar',
|
26
|
-
params: {'controller' => 'home', 'action' => 'index', 'foo' => 'bar'},
|
27
|
-
db_runtime: 0.02, view_runtime: 0.01
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "logs the URL" do
|
32
|
-
subscriber.process_action(event)
|
33
|
-
expect(logstream.string).to include('/home')
|
34
|
-
end
|
35
|
-
|
36
|
-
it "does not log the query string" do
|
37
|
-
subscriber.process_action(event)
|
38
|
-
expect(logstream.string).to_not include('?foo=bar')
|
39
|
-
end
|
40
|
-
|
41
|
-
it "logs the HTTP method" do
|
42
|
-
subscriber.process_action(event)
|
43
|
-
expect(logstream.string).to include('"method":"GET"')
|
44
|
-
end
|
45
|
-
|
46
|
-
it "logs the status code returned" do
|
47
|
-
subscriber.process_action(event)
|
48
|
-
expect(logstream.string).to include('"status":200')
|
49
|
-
end
|
50
|
-
|
51
|
-
it "logs the controller and action" do
|
52
|
-
subscriber.process_action(event)
|
53
|
-
expect(logstream.string).to include('"controller":"home","action":"index"')
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'logs request parameters' do
|
57
|
-
subscriber.process_action(event)
|
58
|
-
expect(logstream.string).to include('"params":{"foo":"bar"}')
|
59
|
-
end
|
60
|
-
|
61
|
-
it "logs how long the request took" do
|
62
|
-
subscriber.process_action(event)
|
63
|
-
expect(logstream.string).to match /"duration":1000.0/
|
64
|
-
end
|
65
|
-
|
66
|
-
it "logs the view rendering time" do
|
67
|
-
subscriber.process_action(event)
|
68
|
-
expect(logstream.string).to match /"view":0.01/
|
69
|
-
end
|
70
|
-
|
71
|
-
it "logs the database rendering time" do
|
72
|
-
subscriber.process_action(event)
|
73
|
-
expect(logstream.string).to match /"db":0.02/
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'logs extra information added in the controller' do
|
77
|
-
controller = Class.new do
|
78
|
-
include Roqua::Support::RequestLogging
|
79
|
-
|
80
|
-
def index
|
81
|
-
add_log_information 'current_user', 'johndoe'
|
82
|
-
end
|
83
|
-
end
|
84
|
-
controller.new.index
|
85
|
-
subscriber.process_action(event)
|
86
|
-
expect(logstream.string).to include('"current_user":"johndoe"')
|
87
|
-
|
88
|
-
# next request should not still maintain this data
|
89
|
-
logstream.truncate 0
|
90
|
-
subscriber.process_action(event)
|
91
|
-
expect(logstream.string).to_not include('current_user')
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'when an exception occured processing the request' do
|
96
|
-
let(:event) do
|
97
|
-
ActiveSupport::Notifications::Event.new('process_action.action_controller',
|
98
|
-
Time.now, Time.now, 2,
|
99
|
-
status: nil, format: 'application/json', method: 'GET', path: '/home?foo=bar',
|
100
|
-
exception: ['AbstractController::ActionNotFound', 'Route not found'],
|
101
|
-
params: {'controller' => 'home', 'action' => 'index', 'foo' => 'bar'},
|
102
|
-
db_runtime: 0.02, view_runtime: 0.01
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
it "logs the 500 status when an exception occurred" do
|
107
|
-
subscriber.process_action(event)
|
108
|
-
expect(logstream.string).to match /"status":500/
|
109
|
-
expect(logstream.string).to match /"error":"AbstractController::ActionNotFound:Route not found"/
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should return an unknown status when no status or exception is found" do
|
113
|
-
event.payload[:status] = nil
|
114
|
-
event.payload[:exception] = nil
|
115
|
-
subscriber.process_action(event)
|
116
|
-
expect(logstream.string).to match /"status":0/
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
context 'when the request redirected' do
|
121
|
-
let(:event) do
|
122
|
-
ActiveSupport::Notifications::Event.new('process_action.action_controller',
|
123
|
-
Time.new(2013, 02, 28, 12, 34, 56),
|
124
|
-
Time.new(2013, 02, 28, 12, 34, 57), 2,
|
125
|
-
status: 200, format: 'application/json', method: 'GET', path: '/home?foo=bar',
|
126
|
-
params: {'controller' => 'home', 'action' => 'index', 'foo' => 'bar'},
|
127
|
-
db_runtime: 0.02, view_runtime: 0.01
|
128
|
-
)
|
129
|
-
end
|
130
|
-
|
131
|
-
let(:redirect) {
|
132
|
-
ActiveSupport::Notifications::Event.new(
|
133
|
-
'redirect_to.action_controller', Time.now, Time.now, 1, location: 'http://example.com', status: 302
|
134
|
-
)
|
135
|
-
}
|
136
|
-
|
137
|
-
it 'logs the redirect' do
|
138
|
-
subscriber.redirect_to(redirect)
|
139
|
-
subscriber.process_action(event)
|
140
|
-
expect(log).to include('"location":"http://example.com"')
|
141
|
-
|
142
|
-
# next request should no longer get location
|
143
|
-
logstream.truncate 0
|
144
|
-
subscriber.process_action(event)
|
145
|
-
expect(log).to_not include('location')
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'roqua/support/stats'
|
3
|
-
|
4
|
-
describe 'Stats' do
|
5
|
-
let(:backend) { double("StatsBackend") }
|
6
|
-
let(:stats) { Roqua::Support::Stats.new(backend) }
|
7
|
-
|
8
|
-
before do
|
9
|
-
Roqua.appname = 'appname'
|
10
|
-
end
|
11
|
-
|
12
|
-
describe 'tracking a value' do
|
13
|
-
it 'reports to backend' do
|
14
|
-
expect(backend).to receive(:submit).with('appname.data_export.duration', 2.3)
|
15
|
-
stats.submit('data_export.duration', 2.3)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/spec/roqua/support_spec.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'roqua/support'
|
2
|
-
|
3
|
-
describe Roqua do
|
4
|
-
describe '#logger' do
|
5
|
-
it 'has a default' do
|
6
|
-
expect(Roqua.logger).to be_an_instance_of(Roqua::LogWrapper)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
describe '#logger=' do
|
11
|
-
let(:logger) { double }
|
12
|
-
|
13
|
-
it 'wraps a given logger' do
|
14
|
-
Roqua.logger = logger
|
15
|
-
expect(Roqua.logger).to be_an_instance_of(Roqua::LogWrapper)
|
16
|
-
expect(Roqua.logger.logger).to eq logger
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|