Skip to content

Commit 5ebed1c

Browse files
committed
tests for baggage and propagation
1 parent 649c031 commit 5ebed1c

File tree

2 files changed

+336
-0
lines changed

2 files changed

+336
-0
lines changed

test/tbaggage.m

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
function tests = tbaggage
2+
% tests for creating and manipulating baggage object
3+
%
4+
% Copyright 2023 The MathWorks, Inc.
5+
6+
tests = functiontests(localfunctions);
7+
end
8+
9+
function setupOnce(testCase)
10+
testCase.TestData.otelroot = getenv("OPENTELEMETRY_MATLAB_INSTALL");
11+
12+
% set up path
13+
addpath(testCase.TestData.otelroot);
14+
15+
testCase.TestData.baggageKeys = ["userId", "serverNode", "isProduction"];
16+
testCase.TestData.baggageValues = ["alice", "DF28", "false"];
17+
end
18+
19+
%% testCreate: creating a baggage object
20+
function testCreate(testCase)
21+
22+
% create a baggage
23+
baggagekeys = testCase.TestData.baggageKeys;
24+
baggagevalues = testCase.TestData.baggageValues;
25+
bag = opentelemetry.baggage.Baggage(dictionary(baggagekeys, baggagevalues));
26+
bagentries = bag.Entries;
27+
28+
% verify same baggage keys (can be in different order), and their values
29+
verifyEmpty(testCase, setxor(keys(bagentries), baggagekeys));
30+
verifyEqual(testCase, bagentries(baggagekeys), baggagevalues);
31+
end
32+
33+
%% testSetEntries: setting baggage entries
34+
function testSetEntries(testCase)
35+
36+
% create a baggage
37+
baggagekeys = testCase.TestData.baggageKeys;
38+
baggagevalues = testCase.TestData.baggageValues;
39+
bag = opentelemetry.baggage.Baggage(dictionary(baggagekeys, baggagevalues));
40+
41+
% add a new key-value pair and modify a value
42+
newkeys = ["location" "serverNode"];
43+
newvalues = ["Natick" "DA45"];
44+
bag = setEntries(bag, newkeys, newvalues);
45+
bagentries = bag.Entries;
46+
47+
[combinedkeys, ia, ib] = union(newkeys, baggagekeys, "stable");
48+
combinedvalues = [newvalues(ia) baggagevalues(ib)];
49+
verifyEmpty(testCase, setxor(keys(bagentries), combinedkeys));
50+
verifyEqual(testCase, bagentries(combinedkeys), combinedvalues);
51+
end
52+
53+
%% testDeleteEntries: deleting baggage entries
54+
function testDeleteEntries(testCase)
55+
56+
% create a baggage
57+
baggagekeys = testCase.TestData.baggageKeys;
58+
baggagevalues = testCase.TestData.baggageValues;
59+
bag = opentelemetry.baggage.Baggage(dictionary(baggagekeys, baggagevalues));
60+
61+
% delete 2 keys: one valid and one nonexistent
62+
deletekeys = ["userId" "location"];
63+
bag = deleteEntries(bag, deletekeys);
64+
bagentries = bag.Entries;
65+
66+
% verify updated baggage keys and values
67+
[newkeys, ia] = setdiff(baggagekeys, deletekeys);
68+
verifyEmpty(testCase, setxor(keys(bagentries), newkeys));
69+
verifyEqual(testCase, bagentries(newkeys), baggagevalues(ia));
70+
end
71+
72+
%% testModify: changing the Entries property of baggage
73+
function testModify(testCase)
74+
75+
% create a baggage
76+
baggagekeys = testCase.TestData.baggageKeys;
77+
baggagevalues = testCase.TestData.baggageValues;
78+
bag = opentelemetry.baggage.Baggage(dictionary(baggagekeys, baggagevalues));
79+
80+
% modify the Entries property
81+
newkeys = ["userId", "location", "serverNode"];
82+
newvalues = ["alice", "Natick", "DF25"];
83+
bag.Entries = dictionary(newkeys, newvalues);
84+
bagentries = bag.Entries;
85+
86+
% verify the modified entries
87+
verifyEmpty(testCase, setxor(keys(bagentries), newkeys));
88+
verifyEqual(testCase, bagentries(newkeys), newvalues);
89+
end

