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,51 +0,0 @@
|
|
1
|
-
require 'active_interaction'
|
2
|
-
require 'active_support/all'
|
3
|
-
require 'roqua/core_ext/active_interaction/filters/date_time_as_unix_extension'
|
4
|
-
|
5
|
-
class DateTimeFilterOperation < ActiveInteraction::Base
|
6
|
-
date_time :date_time, default: nil
|
7
|
-
|
8
|
-
def execute
|
9
|
-
date_time
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
describe RoquaDateTimeAsUnixFilterExtension do
|
14
|
-
let(:time) { Time.now.change(:usec => 0) }
|
15
|
-
|
16
|
-
it 'unix integer time translates correctly to datetime' do
|
17
|
-
expect(DateTimeFilterOperation.run! date_time: time.to_i).to eq time
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'unix integer time as string translates correctly to datetime' do
|
21
|
-
expect(DateTimeFilterOperation.run! date_time: time.to_i.to_s).to eq time
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'transations and empty string to nil' do
|
25
|
-
expect(DateTimeFilterOperation.run! date_time: '').to eq nil
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class TimeFilterOperation < ActiveInteraction::Base
|
30
|
-
time :time, default: nil
|
31
|
-
|
32
|
-
def execute
|
33
|
-
time
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe RoquaDateTimeAsUnixFilterExtension do
|
38
|
-
let(:time) { Time.now.change(:usec => 0) }
|
39
|
-
|
40
|
-
it 'unix integer time translates correctly to time' do
|
41
|
-
expect(TimeFilterOperation.run! time: time.to_i).to eq time
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'unix integer time as string translates correctly to datetime' do
|
45
|
-
expect(TimeFilterOperation.run! time: time.to_i.to_s).to eq time
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'transations and empty string to nil' do
|
49
|
-
expect(TimeFilterOperation.run! time: '').to eq nil
|
50
|
-
end
|
51
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
require 'active_interaction'
|
2
|
-
require 'active_support/all'
|
3
|
-
require 'roqua/core_ext/active_interaction/filters/duration_filter'
|
4
|
-
|
5
|
-
class DurationFilterOperation < ActiveInteraction::Base
|
6
|
-
duration :duration
|
7
|
-
duration :stripped_duration, strip: true, default: nil
|
8
|
-
|
9
|
-
def execute
|
10
|
-
{duration: duration, stripped_duration: stripped_duration}
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe ActiveInteraction::DurationFilter do
|
15
|
-
let(:duration) { 1.week }
|
16
|
-
let(:stripped_duration) { 1.week }
|
17
|
-
|
18
|
-
|
19
|
-
subject { DurationFilterOperation.run!(duration: duration, stripped_duration: stripped_duration) }
|
20
|
-
|
21
|
-
describe 'when given a duration object' do
|
22
|
-
it 'receives the object correctly' do
|
23
|
-
expect(subject[:duration]).to be_a(ActiveSupport::Duration)
|
24
|
-
expect(subject[:duration]).to eq 1.week
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'does not strip non-0 values' do
|
28
|
-
expect(subject[:stripped_duration]).to be_a(ActiveSupport::Duration)
|
29
|
-
expect(subject[:stripped_duration]).to eq 1.week
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe 'when given a 0 duration object' do
|
34
|
-
let(:duration) { 0.weeks }
|
35
|
-
let(:stripped_duration) { 0.weeks }
|
36
|
-
|
37
|
-
it 'receives the object correctly' do
|
38
|
-
expect(subject[:duration]).to be_a(ActiveSupport::Duration)
|
39
|
-
expect(subject[:duration]).to eq 0.weeks
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'strips 0 values' do
|
43
|
-
expect(subject[:stripped_duration]).to eq nil
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe 'when given a hash object' do
|
48
|
-
let(:duration) { {value: '1', unit: 'weeks'} }
|
49
|
-
let(:stripped_duration) { {value: '1', unit: 'weeks'} }
|
50
|
-
|
51
|
-
it 'receives the object correctly' do
|
52
|
-
expect(subject[:duration]).to be_a(ActiveSupport::Duration)
|
53
|
-
expect(subject[:duration]).to eq 1.week
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'does not strip non-0 values' do
|
57
|
-
expect(subject[:stripped_duration]).to be_a(ActiveSupport::Duration)
|
58
|
-
expect(subject[:stripped_duration]).to eq 1.week
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe 'when given a hash {value: "0"} object' do
|
63
|
-
let(:duration) { {value: '0', unit: 'weeks'} }
|
64
|
-
let(:stripped_duration) { {value: '0', unit: 'weeks'} }
|
65
|
-
|
66
|
-
it 'receives the object correctly' do
|
67
|
-
expect(subject[:duration]).to be_a(ActiveSupport::Duration)
|
68
|
-
expect(subject[:duration]).to eq 0.weeks
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'strips 0 values' do
|
72
|
-
expect(subject[:stripped_duration]).to eq nil
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe 'when given a hash {value: ""} object' do
|
77
|
-
let(:duration) { {value: '', unit: 'weeks'} }
|
78
|
-
|
79
|
-
it 'throws a required error when not stripped' do
|
80
|
-
expect { subject }.to raise_error ActiveInteraction::InvalidInteractionError, 'Duration is required'
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe 'when given a hash {value: ""} object' do
|
85
|
-
let(:stripped_duration) { {value: '', unit: 'weeks'} }
|
86
|
-
it 'strips 0 values' do
|
87
|
-
expect(subject[:stripped_duration]).to eq nil
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'rspec-instrumentation-matcher'
|
3
|
-
require 'active_interaction'
|
4
|
-
require 'active_support/all'
|
5
|
-
require 'roqua/core_ext/active_interaction/rails_instrumentation'
|
6
|
-
|
7
|
-
class AIRailsInstrumentationTest < ActiveInteraction::Base
|
8
|
-
string :foo, default: 'bar'
|
9
|
-
|
10
|
-
def execute
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe RoquaRailsActiveInteractionInstrumentation do
|
15
|
-
include RSpec::Instrumentation::Matcher
|
16
|
-
it 'creates an event' do
|
17
|
-
expect { AIRailsInstrumentationTest.run }.to instrument('operation.active_interaction').with(
|
18
|
-
class_name: 'ai_rails_instrumentation_test')
|
19
|
-
end
|
20
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'roqua/core_ext/activerecord/uniq_find_or_create'
|
4
|
-
|
5
|
-
describe ActiveRecord::Base do
|
6
|
-
let(:attributes) { double('attributes') }
|
7
|
-
let(:block) { -> (*args){} }
|
8
|
-
let(:record) { double('record') }
|
9
|
-
|
10
|
-
describe '#uniq_find_or_create_by' do
|
11
|
-
it 'tries to find or create a record by the attributes provided' do
|
12
|
-
expect(ActiveRecord::Base).to receive(:find_or_create_by).with(attributes, &block).and_return record
|
13
|
-
ActiveRecord::Base.uniq_find_or_create_by attributes, &block
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'returns a preexisting or created record by querying it' do
|
17
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by).with(attributes).and_return record
|
18
|
-
expect(ActiveRecord::Base.uniq_find_or_create_by attributes, &block).to eq(record)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'returns a concurrenlty created record' do
|
22
|
-
allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return record
|
23
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by).with(attributes, &block)
|
24
|
-
.and_raise ActiveRecord::RecordNotUnique.new('')
|
25
|
-
expect(ActiveRecord::Base.uniq_find_or_create_by attributes, &block).to eq(record)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'raises when a concurrent record is detected by the database but could not be queried for unknown reasons' do
|
29
|
-
allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return nil
|
30
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by).with(attributes, &block)
|
31
|
-
.and_raise ActiveRecord::RecordNotUnique.new('')
|
32
|
-
expect do
|
33
|
-
ActiveRecord::Base.uniq_find_or_create_by attributes, &block
|
34
|
-
end.to raise_error ActiveRecord::RecordNotUnique
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'returns the created record for inspection when validation fails' do
|
38
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by).with(attributes, &block).and_return record
|
39
|
-
expect(ActiveRecord::Base.uniq_find_or_create_by attributes, &block).to eq(record)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe '#uniq_find_or_create_by!' do
|
44
|
-
it 'tries to find or create a record by the attributes provided' do
|
45
|
-
allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return record
|
46
|
-
expect(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes, &block)
|
47
|
-
ActiveRecord::Base.uniq_find_or_create_by! attributes, &block
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'returns a preexisting or created record by querying it' do
|
51
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes).and_return record
|
52
|
-
expect(ActiveRecord::Base.uniq_find_or_create_by! attributes, &block).to eq(record)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'returns a concurrenlty created record' do
|
56
|
-
allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return record
|
57
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes, &block)
|
58
|
-
.and_raise ActiveRecord::RecordNotUnique.new('')
|
59
|
-
expect(ActiveRecord::Base.uniq_find_or_create_by! attributes, &block).to eq(record)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'raises when a concurrent record is detected by the database but could not be queried for unknown reasons' do
|
63
|
-
allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return nil
|
64
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes, &block)
|
65
|
-
.and_raise ActiveRecord::RecordNotUnique.new('')
|
66
|
-
expect do
|
67
|
-
ActiveRecord::Base.uniq_find_or_create_by! attributes, &block
|
68
|
-
end.to raise_error ActiveRecord::RecordNotUnique
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'raises when creating a new record causes validation failures not due to concurrency' do
|
72
|
-
exception = StandardError.new('some_validation_error')
|
73
|
-
allow(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes, &block).and_raise exception
|
74
|
-
expect { ActiveRecord::Base.uniq_find_or_create_by! attributes, &block }.to raise_error(exception)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'pathname'
|
3
|
-
require 'timecop'
|
4
|
-
require 'fakefs/safe'
|
5
|
-
|
6
|
-
require 'roqua/core_ext/delayed_job/activity_monitoring'
|
7
|
-
|
8
|
-
describe DelayedJobActivityMonitoring do
|
9
|
-
after do
|
10
|
-
Timecop.return
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize_fake_rails_root
|
14
|
-
FileUtils.mkdir_p(File.join('/app', 'tmp'))
|
15
|
-
allow(Rails).to receive(:root).and_return(Pathname.new('/app'))
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:monitoring_filename) { Rails.root.join('tmp', 'delayed_job_activity').to_s }
|
19
|
-
|
20
|
-
it 'creates a file' do
|
21
|
-
FakeFS.with_fresh do
|
22
|
-
initialize_fake_rails_root
|
23
|
-
expect { Delayed::Worker.new.work_off }
|
24
|
-
.to change { File.exist?(monitoring_filename) }
|
25
|
-
|
26
|
-
expect(File.mtime(monitoring_filename))
|
27
|
-
.to be_within(1.second).of(Time.now)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'updates the file modification time' do
|
32
|
-
FakeFS.with_fresh do
|
33
|
-
initialize_fake_rails_root
|
34
|
-
|
35
|
-
Delayed::Worker.new.work_off
|
36
|
-
|
37
|
-
Timecop.travel(1.minute)
|
38
|
-
|
39
|
-
expect { Delayed::Worker.new.work_off }
|
40
|
-
.to change { File.mtime(monitoring_filename) }
|
41
|
-
|
42
|
-
expect(File.mtime(monitoring_filename))
|
43
|
-
.to be_within(1.second).of(Time.now)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe 'when a job is reserved' do
|
48
|
-
let(:max_run_time) { 2.hours }
|
49
|
-
let(:job) do
|
50
|
-
double(
|
51
|
-
name: 'name',
|
52
|
-
id: 123,
|
53
|
-
queue: 'queue',
|
54
|
-
max_run_time: max_run_time,
|
55
|
-
invoke_job: nil,
|
56
|
-
destroy: nil
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'creates a file with a modification time in the future' do
|
61
|
-
FakeFS.with_fresh do
|
62
|
-
initialize_fake_rails_root
|
63
|
-
|
64
|
-
worker = Delayed::Worker.new
|
65
|
-
expect(Delayed::Job).to receive(:reserve).and_return(job)
|
66
|
-
|
67
|
-
expect { worker.send(:reserve_and_run_one_job) }
|
68
|
-
.to change { File.exist?(monitoring_filename) }
|
69
|
-
|
70
|
-
expect(File.mtime(monitoring_filename))
|
71
|
-
.to be_within(1.second).of(max_run_time.from_now)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'roqua/core_ext/enumerable/sort_by_alphanum'
|
2
|
-
|
3
|
-
describe Enumerable do
|
4
|
-
describe '#sort_by_alphanum' do
|
5
|
-
let(:input) { ["004some11thing", "004some10thing", "3another"] }
|
6
|
-
it 'sorts by chunks' do
|
7
|
-
expect(input.sort_by_alphanum).to eq ["3another", "004some10thing", "004some11thing"]
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'can take a block which can transform values before comparison' do
|
11
|
-
expect(input.sort_by_alphanum(&:reverse)).to eq ["004some10thing", "004some11thing", "3another"]
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'sorts shorter strings first' do
|
15
|
-
input = %w[a_2_ a_2 a a_1] # curlies are above alpha in utf-8, Ԙ is multi-byte
|
16
|
-
expect(input.sort_by_alphanum).to eq %w[a a_1 a_2 a_2_]
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'treats non-alphanum as lower than alpha and num' do
|
20
|
-
input = %w[b3a b{c bԘb] # curlies are above alpha in utf-8, Ԙ is multi-byte
|
21
|
-
expect(input.sort_by_alphanum).to eq %w[b{c bԘb b3a]
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'compares number chunks as integers' do
|
25
|
-
expect(%w(004 3).sort_by_alphanum).to eq %w(3 004)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'sorts identical integers by asci' do
|
29
|
-
input = %w[b4e b0004e b04e b004e]
|
30
|
-
expect(input.sort_by_alphanum).to eq %w[b0004e b004e b04e b4e]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'roqua/core_ext/fabrication/singleton'
|
2
|
-
|
3
|
-
def Fabricate(name, overrides={}, &block)
|
4
|
-
rand
|
5
|
-
end
|
6
|
-
|
7
|
-
describe Fabricate do
|
8
|
-
it "returns singleton objects" do
|
9
|
-
# Fabricate.singleton(:one).should == Fabricate.singleton(:one)
|
10
|
-
expect(Fabricate.singleton(:one)).to eq Fabricate.singleton(:one)
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'maintains multiple singletons' do
|
14
|
-
# Fabricate.singleton(:one).should_not == Fabricate.singleton(:two)
|
15
|
-
expect(Fabricate.singleton(:one)).not_to eq Fabricate.singleton(:two)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'clears singletons' do
|
19
|
-
the_one = Fabricate.singleton(:one)
|
20
|
-
Fabricate.clear_singletons!
|
21
|
-
expect(Fabricate.singleton(:one)).not_to eq(the_one)
|
22
|
-
end
|
23
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'roqua/support/request_logger'
|
4
|
-
require 'roqua/logging/roqua_logging_railtie'
|
5
|
-
|
6
|
-
RSpec.shared_examples 'RoQua logging setup' do
|
7
|
-
def configure_roqua_logging(log_to_stdout)
|
8
|
-
ClimateControl.modify RAILS_LOG_TO_STDOUT_USING_ROQUA_LOGGER: log_to_stdout do
|
9
|
-
RoquaLoggingRailtie.configure
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'attaches Roqua::Support::RequestLogger to action_controller' do
|
14
|
-
expect(Roqua::Support::RequestLogger).to receive(:attach_to).with(:action_controller)
|
15
|
-
configure_roqua_logging(log_to_stdout)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
Rspec.describe RoquaLoggingRailtie do
|
20
|
-
context 'when RAILS_LOG_TO_STDOUT_USING_ROQUA_LOGGER is present' do
|
21
|
-
include_examples 'RoQua logging setup'
|
22
|
-
|
23
|
-
let(:log_to_stdout) { 'true' }
|
24
|
-
|
25
|
-
it 'logs to STDOUT' do
|
26
|
-
expect(
|
27
|
-
ActiveSupport::Logger.logger_outputs_to?(Roqua.logger.logger, STDOUT)
|
28
|
-
).to be_truthy
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'logs using a datetimeformat including timezone' do
|
32
|
-
time = Time.zone.local(2021,10,10,16,13)
|
33
|
-
got = Roqua.logger.logger.formatter.call 'INFO', time, 'progname', '{}'
|
34
|
-
expect(got).to match(/I, \[2021-10-10T16:13:00.000\+0000 #\d+] INFO -- progname: {}/)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'when RAILS_LOG_TO_STDOUT_USING_ROQUA_LOGGER is blank' do
|
39
|
-
include_examples 'RoQua logging setup'
|
40
|
-
|
41
|
-
let(:log_to_stdout) { '' }
|
42
|
-
|
43
|
-
it 'logs to a log file' do
|
44
|
-
expect(Roqua.logger.logger.instance_variable_get("@logdev").dev.path)
|
45
|
-
.to eql(Rails.root.join('log/test-events.log').to_s)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'delayed_job_active_record'
|
3
|
-
require 'timecop'
|
4
|
-
|
5
|
-
require 'roqua/probes/delayed_job_probe'
|
6
|
-
|
7
|
-
describe Roqua::Probes::DelayedJobProbe do
|
8
|
-
before { Timecop.freeze }
|
9
|
-
after { Timecop.return }
|
10
|
-
subject(:probe) { described_class.new }
|
11
|
-
|
12
|
-
describe 'backlog_count' do
|
13
|
-
context 'if a single job unlocked job exists that has a run_at in the past' do
|
14
|
-
def create_jobs
|
15
|
-
Delayed::Job.create!(run_at: 1.second.ago)
|
16
|
-
2.times { Delayed::Job.create!(run_at: 1.second.ago, locked_at: Time.zone.now) }
|
17
|
-
Delayed::Job.create!(run_at: Time.zone.now)
|
18
|
-
Delayed::Job.create!(run_at: 1.second.from_now)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'returns 1' do
|
22
|
-
expect { create_jobs }.to change { probe.backlog_count }.from(0).to(1)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe '#call' do
|
28
|
-
it 'sends the correct metric to Appsignal' do
|
29
|
-
expect(probe).to receive(:backlog_count).and_return(12)
|
30
|
-
expect(Appsignal).to receive(:set_gauge).with('delayed_job_backlog_count', 12)
|
31
|
-
probe.call
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'increments the probe call counter' do
|
35
|
-
expect(Appsignal).to receive(:increment_counter).with('probe.call.completed', 1, probe_name: "delayed_job_probe")
|
36
|
-
probe.call
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context '.enable' do
|
41
|
-
before { Appsignal::Minutely.probes.clear }
|
42
|
-
after { Appsignal::Minutely.probes.clear }
|
43
|
-
|
44
|
-
it 'adds our custom probes to Appsignal' do
|
45
|
-
expect { Roqua::Probes::DelayedJobProbe.enable }
|
46
|
-
.to change { Appsignal::Minutely.probes.count }.by(1)
|
47
|
-
|
48
|
-
expect(Appsignal::Minutely.probes[:"Roqua::Probes::DelayedJobProbe"]).to be
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'will not add the same probe twice if called multiple times' do
|
52
|
-
expect { 2.times { Roqua::Probes::DelayedJobProbe.enable } }
|
53
|
-
.to change { Appsignal::Minutely.probes.count }.by(1)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'delayed_job_active_record'
|
3
|
-
require 'timecop'
|
4
|
-
|
5
|
-
require 'roqua/probes/delayed_job_probe'
|
6
|
-
|
7
|
-
describe Roqua::Probes::MonitoringProbe do
|
8
|
-
before { Timecop.freeze }
|
9
|
-
after { Timecop.return }
|
10
|
-
subject(:probe) { described_class.new }
|
11
|
-
|
12
|
-
before do
|
13
|
-
Roqua::Scheduling::CronJob.delete_all
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#call' do
|
17
|
-
it 'sends data to AppSignal' do
|
18
|
-
expect(Appsignal).to receive(:set_gauge).with('scheduler_delay_in_minutes', 10)
|
19
|
-
expect(probe).to receive(:longest_delay_in_minutes).and_return(10)
|
20
|
-
probe.call
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'increments the probe call counter' do
|
24
|
-
expect(Appsignal).to receive(:increment_counter).with('probe.call.completed', 1, probe_name: "monitoring_probe")
|
25
|
-
probe.call
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe 'longest_delay' do
|
30
|
-
it 'returns 0 if there are no schedules' do
|
31
|
-
expect(probe.longest_delay_in_minutes).to eql(0)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'if there is a job that should have run 10 minutes ago' do
|
35
|
-
Roqua::Scheduling::CronJob.create!(
|
36
|
-
name: 'hourly', next_run_at: 10.minutes.ago
|
37
|
-
)
|
38
|
-
expect(probe.longest_delay_in_minutes).to eql(10)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'if there is a job that should have run 10 minutes ago and the previous job was completed 15 minutes ago' do
|
42
|
-
Roqua::Scheduling::CronJob.create!(
|
43
|
-
name: 'hourly', next_run_at: 10.minutes.ago, completed_at: 15.minutes.ago
|
44
|
-
)
|
45
|
-
expect(probe.longest_delay_in_minutes).to eql(10)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'if there is a job that should have run 10 minutes ago and was completed 5 minutes ago' do
|
49
|
-
Roqua::Scheduling::CronJob.create!(
|
50
|
-
name: 'hourly', next_run_at: 10.minutes.ago, completed_at: 5.minutes.ago
|
51
|
-
)
|
52
|
-
expect(probe.longest_delay_in_minutes).to eql(0)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'when there is a job in the future that was never completed' do
|
56
|
-
Roqua::Scheduling::CronJob.create!(
|
57
|
-
name: 'hourly', next_run_at: 3.minutes.from_now
|
58
|
-
)
|
59
|
-
expect(probe.longest_delay_in_minutes).to eql(0)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'when there is a job in the future that was completed' do
|
63
|
-
Roqua::Scheduling::CronJob.create!(
|
64
|
-
name: 'hourly', next_run_at: 3.minutes.from_now, completed_at: 1.minute.ago
|
65
|
-
)
|
66
|
-
expect(probe.longest_delay_in_minutes).to eql(0)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
require 'roqua/responders/active_interaction_aware_responder'
|
4
|
-
class AIAResponder < ActionController::Responder
|
5
|
-
include Roqua::Responders::ActiveInteractionAwareResponder
|
6
|
-
end
|
7
|
-
|
8
|
-
require 'active_interaction'
|
9
|
-
class TestInteraction < ActiveInteraction::Base
|
10
|
-
string :some_string
|
11
|
-
def execute
|
12
|
-
{foo: some_string}
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class ApplicationController < ActionController::Base
|
17
|
-
respond_to :json
|
18
|
-
end
|
19
|
-
|
20
|
-
describe Roqua::Responders::ActiveInteractionAwareResponder, type: :controller do
|
21
|
-
context 'with a valid interaction' do
|
22
|
-
controller(ApplicationController) do
|
23
|
-
self.responder = AIAResponder
|
24
|
-
def index
|
25
|
-
use_case = TestInteraction.run some_string: 'bla'
|
26
|
-
respond_with use_case
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
subject { get :index, format: :json }
|
31
|
-
|
32
|
-
it 'returns the result if valid' do
|
33
|
-
subject
|
34
|
-
expect(response.body).to eq '{"foo":"bla"}'
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'with an invalid interaction' do
|
40
|
-
controller(ApplicationController) do
|
41
|
-
self.responder = AIAResponder
|
42
|
-
def index
|
43
|
-
use_case = TestInteraction.run
|
44
|
-
respond_with use_case
|
45
|
-
end
|
46
|
-
end
|
47
|
-
subject { post :index, format: :json }
|
48
|
-
|
49
|
-
it 'returns the interaction' do
|
50
|
-
subject
|
51
|
-
expect(response.body).to eq '{"errors":{"some_string":["is required"]}}'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'roqua/responders/api_errors_responder'
|
3
|
-
class AEResponder < ActionController::Responder
|
4
|
-
include Roqua::Responders::ApiErrorsResponder
|
5
|
-
end
|
6
|
-
|
7
|
-
class ApplicationController < ActionController::Base
|
8
|
-
respond_to :json
|
9
|
-
end
|
10
|
-
|
11
|
-
class SomeModel
|
12
|
-
include ActiveModel::Model
|
13
|
-
|
14
|
-
attr_accessor :name
|
15
|
-
end
|
16
|
-
|
17
|
-
describe Roqua::Responders::ApiErrorsResponder, type: :controller do
|
18
|
-
context 'with an invalid model' do
|
19
|
-
controller(ApplicationController) do
|
20
|
-
self.responder = AEResponder
|
21
|
-
def index
|
22
|
-
sm = SomeModel.new name: 'foo'
|
23
|
-
sm.errors.add :name, "That is not a real name"
|
24
|
-
respond_with sm
|
25
|
-
end
|
26
|
-
end
|
27
|
-
subject { post :index, format: :json }
|
28
|
-
|
29
|
-
it 'returns the errors scoped on the object name' do
|
30
|
-
subject
|
31
|
-
expect(response.body).to eq '{"errors":{"some_model":{"name":["That is not a real name"]}}}'
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|