Skip to content

Commit 89774ab

Browse files
committed
Add tests
1 parent 948db0c commit 89774ab

File tree

2 files changed

+96
-14
lines changed

2 files changed

+96
-14
lines changed

packages/node/src/integrations/tracing/firebase/otel/patches/firestore.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -253,22 +253,25 @@ function startDBSpan<AppModelType, DbModelType extends DocumentData>(
253253
}
254254

255255
/**
256-
* Sets the server address and port attributes on the span based on the Firestore settings.
256+
* Gets the server address and port attributes from the Firestore settings.
257257
* It's best effort to extract the address and port from the settings, especially for IPv6.
258258
* @param span - The span to set attributes on.
259259
* @param settings - The Firestore settings containing host information.
260260
*/
261-
function setPortAndAddress(span: Span, settings: FirestoreSettings): void {
262-
if (typeof settings.host === 'string') {
263-
let address: string | undefined;
264-
let port: string | undefined;
261+
export function getPortAndAddress(settings: FirestoreSettings): {
262+
address?: string;
263+
port?: number;
264+
} {
265+
let address: string | undefined;
266+
let port: string | undefined;
265267

268+
if (typeof settings.host === 'string') {
266269
if (settings.host.startsWith('[')) {
267270
// IPv6 addresses can be enclosed in square brackets, e.g., [2001:db8::1]:8080
268271
if (settings.host.endsWith(']')) {
269272
// IPv6 with square brackets without port
270273
address = settings.host.replace(/^\[|\]$/g, '');
271-
} else {
274+
} else if (settings.host.includes(']:')) {
272275
// IPv6 with square brackets with port
273276
const lastColonIndex = settings.host.lastIndexOf(':');
274277
if (lastColonIndex !== -1) {
@@ -293,14 +296,11 @@ function setPortAndAddress(span: Span, settings: FirestoreSettings): void {
293296
}
294297
}
295298
}
296-
if (address) {
297-
span.setAttribute(ATTR_SERVER_ADDRESS, address);
298-
}
299-
300-
if (port !== undefined) {
301-
span.setAttribute(ATTR_SERVER_PORT, Number(port));
302-
}
303299
}
300+
return {
301+
address: address,
302+
port: port ? parseInt(port, 10) : undefined,
303+
};
304304
}
305305

306306
function addAttributes<AppModelType, DbModelType extends DocumentData>(
@@ -323,6 +323,14 @@ function addAttributes<AppModelType, DbModelType extends DocumentData>(
323323
'firebase.firestore.options.storageBucket': firestoreOptions.storageBucket,
324324
};
325325

326+
const { address, port } = getPortAndAddress(settings);
327+
328+
if (address) {
329+
attributes[ATTR_SERVER_ADDRESS] = address;
330+
}
331+
if (port) {
332+
attributes[ATTR_SERVER_PORT] = port;
333+
}
334+
326335
span.setAttributes(attributes);
327-
setPortAndAddress(span, settings);
328336
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { beforeEach, describe, expect, it, vi } from 'vitest';
2+
import { getPortAndAddress } from '../../../src/integrations/tracing/firebase/otel/patches/firestore';
3+
4+
describe('setPortAndAddress', () => {
5+
beforeEach(() => {
6+
vi.clearAllMocks();
7+
});
8+
9+
describe('IPv6 addresses', () => {
10+
it('should correctly parse IPv6 address without port', () => {
11+
const { address, port } = getPortAndAddress({ host: '[2001:db8::1]' });
12+
13+
expect(address).toBe('2001:db8::1');
14+
expect(port).toBeUndefined();
15+
});
16+
17+
it('should correctly parse IPv6 address with port', () => {
18+
const { address, port } = getPortAndAddress({ host: '[2001:db8::1]:8080' });
19+
expect(address).toBe('2001:db8::1');
20+
expect(port).toBe(8080);
21+
});
22+
23+
it('should handle IPv6 localhost without port', () => {
24+
const { address, port } = getPortAndAddress({ host: '[::1]' });
25+
26+
expect(address).toBe('::1');
27+
expect(port).toBeUndefined();
28+
});
29+
30+
it('should handle IPv6 localhost with port', () => {
31+
const { address, port } = getPortAndAddress({ host: '[::1]:3000' });
32+
33+
expect(address).toBe('::1');
34+
expect(port).toBe(3000);
35+
});
36+
});
37+
38+
describe('IPv4 and hostname addresses', () => {
39+
it('should correctly parse IPv4 address with port', () => {
40+
const { address, port } = getPortAndAddress({ host: '192.168.1.1:8080' });
41+
42+
expect(address).toBe('192.168.1.1');
43+
expect(port).toBe(8080);
44+
});
45+
46+
it('should correctly parse hostname with port', () => {
47+
const { address, port } = getPortAndAddress({ host: 'localhost:3000' });
48+
49+
expect(address).toBe('localhost');
50+
expect(port).toBe(3000);
51+
});
52+
53+
it('should correctly parse hostname without port', () => {
54+
const { address, port } = getPortAndAddress({ host: 'example.com' });
55+
56+
expect(address).toBe('example.com');
57+
expect(port).toBeUndefined();
58+
});
59+
60+
it('should correctly parse hostname with port', () => {
61+
const { address, port } = getPortAndAddress({ host: 'example.com:4000' });
62+
63+
expect(address).toBe('example.com');
64+
expect(port).toBe(4000);
65+
});
66+
67+
it('should handle empty string', () => {
68+
const { address, port } = getPortAndAddress({ host: '' });
69+
70+
expect(address).toBe('');
71+
expect(port).toBeUndefined();
72+
});
73+
});
74+
});

0 commit comments

Comments
 (0)