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.
 
 
 
 
 
 

49 lines
1.6 KiB

package startup
import (
"context"
"errors"
"testing"
"time"
)
func TestBootstrapOnlyRepairsUninitializedClockOnce(t *testing.T) {
now := time.Unix(300, 0)
calls := 0
b, err := NewClockBootstrap(func() time.Time { return now }, func(_ context.Context, target time.Time) error { calls++; now = target; return nil })
if err != nil {
t.Fatal(err)
}
token := b.Token()
target := time.Date(2026, 9, 9, 1, 0, 0, 0, time.UTC)
if err = b.Sync(context.Background(), "wrong", target); err == nil || calls != 0 {
t.Fatal("bad token accepted")
}
if err = b.Sync(context.Background(), token, time.Time{}); err == nil || calls != 0 {
t.Fatal("bad PC clock accepted")
}
if err = b.Sync(context.Background(), token, target); err != nil || calls != 1 || b.Token() != "" {
t.Fatalf("%v calls=%d", err, calls)
}
now = time.Unix(0, 0)
if err = b.Sync(context.Background(), token, target); err == nil || calls != 1 {
t.Fatal("replay accepted")
}
}
func TestBootstrapDoesNotOverwriteNTPOrConsumeFailedAttempt(t *testing.T) {
now := time.Unix(0, 0)
calls := 0
b, _ := NewClockBootstrap(func() time.Time { return now }, func(context.Context, time.Time) error { calls++; return errors.New("unavailable") })
token := b.Token()
target := time.Date(2026, 9, 9, 1, 0, 0, 0, time.UTC)
if b.Sync(context.Background(), token, target) == nil || b.Token() == "" {
t.Fatal("failure marked successful")
}
if b.Sync(context.Background(), token, target) == nil || calls != 1 {
t.Fatal("failure retry not throttled")
}
now = target
if b.Token() != "" || b.Sync(context.Background(), token, target.Add(time.Hour)) == nil || calls != 1 {
t.Fatal("valid time overwritten")
}
}