Skip to content

Commit 1398bfc

Browse files
committed
Parse binary envelopes in tests
1 parent 9325e24 commit 1398bfc

File tree

2 files changed

+86
-14
lines changed

2 files changed

+86
-14
lines changed

packages/utils/test/envelope.test.ts

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { EventEnvelope } from '@sentry/types';
22

3-
import { addItemToEnvelope, createEnvelope, forEachEnvelopeItem, serializeStringEnvelope } from '../src/envelope';
3+
import {
4+
addItemToEnvelope,
5+
createEnvelope,
6+
forEachEnvelopeItem,
7+
serializeStringEnvelope,
8+
serializeEnvelope,
9+
} from '../src/envelope';
410
import { parseEnvelope } from './testutils';
511

612
describe('envelope', () => {
@@ -29,43 +35,56 @@ describe('envelope', () => {
2935
describe('addItemToEnvelope()', () => {
3036
it('adds an item to an envelope', () => {
3137
const env = createEnvelope<EventEnvelope>({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, []);
32-
const parsedEnvelope = parseEnvelope(serializeStringEnvelope(env));
33-
expect(parsedEnvelope).toHaveLength(1);
34-
expect(parsedEnvelope[0]).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' });
38+
let [envHeaders, items] = parseEnvelope(serializeEnvelope(env));
39+
expect(items).toHaveLength(0);
40+
expect(envHeaders).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' });
3541

3642
const newEnv = addItemToEnvelope<EventEnvelope>(env, [
3743
{ type: 'event' },
3844
{ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' },
3945
]);
40-
const parsedNewEnvelope = parseEnvelope(serializeStringEnvelope(newEnv));
41-
expect(parsedNewEnvelope).toHaveLength(3);
42-
expect(parsedNewEnvelope[0]).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' });
43-
expect(parsedNewEnvelope[1]).toEqual({ type: 'event' });
44-
expect(parsedNewEnvelope[2]).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' });
46+
47+
[envHeaders, items] = parseEnvelope(serializeEnvelope(newEnv));
48+
expect(envHeaders).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' });
49+
expect(items).toHaveLength(1);
50+
expect(items[0]).toEqual([{ type: 'event' }, { event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }]);
4551
});
4652
});
4753

4854
describe('forEachEnvelopeItem', () => {
4955
it('loops through an envelope', () => {
5056
const items: EventEnvelope[1] = [
5157
[{ type: 'event' }, { event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }],
52-
[{ type: 'attachment', filename: 'bar.txt', length: 6 }, new Uint8Array(6)],
53-
[{ type: 'attachment', filename: 'foo.txt', length: 6 }, new Uint8Array(6)],
58+
[{ type: 'attachment', filename: 'bar.txt', length: 6 }, Uint8Array.from([1, 2, 3, 4, 5, 6])],
59+
[{ type: 'attachment', filename: 'foo.txt', length: 6 }, Uint8Array.from([7, 8, 9, 10, 11, 12])],
5460
];
5561

5662
const env = createEnvelope<EventEnvelope>(
5763
{ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' },
5864
items,
5965
);
6066

61-
expect.assertions(6);
67+
expect.assertions(11);
6268

6369
let iteration = 0;
6470
forEachEnvelopeItem(env, (item, type) => {
6571
expect(item).toBe(items[iteration]);
6672
expect(type).toBe(items[iteration][0].type);
6773
iteration = iteration + 1;
6874
});
75+
76+
const [parsedHeaders, parsedItems] = parseEnvelope(serializeEnvelope(env));
77+
expect(parsedHeaders).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' });
78+
expect(parsedItems).toHaveLength(3);
79+
expect(items[0]).toEqual([{ type: 'event' }, { event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }]);
80+
expect(items[1]).toEqual([
81+
{ type: 'attachment', filename: 'bar.txt', length: 6 },
82+
Uint8Array.from([1, 2, 3, 4, 5, 6]),
83+
]);
84+
expect(items[2]).toEqual([
85+
{ type: 'attachment', filename: 'foo.txt', length: 6 },
86+
Uint8Array.from([7, 8, 9, 10, 11, 12]),
87+
]);
6988
});
7089
});
7190
});

packages/utils/test/testutils.ts

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Envelope, BaseEnvelopeHeaders, BaseEnvelopeItemHeaders } from '@sentry/types';
2+
13
export const testOnlyIfNodeVersionAtLeast = (minVersion: number): jest.It => {
24
const currentNodeVersion = process.env.NODE_VERSION;
35

@@ -12,6 +14,57 @@ export const testOnlyIfNodeVersionAtLeast = (minVersion: number): jest.It => {
1214
return it;
1315
};
1416

15-
export function parseEnvelope(env: string): Array<Record<any, any>> {
16-
return env.split('\n').map(e => JSON.parse(e));
17+
/**
18+
* A naive binary envelope parser
19+
*/
20+
export function parseEnvelope(env: string | Uint8Array): Envelope {
21+
if (typeof env === 'string') {
22+
env = new TextEncoder().encode(env);
23+
}
24+
25+
let envelopeHeaders: BaseEnvelopeHeaders | undefined;
26+
let lastItemHeader: BaseEnvelopeItemHeaders | undefined;
27+
const items: [any, any][] = [];
28+
29+
let binaryLength = 0;
30+
while (env.length) {
31+
// Next length is either the binary length from the previous header
32+
// or the next newline character
33+
let i = binaryLength || env.indexOf(0xa);
34+
35+
// If no newline was found, assume this is the last block
36+
if (i < 0) {
37+
i = env.length;
38+
}
39+
40+
// If we read out a length in the previous header, assume binary
41+
if (binaryLength > 0) {
42+
const bin = env.slice(0, binaryLength);
43+
binaryLength = 0;
44+
items.push([lastItemHeader, bin]);
45+
} else {
46+
const json = JSON.parse(new TextDecoder().decode(env.slice(0, i + 1)));
47+
48+
if (typeof json.length === 'number') {
49+
binaryLength = json.length;
50+
}
51+
52+
// First json is always the envelope headers
53+
if (!envelopeHeaders) {
54+
envelopeHeaders = json;
55+
} else {
56+
// If there is a type property, assume this is an item header
57+
if ('type' in json) {
58+
lastItemHeader = json;
59+
} else {
60+
items.push([lastItemHeader, json]);
61+
}
62+
}
63+
}
64+
65+
// Replace the buffer with the previous block and newline removed
66+
env = env.slice(i + 1);
67+
}
68+
69+
return [envelopeHeaders as BaseEnvelopeHeaders, items];
1770
}

0 commit comments

Comments
 (0)