fix: tighten reflect usage in pdh and textfile (#2517)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-07 18:28:33 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 453506f3b8
commit 7ee3b0fb9b
6 changed files with 42 additions and 10 deletions
@@ -323,7 +323,7 @@ func (c *Collector) collectObject(ch chan<- prometheus.Metric, perfDataObject Ob
continue
}
if field.Kind() != reflect.TypeFor[prometheus.ValueType]().Kind() {
if field.Type() != reflect.TypeFor[prometheus.ValueType]() {
errs = append(errs, fmt.Errorf("failed to cast MetricType for %s to prometheus.ValueType", counter.Name))
continue
+2 -2
View File
@@ -22,9 +22,9 @@ import (
"fmt"
"io"
"log/slog"
"maps"
"os"
"path/filepath"
"reflect"
"slices"
"sort"
"strings"
@@ -140,7 +140,7 @@ func duplicateMetricEntry(metricFamilies []*dto.MetricFamily) bool {
_, mapContainsKey := uniqueMetrics[metricName]
// Duplicate metric found with identical labels & label values
if mapContainsKey && reflect.DeepEqual(uniqueMetrics[metricName], labels) {
if mapContainsKey && maps.Equal(uniqueMetrics[metricName], labels) {
return true
}
+2 -2
View File
@@ -18,7 +18,7 @@
package config
import (
"reflect"
"maps"
"testing"
"go.yaml.in/yaml/v3"
@@ -49,7 +49,7 @@ func TestConfigFlattening(t *testing.T) {
}
flattenedValues := flatten(data)
if !reflect.DeepEqual(expectedResult, flattenedValues) {
if !maps.Equal(expectedResult, flattenedValues) {
t.Errorf("Flattened values do not match!\nExpected result: %s\nActual result: %s", expectedResult, flattenedValues)
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ func NewCollectorWithReflection(logger *slog.Logger, resultType CounterType, obj
}
if f, ok := valueType.FieldByName("MetricType"); ok {
if f.Type.Kind() == reflect.TypeFor[prometheus.ValueType]().Kind() {
if f.Type == reflect.TypeFor[prometheus.ValueType]() {
collector.metricsTypeIndexValue = f.Index[0]
}
}
+4 -4
View File
@@ -109,13 +109,13 @@ func (c *Collector) Collect(data any) error {
dv = dv.Elem()
elemType := dv.Type().Elem()
elemValue := reflect.ValueOf(reflect.New(elemType).Interface()).Elem()
if dv.Kind() != reflect.Slice || elemType.Kind() != reflect.Struct {
if dv.Kind() != reflect.Slice || dv.Type().Elem().Kind() != reflect.Struct {
return mi.ErrInvalidEntityType
}
elemType := dv.Type().Elem()
elemValue := reflect.ValueOf(reflect.New(elemType).Interface()).Elem()
perfObjects, err := QueryPerformanceData(c.query, c.object)
if err != nil {
return fmt.Errorf("QueryPerformanceData: %w", err)
+32
View File
@@ -18,7 +18,10 @@
package registry
import (
"errors"
"testing"
"github.com/prometheus-community/windows_exporter/internal/mi"
)
// TestNewCollectorStructTypeParam guards against a regression where
@@ -37,6 +40,35 @@ func TestNewCollectorStructTypeParam(t *testing.T) {
}
}
// TestCollectInvalidEntityType guards against a regression where Collect
// called reflect.Type.Elem() on a non-slice destination and panicked instead
// of returning mi.ErrInvalidEntityType.
func TestCollectInvalidEntityType(t *testing.T) {
t.Parallel()
type counterValues struct {
Name string
}
c := &Collector{}
for name, dst := range map[string]any{
"nil": nil,
"non-pointer": []counterValues{},
"pointer to struct": &counterValues{},
"pointer to []int": &[]int{},
"pointer to integer": new(int),
} {
t.Run(name, func(t *testing.T) {
t.Parallel()
if err := c.Collect(dst); !errors.Is(err, mi.ErrInvalidEntityType) {
t.Errorf("expected %v, got %v", mi.ErrInvalidEntityType, err)
}
})
}
}
func BenchmarkQueryPerformanceData(b *testing.B) {
for b.Loop() {
_, _ = QueryPerformanceData("Global", "")