blob: 8bbc93f6d0f0cb9b558e87334d664d40127355ce [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 clock
import (
"net"
"testing"
"time"
"v.io/v23/verror"
)
func TestWithMockNtpForErr(t *testing.T) {
testStore := createStore(t)
defer destroyStore(t, testStore)
sysClock := MockSystemClock(time.Now(), 0)
ntpSource := MockNtpSource()
ntpSource.Err = net.UnknownNetworkError("network err")
vclock := NewVClockWithMockServices(testStore.st, sysClock, ntpSource)
vclock.runNtpCheck()
clockData := &ClockData{}
if err := vclock.GetClockData(vclock.St(), clockData); verror.ErrorID(err) != verror.ErrNoExist.ID {
t.Errorf("Non-nil clock data found: %v", clockData)
}
}
func TestWithMockNtpForDiffBelowThreshold(t *testing.T) {
testStore := createStore(t)
defer destroyStore(t, testStore)
sysTs := time.Now()
elapsedTime := time.Duration(50)
var skew int64 = 0
sysClock := MockSystemClock(sysTs, elapsedTime)
originalData := NewClockData(skew)
ntpSource := MockNtpSource()
offset := 1800 * time.Millisecond // error threshold is 2 seconds
ntpSource.Data = &NtpData{
offset: offset,
delay: 5 * time.Millisecond,
ntpTs: sysTs.Add(offset),
}
vclock := NewVClockWithMockServices(testStore.st, sysClock, ntpSource)
tx := vclock.St().NewTransaction()
vclock.SetClockData(tx, &originalData)
if err := tx.Commit(); err != nil {
t.Errorf("Error while commiting tx: %v", err)
}
vclock.runNtpCheck()
expectedSystemTimeAtBoot := sysTs.UnixNano() - elapsedTime.Nanoseconds()
expected := newClockData(expectedSystemTimeAtBoot, skew, elapsedTime.Nanoseconds(), &ntpSource.Data.ntpTs, 0, 0)
VerifyClockData(t, vclock, expected)
}
func TestWithMockNtpForDiffAboveThreshold(t *testing.T) {
testStore := createStore(t)
defer destroyStore(t, testStore)
sysTs := time.Now()
elapsedTime := 10 * time.Minute
sysClock := MockSystemClock(sysTs, elapsedTime)
originalData := NewClockData(0)
ntpSource := MockNtpSource()
skew := 2100 * time.Millisecond // error threshold is 2 seconds
ntpSource.Data = &NtpData{
offset: skew,
delay: 5 * time.Millisecond,
ntpTs: sysTs.Add(skew),
}
vclock := NewVClockWithMockServices(testStore.st, sysClock, ntpSource)
tx := vclock.St().NewTransaction()
vclock.SetClockData(tx, &originalData)
if err := tx.Commit(); err != nil {
t.Errorf("Error while commiting tx: %v", err)
}
vclock.runNtpCheck()
expectedBootTime := sysTs.Add(-elapsedTime).UnixNano()
expected := newClockData(expectedBootTime, skew.Nanoseconds(), elapsedTime.Nanoseconds(), &ntpSource.Data.ntpTs, 0, 0)
VerifyClockData(t, vclock, expected)
}
func TestWithMockNtpForDiffBelowThresholdAndExistingLargeSkew(t *testing.T) {
testStore := createStore(t)
defer destroyStore(t, testStore)
sysTs := time.Now()
elapsedTime := 10 * time.Minute
sysClock := MockSystemClock(sysTs, elapsedTime)
originalData := NewClockData(2300 * time.Millisecond.Nanoseconds()) // large skew
ntpSource := MockNtpSource()
skew := 200 * time.Millisecond // error threshold is 2 seconds
ntpSource.Data = &NtpData{
offset: skew,
delay: 5 * time.Millisecond,
ntpTs: sysTs.Add(skew),
}
vclock := NewVClockWithMockServices(testStore.st, sysClock, ntpSource)
tx := vclock.St().NewTransaction()
vclock.SetClockData(tx, &originalData)
if err := tx.Commit(); err != nil {
t.Errorf("Error while commiting tx: %v", err)
}
vclock.runNtpCheck()
expectedBootTime := sysTs.Add(-elapsedTime).UnixNano()
expected := newClockData(expectedBootTime, skew.Nanoseconds(), elapsedTime.Nanoseconds(), &ntpSource.Data.ntpTs, 0, 0)
VerifyClockData(t, vclock, expected)
}
func TestWithMockNtpForDiffBelowThresholdWithNoStoredClockData(t *testing.T) {
testStore := createStore(t)
defer destroyStore(t, testStore)
sysTs := time.Now()
elapsedTime := 10 * time.Minute
sysClock := MockSystemClock(sysTs, elapsedTime)
ntpSource := MockNtpSource()
skew := 200 * time.Millisecond // error threshold is 2 seconds
ntpSource.Data = &NtpData{
offset: skew,
delay: 5 * time.Millisecond,
ntpTs: sysTs.Add(skew),
}
vclock := NewVClockWithMockServices(testStore.st, sysClock, ntpSource)
// no skew data stored
vclock.runNtpCheck()
expectedBootTime := sysTs.Add(-elapsedTime).UnixNano()
expected := newClockData(expectedBootTime, skew.Nanoseconds(), elapsedTime.Nanoseconds(), &ntpSource.Data.ntpTs, 0, 0)
VerifyClockData(t, vclock, expected)
}
/*
// Following two tests are commented out as they hit the real NTP servers
// and can resut into being flaky if the clock of the machine running continuous
// test has a skew more than 2 seconds.
func TestWithRealNtp(t *testing.T) {
testStore := createStore(t)
defer destroyStore(t, testStore)
originalData := NewClockData(100 * time.Millisecond.Nanoseconds()) // small skew
vclock := NewVClockWithMockServices(testStore.st, nil, nil)
tx := vclock.St().NewTransaction()
vclock.SetClockData(tx, &originalData)
if err := tx.Commit(); err != nil {
t.Errorf("Error while commiting tx: %v", err)
}
vclock.runNtpCheck()
clockData := ClockData{}
if err := vclock.GetClockData(vclock.St(), &clockData); err != nil {
t.Errorf("error looking up clock data: %v", err)
}
fmt.Printf("\nClockData old: %#v, new : %#v", originalData, clockData)
}
func TestWithRealNtpForNoClockData(t *testing.T) {
testStore := createStore(t)
defer destroyStore(t, testStore)
vclock := NewVClockWithMockServices(testStore.st, nil, nil)
vclock.runNtpCheck()
clockData := ClockData{}
if err := vclock.GetClockData(vclock.St(), &clockData); err != nil {
t.Errorf("error looking up clock data: %v", err)
}
fmt.Printf("\nClockData: %#v", clockData)
}
*/
func NewClockData(skew int64) ClockData {
return ClockData{
SystemTimeAtBoot: 0,
Skew: skew,
ElapsedTimeSinceBoot: 0,
}
}