Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/otel/common/test/serviceRobustness.spec.ts
13406 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { describe, expect, it } from 'vitest';
7
import { SpanStatusCode } from '../otelService';
8
import { CapturingOTelService } from './capturingOTelService';
9
10
/**
11
* Tests service robustness: buffer cap behavior, runWithTraceContext propagation,
12
* and capturing service correctness.
13
*/
14
describe('OTel Service Robustness', () => {
15
16
describe('CapturingOTelService basics', () => {
17
it('reset clears all captured data', () => {
18
const otel = new CapturingOTelService();
19
20
otel.startSpan('test', { attributes: {} });
21
otel.recordMetric('m', 1);
22
otel.incrementCounter('c');
23
otel.emitLogRecord('log');
24
25
otel.reset();
26
27
expect(otel.spans).toHaveLength(0);
28
expect(otel.metrics).toHaveLength(0);
29
expect(otel.counters).toHaveLength(0);
30
expect(otel.logRecords).toHaveLength(0);
31
});
32
33
it('findSpans filters by name prefix', () => {
34
const otel = new CapturingOTelService();
35
36
otel.startSpan('chat gpt-4o', { attributes: {} });
37
otel.startSpan('chat claude', { attributes: {} });
38
otel.startSpan('execute_tool read', { attributes: {} });
39
40
expect(otel.findSpans('chat')).toHaveLength(2);
41
expect(otel.findSpans('execute_tool')).toHaveLength(1);
42
expect(otel.findSpans('invoke_agent')).toHaveLength(0);
43
});
44
});
45
46
describe('runWithTraceContext', () => {
47
it('executes the function and returns its result', async () => {
48
const otel = new CapturingOTelService();
49
const ctx = { traceId: 'aaaa0000bbbb1111cccc2222dddd3333', spanId: 'eeee4444ffff5555' };
50
51
const result = await otel.runWithTraceContext(ctx, async () => {
52
return 42;
53
});
54
55
expect(result).toBe(42);
56
});
57
58
it('propagates errors from the wrapped function', async () => {
59
const otel = new CapturingOTelService();
60
const ctx = { traceId: '00000000000000000000000000000000', spanId: '0000000000000000' };
61
62
await expect(otel.runWithTraceContext(ctx, async () => {
63
throw new Error('test error');
64
})).rejects.toThrow('test error');
65
});
66
});
67
68
describe('startActiveSpan lifecycle', () => {
69
it('ends span even when fn throws', async () => {
70
const otel = new CapturingOTelService();
71
72
await expect(otel.startActiveSpan('test', { attributes: {} }, async () => {
73
throw new Error('boom');
74
})).rejects.toThrow('boom');
75
76
expect(otel.spans[0].ended).toBe(true);
77
});
78
79
it('returns fn result on success', async () => {
80
const otel = new CapturingOTelService();
81
82
const result = await otel.startActiveSpan('test', { attributes: {} }, async (span) => {
83
span.setStatus(SpanStatusCode.OK);
84
return 'hello';
85
});
86
87
expect(result).toBe('hello');
88
expect(otel.spans[0].statusCode).toBe(SpanStatusCode.OK);
89
});
90
});
91
92
describe('storeTraceContext edge cases', () => {
93
it('overwriting a key replaces the context', () => {
94
const otel = new CapturingOTelService();
95
const ctx1 = { traceId: 'aaaa', spanId: 'bbbb' };
96
const ctx2 = { traceId: 'cccc', spanId: 'dddd' };
97
98
otel.storeTraceContext('key', ctx1);
99
otel.storeTraceContext('key', ctx2);
100
101
expect(otel.getStoredTraceContext('key')).toEqual(ctx2);
102
});
103
});
104
});
105
106