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