Skip to content

Commit 583b386

Browse files
antonisclaude
andcommitted
test(profiling): Add tests for profile timestamp offset fix
Add unit tests for enrichCombinedProfileWithEventContext and enrichAndroidProfileWithEventContext verifying that: - profilingStartTimestampNs is used for the profile timestamp when set - Falls back to event.start_timestamp when not set - profilingStartTimestampNs is stripped from serialized output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent fef6f6c commit 583b386

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
jest.mock('../../src/js/utils/environment');
2+
jest.mock('../../src/js/profiling/debugid');
3+
4+
import type { Event } from '@sentry/core';
5+
6+
import { getDebugMetadata } from '../../src/js/profiling/debugid';
7+
import type { AndroidCombinedProfileEvent, CombinedProfileEvent } from '../../src/js/profiling/types';
8+
import { enrichAndroidProfileWithEventContext, enrichCombinedProfileWithEventContext } from '../../src/js/profiling/utils';
9+
import { getDefaultEnvironment } from '../../src/js/utils/environment';
10+
import { createMockMinimalValidAndroidProfile, createMockMinimalValidHermesProfileEvent } from './fixtures';
11+
12+
describe('enrichCombinedProfileWithEventContext', () => {
13+
beforeEach(() => {
14+
(getDefaultEnvironment as jest.Mock).mockReturnValue('production');
15+
(getDebugMetadata as jest.Mock).mockReturnValue([]);
16+
});
17+
18+
function createMockEvent(overrides?: Partial<Event>): Event {
19+
return {
20+
event_id: 'test-event-id',
21+
transaction: 'test-transaction',
22+
release: 'test-release',
23+
environment: 'test-env',
24+
start_timestamp: 1000,
25+
contexts: {
26+
trace: {
27+
trace_id: '12345678901234567890123456789012',
28+
},
29+
os: { name: 'iOS', version: '17.0' },
30+
device: {},
31+
},
32+
...overrides,
33+
};
34+
}
35+
36+
test('should use profilingStartTimestampNs for timestamp when available', () => {
37+
const profilingStartTimestampNs = 1500 * 1e9; // 1500 seconds in ns
38+
const profile: CombinedProfileEvent = {
39+
...createMockMinimalValidHermesProfileEvent(),
40+
profilingStartTimestampNs,
41+
};
42+
const event = createMockEvent({ start_timestamp: 1000 }); // earlier than profiling start
43+
44+
const result = enrichCombinedProfileWithEventContext('profile-id', profile, event);
45+
46+
expect(result).not.toBeNull();
47+
expect(result!.timestamp).toBe(new Date(profilingStartTimestampNs / 1e6).toISOString());
48+
// Should NOT use event.start_timestamp
49+
expect(result!.timestamp).not.toBe(new Date(1000 * 1000).toISOString());
50+
});
51+
52+
test('should fall back to event.start_timestamp when profilingStartTimestampNs is not set', () => {
53+
const profile: CombinedProfileEvent = createMockMinimalValidHermesProfileEvent();
54+
const event = createMockEvent({ start_timestamp: 1000 });
55+
56+
const result = enrichCombinedProfileWithEventContext('profile-id', profile, event);
57+
58+
expect(result).not.toBeNull();
59+
expect(result!.timestamp).toBe(new Date(1000 * 1000).toISOString());
60+
});
61+
62+
test('should not include profilingStartTimestampNs in the output', () => {
63+
const profile: CombinedProfileEvent = {
64+
...createMockMinimalValidHermesProfileEvent(),
65+
profilingStartTimestampNs: 1500 * 1e9,
66+
};
67+
const event = createMockEvent();
68+
69+
const result = enrichCombinedProfileWithEventContext('profile-id', profile, event);
70+
71+
expect(result).not.toBeNull();
72+
expect(result).not.toHaveProperty('profilingStartTimestampNs');
73+
});
74+
});
75+
76+
describe('enrichAndroidProfileWithEventContext', () => {
77+
beforeEach(() => {
78+
(getDefaultEnvironment as jest.Mock).mockReturnValue('production');
79+
(getDebugMetadata as jest.Mock).mockReturnValue([]);
80+
});
81+
82+
function createMockEvent(overrides?: Partial<Event>): Event {
83+
return {
84+
event_id: 'test-event-id',
85+
transaction: 'test-transaction',
86+
release: 'test-release',
87+
environment: 'test-env',
88+
start_timestamp: 1000,
89+
contexts: {
90+
trace: {
91+
trace_id: '12345678901234567890123456789012',
92+
},
93+
os: { name: 'Android', version: '14' },
94+
device: {},
95+
},
96+
...overrides,
97+
};
98+
}
99+
100+
function createMockAndroidCombinedProfile(
101+
overrides?: Partial<AndroidCombinedProfileEvent>,
102+
): AndroidCombinedProfileEvent {
103+
const hermesProfileEvent = createMockMinimalValidHermesProfileEvent();
104+
return {
105+
platform: 'android',
106+
sampled_profile: createMockMinimalValidAndroidProfile().sampled_profile,
107+
js_profile: hermesProfileEvent.profile,
108+
android_api_level: 34,
109+
duration_ns: '1000000',
110+
active_thread_id: '123',
111+
...overrides,
112+
};
113+
}
114+
115+
test('should use profilingStartTimestampNs for timestamp when available', () => {
116+
const profilingStartTimestampNs = 1500 * 1e9;
117+
const profile = createMockAndroidCombinedProfile({ profilingStartTimestampNs });
118+
const event = createMockEvent({ start_timestamp: 1000 });
119+
120+
const result = enrichAndroidProfileWithEventContext('profile-id', profile, event);
121+
122+
expect(result).not.toBeNull();
123+
expect(result!.timestamp).toBe(new Date(profilingStartTimestampNs / 1e6).toISOString());
124+
expect(result!.timestamp).not.toBe(new Date(1000 * 1000).toISOString());
125+
});
126+
127+
test('should fall back to event.start_timestamp when profilingStartTimestampNs is not set', () => {
128+
const profile = createMockAndroidCombinedProfile();
129+
const event = createMockEvent({ start_timestamp: 1000 });
130+
131+
const result = enrichAndroidProfileWithEventContext('profile-id', profile, event);
132+
133+
expect(result).not.toBeNull();
134+
expect(result!.timestamp).toBe(new Date(1000 * 1000).toISOString());
135+
});
136+
137+
test('should not include profilingStartTimestampNs in the output', () => {
138+
const profile = createMockAndroidCombinedProfile({ profilingStartTimestampNs: 1500 * 1e9 });
139+
const event = createMockEvent();
140+
141+
const result = enrichAndroidProfileWithEventContext('profile-id', profile, event);
142+
143+
expect(result).not.toBeNull();
144+
expect(result).not.toHaveProperty('profilingStartTimestampNs');
145+
});
146+
});

0 commit comments

Comments
 (0)