#46 Add Prometheus exporter
This commit is contained in:

committed by
Sebastian Serth

parent
39fcd255f9
commit
44b32b6f6a
@ -1,5 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :rfc, class: RequestForComment do
|
||||
factory :rfc, class: 'RequestForComment' do
|
||||
association :user, factory: :external_user
|
||||
association :submission
|
||||
association :exercise, factory: :dummy
|
||||
@ -7,5 +9,12 @@ FactoryBot.define do
|
||||
sequence :question do |n|
|
||||
"test question #{n}"
|
||||
end
|
||||
|
||||
factory :rfc_with_comment, class: 'RequestForComment' do
|
||||
after(:create) do |rfc|
|
||||
rfc.file = rfc.submission.files.first
|
||||
Comment.create(file: rfc.file, user: rfc.user, text: "comment for rfc #{rfc.question}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
101
spec/features/prometheus/controller_spec.rb
Normal file
101
spec/features/prometheus/controller_spec.rb
Normal file
@ -0,0 +1,101 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Prometheus::Controller do
|
||||
def stub_metrics
|
||||
%i[increment decrement observe].each do |method|
|
||||
%i[@instance_count @rfc_count @rfc_commented_count].each do |metric|
|
||||
allow(described_class.instance_variable_get(metric)).to receive(method)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
ApplicationRecord.include Prometheus::Record
|
||||
described_class.initialize_metrics
|
||||
stub_metrics
|
||||
end
|
||||
|
||||
describe 'instance count' do
|
||||
it 'initializes the metrics with the current database entries' do
|
||||
FactoryBot.create_list(:proxy_exercise, 3)
|
||||
described_class.register_metrics
|
||||
stub_metrics
|
||||
described_class.initialize_instance_count
|
||||
expect(described_class.instance_variable_get(:@instance_count)).to(have_received(:observe).with(ProxyExercise.count, class: ProxyExercise.name).once)
|
||||
end
|
||||
|
||||
it 'gets notified when an object is created' do
|
||||
allow(described_class).to receive(:create_notification)
|
||||
proxy_exercise = FactoryBot.create(:proxy_exercise)
|
||||
expect(described_class).to have_received(:create_notification).with(proxy_exercise).once
|
||||
end
|
||||
|
||||
it 'gets notified when an object is destroyed' do
|
||||
allow(described_class).to receive(:destroy_notification)
|
||||
proxy_exercise = FactoryBot.create(:proxy_exercise).destroy
|
||||
expect(described_class).to have_received(:destroy_notification).with(proxy_exercise).once
|
||||
end
|
||||
|
||||
it 'increments gauge when creating a new instance' do
|
||||
FactoryBot.create(:proxy_exercise)
|
||||
expect(described_class.instance_variable_get(:@instance_count)).to(
|
||||
have_received(:increment).with(class: ProxyExercise.name).once
|
||||
)
|
||||
end
|
||||
|
||||
it 'decrements gauge when deleting an object' do
|
||||
FactoryBot.create(:proxy_exercise).destroy
|
||||
expect(described_class.instance_variable_get(:@instance_count)).to(
|
||||
have_received(:decrement).with(class: ProxyExercise.name).once
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'rfc count' do
|
||||
context 'when initializing an rfc' do
|
||||
it 'updates rfc count when creating an ongoing rfc' do
|
||||
FactoryBot.create(:rfc)
|
||||
expect(described_class.instance_variable_get(:@rfc_count)).to(
|
||||
have_received(:increment).with(state: RequestForComment::ONGOING).once
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when changing the state of an rfc' do
|
||||
let(:rfc) { FactoryBot.create(:rfc) }
|
||||
|
||||
it 'updates rfc count when soft-solving an rfc' do
|
||||
rfc.full_score_reached = true
|
||||
rfc.save
|
||||
expect(described_class.instance_variable_get(:@rfc_count)).to(have_received(:increment).with(state: RequestForComment::SOFT_SOLVED).once)
|
||||
expect(described_class.instance_variable_get(:@rfc_count)).to(have_received(:decrement).with(state: RequestForComment::ONGOING).once)
|
||||
end
|
||||
|
||||
it 'updates rfc count when solving an rfc' do
|
||||
rfc.solved = true
|
||||
rfc.save
|
||||
expect(described_class.instance_variable_get(:@rfc_count)).to(have_received(:increment).with(state: RequestForComment::SOLVED).once)
|
||||
expect(described_class.instance_variable_get(:@rfc_count)).to(have_received(:decrement).with(state: RequestForComment::ONGOING).once)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when commenting an rfc' do
|
||||
it 'updates comment metric when commenting an rfc' do
|
||||
FactoryBot.create(:rfc_with_comment)
|
||||
expect(described_class.instance_variable_get(:@rfc_commented_count)).to have_received(:increment)
|
||||
end
|
||||
|
||||
it 'does not update comment metric when commenting an rfc that already has a comment' do
|
||||
rfc = FactoryBot.create(:rfc_with_comment)
|
||||
expect(described_class.instance_variable_get(:@rfc_commented_count)).to have_received(:increment).once
|
||||
|
||||
Comment.create(file: rfc.file, user: rfc.user, text: "comment a for rfc #{rfc.question}")
|
||||
Comment.create(file: rfc.file, user: rfc.user, text: "comment b for rfc #{rfc.question}")
|
||||
# instance count has only been updated for the creation of the commented rfc and not for additional comments
|
||||
expect(described_class.instance_variable_get(:@rfc_commented_count)).to have_received(:increment).once
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
19
spec/models/request_for_comment_spec.rb
Normal file
19
spec/models/request_for_comment_spec.rb
Normal file
@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe RequestForComment do
|
||||
let!(:rfc) { FactoryBot.create(:rfc) }
|
||||
|
||||
describe 'scope with_comments' do
|
||||
let!(:rfc2) { FactoryBot.create(:rfc_with_comment) }
|
||||
|
||||
it 'includes all RfCs with comments' do
|
||||
expect(described_class.with_comments).to include(rfc2)
|
||||
end
|
||||
|
||||
it 'does not include any RfC without a comment' do
|
||||
expect(described_class.with_comments).not_to include(rfc)
|
||||
end
|
||||
end
|
||||
end
|
@ -1,7 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
||||
ENV['RAILS_ENV'] ||= 'test'
|
||||
require 'spec_helper'
|
||||
require File.expand_path('../../config/environment', __FILE__)
|
||||
require 'support/prometheus_client_stub'
|
||||
require File.expand_path('../config/environment', __dir__)
|
||||
require 'rspec/rails'
|
||||
require 'pundit/rspec'
|
||||
|
||||
@ -12,7 +15,7 @@ require 'pundit/rspec'
|
||||
# run twice. It is recommended that you do not name files matching this glob to
|
||||
# end with _spec.rb. You can configure this pattern with with the --pattern
|
||||
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
|
||||
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
|
||||
Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
|
||||
|
||||
# Checks for pending migrations before tests are run.
|
||||
# If you are not using ActiveRecord, you can remove this line.
|
||||
|
15
spec/support/prometheus_client_stub.rb
Normal file
15
spec/support/prometheus_client_stub.rb
Normal file
@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'prometheus_exporter/client'
|
||||
require 'rails_helper'
|
||||
|
||||
module Prometheus
|
||||
# A stub to disable server functionality in the specs and stub all registered metrics
|
||||
module StubClient
|
||||
def send(str)
|
||||
# Do nothing
|
||||
end
|
||||
end
|
||||
|
||||
PrometheusExporter::Client.prepend StubClient
|
||||
end
|
Reference in New Issue
Block a user