167 lines
3.4 KiB
Go
167 lines
3.4 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package nomad
|
|
|
|
import (
|
|
"bytes"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"github.com/hashicorp/go-msgpack/codec"
|
|
"github.com/hashicorp/nomad/ci"
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
)
|
|
|
|
func TestTimeTable(t *testing.T) {
|
|
ci.Parallel(t)
|
|
tt := NewTimeTable(time.Second, time.Minute)
|
|
|
|
index := tt.NearestIndex(time.Now())
|
|
if index != 0 {
|
|
t.Fatalf("bad: %v", index)
|
|
}
|
|
|
|
when := tt.NearestTime(1000)
|
|
if !when.IsZero() {
|
|
t.Fatalf("bad: %v", when)
|
|
}
|
|
|
|
// Witness some data
|
|
start := time.Now()
|
|
plusOne := start.Add(time.Minute)
|
|
plusTwo := start.Add(2 * time.Minute)
|
|
plusFive := start.Add(5 * time.Minute)
|
|
plusThirty := start.Add(30 * time.Minute)
|
|
plusHour := start.Add(60 * time.Minute)
|
|
plusHourHalf := start.Add(90 * time.Minute)
|
|
|
|
tt.Witness(2, start)
|
|
tt.Witness(2, start)
|
|
|
|
tt.Witness(10, plusOne)
|
|
tt.Witness(10, plusOne)
|
|
|
|
tt.Witness(20, plusTwo)
|
|
tt.Witness(20, plusTwo)
|
|
|
|
tt.Witness(30, plusFive)
|
|
tt.Witness(30, plusFive)
|
|
|
|
tt.Witness(40, plusThirty)
|
|
tt.Witness(40, plusThirty)
|
|
|
|
tt.Witness(50, plusHour)
|
|
tt.Witness(50, plusHour)
|
|
|
|
type tcase struct {
|
|
when time.Time
|
|
expectIndex uint64
|
|
|
|
index uint64
|
|
expectWhen time.Time
|
|
}
|
|
cases := []tcase{
|
|
// Exact match
|
|
{start, 2, 2, start},
|
|
{plusOne, 10, 10, plusOne},
|
|
{plusHour, 50, 50, plusHour},
|
|
|
|
// Before the newest entry
|
|
{plusHourHalf, 50, 51, plusHour},
|
|
|
|
// After the oldest entry
|
|
{time.Time{}, 0, 1, time.Time{}},
|
|
|
|
// Mid range
|
|
{start.Add(3 * time.Minute), 20, 25, plusTwo},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
index := tt.NearestIndex(tc.when)
|
|
if index != tc.expectIndex {
|
|
t.Fatalf("bad: %v %v", index, tc.expectIndex)
|
|
}
|
|
|
|
when := tt.NearestTime(tc.index)
|
|
if when != tc.expectWhen {
|
|
t.Fatalf("bad: for %d %v %v", tc.index, when, tc.expectWhen)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTimeTable_SerializeDeserialize(t *testing.T) {
|
|
ci.Parallel(t)
|
|
tt := NewTimeTable(time.Second, time.Minute)
|
|
|
|
// Witness some data
|
|
start := time.Now()
|
|
plusOne := start.Add(time.Minute)
|
|
plusTwo := start.Add(2 * time.Minute)
|
|
plusFive := start.Add(5 * time.Minute)
|
|
plusThirty := start.Add(30 * time.Minute)
|
|
plusHour := start.Add(60 * time.Minute)
|
|
|
|
tt.Witness(2, start)
|
|
tt.Witness(10, plusOne)
|
|
tt.Witness(20, plusTwo)
|
|
tt.Witness(30, plusFive)
|
|
tt.Witness(40, plusThirty)
|
|
tt.Witness(50, plusHour)
|
|
|
|
var buf bytes.Buffer
|
|
enc := codec.NewEncoder(&buf, structs.MsgpackHandle)
|
|
|
|
err := tt.Serialize(enc)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
|
|
dec := codec.NewDecoder(&buf, structs.MsgpackHandle)
|
|
|
|
tt2 := NewTimeTable(time.Second, time.Minute)
|
|
err = tt2.Deserialize(dec)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
|
|
o := cmp.AllowUnexported(TimeTable{})
|
|
o2 := cmpopts.IgnoreTypes(sync.RWMutex{})
|
|
if !cmp.Equal(tt.table, tt2.table, o, o2) {
|
|
t.Fatalf("bad: %s", cmp.Diff(tt, tt2, o, o2))
|
|
}
|
|
}
|
|
|
|
func TestTimeTable_Overflow(t *testing.T) {
|
|
ci.Parallel(t)
|
|
tt := NewTimeTable(time.Second, 3*time.Second)
|
|
|
|
// Witness some data
|
|
start := time.Now()
|
|
plusOne := start.Add(time.Second)
|
|
plusTwo := start.Add(2 * time.Second)
|
|
plusThree := start.Add(3 * time.Second)
|
|
|
|
tt.Witness(10, start)
|
|
tt.Witness(20, plusOne)
|
|
tt.Witness(30, plusTwo)
|
|
tt.Witness(40, plusThree)
|
|
|
|
if len(tt.table) != 3 {
|
|
t.Fatalf("bad")
|
|
}
|
|
|
|
index := tt.NearestIndex(start)
|
|
if index != 0 {
|
|
t.Fatalf("bad: %v %v", index, 0)
|
|
}
|
|
|
|
when := tt.NearestTime(15)
|
|
if !when.IsZero() {
|
|
t.Fatalf("bad: %v", when)
|
|
}
|
|
}
|