Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit cb9a2a7

Browse files
SergeyKanzhelevBogdan Drutu
authored andcommitted
Http out test cases (#183)
* added http out test cases * mention client error codes * removed controversial error from spec * Include status in client views (#184) * added http.url into the spec * actual http.url description * Update HTTP.md * addressed comments * Update trace/HTTP.md Co-Authored-By: SergeyKanzhelev <S.Kanzhelev@live.com> * Update trace/HTTP.md Co-Authored-By: SergeyKanzhelev <S.Kanzhelev@live.com>
1 parent 3ae5608 commit cb9a2a7

2 files changed

Lines changed: 351 additions & 16 deletions

File tree

trace/HTTP.md

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ status code.
5353

5454
| HTTP code | Trace status code |
5555
|-----------------------|------------------------|
56-
| 0...199 | 2 Unknown |
56+
| 0...199 | 2 (UNKNOWN) |
5757
| 200...399 | 0 (OK) |
5858
| 400 Bad Request | 3 (INVALID_ARGUMENT) |
5959
| 504 Gateway Timeout | 4 (DEADLINE_EXCEEDED) |
@@ -66,7 +66,20 @@ status code.
6666

6767
Notes: 401 Unauthorized actually means unauthenticated according to RFC 7235, 3.1.
6868

69-
The Status message should be the Reason-Phrase (RFC 2616 6.1.1) from the response status line (if available).
69+
The Status message should be the Reason-Phrase (RFC 2616 6.1.1) from the
70+
response status line (if available).
71+
72+
### Client errors for client HTTP calls
73+
74+
There are a number of client errors when trying to access http endpoint. Here
75+
are examples of mapping those to the OpenCensus status codes.
76+
77+
| Client error | Trace status code |
78+
|------------------------------|-----------------------|
79+
| DNS resolution failed | 2 (UNKNOWN) |
80+
| Request cancelled by caller | 1 (CANCELLED) |
81+
| URL cannot be parsed | 3 (INVALID_ARGUMENT) |
82+
| Request timed out | 1 (DEADLINE_EXCEEDED) |
7083

7184
## Message events
7285

@@ -90,20 +103,22 @@ Implementations SHOULD create message event when response size is determined.
90103
## Attributes
91104

92105
Implementations SHOULD set the following attributes on the client and server spans. For a server,
93-
request represents the incoming request. For a client, request represents the outgoing request.
94-
95-
All attributes are optional.
96-
97-
| Attribute name | Description | Example value |
98-
|---------------------------|-----------------------------|---------------------------------|
99-
| "http.host" | Request URL host | "example.com:779" |
100-
| "http.method" | Request URL method | "GET" |
101-
| "http.path" | Request URL path | "/users/25f4c31d" |
102-
| "http.route" | Matched request URL route | "/users/:userID" |
103-
| "http.user_agent" | Request user-agent | "HTTPClient/1.2" |
104-
| "http.status_code" | Response status code | 200 |
105-
106-
Exporters should always export the collected attributes. Exporters should map the collected
106+
request represents the incoming request. For a client, request represents the outgoing request.
107+
108+
All attributes are optional, but collector should make the best effort to
109+
collect those.
110+
111+
| Attribute name | Description | Type |Example value |
112+
|---------------------------|-----------------------------|--------|---------------------------|
113+
| "http.host" | Request URL host | string | `example.com:779` |
114+
| "http.method" | Request URL method | string | `GET` |
115+
| "http.path" | Request URL path. If empty - set to `/` | `/users/25f4c31d` |
116+
| "http.route" | Matched request URL route | string | `/users/:userID` |
117+
| "http.user_agent" | Request user-agent. Do not inject attribute if user-agent is empty. | string | `HTTPClient/1.2` |
118+
| "http.status_code" | Response status code | int64 | `200` |
119+
| "http.url" | Absolute request URL | string | `https://example.com:779/path/12314/?q=ddds#123` |
120+
121+
Exporters should always export the collected attributes. Exporters should map the collected
107122
attributes to backend's known attributes/labels.
108123

109124
The following table summarizes how OpenCensus attributes maps to the
@@ -117,6 +132,52 @@ known attributes/labels on supported tracing backends.
117132
| "http.route" | "http.route" | "http.route" | "/http/route" |
118133
| "http.user_agent" | "http.user_agent" | "http.user_agent" | "/http/user_agent" |
119134
| "http.status_code" | "http.status_code" | "http.status_code" | "/http/status_code" |
135+
| "http.url" | "http.url" | "http.url" | "/http/url" |
136+
137+
References:
138+
139+
- [Stackdriver Trace
140+
label](https://cloud.google.com/trace/docs/reference/v1/rest/v1/projects.traces)
141+
- [Jaeger/Open Tracing](https://github.com/opentracing/specification/blob/master/semantic_conventions.md)
142+
- [Zipkin](https://github.com/openzipkin/zipkin-api/blob/master/thrift/zipkinCore.thrift)
143+
144+
## Test Cases
145+
146+
Test cases for outgoing http calls are in the file
147+
[http-out-test-cases.json](http-out-test-cases.json).
148+
149+
File consists of a set of test cases. Each test case represents outgoing http
150+
call, response it receives and the resulting span properties. It looks like
151+
this:
152+
153+
``` json
154+
{
155+
"name": "Name is populated as a path",
156+
"method": "GET",
157+
"url": "http://{host}:{port}/path/to/resource/",
158+
"headers": {
159+
"User-Agent": "test-user-agent"
160+
},
161+
"responseCode": 200,
162+
"spanName": "/path/to/resource/",
163+
"spanStatus": "OK",
164+
"spanKind": "Client",
165+
"spanAttributes": {
166+
"http.path": "/path/to/resource/",
167+
"http.method": "GET",
168+
"http.host": "{host}:{port}",
169+
"http.status_code": "200",
170+
"http.user_agent": "test-user-agent"
171+
}
172+
}
173+
```
174+
175+
Where `name` is the name of the test case. Properties `method`, `url` and
176+
`headers` collection represents the outgoing call. The field `responseCode`
177+
describes the response status code.
178+
179+
The rest of the properties describe the span details of the resulting span -
180+
it's name, kind, status and attributes.
120181

121182
## Sampling
122183

trace/http-out-test-cases.json

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
[
2+
{
3+
"name": "Successful GET call to https://example.com",
4+
"method": "GET",
5+
"url": "https://example.com/",
6+
"spanName": "/",
7+
"spanStatus": "OK",
8+
"spanKind": "Client",
9+
"spanAttributes": {
10+
"http.path": "/",
11+
"http.method": "GET",
12+
"http.host": "example.com",
13+
"http.status_code": "200",
14+
"http.url": "https://example.com/"
15+
}
16+
},
17+
{
18+
"name": "Successfully POST call to https://example.com",
19+
"method": "POST",
20+
"url": "https://example.com/",
21+
"spanName": "/",
22+
"spanStatus": "OK",
23+
"spanKind": "Client",
24+
"spanAttributes": {
25+
"http.path": "/",
26+
"http.method": "POST",
27+
"http.host": "example.com",
28+
"http.status_code": "200",
29+
"http.url": "https://example.com/"
30+
}
31+
},
32+
{
33+
"name": "Name is populated as a path",
34+
"method": "GET",
35+
"url": "http://{host}:{port}/path/to/resource/",
36+
"responseCode": 200,
37+
"spanName": "/path/to/resource/",
38+
"spanStatus": "OK",
39+
"spanKind": "Client",
40+
"spanAttributes": {
41+
"http.path": "/path/to/resource/",
42+
"http.method": "GET",
43+
"http.host": "{host}:{port}",
44+
"http.status_code": "200",
45+
"http.url": "http://{host}:{port}/path/to/resource/"
46+
}
47+
},
48+
{
49+
"name": "Call that cannot resolve DNS will be reported as error span",
50+
"method": "GET",
51+
"url": "https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/",
52+
"spanName": "/",
53+
"spanStatus": "UNKNOWN",
54+
"spanKind": "Client",
55+
"spanAttributes": {
56+
"http.path": "/",
57+
"http.method": "GET",
58+
"http.host": "sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com",
59+
"http.url": "https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/"
60+
}
61+
},
62+
{
63+
"name": "Response code: 199. This test case is not possible to implement on some platforms as they don't allow to return this status code. Keeping this test case for visibility, but it actually simply a fallback into 200 test case",
64+
"method": "GET",
65+
"url": "http://{host}:{port}/",
66+
"responseCode": 200,
67+
"spanName": "/",
68+
"spanStatus": "OK",
69+
"spanKind": "Client",
70+
"spanAttributes": {
71+
"http.path": "/",
72+
"http.method": "GET",
73+
"http.host": "{host}:{port}",
74+
"http.status_code": "200",
75+
"http.url": "http://{host}:{port}/"
76+
}
77+
},
78+
{
79+
"name": "Response code: 200",
80+
"method": "GET",
81+
"url": "http://{host}:{port}/",
82+
"responseCode": 200,
83+
"spanName": "/",
84+
"spanStatus": "OK",
85+
"spanKind": "Client",
86+
"spanAttributes": {
87+
"http.path": "/",
88+
"http.method": "GET",
89+
"http.host": "{host}:{port}",
90+
"http.status_code": "200",
91+
"http.url": "http://{host}:{port}/"
92+
}
93+
},
94+
{
95+
"name": "Response code: 399",
96+
"method": "GET",
97+
"url": "http://{host}:{port}/",
98+
"responseCode": 399,
99+
"spanName": "/",
100+
"spanStatus": "OK",
101+
"spanKind": "Client",
102+
"spanAttributes": {
103+
"http.path": "/",
104+
"http.method": "GET",
105+
"http.host": "{host}:{port}",
106+
"http.status_code": "399",
107+
"http.url": "http://{host}:{port}/"
108+
}
109+
},
110+
{
111+
"name": "Response code: 400",
112+
"method": "GET",
113+
"url": "http://{host}:{port}/",
114+
"responseCode": 400,
115+
"spanName": "/",
116+
"spanStatus": "INVALID_ARGUMENT",
117+
"spanKind": "Client",
118+
"spanAttributes": {
119+
"http.path": "/",
120+
"http.method": "GET",
121+
"http.host": "{host}:{port}",
122+
"http.status_code": "400",
123+
"http.url": "http://{host}:{port}/"
124+
}
125+
},
126+
{
127+
"name": "Response code: 401",
128+
"method": "GET",
129+
"url": "http://{host}:{port}/",
130+
"responseCode": 401,
131+
"spanName": "/",
132+
"spanStatus": "UNAUTHENTICATED",
133+
"spanKind": "Client",
134+
"spanAttributes": {
135+
"http.path": "/",
136+
"http.method": "GET",
137+
"http.host": "{host}:{port}",
138+
"http.status_code": "401",
139+
"http.url": "http://{host}:{port}/"
140+
}
141+
},
142+
{
143+
"name": "Response code: 403",
144+
"method": "GET",
145+
"url": "http://{host}:{port}/",
146+
"responseCode": 403,
147+
"spanName": "/",
148+
"spanStatus": "PERMISSION_DENIED",
149+
"spanKind": "Client",
150+
"spanAttributes": {
151+
"http.path": "/",
152+
"http.method": "GET",
153+
"http.host": "{host}:{port}",
154+
"http.status_code": "403",
155+
"http.url": "http://{host}:{port}/"
156+
}
157+
},
158+
{
159+
"name": "Response code: 404",
160+
"method": "GET",
161+
"url": "http://{host}:{port}/",
162+
"responseCode": 404,
163+
"spanName": "/",
164+
"spanStatus": "NOT_FOUND",
165+
"spanKind": "Client",
166+
"spanAttributes": {
167+
"http.path": "/",
168+
"http.method": "GET",
169+
"http.host": "{host}:{port}",
170+
"http.status_code": "404",
171+
"http.url": "http://{host}:{port}/"
172+
}
173+
},
174+
{
175+
"name": "Response code: 429",
176+
"method": "GET",
177+
"url": "http://{host}:{port}/",
178+
"responseCode": 429,
179+
"spanName": "/",
180+
"spanStatus": "RESOURCE_EXHAUSTED",
181+
"spanKind": "Client",
182+
"spanAttributes": {
183+
"http.path": "/",
184+
"http.method": "GET",
185+
"http.host": "{host}:{port}",
186+
"http.status_code": "429",
187+
"http.url": "http://{host}:{port}/"
188+
}
189+
},
190+
{
191+
"name": "Response code: 501",
192+
"method": "GET",
193+
"url": "http://{host}:{port}/",
194+
"responseCode": 501,
195+
"spanName": "/",
196+
"spanStatus": "UNIMPLEMENTED",
197+
"spanKind": "Client",
198+
"spanAttributes": {
199+
"http.path": "/",
200+
"http.method": "GET",
201+
"http.host": "{host}:{port}",
202+
"http.status_code": "501",
203+
"http.url": "http://{host}:{port}/"
204+
}
205+
},
206+
{
207+
"name": "Response code: 503",
208+
"method": "GET",
209+
"url": "http://{host}:{port}/",
210+
"responseCode": 503,
211+
"spanName": "/",
212+
"spanStatus": "UNAVAILABLE",
213+
"spanKind": "Client",
214+
"spanAttributes": {
215+
"http.path": "/",
216+
"http.method": "GET",
217+
"http.host": "{host}:{port}",
218+
"http.status_code": "503",
219+
"http.url": "http://{host}:{port}/"
220+
}
221+
},
222+
{
223+
"name": "Response code: 504",
224+
"method": "GET",
225+
"url": "http://{host}:{port}/",
226+
"responseCode": 504,
227+
"spanName": "/",
228+
"spanStatus": "DEADLINE_EXCEEDED",
229+
"spanKind": "Client",
230+
"spanAttributes": {
231+
"http.path": "/",
232+
"http.method": "GET",
233+
"http.host": "{host}:{port}",
234+
"http.status_code": "504",
235+
"http.url": "http://{host}:{port}/"
236+
}
237+
},
238+
{
239+
"name": "Response code: 600",
240+
"method": "GET",
241+
"url": "http://{host}:{port}/",
242+
"responseCode": 600,
243+
"spanName": "/",
244+
"spanStatus": "UNKNOWN",
245+
"spanKind": "Client",
246+
"spanAttributes": {
247+
"http.path": "/",
248+
"http.method": "GET",
249+
"http.host": "{host}:{port}",
250+
"http.status_code": "600",
251+
"http.url": "http://{host}:{port}/"
252+
}
253+
},
254+
{
255+
"name": "User agent attribute populated",
256+
"method": "GET",
257+
"url": "http://{host}:{port}/",
258+
"headers": {
259+
"User-Agent": "test-user-agent"
260+
},
261+
"responseCode": 200,
262+
"spanName": "/",
263+
"spanStatus": "OK",
264+
"spanKind": "Client",
265+
"spanAttributes": {
266+
"http.path": "/",
267+
"http.method": "GET",
268+
"http.host": "{host}:{port}",
269+
"http.status_code": "200",
270+
"http.user_agent": "test-user-agent",
271+
"http.url": "http://{host}:{port}/"
272+
}
273+
}
274+
]

0 commit comments

Comments
 (0)