OSDN Git Service

2407a4ac642d5ccf56e08e30e4ad94d000e35021
[pf3gnuchains/gcc-fork.git] / libgo / go / time / sleep_test.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package time_test
6
7 import (
8         "errors"
9         "fmt"
10         "testing"
11         "sort"
12         . "time"
13 )
14
15 func TestSleep(t *testing.T) {
16         const delay = int64(100e6)
17         go func() {
18                 Sleep(delay / 2)
19                 Interrupt()
20         }()
21         start := Nanoseconds()
22         Sleep(delay)
23         duration := Nanoseconds() - start
24         if duration < delay {
25                 t.Fatalf("Sleep(%d) slept for only %d ns", delay, duration)
26         }
27 }
28
29 // Test the basic function calling behavior. Correct queueing
30 // behavior is tested elsewhere, since After and AfterFunc share
31 // the same code.
32 func TestAfterFunc(t *testing.T) {
33         i := 10
34         c := make(chan bool)
35         var f func()
36         f = func() {
37                 i--
38                 if i >= 0 {
39                         AfterFunc(0, f)
40                         Sleep(1e9)
41                 } else {
42                         c <- true
43                 }
44         }
45
46         AfterFunc(0, f)
47         <-c
48 }
49
50 func BenchmarkAfterFunc(b *testing.B) {
51         i := b.N
52         c := make(chan bool)
53         var f func()
54         f = func() {
55                 i--
56                 if i >= 0 {
57                         AfterFunc(0, f)
58                 } else {
59                         c <- true
60                 }
61         }
62
63         AfterFunc(0, f)
64         <-c
65 }
66
67 func BenchmarkAfter(b *testing.B) {
68         for i := 0; i < b.N; i++ {
69                 <-After(1)
70         }
71 }
72
73 func BenchmarkStop(b *testing.B) {
74         for i := 0; i < b.N; i++ {
75                 NewTimer(1e9).Stop()
76         }
77 }
78
79 func TestAfter(t *testing.T) {
80         const delay = int64(100e6)
81         start := Nanoseconds()
82         end := <-After(delay)
83         if duration := Nanoseconds() - start; duration < delay {
84                 t.Fatalf("After(%d) slept for only %d ns", delay, duration)
85         }
86         if min := start + delay; end < min {
87                 t.Fatalf("After(%d) expect >= %d, got %d", delay, min, end)
88         }
89 }
90
91 func TestAfterTick(t *testing.T) {
92         const (
93                 Delta = 100 * 1e6
94                 Count = 10
95         )
96         t0 := Nanoseconds()
97         for i := 0; i < Count; i++ {
98                 <-After(Delta)
99         }
100         t1 := Nanoseconds()
101         ns := t1 - t0
102         target := int64(Delta * Count)
103         slop := target * 2 / 10
104         if ns < target-slop || ns > target+slop {
105                 t.Fatalf("%d ticks of %g ns took %g ns, expected %g", Count, float64(Delta), float64(ns), float64(target))
106         }
107 }
108
109 func TestAfterStop(t *testing.T) {
110         const msec = 1e6
111         AfterFunc(100*msec, func() {})
112         t0 := NewTimer(50 * msec)
113         c1 := make(chan bool, 1)
114         t1 := AfterFunc(150*msec, func() { c1 <- true })
115         c2 := After(200 * msec)
116         if !t0.Stop() {
117                 t.Fatalf("failed to stop event 0")
118         }
119         if !t1.Stop() {
120                 t.Fatalf("failed to stop event 1")
121         }
122         <-c2
123         select {
124         case <-t0.C:
125                 t.Fatalf("event 0 was not stopped")
126         case <-c1:
127                 t.Fatalf("event 1 was not stopped")
128         default:
129         }
130         if t1.Stop() {
131                 t.Fatalf("Stop returned true twice")
132         }
133 }
134
135 func TestAfterQueuing(t *testing.T) {
136         // This test flakes out on some systems,
137         // so we'll try it a few times before declaring it a failure.
138         const attempts = 3
139         err := errors.New("!=nil")
140         for i := 0; i < attempts && err != nil; i++ {
141                 if err = testAfterQueuing(t); err != nil {
142                         t.Logf("attempt %v failed: %v", i, err)
143                 }
144         }
145         if err != nil {
146                 t.Fatal(err)
147         }
148 }
149
150 // For gccgo omit 0 for now because it can take too long to start the
151 var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8, /*0*/}
152
153 type afterResult struct {
154         slot int
155         t    int64
156 }
157
158 func await(slot int, result chan<- afterResult, ac <-chan int64) {
159         result <- afterResult{slot, <-ac}
160 }
161
162 func testAfterQueuing(t *testing.T) error {
163         const (
164                 Delta = 100 * 1e6
165         )
166         // make the result channel buffered because we don't want
167         // to depend on channel queueing semantics that might
168         // possibly change in the future.
169         result := make(chan afterResult, len(slots))
170
171         t0 := Nanoseconds()
172         for _, slot := range slots {
173                 go await(slot, result, After(int64(slot)*Delta))
174         }
175         sort.Ints(slots)
176         for _, slot := range slots {
177                 r := <-result
178                 if r.slot != slot {
179                         return fmt.Errorf("after queue got slot %d, expected %d", r.slot, slot)
180                 }
181                 ns := r.t - t0
182                 target := int64(slot * Delta)
183                 slop := int64(Delta) / 4
184                 if ns < target-slop || ns > target+slop {
185                         return fmt.Errorf("after queue slot %d arrived at %g, expected [%g,%g]", slot, float64(ns), float64(target-slop), float64(target+slop))
186                 }
187         }
188         return nil
189 }