1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ocgrpc_test
16
17 import (
18 "context"
19 "io"
20 "testing"
21 "time"
22
23 "go.opencensus.io/internal/testpb"
24 "go.opencensus.io/trace"
25 )
26
27 type testExporter struct {
28 ch chan *trace.SpanData
29 }
30
31 func (t *testExporter) ExportSpan(s *trace.SpanData) {
32 go func() { t.ch <- s }()
33 }
34
35 func TestStreaming(t *testing.T) {
36 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
37 te := testExporter{make(chan *trace.SpanData)}
38 trace.RegisterExporter(&te)
39 defer trace.UnregisterExporter(&te)
40
41 client, cleanup := testpb.NewTestClient(t)
42
43 stream, err := client.Multiple(context.Background())
44 if err != nil {
45 t.Fatalf("Call failed: %v", err)
46 }
47
48 err = stream.Send(&testpb.FooRequest{})
49 if err != nil {
50 t.Fatalf("Couldn't send streaming request: %v", err)
51 }
52 stream.CloseSend()
53
54 for {
55 _, err := stream.Recv()
56 if err == io.EOF {
57 break
58 }
59 if err != nil {
60 t.Errorf("stream.Recv() = %v; want no errors", err)
61 }
62 }
63
64 cleanup()
65
66 s1 := <-te.ch
67 s2 := <-te.ch
68
69 checkSpanData(t, s1, s2, "testpb.Foo.Multiple", true)
70
71 select {
72 case <-te.ch:
73 t.Fatal("received extra exported spans")
74 case <-time.After(time.Second / 10):
75 }
76 }
77
78 func TestStreamingFail(t *testing.T) {
79 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
80 te := testExporter{make(chan *trace.SpanData)}
81 trace.RegisterExporter(&te)
82 defer trace.UnregisterExporter(&te)
83
84 client, cleanup := testpb.NewTestClient(t)
85
86 stream, err := client.Multiple(context.Background())
87 if err != nil {
88 t.Fatalf("Call failed: %v", err)
89 }
90
91 err = stream.Send(&testpb.FooRequest{Fail: true})
92 if err != nil {
93 t.Fatalf("Couldn't send streaming request: %v", err)
94 }
95 stream.CloseSend()
96
97 for {
98 _, err := stream.Recv()
99 if err == nil || err == io.EOF {
100 t.Errorf("stream.Recv() = %v; want errors", err)
101 } else {
102 break
103 }
104 }
105
106 s1 := <-te.ch
107 s2 := <-te.ch
108
109 checkSpanData(t, s1, s2, "testpb.Foo.Multiple", false)
110 cleanup()
111
112 select {
113 case <-te.ch:
114 t.Fatal("received extra exported spans")
115 case <-time.After(time.Second / 10):
116 }
117 }
118
119 func TestSingle(t *testing.T) {
120 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
121 te := testExporter{make(chan *trace.SpanData)}
122 trace.RegisterExporter(&te)
123 defer trace.UnregisterExporter(&te)
124
125 client, cleanup := testpb.NewTestClient(t)
126
127 _, err := client.Single(context.Background(), &testpb.FooRequest{})
128 if err != nil {
129 t.Fatalf("Couldn't send request: %v", err)
130 }
131
132 s1 := <-te.ch
133 s2 := <-te.ch
134
135 checkSpanData(t, s1, s2, "testpb.Foo.Single", true)
136 cleanup()
137
138 select {
139 case <-te.ch:
140 t.Fatal("received extra exported spans")
141 case <-time.After(time.Second / 10):
142 }
143 }
144
145 func TestServerSpanDuration(t *testing.T) {
146 client, cleanup := testpb.NewTestClient(t)
147 defer cleanup()
148
149 te := testExporter{make(chan *trace.SpanData, 100)}
150 trace.RegisterExporter(&te)
151 defer trace.UnregisterExporter(&te)
152
153 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
154
155 ctx := context.Background()
156 const sleep = 100 * time.Millisecond
157 client.Single(ctx, &testpb.FooRequest{SleepNanos: int64(sleep)})
158
159 loop:
160 for {
161 select {
162 case span := <-te.ch:
163 if span.SpanKind != trace.SpanKindServer {
164 continue loop
165 }
166 if got, want := span.EndTime.Sub(span.StartTime), sleep; got < want {
167 t.Errorf("span duration = %dns; want at least %dns", got, want)
168 }
169 break loop
170 default:
171 t.Fatal("no more spans")
172 }
173 }
174 }
175
176 func TestSingleFail(t *testing.T) {
177 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
178 te := testExporter{make(chan *trace.SpanData)}
179 trace.RegisterExporter(&te)
180 defer trace.UnregisterExporter(&te)
181
182 client, cleanup := testpb.NewTestClient(t)
183
184 _, err := client.Single(context.Background(), &testpb.FooRequest{Fail: true})
185 if err == nil {
186 t.Fatalf("Got nil error from request, want non-nil")
187 }
188
189 s1 := <-te.ch
190 s2 := <-te.ch
191
192 checkSpanData(t, s1, s2, "testpb.Foo.Single", false)
193 cleanup()
194
195 select {
196 case <-te.ch:
197 t.Fatal("received extra exported spans")
198 case <-time.After(time.Second / 10):
199 }
200 }
201
202 func checkSpanData(t *testing.T, s1, s2 *trace.SpanData, methodName string, success bool) {
203 t.Helper()
204
205 if s1.SpanKind == trace.SpanKindServer {
206 s1, s2 = s2, s1
207 }
208
209 if got, want := s1.Name, methodName; got != want {
210 t.Errorf("Got name %q want %q", got, want)
211 }
212 if got, want := s2.Name, methodName; got != want {
213 t.Errorf("Got name %q want %q", got, want)
214 }
215 if got, want := s2.SpanContext.TraceID, s1.SpanContext.TraceID; got != want {
216 t.Errorf("Got trace IDs %s and %s, want them equal", got, want)
217 }
218 if got, want := s2.ParentSpanID, s1.SpanContext.SpanID; got != want {
219 t.Errorf("Got ParentSpanID %s, want %s", got, want)
220 }
221 if got := (s1.Status.Code == 0); got != success {
222 t.Errorf("Got success=%t want %t", got, success)
223 }
224 if got := (s2.Status.Code == 0); got != success {
225 t.Errorf("Got success=%t want %t", got, success)
226 }
227 if s1.HasRemoteParent {
228 t.Errorf("Got HasRemoteParent=%t, want false", s1.HasRemoteParent)
229 }
230 if !s2.HasRemoteParent {
231 t.Errorf("Got HasRemoteParent=%t, want true", s2.HasRemoteParent)
232 }
233 }
234
View as plain text