mirror of
https://github.com/hikhvar/mqtt2prometheus.git
synced 2026-02-14 09:59:52 +00:00
When generating metric values using expression evaluation, there are new use-cases for more than one configuration for each sensor value. Expressions are more flexible than aggregation rules in Prometheus, so it makes sense to derive multiple metrics from the same sensor input.
159 lines
3.7 KiB
Go
159 lines
3.7 KiB
Go
package metrics
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/hikhvar/mqtt2prometheus/pkg/config"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
func TestNewJSONObjectExtractor_parseMetric(t *testing.T) {
|
|
now = testNow
|
|
type fields struct {
|
|
metricConfigs map[string][]*config.MetricConfig
|
|
}
|
|
type args struct {
|
|
metricPath string
|
|
deviceID string
|
|
value string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
separator string
|
|
fields fields
|
|
args args
|
|
want Metric
|
|
wantErr bool
|
|
noValue bool
|
|
}{
|
|
{
|
|
name: "string value",
|
|
separator: "->",
|
|
fields: fields{
|
|
map[string][]*config.MetricConfig{
|
|
"SDS0X1->PM2->5": {
|
|
{
|
|
PrometheusName: "temperature",
|
|
MQTTName: "SDS0X1.PM2.5",
|
|
ValueType: "gauge",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
metricPath: "topic",
|
|
deviceID: "dht22",
|
|
value: "{\"SDS0X1\":{\"PM2\":{\"5\":4.9}}}",
|
|
},
|
|
want: Metric{
|
|
Description: prometheus.NewDesc("temperature", "", []string{"sensor", "topic"}, nil),
|
|
ValueType: prometheus.GaugeValue,
|
|
Value: 4.9,
|
|
IngestTime: testNow(),
|
|
Topic: "topic",
|
|
},
|
|
}, {
|
|
name: "string value with dots in path",
|
|
separator: "->",
|
|
fields: fields{
|
|
map[string][]*config.MetricConfig{
|
|
"SDS0X1->PM2.5": {
|
|
{
|
|
PrometheusName: "temperature",
|
|
MQTTName: "SDS0X1->PM2.5",
|
|
ValueType: "gauge",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
metricPath: "topic",
|
|
deviceID: "dht22",
|
|
value: "{\"SDS0X1\":{\"PM2.5\":4.9,\"PM10\":8.5}}",
|
|
},
|
|
want: Metric{
|
|
Description: prometheus.NewDesc("temperature", "", []string{"sensor", "topic"}, nil),
|
|
ValueType: prometheus.GaugeValue,
|
|
Value: 4.9,
|
|
IngestTime: testNow(),
|
|
Topic: "topic",
|
|
},
|
|
}, {
|
|
name: "metric matching SensorNameFilter",
|
|
separator: ".",
|
|
fields: fields{
|
|
map[string][]*config.MetricConfig{
|
|
"temperature": {
|
|
{
|
|
PrometheusName: "temperature",
|
|
MQTTName: "temperature",
|
|
ValueType: "gauge",
|
|
SensorNameFilter: *config.MustNewRegexp(".*22$"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
metricPath: "topic",
|
|
deviceID: "dht22",
|
|
value: "{\"temperature\": 8.5}",
|
|
},
|
|
want: Metric{
|
|
Description: prometheus.NewDesc("temperature", "", []string{"sensor", "topic"}, nil),
|
|
ValueType: prometheus.GaugeValue,
|
|
Value: 8.5,
|
|
IngestTime: testNow(),
|
|
Topic: "topic",
|
|
},
|
|
}, {
|
|
name: "metric not matching SensorNameFilter",
|
|
separator: ".",
|
|
fields: fields{
|
|
map[string][]*config.MetricConfig{
|
|
"temperature": {
|
|
{
|
|
PrometheusName: "temperature",
|
|
MQTTName: "temperature",
|
|
ValueType: "gauge",
|
|
SensorNameFilter: *config.MustNewRegexp(".*fail$"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
args: args{
|
|
metricPath: "topic",
|
|
deviceID: "dht22",
|
|
value: "{\"temperature\": 8.5}",
|
|
},
|
|
want: Metric{},
|
|
noValue: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
p := Parser{
|
|
separator: tt.separator,
|
|
metricConfigs: tt.fields.metricConfigs,
|
|
}
|
|
extractor := NewJSONObjectExtractor(p)
|
|
|
|
got, err := extractor(tt.args.metricPath, []byte(tt.args.value), tt.args.deviceID)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("parseMetric() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
|
|
if len(got) == 0 {
|
|
if !tt.noValue {
|
|
t.Errorf("parseMetric() got = %v, want %v", nil, tt.want)
|
|
}
|
|
} else if !reflect.DeepEqual(got[0], tt.want) {
|
|
t.Errorf("parseMetric() got = %v, want %v", got[0], tt.want)
|
|
} else if len(got) > 1 {
|
|
t.Errorf("unexpected result got = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|