github.com/letsencrypt/trillian@v1.1.2-0.20180615153820-ae375a99d36a/util/timesource.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package util
    16  
    17  import (
    18  	"sync"
    19  	"time"
    20  )
    21  
    22  // TimeSource can provide the current time, or be replaced by a mock in tests to return
    23  // specific values.
    24  type TimeSource interface {
    25  	// Now returns the current time in real implementations or a suitable value in others
    26  	Now() time.Time
    27  }
    28  
    29  // SecondsSince returns the time in seconds elapsed since t until now, as
    30  // measured by the TimeSource.
    31  func SecondsSince(ts TimeSource, t time.Time) float64 {
    32  	return ts.Now().Sub(t).Seconds()
    33  }
    34  
    35  // SystemTimeSource provides the current system local time
    36  type SystemTimeSource struct{}
    37  
    38  // Now returns the true current local time.
    39  func (s SystemTimeSource) Now() time.Time {
    40  	return time.Now()
    41  }
    42  
    43  // FakeTimeSource provides a time that can be any arbitrarily set value for use in tests.
    44  // It should not be used in production code.
    45  type FakeTimeSource struct {
    46  	// fakeTime is the value that this fake time source will return.
    47  	mu       sync.Mutex
    48  	fakeTime time.Time
    49  }
    50  
    51  // NewFakeTimeSource creates a FakeTimeSource instance
    52  func NewFakeTimeSource(t time.Time) *FakeTimeSource {
    53  	return &FakeTimeSource{fakeTime: t}
    54  }
    55  
    56  // Now returns the time value this instance contains
    57  func (f *FakeTimeSource) Now() time.Time {
    58  	f.mu.Lock()
    59  	defer f.mu.Unlock()
    60  	return f.fakeTime
    61  }
    62  
    63  // Set gives the time that this instance will report
    64  func (f *FakeTimeSource) Set(t time.Time) {
    65  	f.mu.Lock()
    66  	defer f.mu.Unlock()
    67  	f.fakeTime = t
    68  }
    69  
    70  // IncrementingFakeTimeSource takes a base time and several increments, which will be applied to
    71  // the base time each time Now() is called. The first call will return the base time + zeroth
    72  // increment. If called more times than provided for then it will panic. Does not require that
    73  // increments increase monotonically.
    74  type IncrementingFakeTimeSource struct {
    75  	BaseTime      time.Time
    76  	Increments    []time.Duration
    77  	NextIncrement int
    78  }
    79  
    80  // Now returns the current time according to this time source, which depends on how many times
    81  // this method has already been invoked.
    82  func (a *IncrementingFakeTimeSource) Now() time.Time {
    83  	adjustedTime := a.BaseTime.Add(a.Increments[a.NextIncrement])
    84  	a.NextIncrement++
    85  
    86  	return adjustedTime
    87  }