-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from senid231/add-test-gauge-with-time
add tests for gauge_with_time, add rspec matchers
- Loading branch information
Showing
7 changed files
with
198 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative 'rspec/matchers' | ||
|
||
RSpec.configure do |config| | ||
config.include PrometheusExporter::Ext::RSpec::Matchers | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'date' | ||
require_relative 'metric_matcher' | ||
|
||
module PrometheusExporter::Ext::RSpec | ||
module Matchers | ||
def a_prometheus_metric(klass, name) | ||
MetricMatcher.new(klass, name) | ||
end | ||
|
||
# Matches approximate milliseconds since epoch | ||
# @param date_time [DateTime] default DateTime.now | ||
# @param delta [Integer] default 1000 ms | ||
# @return [RSpec::Matchers::BuiltIn::BeWithin] | ||
def ms_since_epoch(date_time: DateTime.now, delta: 1_000) | ||
be_within(delta).of(date_time.strftime('%Q').to_i) | ||
end | ||
|
||
def a_gauge_metric(name) | ||
a_prometheus_metric(PrometheusExporter::Metric::Gauge, name) | ||
end | ||
|
||
def a_gauge_with_time_metric(name) | ||
a_prometheus_metric(PrometheusExporter::Ext::Metric::GaugeWithTime, name) | ||
end | ||
|
||
def a_counter_metric(name) | ||
a_prometheus_metric(PrometheusExporter::Metric::Counter, name) | ||
end | ||
|
||
def a_histogram_metric(name) | ||
a_prometheus_metric(PrometheusExporter::Metric::Histogram, name) | ||
end | ||
|
||
def a_summary_metric(name) | ||
a_prometheus_metric(PrometheusExporter::Metric::Summary, name) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# frozen_string_literal: true | ||
|
||
module PrometheusExporter::Ext::RSpec | ||
class MetricMatcher | ||
include RSpec::Matchers::DSL::DefaultImplementations | ||
include RSpec::Matchers | ||
include RSpec::Matchers::Composable | ||
|
||
attr_reader :metric_class, :metric_name, :metric_payload, :actual | ||
|
||
def initialize(metric_class, metric_name) | ||
@metric_class = metric_class | ||
@metric_name = metric_name.to_s | ||
@metric_payload = nil | ||
end | ||
|
||
def name | ||
'be a prometheus metric' | ||
end | ||
|
||
def expected | ||
"#{metric_class}(name=#{metric_name}, to_h=#{description_of(metric_payload)})" | ||
end | ||
|
||
def matches?(actual) | ||
@actual = actual | ||
|
||
return false unless values_match?(metric_class, actual.class) | ||
return false unless values_match?(metric_name, actual.name.to_s) | ||
return false if !metric_payload.nil? && !values_match?(metric_payload, actual.to_h) | ||
|
||
true | ||
end | ||
|
||
def with(value, labels) | ||
@metric_payload ||= {} | ||
metric_payload[labels.transform_keys(&:to_s)] = value | ||
self | ||
end | ||
|
||
def description_of(object) | ||
RSpec::Support::ObjectFormatter.new(nil).format(object) | ||
end | ||
end | ||
end |
98 changes: 98 additions & 0 deletions
98
spec/prometheus_exporter/ext/metric/gauge_with_time_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'prometheus_exporter/ext/metric/gauge_with_time' | ||
|
||
RSpec.describe PrometheusExporter::Ext::Metric::GaugeWithTime do | ||
describe '#to_prometheus_text' do | ||
subject { metric.to_prometheus_text } | ||
|
||
let(:metric) { described_class.new('metric_name', 'help_msg') } | ||
|
||
it 'returns correct text' do | ||
expect(subject).to eq("# HELP metric_name help_msg\n# TYPE metric_name gauge\n\n") | ||
end | ||
|
||
context 'with metric_text' do | ||
let(:metric_text) { "metric_text 1\nmetric_text 2" } | ||
|
||
before { allow(metric).to receive(:metric_text).once.and_return(metric_text) } | ||
|
||
it 'returns correct text' do | ||
title = "# HELP metric_name help_msg\n# TYPE metric_name gauge" | ||
expect(subject).to eq("#{title}\n#{metric_text}\n") | ||
end | ||
end | ||
end | ||
|
||
describe '#metric_text' do | ||
subject { metric.metric_text.split("\n") } | ||
|
||
let(:metric) { described_class.new('metric_name', 'help_msg') } | ||
|
||
it 'returns correct text' do | ||
expect(subject).to eq([]) | ||
end | ||
|
||
it 'has correct to_h' do | ||
expect(metric.to_h).to eq({}) | ||
end | ||
|
||
context 'when metric has data with stubbed timestamps' do | ||
let!(:date_time_old) { DateTime.now - 25 } | ||
let!(:date_time_new) { DateTime.now } | ||
|
||
before do | ||
allow(DateTime).to receive(:now).once.and_return(date_time_old) | ||
metric.observe(1, 'foo' => 'bar') | ||
|
||
allow(DateTime).to receive(:now).once.and_return(date_time_new) | ||
metric.observe(2, 'baz' => 'boo') | ||
end | ||
|
||
it 'returns correct text' do | ||
expect(subject).to contain_exactly( | ||
%(metric_name{foo="bar"} 1 #{date_time_old.strftime('%Q').to_i}), | ||
%(metric_name{baz="boo"} 2 #{date_time_new.strftime('%Q').to_i}) | ||
) | ||
end | ||
|
||
it 'has correct to_h' do | ||
expect(metric.to_h).to match( | ||
{ | ||
{ 'foo' => 'bar' } => [1, date_time_old.strftime('%Q').to_i], | ||
{ 'baz' => 'boo' } => [2, date_time_new.strftime('%Q').to_i] | ||
} | ||
) | ||
end | ||
|
||
it 'matches a_gauge_with_time_metric' do | ||
expect(metric).to a_gauge_with_time_metric('metric_name') | ||
.with([1, date_time_old.strftime('%Q').to_i], foo: 'bar') | ||
.with([2, date_time_new.strftime('%Q').to_i], baz: 'boo') | ||
end | ||
end | ||
|
||
context 'when metric has data without stubbed timestamps' do | ||
before do | ||
metric.observe(1, 'foo' => 'bar') | ||
sleep 0.2 | ||
metric.observe(2, 'baz' => 'boo') | ||
end | ||
|
||
it 'has correct to_h' do | ||
expect(metric.to_h).to match( | ||
{ | ||
{ 'foo' => 'bar' } => [1, ms_since_epoch], | ||
{ 'baz' => 'boo' } => [2, ms_since_epoch] | ||
} | ||
) | ||
end | ||
|
||
it 'matches a_gauge_with_time_metric' do | ||
expect(metric).to a_gauge_with_time_metric('metric_name') | ||
.with([1, ms_since_epoch], foo: 'bar') | ||
.with([2, ms_since_epoch], baz: 'boo') | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters