blob: 6426918a4a7c57c4ea2fda02e017856108e4aac7 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vclock
// Utilities for testing vclock.
import (
"reflect"
"testing"
"time"
"v.io/x/ref/services/syncbase/store/memstore"
)
////////////////////////////////////////
// Mock SystemClock
var _ SystemClock = (*mockSystemClock)(nil)
func newMockSystemClock(now time.Time, elapsedTime time.Duration) *mockSystemClock {
return &mockSystemClock{
now: now,
elapsedTime: elapsedTime,
}
}
type mockSystemClock struct {
now time.Time
elapsedTime time.Duration
}
func (sc *mockSystemClock) Now() time.Time {
return sc.now
}
func (sc *mockSystemClock) SetNow(now time.Time) {
sc.now = now
}
func (sc *mockSystemClock) ElapsedTime() (time.Duration, error) {
return sc.elapsedTime, nil
}
func (sc *mockSystemClock) SetElapsedTime(elapsedTime time.Duration) {
sc.elapsedTime = elapsedTime
}
////////////////////////////////////////
// Mock NtpSource
var _ NtpSource = (*ntpSourceMockImpl)(nil)
func newMockNtpSource() *ntpSourceMockImpl {
return &ntpSourceMockImpl{}
}
type ntpSourceMockImpl struct {
Err error
Data *NtpData
}
func (ns *ntpSourceMockImpl) NtpSync(sampleCount int) (*NtpData, error) {
if ns.Err != nil {
return nil, ns.Err
}
return ns.Data, nil
}
// NewVClockForTests returns a *VClock suitable for tests. It mimics "real"
// Syncbase behavior in that it calls InitVClockData to ensure that VClockData
// exists in the store.
func NewVClockForTests(sc SystemClock) *VClock {
if sc == nil {
sc = newRealSystemClock()
}
c := &VClock{
st: memstore.New(),
sysClock: sc,
}
if err := c.InitVClockData(); err != nil {
panic(err)
}
return c
}
////////////////////////////////////////
// Utility functions
// checkEqVClockData checks equality of got and want.
func checkEqVClockData(t *testing.T, got, want VClockData) {
// Make sure all time.Time location values are UTC so that DeepEqual doesn't
// trip up over unequal locations. Locations are irrelevant for us: they are
// not persisted, and they only affect the presentation of time.Time values
// (e.g. when printing using fmt).
got.SystemTimeAtBoot = got.SystemTimeAtBoot.UTC()
got.LastNtpTs = got.LastNtpTs.UTC()
want.SystemTimeAtBoot = want.SystemTimeAtBoot.UTC()
want.LastNtpTs = want.LastNtpTs.UTC()
if !reflect.DeepEqual(got, want) {
t.Errorf("Got %v, want %v", got, want)
}
}
// checkEqSubsetOfVClockData checks equality of got and want, ignoring
// SystemTimeAtBoot and ElapsedTimeSinceBoot.
func checkEqSubsetOfVClockData(t *testing.T, got, want VClockData) {
got.SystemTimeAtBoot = time.Time{}
got.ElapsedTimeSinceBoot = 0
want.SystemTimeAtBoot = time.Time{}
want.ElapsedTimeSinceBoot = 0
checkEqVClockData(t, got, want)
}
func verifyVClockData(t *testing.T, c *VClock, want *VClockData) {
got := &VClockData{}
if err := c.GetVClockData(got); err != nil {
t.Errorf("Error fetching VClockData: %v", err)
return
}
checkEqVClockData(t, *got, *want)
}
func newVClockData(systemTimeAtBoot time.Time, skew, elapsedTimeSinceBoot time.Duration, lastNtpTs time.Time, numReboots, numHops uint16) *VClockData {
return &VClockData{
SystemTimeAtBoot: systemTimeAtBoot,
Skew: skew,
ElapsedTimeSinceBoot: elapsedTimeSinceBoot,
LastNtpTs: lastNtpTs,
NumReboots: numReboots,
NumHops: numHops,
}
}