roqua-support 0.4.2 → 0.4.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/roqua/core_ext/enumerable/sort_by_alphanum.rb +2 -0
- data/lib/roqua/probes/base_probe.rb +3 -0
- data/lib/roqua/support/errors.rb +1 -1
- data/lib/roqua-support/version.rb +1 -1
- data/roqua-support.gemspec +1 -1
- metadata +4 -72
- 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 -28
- 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 -169
- 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,169 +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(:is_ignored_exception?).and_return(false)
|
100
|
-
allow(Appsignal).to receive(:agent).and_return(agent)
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'it will send an error' do
|
104
|
-
expect(Appsignal).to receive(:send_error)
|
105
|
-
Roqua::Support::Errors.report exception
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'defaults to a background job' do
|
109
|
-
transaction = Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::FRONTEND, nil)
|
110
|
-
expect(Appsignal).to receive(:send_error).with(exception).and_yield(transaction)
|
111
|
-
Roqua::Support::Errors.report exception
|
112
|
-
expect(transaction.namespace).to eq Appsignal::Transaction::BACKGROUND_JOB
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'it will send an error under the provided category' do
|
116
|
-
transaction = Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::FRONTEND, nil)
|
117
|
-
expect(Appsignal)
|
118
|
-
.to receive(:send_error)
|
119
|
-
.with(exception).and_yield(transaction)
|
120
|
-
|
121
|
-
Roqua::Support::Errors.report exception, a: 'b', namespace: :web
|
122
|
-
expect(transaction.namespace).to eq Appsignal::Transaction::HTTP_REQUEST
|
123
|
-
expect(transaction.tags).to eq a: 'b'
|
124
|
-
end
|
125
|
-
|
126
|
-
describe 'when a current transaction is present' do
|
127
|
-
let(:current_transaction) do
|
128
|
-
Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, nil)
|
129
|
-
end
|
130
|
-
|
131
|
-
before do
|
132
|
-
expect(Appsignal::Transaction).to receive(:current).at_least(:once).and_return(current_transaction)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'sets the correct properties if a current transaction is present' do
|
136
|
-
expect(current_transaction).to receive(:set_tags).with(a: 'b').and_call_original
|
137
|
-
expect(current_transaction).to receive(:add_exception).with(exception).and_call_original
|
138
|
-
|
139
|
-
Roqua::Support::Errors.report exception, a: 'b', namespace: :web
|
140
|
-
end
|
141
|
-
|
142
|
-
describe "if the current transaction isn't a http request" do
|
143
|
-
let(:current_transaction) do
|
144
|
-
Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::BACKGROUND_JOB, nil)
|
145
|
-
end
|
146
|
-
|
147
|
-
it "will not set the properties if the current transaction isn't a http request" do
|
148
|
-
expect(current_transaction).to_not receive(:set_tags)
|
149
|
-
expect(current_transaction).to_not receive(:add_exception)
|
150
|
-
|
151
|
-
Roqua::Support::Errors.report exception, a: 'b', namespace: :web
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
context '.appsignal_namespace_for_category' do
|
158
|
-
it 'returns the correct string based on the category' do
|
159
|
-
expect(Roqua::Support::Errors.appsignal_namespace_for_category(:background))
|
160
|
-
.to eql(Appsignal::Transaction::BACKGROUND_JOB)
|
161
|
-
|
162
|
-
expect(Roqua::Support::Errors.appsignal_namespace_for_category(:web))
|
163
|
-
.to eql(Appsignal::Transaction::HTTP_REQUEST)
|
164
|
-
|
165
|
-
expect(Roqua::Support::Errors.appsignal_namespace_for_category(''))
|
166
|
-
.to eql(Appsignal::Transaction::BLANK)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
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
|