~ubuntu-branches/ubuntu/vivid/juju-core/vivid-proposed

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/testing/clock.go

  • Committer: Package Import Robot
  • Author(s): Curtis C. Hovey
  • Date: 2015-09-29 19:43:29 UTC
  • mfrom: (47.1.4 wily-proposed)
  • Revision ID: package-import@ubuntu.com-20150929194329-9y496tbic30hc7vp
Tags: 1.24.6-0ubuntu1~15.04.1
Backport of 1.24.6 from wily. (LP: #1500916, #1497087)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package testing
 
5
 
 
6
import (
 
7
        "sort"
 
8
        "sync"
 
9
        "time"
 
10
)
 
11
 
 
12
// Clock implements state/lease.Clock for testing purposes.
 
13
type Clock struct {
 
14
        mu     sync.Mutex
 
15
        now    time.Time
 
16
        alarms []alarm
 
17
}
 
18
 
 
19
// NewClock returns a new clock set to the supplied time.
 
20
func NewClock(now time.Time) *Clock {
 
21
        return &Clock{now: now}
 
22
}
 
23
 
 
24
// Now is part of the lease.Clock interface.
 
25
func (clock *Clock) Now() time.Time {
 
26
        clock.mu.Lock()
 
27
        defer clock.mu.Unlock()
 
28
        return clock.now
 
29
}
 
30
 
 
31
// Alarm is part of the lease.Clock interface.
 
32
func (clock *Clock) Alarm(t time.Time) <-chan time.Time {
 
33
        clock.mu.Lock()
 
34
        defer clock.mu.Unlock()
 
35
        notify := make(chan time.Time, 1)
 
36
        if !clock.now.Before(t) {
 
37
                notify <- clock.now
 
38
        } else {
 
39
                clock.alarms = append(clock.alarms, alarm{t, notify})
 
40
                sort.Sort(byTime(clock.alarms))
 
41
        }
 
42
        return notify
 
43
}
 
44
 
 
45
// Advance advances the result of Now by the supplied duration, and sends
 
46
// the "current" time on all alarms which are no longer "in the future".
 
47
func (clock *Clock) Advance(d time.Duration) {
 
48
        clock.mu.Lock()
 
49
        defer clock.mu.Unlock()
 
50
        clock.now = clock.now.Add(d)
 
51
        rung := 0
 
52
        for _, alarm := range clock.alarms {
 
53
                if clock.now.Before(alarm.time) {
 
54
                        break
 
55
                }
 
56
                alarm.notify <- clock.now
 
57
                rung++
 
58
        }
 
59
        clock.alarms = clock.alarms[rung:]
 
60
}
 
61
 
 
62
// alarm records the time at which we're expected to send on notify.
 
63
type alarm struct {
 
64
        time   time.Time
 
65
        notify chan time.Time
 
66
}
 
67
 
 
68
// byTime is used to sort alarms by time.
 
69
type byTime []alarm
 
70
 
 
71
func (a byTime) Len() int           { return len(a) }
 
72
func (a byTime) Less(i, j int) bool { return a[i].time.Before(a[j].time) }
 
73
func (a byTime) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }