Skip to content

Commit fb12908

Browse files
committed
add tests for AutoTrace
1 parent db5ea0b commit fb12908

File tree

2 files changed

+200
-9
lines changed

2 files changed

+200
-9
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function yf = example1_trycatch(at, n)
2+
% example code for testing auto instrumentation. This example should not
3+
% use beginTrace method and instead should be called directly.
4+
5+
% Copyright 2024 The MathWorks, Inc.
6+
7+
try
8+
[x, y] = generate_data(n);
9+
yf = best_fit_line(x,y);
10+
catch ME
11+
handleError(at, ME);
12+
end

test/tautotrace.m

Lines changed: 188 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ function setupOnce(testCase)
2121
% add the utils folder to the path
2222
utilsfolder = fullfile(fileparts(mfilename('fullpath')), "utils");
2323
testCase.applyFixture(matlab.unittest.fixtures.PathFixture(utilsfolder));
24-
% add the example folder to the path
24+
% add the example folders to the path
2525
example1folder = fullfile(fileparts(mfilename('fullpath')), "autotrace_examples", "example1");
2626
testCase.applyFixture(matlab.unittest.fixtures.PathFixture(example1folder));
2727
commonSetupOnce(testCase);
28+
29+
% configure the global tracer provider
30+
tp = opentelemetry.sdk.trace.TracerProvider();
31+
setTracerProvider(tp);
2832
end
2933
end
3034

@@ -43,12 +47,7 @@ function teardown(testCase)
4347
methods (Test)
4448
function testBasic(testCase)
4549
% testBasic: instrument a simple example
46-
47-
% configure the global tracer provider
48-
tp = opentelemetry.sdk.trace.TracerProvider();
49-
setTracerProvider(tp);
50-
clear("tp");
51-
50+
5251
% set up AutoTrace
5352
at = opentelemetry.autoinstrument.AutoTrace(@example1);
5453

@@ -59,11 +58,191 @@ function testBasic(testCase)
5958
results = readJsonResults(testCase);
6059
verifyNumElements(testCase, results, 3);
6160

