Skip to content

Commit 1cfa98b

Browse files
committed
add tests for b3 multi propagation
1 parent ca6ec64 commit 1cfa98b

File tree

6 files changed

+170
-25
lines changed

6 files changed

+170
-25
lines changed

instrumentation/nginx/src/otel_ngx_module.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ nostd::string_view WithoutOtelVarPrefix(ngx_str_t value) {
237237

238238
static ngx_int_t
239239
OtelGetSampled(ngx_http_request_t* req, ngx_http_variable_value_t* v, uintptr_t data) {
240+
(void)data;
241+
242+
if (!IsOtelEnabled(req)) {
243+
v->valid = 0;
244+
v->not_found = 1;
245+
return NGX_OK;
246+
}
247+
240248
TraceContext* traceContext = GetTraceContext(req);
241249

242250
if (traceContext == nullptr || !traceContext->request_span) {
@@ -251,7 +259,7 @@ OtelGetSampled(ngx_http_request_t* req, ngx_http_variable_value_t* v, uintptr_t
251259
if (spanContext.IsValid()) {
252260
u_char* isSampled = spanContext.trace_flags().IsSampled() ? (u_char*) "1" : (u_char*) "0";
253261

254-
v->len = strlen((const char*)isSampled);
262+
v->len = 1;
255263
v->valid = 1;
256264
v->no_cacheable = 1;
257265
v->not_found = 0;

instrumentation/nginx/src/propagate.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ static bool FindHeader(ngx_http_request_t* req, nostd::string_view key, nostd::s
4242
}
4343

4444

45-
static bool HasHeader(ngx_http_request_t* req, nostd::string_view header) {
46-
nostd::string_view value;
47-
return FindHeader(req, header, &value);
48-
}
49-
5045
class TextMapCarrierNgx : public opentelemetry::context::propagation::TextMapCarrier
5146
{
5247
public:
@@ -79,15 +74,9 @@ opentelemetry::context::Context ExtractContext(OtelCarrier* carrier) {
7974
case TracePropagationW3C: {
8075
return OtelW3CPropagator().Extract(textMapCarrier, root);
8176
}
82-
case TracePropagationB3Multi: {
83-
return OtelB3MultiPropagator().Extract(textMapCarrier, root);
84-
}
77+
case TracePropagationB3Multi:
8578
case TracePropagationB3: {
86-
if (HasHeader(carrier->req, "b3")) {
87-
return OtelB3Propagator().Extract(textMapCarrier, root);
88-
}
89-
90-
return OtelB3MultiPropagator().Extract(textMapCarrier, root);
79+
return OtelB3Propagator().Extract(textMapCarrier, root);
9180
}
9281
default:
9382
return root;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
$b3_trace_id = $_SERVER["HTTP_B3_TRACEID"];
3+
$b3_span_id = $_SERVER["HTTP_B3_SPANID"];
4+
$b3_sampled = $_SERVER["HTTP_B3_SAMPLED"];
5+
6+
if (!preg_match("/^([0-9a-f]{32}|[0-9a-f]{16})$/", $b3_trace_id)) {
7+
throw new Exception("invalid or missing x-b3-traceid header");
8+
}
9+
10+
if (!preg_match("/^[0-9a-f]{16}$/", $b3_span_id)) {
11+
throw new Exception("invalid or missing x-b3-spanid header");
12+
}
13+
14+
if (!preg_match("/^[0-1]$/", $b3_sampled)) {
15+
throw new Exception("invalid or missing x-b3-sampled header");
16+
}
17+
18+
header("Content-Type: application/json");
19+
echo(json_encode(array(
20+
"x-b3-traceid" => $b3_trace_id,
21+
"x-b3-spanid" => $b3_span_id,
22+
"x-b3-sampled" => $b3_sampled
23+
)));
24+
?>

instrumentation/nginx/test/backend/simple_express/index.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const express = require('express')
2-
const app = express()
3-
const port = 3500
1+
const express = require('express');
2+
const app = express();
3+
const port = 3500;
44

55
const traceparentRegex = /00-[0-9a-f]{32}-[0-9a-f]{16}-0[0-1]/;
66

@@ -22,6 +22,30 @@ app.get("/b3", (req, res) => {
2222
res.json({"b3": header});
2323
});
2424

25+
app.get("/b3multi", (req, res) => {
26+
let traceId = req.header("x-b3-traceid");
27+
let spanId = req.header("x-b3-spanid");
28+
let sampled = req.header("x-b3-sampled");
29+
30+
if (!/^([0-9a-f]{32}|[0-9a-f]{16})$/.test(traceId)) {
31+
throw "Missing x-b3-traceid header";
32+
}
33+
34+
if (!/^[0-9a-f]{16}$/.test(spanId)) {
35+
throw "Missing x-b3-spanid header";
36+
}
37+
38+
if (!["0", "1"].includes(sampled)) {
39+
throw "Missing x-b3-sampled header";
40+
}
41+
42+
res.json({
43+
"x-b3-traceid": traceId,
44+
"x-b3-spanid": spanId,
45+
"x-b3-sampled": sampled
46+
});
47+
});
48+
2549
app.get("/off", (req, res) => {
2650
if (req.header("traceparent") !== undefined) {
2751
throw "Found traceparent header, but expected none";

instrumentation/nginx/test/conf/nginx.conf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ http {
4242
proxy_pass http://node-backend/b3;
4343
}
4444

45+
location = /b3multi {
46+
opentelemetry_operation_name test_b3multi;
47+
opentelemetry_propagate b3multi;
48+
proxy_pass http://node-backend/b3multi;
49+
}
50+
4551
location = /off {
4652
opentelemetry off;
4753
proxy_pass http://node-backend/off;
@@ -126,6 +132,22 @@ http {
126132
return 200 "";
127133
}
128134

135+
location = /b3multi.php {
136+
include /etc/nginx/fastcgi_params;
137+
root /var/www/html/php;
138+
opentelemetry_operation_name php_fpm_b3multi;
139+
opentelemetry_propagate b3multi;
140+
fastcgi_pass php-backend:9000;
141+
}
142+
143+
location = /b3.php {
144+
include /etc/nginx/fastcgi_params;
145+
root /var/www/html/php;
146+
opentelemetry_operation_name php_fpm_b3;
147+
opentelemetry_propagate b3;
148+
fastcgi_pass php-backend:9000;
149+
}
150+
129151
location ~ \.php$ {
130152
include /etc/nginx/fastcgi_params;
131153
root /var/www/html/php;

instrumentation/nginx/test/instrumentation/test/instrumentation_test.exs

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -316,29 +316,79 @@ defmodule InstrumentationTest do
316316
test_parent_span("#{@host}/app.php", ctx)
317317
end
318318

319-
test "HTTP upstream | test b3 injection", %{trace_file: trace_file} do
320-
%HTTPoison.Response{status_code: status} = HTTPoison.get!("#{@host}/b3")
319+
test "HTTP upstream | b3 injection", %{trace_file: trace_file} do
320+
%HTTPoison.Response{status_code: status, body: body} = HTTPoison.get!("#{@host}/b3")
321+
322+
%{"b3" => b3} = Jason.decode!(body)
323+
[trace_id, span_id, _] = String.split(b3, "-")
321324

322325
[trace] = read_traces(trace_file, 1)
323326
[span] = collect_spans(trace)
324327

325328
assert status == 200
326329
assert span["parentSpanId"] == ""
330+
assert span["traceId"] == trace_id
331+
assert span["spanId"] == span_id
327332
assert span["name"] == "test_b3"
328333
end
329334

330-
test "PHP-FPM upstream | test b3 injection", %{trace_file: trace_file} do
331-
%HTTPoison.Response{status_code: status} = HTTPoison.get!("#{@host}/b3")
335+
test "PHP-FPM upstream | b3 propagation", %{trace_file: trace_file} do
336+
input_trace_id = "aad85b4f655feed4d594a01cfa6a1d64"
337+
input_span_id = "2a9d49c3e3b7c461"
338+
339+
%HTTPoison.Response{status_code: status, body: body} =
340+
HTTPoison.get!("#{@host}/b3.php", [
341+
{"b3", "#{input_trace_id}-#{input_span_id}-1"}
342+
])
343+
344+
%{"b3" => b3} = Jason.decode!(body)
345+
[trace_id, span_id, _] = String.split(b3, "-")
346+
347+
assert input_trace_id == trace_id
348+
assert input_span_id != span_id
332349

333350
[trace] = read_traces(trace_file, 1)
334351
[span] = collect_spans(trace)
335352

336353
assert status == 200
337-
assert span["parentSpanId"] == ""
338-
assert span["name"] == "test_b3"
354+
assert span["parentSpanId"] == input_span_id
355+
assert span["traceId"] == input_trace_id
356+
assert span["spanId"] == span_id
357+
assert span["name"] == "php_fpm_b3"
358+
end
359+
360+
test "PHP-FPM upstream | multiheader b3 propagation", %{trace_file: trace_file} do
361+
input_trace_id = "aad85b4f655feed4d594a01cfa6a1d64"
362+
input_span_id = "2a9d49c3e3b7c461"
363+
364+
%HTTPoison.Response{status_code: status, body: body} =
365+
HTTPoison.get!("#{@host}/b3multi.php", [
366+
{"X-B3-TraceId", input_trace_id},
367+
{"X-B3-SpanId", input_span_id},
368+
{"X-B3-Sampled", "1"}
369+
])
370+
371+
%{
372+
"x-b3-traceid" => trace_id,
373+
"x-b3-spanid" => span_id,
374+
"x-b3-sampled" => sampled
375+
} = Jason.decode!(body)
376+
377+
assert sampled == "1"
378+
assert input_trace_id == trace_id
379+
assert input_span_id != span_id
380+
381+
[trace] = read_traces(trace_file, 1)
382+
[span] = collect_spans(trace)
383+
384+
assert status == 200
385+
assert span["parentSpanId"] == input_span_id
386+
assert span["traceId"] == input_trace_id
387+
assert span["spanId"] == span_id
388+
assert span["name"] == "php_fpm_b3multi"
339389
end
340390

341-
test "HTTP upstream | test b3 propagation", %{trace_file: trace_file} do
391+
test "HTTP upstream | b3 propagation", %{trace_file: trace_file} do
342392
parent_span_id = "2a9d49c3e3b7c461"
343393
input_trace_id = "aad85b4f655feed4d594a01cfa6a1d62"
344394

@@ -361,7 +411,7 @@ defmodule InstrumentationTest do
361411
assert span["name"] == "test_b3"
362412
end
363413

364-
test "HTTP upstream | multiheader b3 propagation", %{trace_file: trace_file} do
414+
test "HTTP upstream | multiheader b3 extraction", %{trace_file: trace_file} do
365415
parent_span_id = "2a9d49c3e3b7c461"
366416
input_trace_id = "aad85b4f655feed4d594a01cfa6a1d62"
367417

@@ -386,6 +436,34 @@ defmodule InstrumentationTest do
386436
assert span["name"] == "test_b3"
387437
end
388438

439+
test "HTTP upstream | multiheader b3 injection", %{trace_file: trace_file} do
440+
span_id = "2a9d49c3e3b7c462"
441+
trace_id = "aad85b4f655feed4d594a01cfa6a1d63"
442+
443+
%HTTPoison.Response{status_code: status, body: body} =
444+
HTTPoison.get!("#{@host}/b3multi", [
445+
{"b3", "#{trace_id}-#{span_id}-1"}
446+
])
447+
448+
[trace] = read_traces(trace_file, 1)
449+
[span] = collect_spans(trace)
450+
451+
%{
452+
"x-b3-traceid" => header_trace_id,
453+
"x-b3-spanid" => header_span_id,
454+
"x-b3-sampled" => header_sampled
455+
} = Jason.decode!(body)
456+
457+
assert header_trace_id == trace_id
458+
assert header_span_id != span_id
459+
assert header_sampled == "1"
460+
461+
assert status == 200
462+
assert span["parentSpanId"] == span_id
463+
assert span["spanId"] != span_id
464+
assert span["name"] == "test_b3multi"
465+
end
466+
389467
test "Accessing a file produces a span", %{trace_file: trace_file} do
390468
%HTTPoison.Response{status_code: status, body: body} =
391469
HTTPoison.get!("#{@host}/files/content.txt")

0 commit comments

Comments
 (0)