...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package testutil
16
17 import (
18 "errors"
19 "fmt"
20 "sync"
21 "time"
22 )
23
24 type Action struct {
25 Name string
26 Params []interface{}
27 }
28
29 type Recorder interface {
30
31
32 Record(a Action)
33
34 Wait(n int) ([]Action, error)
35
36 Action() []Action
37
38 Chan() <-chan Action
39 }
40
41
42 type RecorderBuffered struct {
43 sync.Mutex
44 actions []Action
45 }
46
47 func (r *RecorderBuffered) Record(a Action) {
48 r.Lock()
49 r.actions = append(r.actions, a)
50 r.Unlock()
51 }
52
53 func (r *RecorderBuffered) Action() []Action {
54 r.Lock()
55 cpy := make([]Action, len(r.actions))
56 copy(cpy, r.actions)
57 r.Unlock()
58 return cpy
59 }
60
61 func (r *RecorderBuffered) Wait(n int) (acts []Action, err error) {
62
63 WaitSchedule()
64 acts = r.Action()
65 if len(acts) < n {
66 err = newLenErr(n, len(acts))
67 }
68 return acts, err
69 }
70
71 func (r *RecorderBuffered) Chan() <-chan Action {
72 ch := make(chan Action)
73 go func() {
74 acts := r.Action()
75 for i := range acts {
76 ch <- acts[i]
77 }
78 close(ch)
79 }()
80 return ch
81 }
82
83
84 type recorderStream struct {
85 ch chan Action
86 waitTimeout time.Duration
87 }
88
89 func NewRecorderStream() Recorder {
90 return NewRecorderStreamWithWaitTimout(time.Duration(5 * time.Second))
91 }
92
93 func NewRecorderStreamWithWaitTimout(waitTimeout time.Duration) Recorder {
94 return &recorderStream{ch: make(chan Action), waitTimeout: waitTimeout}
95 }
96
97 func (r *recorderStream) Record(a Action) {
98 r.ch <- a
99 }
100
101 func (r *recorderStream) Action() (acts []Action) {
102 for {
103 select {
104 case act := <-r.ch:
105 acts = append(acts, act)
106 default:
107 return acts
108 }
109 }
110 }
111
112 func (r *recorderStream) Chan() <-chan Action {
113 return r.ch
114 }
115
116 func (r *recorderStream) Wait(n int) ([]Action, error) {
117 acts := make([]Action, n)
118 timeoutC := time.After(r.waitTimeout)
119 for i := 0; i < n; i++ {
120 select {
121 case acts[i] = <-r.ch:
122 case <-timeoutC:
123 acts = acts[:i]
124 return acts, newLenErr(n, i)
125 }
126 }
127
128 select {
129 case act := <-r.ch:
130 acts = append(acts, act)
131 case <-time.After(10 * time.Millisecond):
132 }
133 return acts, nil
134 }
135
136 func newLenErr(expected int, actual int) error {
137 s := fmt.Sprintf("len(actions) = %d, expected >= %d", actual, expected)
138 return errors.New(s)
139 }
140
View as plain text