1 package opencensus_test
2
3 import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "errors"
8 "fmt"
9 "net/http"
10 "net/http/httptest"
11 "net/url"
12 "testing"
13
14 "go.opencensus.io/plugin/ochttp"
15 "go.opencensus.io/plugin/ochttp/propagation/b3"
16 "go.opencensus.io/plugin/ochttp/propagation/tracecontext"
17 "go.opencensus.io/trace"
18 "go.opencensus.io/trace/propagation"
19
20 "github.com/go-kit/kit/endpoint"
21 ockit "github.com/go-kit/kit/tracing/opencensus"
22 jsonrpc "github.com/go-kit/kit/transport/http/jsonrpc"
23 )
24
25 func TestJSONRPCClientTrace(t *testing.T) {
26 t.Skip("FLAKY")
27
28 var (
29 err error
30 rec = &recordingExporter{}
31 rURL, _ = url.Parse("https://httpbin.org/anything")
32 endpointName = "DummyEndpoint"
33 )
34
35 trace.RegisterExporter(rec)
36
37 traces := []struct {
38 name string
39 err error
40 }{
41 {"", nil},
42 {"CustomName", nil},
43 {"", errors.New("dummy-error")},
44 }
45
46 for _, tr := range traces {
47 clientTracer := ockit.JSONRPCClientTrace(
48 ockit.WithName(tr.name),
49 ockit.WithSampler(trace.AlwaysSample()),
50 )
51 ep := jsonrpc.NewClient(
52 rURL,
53 endpointName,
54 jsonrpc.ClientRequestEncoder(func(ctx context.Context, i interface{}) (json.RawMessage, error) {
55 return json.RawMessage(`{}`), nil
56 }),
57 jsonrpc.ClientResponseDecoder(func(ctx context.Context, r jsonrpc.Response) (response interface{}, err error) {
58 return nil, tr.err
59 }),
60 clientTracer,
61 ).Endpoint()
62
63 ctx, parentSpan := trace.StartSpan(context.Background(), "test")
64
65 _, err = ep(ctx, nil)
66 if want, have := tr.err, err; want != have {
67 t.Fatalf("unexpected error, want %v, have %v", tr.err, err)
68 }
69
70 spans := rec.Flush()
71 if want, have := 1, len(spans); want != have {
72 t.Fatalf("incorrect number of spans, want %d, have %d", want, have)
73 }
74
75 span := spans[0]
76 if want, have := parentSpan.SpanContext().SpanID, span.ParentSpanID; want != have {
77 t.Errorf("incorrect parent ID, want %s, have %s", want, have)
78 }
79
80 if want, have := tr.name, span.Name; want != have && want != "" {
81 t.Errorf("incorrect span name, want %s, have %s", want, have)
82 }
83
84 if want, have := endpointName, span.Name; want != have && tr.name == "" {
85 t.Errorf("incorrect span name, want %s, have %s", want, have)
86 }
87
88 code := trace.StatusCodeOK
89 if tr.err != nil {
90 code = trace.StatusCodeUnknown
91
92 if want, have := err.Error(), span.Status.Message; want != have {
93 t.Errorf("incorrect span status msg, want %s, have %s", want, have)
94 }
95 }
96
97 if want, have := int32(code), span.Status.Code; want != have {
98 t.Errorf("incorrect span status code, want %d, have %d", want, have)
99 }
100 }
101 }
102
103 func TestJSONRPCServerTrace(t *testing.T) {
104 var (
105 endpointName = "DummyEndpoint"
106 rec = &recordingExporter{}
107 )
108
109 trace.RegisterExporter(rec)
110
111 traces := []struct {
112 useParent bool
113 name string
114 err error
115 propagation propagation.HTTPFormat
116 }{
117 {false, "", nil, nil},
118 {true, "", nil, nil},
119 {true, "CustomName", nil, &b3.HTTPFormat{}},
120 {true, "", errors.New("dummy-error"), &tracecontext.HTTPFormat{}},
121 }
122
123 for _, tr := range traces {
124 var client http.Client
125
126 handler := jsonrpc.NewServer(
127 jsonrpc.EndpointCodecMap{
128 endpointName: jsonrpc.EndpointCodec{
129 Endpoint: endpoint.Nop,
130 Decode: func(context.Context, json.RawMessage) (interface{}, error) { return nil, nil },
131 Encode: func(context.Context, interface{}) (json.RawMessage, error) { return nil, tr.err },
132 },
133 },
134 ockit.JSONRPCServerTrace(
135 ockit.WithName(tr.name),
136 ockit.WithSampler(trace.AlwaysSample()),
137 ockit.WithHTTPPropagation(tr.propagation),
138 ),
139 )
140
141 server := httptest.NewServer(handler)
142 defer server.Close()
143
144 jsonStr := []byte(fmt.Sprintf(`{"method":"%s"}`, endpointName))
145 req, err := http.NewRequest("POST", server.URL, bytes.NewBuffer(jsonStr))
146 if err != nil {
147 t.Fatalf("unable to create JSONRPC request: %v", err)
148 }
149
150 if tr.useParent {
151 client = http.Client{
152 Transport: &ochttp.Transport{
153 StartOptions: trace.StartOptions{
154 Sampler: trace.AlwaysSample(),
155 },
156 Propagation: tr.propagation,
157 },
158 }
159 }
160
161 resp, err := client.Do(req.WithContext(context.Background()))
162 if err != nil {
163 t.Fatalf("unable to send JSONRPC request: %v", err)
164 }
165 resp.Body.Close()
166
167 spans := rec.Flush()
168
169 expectedSpans := 1
170 if tr.useParent {
171 expectedSpans++
172 }
173
174 if want, have := expectedSpans, len(spans); want != have {
175 t.Fatalf("incorrect number of spans, want %d, have %d", want, have)
176 }
177
178 if tr.useParent {
179 if want, have := spans[1].TraceID, spans[0].TraceID; want != have {
180 t.Errorf("incorrect trace ID, want %s, have %s", want, have)
181 }
182
183 if want, have := spans[1].SpanID, spans[0].ParentSpanID; want != have {
184 t.Errorf("incorrect span ID, want %s, have %s", want, have)
185 }
186 }
187
188 if want, have := tr.name, spans[0].Name; want != have && want != "" {
189 t.Errorf("incorrect span name, want %s, have %s", want, have)
190 }
191
192 if want, have := endpointName, spans[0].Name; want != have && tr.name == "" {
193 t.Errorf("incorrect span name, want %s, have %s", want, have)
194 }
195 }
196 }
197
View as plain text