test/tcontextPropagation.m

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ function setupOnce(testCase)
1515
testCase.TestData.traceState = "foo=00f067aa0ba902b7";
1616
testCase.TestData.headers = ["traceparent", "00-" + testCase.TestData.traceId + ...
1717
"-" + testCase.TestData.spanId + "-01"; "tracestate", testCase.TestData.traceState];
18+
testCase.TestData.baggageKeys = ["userId", "serverNode", "isProduction"];
19+
testCase.TestData.baggageValues = ["alice", "DF28", "false"];
20+
testCase.TestData.baggageHeaders = ["baggage", strjoin(strcat(testCase.TestData.baggageKeys, ...
21+
'=', testCase.TestData.baggageValues), ',')];
1822
end
1923

2024
function setup(testCase)
@@ -146,4 +150,247 @@ function testInjectContext(testCase)
146150
% verify the injected traceparent contains the trace and span IDs
147151
verifySubstring(testCase, headers(1,2), spancontext.TraceId);
148152
verifySubstring(testCase, headers(1,2), spancontext.SpanId);
153+
end
154+
155+
%% testExtractBaggage: extracting baggage from HTTP header
156+
function testExtractBaggage(testCase)
157+
158+
carrier = opentelemetry.context.propagation.TextMapCarrier(testCase.TestData.baggageHeaders);
159+
propagator = opentelemetry.baggage.propagation.BaggagePropagator();
160+
context = opentelemetry.context.getCurrentContext();
161+
newcontext = propagator.extract(carrier, context);
162+
bag = opentelemetry.baggage.Context.extractBaggage(newcontext);
163+
bag = bag.Entries;
164+
165+
baggagekeys = testCase.TestData.baggageKeys;
166+
nkeys = length(baggagekeys);
167+
for i = 1:nkeys
168+
verifyTrue(testCase, isKey(bag, baggagekeys(i)));
169+
verifyEqual(testCase, bag(baggagekeys(i)), testCase.TestData.baggageValues(i));
170+
end
171+
172+
end
173+
174+
%% testInjectBaggage: injecting baggage into carrier
175+
function testInjectBaggage(testCase)
176+
177+
% create a baggage
178+
bag = opentelemetry.baggage.Baggage(dictionary(testCase.TestData.baggageKeys, ...
179+
testCase.TestData.baggageValues));
180+
181+
% insert baggage into context and inject
182+
propagator = opentelemetry.baggage.propagation.BaggagePropagator();
183+
context = opentelemetry.context.getCurrentContext();
184+
newcontext = opentelemetry.baggage.Context.insertBaggage(context, bag);
185+
carrier = opentelemetry.context.propagation.TextMapCarrier();
186+
carrier = propagator.inject(carrier, newcontext);
187+
headers = carrier.Headers;
188+
189+
% verify the baggage header
190+
verifyEqual(testCase, headers, testCase.TestData.baggageHeaders);
191+
end
192+
193+
%% testExtractContextBaggage: extractContext convenience function for baggage
194+
function testExtractContextBaggage(testCase)
195+
% set global propagator
196+
propagator = opentelemetry.baggage.propagation.BaggagePropagator();
197+
opentelemetry.context.propagation.Propagator.setTextMapPropagator(propagator);
198+
199+
% set up carrier and extract
200+
carrier = opentelemetry.context.propagation.TextMapCarrier(testCase.TestData.baggageHeaders);
201+
context = opentelemetry.context.propagation.extractContext(carrier);
202+
bag = opentelemetry.baggage.Context.extractBaggage(context);
203+
bag = bag.Entries;
204+
205+
baggagekeys = testCase.TestData.baggageKeys;
206+
nkeys = length(baggagekeys);
207+
for i = 1:nkeys
208+
verifyTrue(testCase, isKey(bag, baggagekeys(i)));
209+
verifyEqual(testCase, bag(baggagekeys(i)), testCase.TestData.baggageValues(i));
210+
end
211+
212+
end
213+
214+
%% testInjectContextBaggage: injectContext convenience function for baggage
215+
function testInjectContextBaggage(testCase)
216+
% set global propagator
217+
propagator = opentelemetry.baggage.propagation.BaggagePropagator();
218+
opentelemetry.context.propagation.Propagator.setTextMapPropagator(propagator);
219+
220+
% create a baggage and put it into the current context
221+
bag = opentelemetry.baggage.Baggage(dictionary(testCase.TestData.baggageKeys, ...
222+
testCase.TestData.baggageValues));
223+
context = opentelemetry.context.getCurrentContext();
224+
newcontext = opentelemetry.baggage.Context.insertBaggage(context, bag);
225+
token = setCurrentContext(newcontext); %#ok<NASGU>
226+
227+
% inject
228+
carrier = opentelemetry.context.propagation.injectContext();
229+
headers = carrier.Headers;
230+
231+
% verify the baggage header
232+
verifyEqual(testCase, headers, testCase.TestData.baggageHeaders);
233+
end
234+
235+
%% testCompositeExtract: extracting from HTTP header with a composite propagator
236+
function testCompositeExtract(testCase)
237+
238+
carrier = opentelemetry.context.propagation.TextMapCarrier([testCase.TestData.headers; ...
239+
testCase.TestData.baggageHeaders]);
240+
241+
% define composite propagator
242+
propagator = opentelemetry.context.propagation.CompositePropagator(...
243+
opentelemetry.trace.propagation.TraceContextPropagator, ...
244+
opentelemetry.baggage.propagation.BaggagePropagator);
245+
context = opentelemetry.context.getCurrentContext();
246+
newcontext = propagator.extract(carrier, context);
247+
248+
% extract baggage from context and verify
249+
bag = opentelemetry.baggage.Context.extractBaggage(newcontext);
250+
bag = bag.Entries;
251+
252+
baggagekeys = testCase.TestData.baggageKeys;
253+
nkeys = length(baggagekeys);
254+
for i = 1:nkeys
255+
verifyTrue(testCase, isKey(bag, baggagekeys(i)));
256+
verifyEqual(testCase, bag(baggagekeys(i)), testCase.TestData.baggageValues(i));
257+
end
258+
259+
% start a span using extracted context as parent
260+
tp = opentelemetry.sdk.trace.TracerProvider();
261+
tr = getTracer(tp, "bar");
262+
sp = startSpan(tr, "quux", Context=newcontext);
263+
endSpan(sp);
264+
265+
% perform test comparisons
266+
results = readJsonResults(testCase);
267+
results = results{1};
268+
269+
% check trace and parent IDs
270+
verifyEqual(testCase, string(results.resourceSpans.scopeSpans.spans.traceId), ...
271+
testCase.TestData.traceId);
272+
verifyEqual(testCase, string(results.resourceSpans.scopeSpans.spans.parentSpanId), ...
273+
testCase.TestData.spanId);
274+
% check trace state in span context
275+
spancontext = getContext(sp);
276+
verifyEqual(testCase, spancontext.TraceState, testCase.TestData.traceState);
277+
end
278+
279+
%% testCompositeInject: injecting into carrier using composite propagator
280+
function testCompositeInject(testCase)
281+
282+
% create composite propagator
283+
propagator = opentelemetry.context.propagation.CompositePropagator(...
284+
opentelemetry.trace.propagation.TraceContextPropagator, ...
285+
opentelemetry.baggage.propagation.BaggagePropagator);
286+
287+
% start a span, make it current, and get the current context
288+
tp = opentelemetry.sdk.trace.TracerProvider();
289+
tr = getTracer(tp, "foo");
290+
sp = startSpan(tr, "bar");
291+
scope = makeCurrent(sp); %#ok<NASGU>
292+
context = opentelemetry.context.getCurrentContext();
293+
294+
% create baggage and insert into context
295+
bag = opentelemetry.baggage.Baggage(dictionary(testCase.TestData.baggageKeys, ...
296+
testCase.TestData.baggageValues));
297+
newcontext = opentelemetry.baggage.Context.insertBaggage(context, bag);
298+
299+
% inject context into carrier
300+
carrier = opentelemetry.context.propagation.TextMapCarrier();
301+
carrier = propagator.inject(carrier, newcontext);
302+
headers = carrier.Headers;
303+
304+
endSpan(sp);
305+
306+
% verify number of fields are injected
307+
verifyEqual(testCase, size(headers), [2 2]);
308+
309+
% verify the baggage header
310+
baggagerow = find(headers(:,1) == "baggage");
311+
verifyNotEmpty(testCase, baggagerow);
312+
verifyEqual(testCase, headers(baggagerow, :), testCase.TestData.baggageHeaders);
313+
314+
results = readJsonResults(testCase);
315+
results = results{1};
316+
317+
% verify traceparent field
318+
traceparentrow = find(headers(:,1) == "traceparent");
319+
verifyNotEmpty(testCase, traceparentrow);
320+
321+
% verify the traceparent field contains both the trace and span IDs
322+
verifySubstring(testCase, headers(traceparentrow,2), string(results.resourceSpans.scopeSpans.spans.traceId));
323+
verifySubstring(testCase, headers(traceparentrow,2), string(results.resourceSpans.scopeSpans.spans.spanId));
324+
end
325+
326+
%% testExtractContextComposite: extractContext convenience function for composite extract
327+
function testExtractContextComposite(testCase)
328+
% set global propagator
329+
propagator = opentelemetry.context.propagation.CompositePropagator(...
330+
opentelemetry.trace.propagation.TraceContextPropagator, ...
331+
opentelemetry.baggage.propagation.BaggagePropagator);
332+
opentelemetry.context.propagation.Propagator.setTextMapPropagator(propagator);
333+
334+
% set up carrier and extract
335+
carrier = opentelemetry.context.propagation.TextMapCarrier([testCase.TestData.headers; ...
336+
testCase.TestData.baggageHeaders]);
337+
context = opentelemetry.context.propagation.extractContext(carrier);
338+
339+
% extract baggage and verify
340+
bag = opentelemetry.baggage.Context.extractBaggage(context);
341+
bag = bag.Entries;
342+
343+
baggagekeys = testCase.TestData.baggageKeys;
344+
nkeys = length(baggagekeys);
345+
for i = 1:nkeys
346+
verifyTrue(testCase, isKey(bag, baggagekeys(i)));
347+
verifyEqual(testCase, bag(baggagekeys(i)), testCase.TestData.baggageValues(i));
348+
end
349+
350+
% extract span and verify
351+
span = opentelemetry.trace.Context.extractSpan(context);
352+
spancontext = getContext(span);
353+
354+
% verify extracted trace and span IDs and trace state
355+
verifyEqual(testCase, spancontext.TraceId, testCase.TestData.traceId);
356+
verifyEqual(testCase, spancontext.SpanId, testCase.TestData.spanId);
357+
verifyEqual(testCase, spancontext.TraceState, testCase.TestData.traceState);
358+
end
359+
360+
%% testInjectContextComposite: injectContext convenience function for composite injection
361+
function testInjectContextComposite(testCase)
362+
% set global propagator
363+
propagator = opentelemetry.context.propagation.CompositePropagator(...
364+
opentelemetry.trace.propagation.TraceContextPropagator, ...
365+
opentelemetry.baggage.propagation.BaggagePropagator);
366+
opentelemetry.context.propagation.Propagator.setTextMapPropagator(propagator);
367+
368+
% start a span and put it into the current context
369+
tp = opentelemetry.sdk.trace.TracerProvider();
370+
tr = getTracer(tp, "foo");
371+
sp = startSpan(tr, "bar");
372+
scope = makeCurrent(sp); %#ok<NASGU>
373+
374+
% create a baggage and put it into the current context
375+
bag = opentelemetry.baggage.Baggage(dictionary(testCase.TestData.baggageKeys, ...
376+
testCase.TestData.baggageValues));
377+
context = opentelemetry.context.getCurrentContext();
378+
newcontext = opentelemetry.baggage.Context.insertBaggage(context, bag);
379+
token = setCurrentContext(newcontext); %#ok<NASGU>
380+
381+
% inject
382+
carrier = opentelemetry.context.propagation.injectContext();
383+
headers = carrier.Headers;
384+
385+
% verify the baggage header
386+
baggagerow = find(headers(:,1) == "baggage");
387+
verifyNotEmpty(testCase, baggagerow);
388+
verifyEqual(testCase, headers(baggagerow,:), testCase.TestData.baggageHeaders);
389+
390+
% verify the injected traceparent contains the trace and span IDs
391+
traceparentrow = find(headers(:,1) == "traceparent");
392+
verifyNotEmpty(testCase, traceparentrow);
393+
spancontext = getContext(sp);
394+
verifySubstring(testCase, headers(traceparentrow,2), spancontext.TraceId);
395+
verifySubstring(testCase, headers(traceparentrow,2), spancontext.SpanId);
149396
end

0 commit comments

Comments
 (0)