62-
% check logger name, log body and severity, trace and span IDs
63-
verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.scope.name), "AutoTrace");
61+
% check tracer and span names
62+
verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.scope.name), "AutoTrace"); % default name
6463
verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), "generate_data");
6564
verifyEqual(testCase, string(results{2}.resourceSpans.scopeSpans.spans.name), "best_fit_line");
6665
verifyEqual(testCase, string(results{3}.resourceSpans.scopeSpans.spans.name), "example1");
66+
67+
% check they belong to the same trace
68+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.traceId, results{2}.resourceSpans.scopeSpans.spans.traceId);
69+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.traceId, results{3}.resourceSpans.scopeSpans.spans.traceId);
70+
71+
% check parent children relationship
72+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.parentSpanId, results{3}.resourceSpans.scopeSpans.spans.spanId);
73+
verifyEqual(testCase, results{2}.resourceSpans.scopeSpans.spans.parentSpanId, results{3}.resourceSpans.scopeSpans.spans.spanId);
74+
end
75+
76+
function testIncludeExcludeFiles(testCase)
77+
% testIncludeExcludeFiles: AdditionalFiles and ExcludeFiles options
78+
79+
% set up AutoTrace
80+
at = opentelemetry.autoinstrument.AutoTrace(@example1, ...
81+
"AdditionalFiles", "polyfit", "ExcludeFiles", "generate_data");
82+
83+
% run the example
84+
[~] = beginTrace(at, 100);
85+
86+
% perform test comparisons
87+
results = readJsonResults(testCase);
88+
verifyNumElements(testCase, results, 3);
89+
90+
% check span names
91+
verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), "polyfit");
92+
verifyEqual(testCase, string(results{2}.resourceSpans.scopeSpans.spans.name), "best_fit_line");
93+
verifyEqual(testCase, string(results{3}.resourceSpans.scopeSpans.spans.name), "example1");
94+
95+
% check parent children relationship
96+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.parentSpanId, results{2}.resourceSpans.scopeSpans.spans.spanId);
97+
verifyEqual(testCase, results{2}.resourceSpans.scopeSpans.spans.parentSpanId, results{3}.resourceSpans.scopeSpans.spans.spanId);
98+
end
99+
100+
function testDisableFileDetection(testCase)
101+
% testDisableFileDetection: AutoDetectFiles set to false
102+
103+
% set up AutoTrace
104+
at = opentelemetry.autoinstrument.AutoTrace(@example1, ...
105+
"AutoDetectFiles", false);
106+
107+
% run the example
108+
[~] = beginTrace(at, 100);
109+
110+
% perform test comparisons
111+
results = readJsonResults(testCase);
112+
113+
% should only be 1 span
114+
verifyNumElements(testCase, results, 1);
115+
verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), "example1");
116+
end
117+
118+
function testNonFileOptions(testCase)
119+
% testNonFileOptions: other options not related to files,
120+
% "TracerName", "TracerVersion", "TracerSchema", "Attributes",
121+
% "SpanKind"
122+
123+
tracername = "foo";
124+
tracerversion = "1.1";
125+
tracerschema = "https://opentelemetry.io/schemas/1.28.0";
126+
spankind = "consumer";
127+
attrnames = ["foo" "bar"];
128+
attrvalues = [1 2];
129+
attrs = dictionary(attrnames, attrvalues);
130+
% set up AutoTrace
131+
at = opentelemetry.autoinstrument.AutoTrace(@example1, ...
132+
"TracerName", tracername, "TracerVersion", tracerversion, ...
133+
"TracerSchema", tracerschema, "SpanKind", spankind, "Attributes", attrs);
134+
135+
% run the example
136+
[~] = beginTrace(at, 100);
137+
138+
% perform test comparisons
139+
results = readJsonResults(testCase);
140+
verifyNumElements(testCase, results, 3);
141+
142+
% check specified options in each span
143+
for i = 1:numel(results)
144+
verifyEqual(testCase, string(results{i}.resourceSpans.scopeSpans.scope.name), tracername);
145+
verifyEqual(testCase, string(results{i}.resourceSpans.scopeSpans.scope.version), tracerversion);
146+
verifyEqual(testCase, string(results{i}.resourceSpans.scopeSpans.schemaUrl), tracerschema);
147+
verifyEqual(testCase, results{i}.resourceSpans.scopeSpans.spans.kind, 5); % SpanKind consumer
148+
149+
% attributes
150+
attrkeys = string({results{i}.resourceSpans.scopeSpans.spans.attributes.key});
151+
152+
for ii = 1:numel(attrnames)
153+
attrnameii = attrnames(ii);
154+
idxii = find(attrkeys == attrnameii);
155+
verifyNotEmpty(testCase, idxii);
156+
verifyEqual(testCase, results{i}.resourceSpans.scopeSpans.spans.attributes(idxii).value.doubleValue, ...
157+
attrvalues(ii));
158+
end
159+
end
160+
end
161+
162+
function testError(testCase)
163+
% testError: handling error situation
164+
165+
% set up AutoTrace
166+
at = opentelemetry.autoinstrument.AutoTrace(@example1);
167+
168+
% run the example with an invalid input, check for error
169+
verifyError(testCase, @()beginTrace(at, "invalid"), "MATLAB:colon:inputsMustBeNumericCharLogical");
170+
171+
% perform test comparisons
172+
results = readJsonResults(testCase);
173+
verifyNumElements(testCase, results, 2);
174+
175+
% check span names
176+
verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), "generate_data");
177+
verifyEqual(testCase, string(results{2}.resourceSpans.scopeSpans.spans.name), "example1");
178+
179+
% check parent children relationship
180+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.parentSpanId, results{2}.resourceSpans.scopeSpans.spans.spanId);
181+
182+
% check error status
183+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.status.code, 2); % error
184+
verifyEmpty(testCase, fieldnames(results{2}.resourceSpans.scopeSpans.spans.status)); % ok, no error
185+
end
186+
187+
function testHandleError(testCase)
188+
% testHandleError: directly call handleError method rather than using
189+
% beginTrace method. This test should use example1_trycatch, which
190+
% wraps a try-catch in the input function and calls handleError
191+
% in the catch block.
192+
193+
% set up AutoTrace, using example1_trycatch
194+
at = opentelemetry.autoinstrument.AutoTrace(@example1_trycatch);
195+
196+
% call example directly instead of calling beginTrace, and pass
197+
% in an invalid input
198+
verifyError(testCase, @()example1_trycatch(at, "invalid"), "MATLAB:colon:inputsMustBeNumericCharLogical");
199+
200+
% perform test comparisons
201+
results = readJsonResults(testCase);
202+
verifyNumElements(testCase, results, 2);
203+
204+
% check span names
205+
verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), "generate_data");
206+
verifyEqual(testCase, string(results{2}.resourceSpans.scopeSpans.spans.name), "example1_trycatch");
207+
208+
% check parent children relationship
209+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.parentSpanId, results{2}.resourceSpans.scopeSpans.spans.spanId);
210+
211+
% check error status
212+
verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.status.code, 2); % error
213+
verifyEmpty(testCase, fieldnames(results{2}.resourceSpans.scopeSpans.spans.status)); % ok, no error
214+
end
215+
216+
function testMultipleInstances(testCase)
217+
% testMultipleInstances: multiple overlapped instances should
218+
% return an error
219+
220+
% set up AutoTrace
221+
at = opentelemetry.autoinstrument.AutoTrace(@example1); %#ok<NASGU>
222+
223+
% set up another identical instance, check for error
224+
verifyError(testCase, @()opentelemetry.autoinstrument.AutoTrace(@example1), "opentelemetry:autoinstrument:AutoTrace:OverlappedInstances");
225+
end
226+
227+
function testClearInstance(~)
228+
% testClearInstance: clear an instance and recreate a new instance
229+
230+
% create and instance and then clear
231+
at = opentelemetry.autoinstrument.AutoTrace(@example1); %#ok<NASGU>
232+
clear("at")
233+
234+
% create a new instance should not result in any error
235+
at = opentelemetry.autoinstrument.AutoTrace(@example1); %#ok<NASGU>
236+
end
237+
238+
function testInvalidInputFunction(testCase)
239+
% testInvalidInputFunction: negative test for invalid input
240+
241+
% anonymous function
242+
verifyError(testCase, @()opentelemetry.autoinstrument.AutoTrace(@()example1), "opentelemetry:autoinstrument:AutoTrace:AnonymousFunction");
243+
244+
% builtin function
245+
verifyError(testCase, @()opentelemetry.autoinstrument.AutoTrace(@uplus), "opentelemetry:autoinstrument:AutoTrace:InvalidMFile");
67246
end
68247
end
69248
end

0 commit comments

Comments
 (0)