Files
zeekay a69115fd35 fork: prometheus/common v0.67.5 — drop mwitkow/go-conntrack instrumentation
Module path renamed github.com/prometheus/common → github.com/hanzoai/common.
The only functional patch is config/http_config.go: strip conntrack-based
dial-context instrumentation, replace with stdlib net.Dialer. This breaks
the transitive chain prometheus/common/config → mwitkow/go-conntrack →
prometheus/client_golang/prometheus that was leaking into every consumer
of prometheus/common/config (alertmanager notifiers, etc.).

Functional impact: HTTP clients built via NewClientFromConfig no longer
emit go-conntrack connection-tracking metrics (active/closed counters).
The connection count is observable via the underlying http.Transport
metrics that luxfi/metric ships, so this is loss-of-observability-zero
for callers on the Hanzo/Lux stack.
2026-05-22 21:07:19 -07:00

463 lines
9.9 KiB
Go

// Copyright 2013 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package model
import (
"encoding/json"
"strconv"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestComparators(t *testing.T) {
t1a := TimeFromUnix(0)
t1b := TimeFromUnix(0)
t2 := TimeFromUnix(2*second - 1)
require.Truef(t, t1a.Equal(t1b), "Expected %s to be equal to %s", t1a, t1b)
require.Falsef(t, t1a.Equal(t2), "Expected %s to not be equal to %s", t1a, t2)
require.Truef(t, t1a.Before(t2), "Expected %s to be before %s", t1a, t2)
require.Falsef(t, t1a.Before(t1b), "Expected %s to not be before %s", t1a, t1b)
require.Truef(t, t2.After(t1a), "Expected %s to be after %s", t2, t1a)
require.Falsef(t, t1b.After(t1a), "Expected %s to not be after %s", t1b, t1a)
}
func TestTimeConversions(t *testing.T) {
unixSecs := int64(1136239445)
unixNsecs := int64(123456789)
unixNano := unixSecs*1e9 + unixNsecs
t1 := time.Unix(unixSecs, unixNsecs-unixNsecs%nanosPerTick)
t2 := time.Unix(unixSecs, unixNsecs)
ts := TimeFromUnixNano(unixNano)
require.Truef(t, ts.Time().Equal(t1), "Expected %s, got %s", t1, ts.Time())
// Test available precision.
ts = TimeFromUnixNano(t2.UnixNano())
require.Truef(t, ts.Time().Equal(t1), "Expected %s, got %s", t1, ts.Time())
require.Equalf(t, ts.UnixNano(), unixNano-unixNano%nanosPerTick, "Expected %d, got %d", unixNano, ts.UnixNano())
}
func TestDuration(t *testing.T) {
duration := time.Second + time.Minute + time.Hour
goTime := time.Unix(1136239445, 0)
ts := TimeFromUnix(goTime.Unix())
require.Truef(t, goTime.Add(duration).Equal(ts.Add(duration).Time()), "Expected %s to be equal to %s", goTime.Add(duration), ts.Add(duration))
earlier := ts.Add(-duration)
delta := ts.Sub(earlier)
require.Equalf(t, delta, duration, "Expected %s to be equal to %s", delta, duration)
}
func TestParseDuration(t *testing.T) {
type testCase struct {
in string
out time.Duration
expectedString string
allowedNegative bool
}
baseCases := []testCase{
{
in: "0",
out: 0,
expectedString: "0s",
allowedNegative: false,
},
{
in: "0w",
out: 0,
expectedString: "0s",
allowedNegative: false,
},
{
in: "0s",
out: 0,
expectedString: "",
allowedNegative: false,
},
{
in: "324ms",
out: 324 * time.Millisecond,
expectedString: "",
allowedNegative: false,
},
{
in: "3s",
out: 3 * time.Second,
expectedString: "",
allowedNegative: false,
},
{
in: "5m",
out: 5 * time.Minute,
expectedString: "",
allowedNegative: false,
},
{
in: "1h",
out: time.Hour,
expectedString: "",
allowedNegative: false,
},
{
in: "4d",
out: 4 * 24 * time.Hour,
expectedString: "",
allowedNegative: false,
},
{
in: "4d1h",
out: 4*24*time.Hour + time.Hour,
expectedString: "",
allowedNegative: false,
},
{
in: "14d",
out: 14 * 24 * time.Hour,
expectedString: "2w",
allowedNegative: false,
},
{
in: "3w",
out: 3 * 7 * 24 * time.Hour,
expectedString: "",
allowedNegative: false,
},
{
in: "3w2d1h",
out: 3*7*24*time.Hour + 2*24*time.Hour + time.Hour,
expectedString: "23d1h",
allowedNegative: false,
},
{
in: "10y",
out: 10 * 365 * 24 * time.Hour,
expectedString: "",
allowedNegative: false,
},
}
negativeCases := []testCase{
{
in: "-3s",
out: -3 * time.Second,
expectedString: "",
allowedNegative: true,
},
{
in: "-5m",
out: -5 * time.Minute,
expectedString: "",
allowedNegative: true,
},
{
in: "-1h",
out: -1 * time.Hour,
expectedString: "",
allowedNegative: true,
},
{
in: "-2d",
out: -2 * 24 * time.Hour,
expectedString: "",
allowedNegative: true,
},
{
in: "-1w",
out: -7 * 24 * time.Hour,
expectedString: "",
allowedNegative: true,
},
{
in: "-3w2d1h",
out: -(3*7*24*time.Hour + 2*24*time.Hour + time.Hour),
expectedString: "-23d1h",
allowedNegative: true,
},
{
in: "-10y",
out: -10 * 365 * 24 * time.Hour,
expectedString: "",
allowedNegative: true,
},
}
for _, c := range baseCases {
c.allowedNegative = true
negativeCases = append(negativeCases, c)
}
allCases := append(baseCases, negativeCases...)
for _, c := range allCases {
var (
d Duration
err error
)
if c.allowedNegative {
d, err = ParseDurationAllowNegative(c.in)
} else {
d, err = ParseDuration(c.in)
}
if err != nil {
t.Errorf("Unexpected error on input %q", c.in)
}
if time.Duration(d) != c.out {
t.Errorf("Expected %v but got %v", c.out, d)
}
expectedString := c.expectedString
if expectedString == "" {
expectedString = c.in
}
if d.String() != expectedString {
t.Errorf("Expected duration string %q but got %q", c.in, d.String())
}
}
}
func TestDuration_UnmarshalText(t *testing.T) {
cases := []struct {
in string
out time.Duration
expectedString string
}{
{
in: "0",
out: 0,
expectedString: "0s",
}, {
in: "0w",
out: 0,
expectedString: "0s",
}, {
in: "0s",
out: 0,
}, {
in: "324ms",
out: 324 * time.Millisecond,
}, {
in: "3s",
out: 3 * time.Second,
}, {
in: "5m",
out: 5 * time.Minute,
}, {
in: "1h",
out: time.Hour,
}, {
in: "4d",
out: 4 * 24 * time.Hour,
}, {
in: "4d1h",
out: 4*24*time.Hour + time.Hour,
}, {
in: "14d",
out: 14 * 24 * time.Hour,
expectedString: "2w",
}, {
in: "3w",
out: 3 * 7 * 24 * time.Hour,
}, {
in: "3w2d1h",
out: 3*7*24*time.Hour + 2*24*time.Hour + time.Hour,
expectedString: "23d1h",
}, {
in: "10y",
out: 10 * 365 * 24 * time.Hour,
},
}
for _, c := range cases {
var d Duration
err := d.UnmarshalText([]byte(c.in))
if err != nil {
t.Errorf("Unexpected error on input %q", c.in)
}
if time.Duration(d) != c.out {
t.Errorf("Expected %v but got %v", c.out, d)
}
expectedString := c.expectedString
if c.expectedString == "" {
expectedString = c.in
}
text, _ := d.MarshalText() // MarshalText returns hardcoded nil
if string(text) != expectedString {
t.Errorf("Expected duration string %q but got %q", c.in, d.String())
}
}
}
func TestDuration_UnmarshalJSON(t *testing.T) {
cases := []struct {
in string
out time.Duration
expectedString string
}{
{
in: `"0"`,
out: 0,
expectedString: `"0s"`,
},
{
in: `"0w"`,
out: 0,
expectedString: `"0s"`,
},
{
in: `"0s"`,
out: 0,
},
{
in: `"324ms"`,
out: 324 * time.Millisecond,
},
{
in: `"3s"`,
out: 3 * time.Second,
},
{
in: `"5m"`,
out: 5 * time.Minute,
},
{
in: `"1h"`,
out: time.Hour,
},
{
in: `"4d"`,
out: 4 * 24 * time.Hour,
},
{
in: `"4d1h"`,
out: 4*24*time.Hour + time.Hour,
},
{
in: `"14d"`,
out: 14 * 24 * time.Hour,
expectedString: `"2w"`,
},
{
in: `"3w"`,
out: 3 * 7 * 24 * time.Hour,
},
{
in: `"3w2d1h"`,
out: 3*7*24*time.Hour + 2*24*time.Hour + time.Hour,
expectedString: `"23d1h"`,
},
{
in: `"10y"`,
out: 10 * 365 * 24 * time.Hour,
},
{
in: `"289y"`,
out: 289 * 365 * 24 * time.Hour,
},
}
for _, c := range cases {
var d Duration
err := json.Unmarshal([]byte(c.in), &d)
if err != nil {
t.Errorf("Unexpected error on input %q", c.in)
}
if time.Duration(d) != c.out {
t.Errorf("Expected %v but got %v", c.out, d)
}
expectedString := c.expectedString
if c.expectedString == "" {
expectedString = c.in
}
bytes, err := json.Marshal(d)
if err != nil {
t.Errorf("Unexpected error on marshal of %v: %s", d, err)
}
if string(bytes) != expectedString {
t.Errorf("Expected duration string %q but got %q", c.in, d.String())
}
}
}
func TestParseBadDuration(t *testing.T) {
cases := []string{
"1",
"1y1m1d",
"1.5d",
"d",
"294y",
"200y10400w",
"107675d",
"2584200h",
"",
}
for _, c := range cases {
_, err := ParseDuration(c)
if err == nil {
t.Errorf("Expected error on input %s", c)
}
}
}
func TestTimeJSON(t *testing.T) {
tests := []struct {
in Time
out string
}{
{Time(1), `0.001`},
{Time(-1), `-0.001`},
}
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
b, err := test.in.MarshalJSON()
require.NoErrorf(t, err, "Error marshaling time: %v", err)
if string(b) != test.out {
t.Errorf("Mismatch in marshal expected=%s actual=%s", test.out, b)
}
var tm Time
err = tm.UnmarshalJSON(b)
require.NoErrorf(t, err, "Error Unmarshaling time: %v", err)
require.Truef(t, test.in.Equal(tm), "Mismatch after Unmarshal expected=%v actual=%v", test.in, tm)
})
}
}
func BenchmarkParseDuration(b *testing.B) {
const data = "30s"
for i := 0; i < b.N; i++ {
_, err := ParseDuration(data)
require.NoError(b, err)
}
}