-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The previous pseudo class LabelSet didn't communicate the behavior very well. This change introduces a real validator class. This does not only make the validation character clear, but will also allow it to validate label sets per metric object, instead of using the previous global lookup table.
- Loading branch information
Showing
6 changed files
with
145 additions
and
105 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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,59 @@ | ||
# encoding: UTF-8 | ||
|
||
module Prometheus | ||
module Client | ||
# LabelSetValidator ensures that all used label sets comply with the | ||
# Prometheus specification. | ||
class LabelSetValidator | ||
# TODO: we might allow setting :instance in the future | ||
RESERVED_LABELS = [:job, :instance] | ||
|
||
class LabelSetError < StandardError; end | ||
class InvalidLabelSetError < LabelSetError; end | ||
class InvalidLabelError < LabelSetError; end | ||
class ReservedLabelError < LabelSetError; end | ||
|
||
def initialize | ||
@validated = {} | ||
end | ||
|
||
def valid?(labels) | ||
unless labels.respond_to?(:all?) | ||
fail InvalidLabelSetError, "#{labels} is not a valid label set" | ||
end | ||
|
||
labels.all? do |key, _| | ||
validate_symbol(key) | ||
validate_name(key) | ||
validate_reserved_key(key) | ||
end | ||
end | ||
|
||
def validate(labels) | ||
@validated[labels.hash] ||= valid?(labels) | ||
|
||
labels | ||
end | ||
|
||
private | ||
|
||
def validate_symbol(key) | ||
return true if key.is_a?(Symbol) | ||
|
||
fail InvalidLabelError, "label #{key} is not a symbol" | ||
end | ||
|
||
def validate_name(key) | ||
return true unless key.to_s.start_with?('__') | ||
|
||
fail ReservedLabelError, "label #{key} must not start with __" | ||
end | ||
|
||
def validate_reserved_key(key) | ||
return true unless RESERVED_LABELS.include?(key) | ||
|
||
fail ReservedLabelError, "#{key} is reserved" | ||
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
This file was deleted.
Oops, something went wrong.
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,61 @@ | ||
# encoding: UTF-8 | ||
|
||
require 'prometheus/client/label_set_validator' | ||
|
||
describe Prometheus::Client::LabelSetValidator do | ||
let(:validator) { Prometheus::Client::LabelSetValidator.new } | ||
let(:invalid) { Prometheus::Client::LabelSetValidator::InvalidLabelSetError } | ||
|
||
describe '.new' do | ||
it 'returns an instance of a LabelSetValidator' do | ||
expect(validator).to be_a(Prometheus::Client::LabelSetValidator) | ||
end | ||
end | ||
|
||
describe '#valid?' do | ||
it 'returns true for a valid label check' do | ||
expect(validator.valid?(version: 'alpha')).to eql(true) | ||
end | ||
|
||
it 'raises Invaliddescribed_classError if a label set is not a hash' do | ||
expect do | ||
validator.valid?('invalid') | ||
end.to raise_exception invalid | ||
end | ||
|
||
it 'raises InvalidLabelError if a label key is not a symbol' do | ||
expect do | ||
validator.valid?('key' => 'value') | ||
end.to raise_exception(described_class::InvalidLabelError) | ||
end | ||
|
||
it 'raises InvalidLabelError if a label key starts with __' do | ||
expect do | ||
validator.valid?(__reserved__: 'key') | ||
end.to raise_exception(described_class::ReservedLabelError) | ||
end | ||
|
||
it 'raises ReservedLabelError if a label key is reserved' do | ||
[:job, :instance].each do |label| | ||
expect do | ||
validator.valid?(label => 'value') | ||
end.to raise_exception(described_class::ReservedLabelError) | ||
end | ||
end | ||
end | ||
|
||
describe '#validate' do | ||
it 'returns a given valid label set' do | ||
hash = { version: 'alpha' } | ||
|
||
expect(validator.validate(hash)).to eql(hash) | ||
end | ||
|
||
it 'raises an exception if a given label set is not valid' do | ||
input = 'broken' | ||
validator.should_receive(:valid?).with(input).and_raise(invalid) | ||
|
||
expect { validator.validate(input) }.to raise_exception(invalid) | ||
end | ||
end | ||
end |