Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
loki/pkg/util/time_test.go

306 lines
6.6 KiB

package util
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestTimeFromMillis(t *testing.T) {
var testExpr = []struct {
input int64
expected time.Time
}{
{input: 1000, expected: time.Unix(1, 0)},
{input: 1500, expected: time.Unix(1, 500*nanosecondsInMillisecond)},
}
for i, c := range testExpr {
t.Run(fmt.Sprint(i), func(t *testing.T) {
res := TimeFromMillis(c.input)
require.Equal(t, c.expected, res)
})
}
}
func TestDurationWithJitter(t *testing.T) {
const numRuns = 1000
for i := 0; i < numRuns; i++ {
actual := DurationWithJitter(time.Minute, 0.5)
assert.GreaterOrEqual(t, int64(actual), int64(30*time.Second))
assert.LessOrEqual(t, int64(actual), int64(90*time.Second))
}
}
func TestDurationWithJitter_ZeroInputDuration(t *testing.T) {
assert.Equal(t, time.Duration(0), DurationWithJitter(time.Duration(0), 0.5))
}
func TestDurationWithPositiveJitter(t *testing.T) {
const numRuns = 1000
for i := 0; i < numRuns; i++ {
actual := DurationWithPositiveJitter(time.Minute, 0.5)
assert.GreaterOrEqual(t, int64(actual), int64(60*time.Second))
assert.LessOrEqual(t, int64(actual), int64(90*time.Second))
}
}
func TestDurationWithPositiveJitter_ZeroInputDuration(t *testing.T) {
assert.Equal(t, time.Duration(0), DurationWithPositiveJitter(time.Duration(0), 0.5))
}
func TestParseTime(t *testing.T) {
var tests = []struct {
input string
fail bool
result time.Time
}{
{
input: "",
fail: true,
}, {
input: "abc",
fail: true,
}, {
input: "30s",
fail: true,
}, {
input: "123",
result: time.Unix(123, 0),
}, {
input: "123.123",
result: time.Unix(123, 123000000),
}, {
input: "2015-06-03T13:21:58.555Z",
result: time.Unix(1433337718, 555*time.Millisecond.Nanoseconds()),
}, {
input: "2015-06-03T14:21:58.555+01:00",
result: time.Unix(1433337718, 555*time.Millisecond.Nanoseconds()),
}, {
// Test nanosecond rounding.
input: "2015-06-03T13:21:58.56789Z",
result: time.Unix(1433337718, 567*1e6),
}, {
// Test float rounding.
input: "1543578564.705",
result: time.Unix(1543578564, 705*1e6),
},
}
for _, test := range tests {
ts, err := ParseTime(test.input)
if test.fail {
require.Error(t, err)
continue
}
require.NoError(t, err)
assert.Equal(t, TimeToMillis(test.result), ts)
}
}
func TestNewDisableableTicker_Enabled(t *testing.T) {
stop, ch := NewDisableableTicker(10 * time.Millisecond)
defer stop()
time.Sleep(100 * time.Millisecond)
select {
case <-ch:
break
default:
t.Error("ticker should have ticked when enabled")
}
}
func TestNewDisableableTicker_Disabled(t *testing.T) {
stop, ch := NewDisableableTicker(0)
defer stop()
time.Sleep(100 * time.Millisecond)
select {
case <-ch:
t.Error("ticker should not have ticked when disabled")
default:
break
}
}
type timeInterval struct {
from, through time.Time
}
func TestForInterval(t *testing.T) {
splitInterval := 10 * time.Second
for _, tc := range []struct {
name string
inp timeInterval
expectedIntervals []timeInterval
endTimeInclusive bool
}{
{
name: "range smaller than split interval",
inp: timeInterval{
from: time.Unix(5, 0),
through: time.Unix(8, 0),
},
expectedIntervals: []timeInterval{
{
from: time.Unix(5, 0),
through: time.Unix(8, 0),
},
},
},
{
name: "range exactly equal and aligned to split interval",
inp: timeInterval{
from: time.Unix(10, 0),
through: time.Unix(20, 0),
},
expectedIntervals: []timeInterval{
{
from: time.Unix(10, 0),
through: time.Unix(20, 0),
},
},
},
{
name: "multiple splits with end time not inclusive",
inp: timeInterval{
from: time.Unix(5, 0),
through: time.Unix(28, 0),
},
expectedIntervals: []timeInterval{
{
from: time.Unix(5, 0),
through: time.Unix(10, 0),
},
{
from: time.Unix(10, 0),
through: time.Unix(20, 0),
},
{
from: time.Unix(20, 0),
through: time.Unix(28, 0),
},
},
},
{
name: "multiple splits with end time inclusive",
inp: timeInterval{
from: time.Unix(5, 0),
through: time.Unix(28, 0),
},
endTimeInclusive: true,
expectedIntervals: []timeInterval{
{
from: time.Unix(5, 0),
through: time.Unix(10, 0).Add(-time.Millisecond),
},
{
from: time.Unix(10, 0),
through: time.Unix(20, 0).Add(-time.Millisecond),
},
{
from: time.Unix(20, 0),
through: time.Unix(28, 0),
},
},
},
} {
t.Run(tc.name, func(t *testing.T) {
var actualIntervals []timeInterval
ForInterval(splitInterval, tc.inp.from, tc.inp.through, tc.endTimeInclusive, func(start, end time.Time) {
actualIntervals = append(actualIntervals, timeInterval{
from: start,
through: end,
})
})
require.Equal(t, tc.expectedIntervals, actualIntervals)
})
}
}
func TestForInterval_OfZero(t *testing.T) {
var actualIntervals []timeInterval
from := time.Unix(5, 0)
through := time.Unix(8, 0)
endTimeInclusive := true
ForInterval(0, from, through, endTimeInclusive, func(start, end time.Time) {
actualIntervals = append(actualIntervals, timeInterval{
from: start,
through: end,
})
})
require.Equal(t, []timeInterval{
{
from: time.Unix(5, 0),
through: time.Unix(8, 0),
},
}, actualIntervals)
}
func TestGetFactorOfTime(t *testing.T) {
for _, tc := range []struct {
desc string
from, through, extentMin, extentMax int64
exp float64
}{
{
desc: "equal",
from: 10, through: 20,
extentMin: 10, extentMax: 20,
exp: 1,
},
{
desc: "50% overlap on left",
from: 10, through: 20,
extentMin: 5, extentMax: 15,
exp: 0.5,
},
{
desc: "50% overlap on right",
from: 10, through: 20,
extentMin: 15, extentMax: 25,
exp: 0.5,
},
{
desc: "10% overlap on right",
from: 15, through: 16,
extentMin: 15, extentMax: 25,
exp: 0.1,
},
{
desc: "no overlap",
from: 10, through: 20,
extentMin: 25, extentMax: 35,
exp: 0,
},
{
desc: "no overlap, through=extentMin",
from: 10, through: 20,
extentMin: 20, extentMax: 35,
exp: 0,
},
{
desc: "factor would be NaN",
from: 1685655637000000000, through: 1685656237000000000,
extentMin: 1685656107442496000, extentMax: 1685656107442496000,
exp: 1,
},
} {
t.Run(tc.desc, func(t *testing.T) {
factor := GetFactorOfTime(tc.from, tc.through, tc.extentMin, tc.extentMax)
require.Equal(t, tc.exp, factor)
})
}
}