@@ -1,380 +0,0 @@
1−package clock_test
2−
3−import (
4− "sync"
5− "sync/atomic"
6− "time"
7−
8− "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/clock"
9− . "github.com/onsi/ginkgo/v2"
10− . "github.com/onsi/gomega"
11−)
12−
13−const (
14− testGlobalEpoch = 1000000000
15− testLocalEpoch = 1234567890
16−)
17−
18−var _ = Describe("Clock suite", func() {
19− var testClock = clock.Clock{}
20−
21− AfterEach(func() {
22− clock.Reset()
23− testClock.Reset()
24− })
25−
26− Context("Global time not overridden", func() {
27− It("errors when trying to Add", func() {
28− err := clock.Add(123 * time.Hour)
29− Expect(err).To(HaveOccurred())
30− })
31−
32− Context("Clock not mocked via Set", func() {
33− const (
34− outsideTolerance = int32(0)
35− withinTolerance = int32(1)
36− )
37−
38− It("uses time.After for After", func() {
39− var tolerance int32
40− go func() {
41− time.Sleep(10 * time.Millisecond)
42− atomic.StoreInt32(&tolerance, withinTolerance)
43− }()
44− go func() {
45− time.Sleep(30 * time.Millisecond)
46− atomic.StoreInt32(&tolerance, outsideTolerance)
47− }()
48−
49− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
50−
51− <-testClock.After(20 * time.Millisecond)
52− Expect(atomic.LoadInt32(&tolerance)).To(Equal(withinTolerance))
53−
54− <-testClock.After(20 * time.Millisecond)
55− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
56− })
57−
58− It("uses time.AfterFunc for AfterFunc", func() {
59− var tolerance int32
60− go func() {
61− time.Sleep(10 * time.Millisecond)
62− atomic.StoreInt32(&tolerance, withinTolerance)
63− }()
64− go func() {
65− time.Sleep(30 * time.Millisecond)
66− atomic.StoreInt32(&tolerance, outsideTolerance)
67− }()
68−
69− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
70−
71− var wg sync.WaitGroup
72− wg.Add(1)
73− testClock.AfterFunc(20*time.Millisecond, func() {
74− wg.Done()
75− })
76− wg.Wait()
77− Expect(atomic.LoadInt32(&tolerance)).To(Equal(withinTolerance))
78−
79− wg.Add(1)
80− testClock.AfterFunc(20*time.Millisecond, func() {
81− wg.Done()
82− })
83− wg.Wait()
84− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
85− })
86−
87− It("uses time.Now for Now", func() {
88− a := time.Now()
89− b := testClock.Now()
90− Expect(b.Sub(a).Round(10 * time.Millisecond)).To(Equal(0 * time.Millisecond))
91− })
92−
93− It("uses time.Since for Since", func() {
94− past := time.Now().Add(-60 * time.Second)
95− Expect(time.Since(past).Round(10 * time.Millisecond)).
96− To(Equal(60 * time.Second))
97− })
98−
99− It("uses time.Sleep for Sleep", func() {
100− var tolerance int32
101− go func() {
102− time.Sleep(10 * time.Millisecond)
103− atomic.StoreInt32(&tolerance, withinTolerance)
104− }()
105− go func() {
106− time.Sleep(30 * time.Millisecond)
107− atomic.StoreInt32(&tolerance, outsideTolerance)
108− }()
109−
110− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
111−
112− testClock.Sleep(20 * time.Millisecond)
113− Expect(atomic.LoadInt32(&tolerance)).To(Equal(withinTolerance))
114−
115− testClock.Sleep(20 * time.Millisecond)
116− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
117− })
118−
119− It("uses time.Tick for Tick", func() {
120− var tolerance int32
121− go func() {
122− time.Sleep(10 * time.Millisecond)
123− atomic.StoreInt32(&tolerance, withinTolerance)
124− }()
125− go func() {
126− time.Sleep(50 * time.Millisecond)
127− atomic.StoreInt32(&tolerance, outsideTolerance)
128− }()
129−
130− ch := testClock.Tick(20 * time.Millisecond)
131− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
132− <-ch
133− Expect(atomic.LoadInt32(&tolerance)).To(Equal(withinTolerance))
134− <-ch
135− Expect(atomic.LoadInt32(&tolerance)).To(Equal(withinTolerance))
136− <-ch
137− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
138− })
139−
140− It("uses time.Ticker for Ticker", func() {
141− var tolerance int32
142− go func() {
143− time.Sleep(10 * time.Millisecond)
144− atomic.StoreInt32(&tolerance, withinTolerance)
145− }()
146− go func() {
147− time.Sleep(50 * time.Millisecond)
148− atomic.StoreInt32(&tolerance, outsideTolerance)
149− }()
150−
151− ticker := testClock.Ticker(20 * time.Millisecond)
152− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
153− <-ticker.C
154− Expect(atomic.LoadInt32(&tolerance)).To(Equal(withinTolerance))
155− <-ticker.C
156− Expect(atomic.LoadInt32(&tolerance)).To(Equal(withinTolerance))
157− <-ticker.C
158− Expect(atomic.LoadInt32(&tolerance)).To(Equal(outsideTolerance))
159− })
160−
161− It("errors if Add is used", func() {
162− err := testClock.Add(100 * time.Second)
163− Expect(err).To(HaveOccurred())
164− })
165− })
166−
167− Context("Clock mocked via Set", func() {
168− var now = time.Unix(testLocalEpoch, 0)
169−
170− BeforeEach(func() {
171− testClock.Set(now)
172− })
173−
174− It("mocks After", func() {
175− var after int32
176− ready := make(chan struct{})
177− ch := testClock.After(10 * time.Second)
178− go func(ch <-chan time.Time) {
179− close(ready)
180− <-ch
181− atomic.StoreInt32(&after, 1)
182− }(ch)
183− <-ready
184−
185− err := testClock.Add(9 * time.Second)
186− Expect(err).ToNot(HaveOccurred())
187− Expect(atomic.LoadInt32(&after)).To(Equal(int32(0)))
188−
189− err = testClock.Add(1 * time.Second)
190− Expect(err).ToNot(HaveOccurred())
191− Expect(atomic.LoadInt32(&after)).To(Equal(int32(1)))
192− })
193−
194− It("mocks AfterFunc", func() {
195− var after int32
196− testClock.AfterFunc(10*time.Second, func() {
197− atomic.StoreInt32(&after, 1)
198− })
199−
200− err := testClock.Add(9 * time.Second)
201− Expect(err).ToNot(HaveOccurred())
202− Expect(atomic.LoadInt32(&after)).To(Equal(int32(0)))
203−
204− err = testClock.Add(1 * time.Second)
205− Expect(err).ToNot(HaveOccurred())
206− Expect(atomic.LoadInt32(&after)).To(Equal(int32(1)))
207− })
208−
209− It("mocks AfterFunc with a stopped timer", func() {
210− var after int32
211− timer := testClock.AfterFunc(10*time.Second, func() {
212− atomic.StoreInt32(&after, 1)
213− })
214− timer.Stop()
215−
216− err := testClock.Add(11 * time.Second)
217− Expect(err).ToNot(HaveOccurred())
218− Expect(atomic.LoadInt32(&after)).To(Equal(int32(0)))
219− })
220−
221− It("mocks Now", func() {
222− Expect(testClock.Now()).To(Equal(now))
223− err := testClock.Add(123 * time.Hour)
224− Expect(err).ToNot(HaveOccurred())
225− Expect(testClock.Now()).To(Equal(now.Add(123 * time.Hour)))
226− })
227−
228− It("mocks Since", func() {
229− Expect(testClock.Since(time.Unix(testLocalEpoch-100, 0))).
230− To(Equal(100 * time.Second))
231− })
232−
233− It("mocks Sleep", func() {
234− var after int32
235− ready := make(chan struct{})
236− go func() {
237− close(ready)
238− testClock.Sleep(10 * time.Second)
239− atomic.StoreInt32(&after, 1)
240− }()
241− <-ready
242−
243− err := testClock.Add(9 * time.Second)
244− Expect(err).ToNot(HaveOccurred())
245− Expect(atomic.LoadInt32(&after)).To(Equal(int32(0)))
246−
247− err = testClock.Add(1 * time.Second)
248− Expect(err).ToNot(HaveOccurred())
249− Expect(atomic.LoadInt32(&after)).To(Equal(int32(1)))
250− })
251−
252− It("mocks Tick", func() {
253− var ticks int32
254− ready := make(chan struct{})
255− go func() {
256− close(ready)
257− tick := testClock.Tick(10 * time.Second)
258− for ticks < 5 {
259− <-tick
260− atomic.AddInt32(&ticks, 1)
261− }
262− }()
263− <-ready
264−
265− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(0)))
266−
267− err := testClock.Add(9 * time.Second)
268− Expect(err).ToNot(HaveOccurred())
269− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(0)))
270−
271− err = testClock.Add(1 * time.Second)
272− Expect(err).ToNot(HaveOccurred())
273− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(1)))
274−
275− err = testClock.Add(30 * time.Second)
276− Expect(err).ToNot(HaveOccurred())
277− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(4)))
278−
279− err = testClock.Add(10 * time.Second)
280− Expect(err).ToNot(HaveOccurred())
281− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(5)))
282− })
283−
284− It("mocks Ticker", func() {
285− var ticks int32
286− ready := make(chan struct{})
287− go func() {
288− ticker := testClock.Ticker(10 * time.Second)
289− close(ready)
290− for ticks < 5 {
291− <-ticker.C
292− atomic.AddInt32(&ticks, 1)
293− }
294− }()
295− <-ready
296−
297− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(0)))
298−
299− err := testClock.Add(9 * time.Second)
300− Expect(err).ToNot(HaveOccurred())
301− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(0)))
302−
303− err = testClock.Add(1 * time.Second)
304− Expect(err).ToNot(HaveOccurred())
305− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(1)))
306−
307− err = testClock.Add(30 * time.Second)
308− Expect(err).ToNot(HaveOccurred())
309− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(4)))
310−
311− err = testClock.Add(10 * time.Second)
312− Expect(err).ToNot(HaveOccurred())
313− Expect(atomic.LoadInt32(&ticks)).To(Equal(int32(5)))
314− })
315−
316− It("mocks Timer", func() {
317− var after int32
318− ready := make(chan struct{})
319− go func() {
320− timer := testClock.Timer(10 * time.Second)
321− close(ready)
322− <-timer.C
323− atomic.AddInt32(&after, 1)
324− }()
325− <-ready
326−
327− err := testClock.Add(9 * time.Second)
328− Expect(err).ToNot(HaveOccurred())
329− Expect(atomic.LoadInt32(&after)).To(Equal(int32(0)))
330−
331− err = testClock.Add(1 * time.Second)
332− Expect(err).ToNot(HaveOccurred())
333− Expect(atomic.LoadInt32(&after)).To(Equal(int32(1)))
334− })
335− })
336− })
337−
338− Context("Global time overridden", func() {
339− var (
340− globalNow = time.Unix(testGlobalEpoch, 0)
341− localNow = time.Unix(testLocalEpoch, 0)
342− )
343−
344− BeforeEach(func() {
345− clock.Set(globalNow)
346− })
347−
348− Context("Clock not mocked via Set", func() {
349− It("uses globally mocked Now", func() {
350− Expect(testClock.Now()).To(Equal(globalNow))
351− err := clock.Add(123 * time.Hour)
352− Expect(err).ToNot(HaveOccurred())
353− Expect(testClock.Now()).To(Equal(globalNow.Add(123 * time.Hour)))
354− })
355−
356− It("errors when Add is called on the local Clock", func() {
357− err := testClock.Add(100 * time.Hour)
358− Expect(err).To(HaveOccurred())
359− })
360− })
361−
362− Context("Clock is mocked via Set", func() {
363− BeforeEach(func() {
364− testClock.Set(localNow)
365− })
366−
367− It("uses the local mock and ignores the global", func() {
368− Expect(testClock.Now()).To(Equal(localNow))
369−
370− err := clock.Add(456 * time.Hour)
371− Expect(err).ToNot(HaveOccurred())
372−
373− err = testClock.Add(123 * time.Hour)
374− Expect(err).ToNot(HaveOccurred())
375−
376− Expect(testClock.Now()).To(Equal(localNow.Add(123 * time.Hour)))
377− })
378− })
379− })
380−})