Initial commit: add .gitignore and README
This commit is contained in:
201
tests/performance/transport/load-tests.test.ts
Normal file
201
tests/performance/transport/load-tests.test.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* Performance and Load Tests
|
||||
* Tests system behavior under load
|
||||
*/
|
||||
|
||||
import { TLSClient } from '@/transport/tls-client/tls-client';
|
||||
import { LengthPrefixFramer } from '@/transport/framing/length-prefix';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
describe('Performance and Load Tests', () => {
|
||||
const pacs008Template = readFileSync(
|
||||
join(__dirname, '../../../docs/examples/pacs008-template-a.xml'),
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
describe('Connection Performance', () => {
|
||||
it('should establish connection within acceptable time', async () => {
|
||||
const tlsClient = new TLSClient();
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
const connection = await tlsClient.connect();
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
expect(connection.connected).toBe(true);
|
||||
expect(duration).toBeLessThan(10000); // Should connect within 10 seconds
|
||||
} finally {
|
||||
await tlsClient.close();
|
||||
}
|
||||
}, 15000);
|
||||
|
||||
it('should handle multiple sequential connections efficiently', async () => {
|
||||
const connections: TLSClient[] = [];
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const client = new TLSClient();
|
||||
await client.connect();
|
||||
connections.push(client);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
const avgTime = duration / 5;
|
||||
|
||||
expect(avgTime).toBeLessThan(5000); // Average should be under 5 seconds
|
||||
} finally {
|
||||
for (const client of connections) {
|
||||
await client.close();
|
||||
}
|
||||
}
|
||||
}, 60000);
|
||||
});
|
||||
|
||||
describe('Message Framing Performance', () => {
|
||||
it('should frame messages quickly', () => {
|
||||
const message = Buffer.from(pacs008Template, 'utf-8');
|
||||
const iterations = 1000;
|
||||
const startTime = Date.now();
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
LengthPrefixFramer.frame(message);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
const opsPerSecond = (iterations / duration) * 1000;
|
||||
|
||||
expect(opsPerSecond).toBeGreaterThan(10000); // Should handle 10k+ ops/sec
|
||||
});
|
||||
|
||||
it('should unframe messages quickly', () => {
|
||||
const message = Buffer.from(pacs008Template, 'utf-8');
|
||||
const framed = LengthPrefixFramer.frame(message);
|
||||
const iterations = 1000;
|
||||
const startTime = Date.now();
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
LengthPrefixFramer.unframe(framed);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
const opsPerSecond = (iterations / duration) * 1000;
|
||||
|
||||
expect(opsPerSecond).toBeGreaterThan(10000);
|
||||
});
|
||||
|
||||
it('should handle large messages efficiently', () => {
|
||||
const largeMessage = Buffer.alloc(1024 * 1024); // 1MB
|
||||
largeMessage.fill('A');
|
||||
|
||||
const startTime = Date.now();
|
||||
const framed = LengthPrefixFramer.frame(largeMessage);
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
expect(duration).toBeLessThan(100); // Should frame 1MB in under 100ms
|
||||
expect(framed.length).toBe(4 + largeMessage.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Concurrent Operations', () => {
|
||||
it('should handle concurrent message transmissions', async () => {
|
||||
const client = new TLSClient();
|
||||
const messageCount = 10;
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
await client.connect();
|
||||
|
||||
const promises = Array.from({ length: messageCount }, async () => {
|
||||
const messageId = uuidv4();
|
||||
const paymentId = uuidv4();
|
||||
const uetr = uuidv4();
|
||||
const xmlContent = pacs008Template.replace(
|
||||
'03BD66B4-6C81-48DB-B3D8-F5E5E0DC809A',
|
||||
uetr
|
||||
);
|
||||
|
||||
try {
|
||||
await client.sendMessage(messageId, paymentId, uetr, xmlContent);
|
||||
} catch (error) {
|
||||
// Expected if receiver unavailable
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.allSettled(promises);
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
expect(duration).toBeLessThan(60000); // Should complete within 60 seconds
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
}, 120000);
|
||||
});
|
||||
|
||||
describe('Memory Usage', () => {
|
||||
it('should not leak memory with repeated connections', async () => {
|
||||
const initialMemory = process.memoryUsage().heapUsed;
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const client = new TLSClient();
|
||||
try {
|
||||
await client.connect();
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
} catch (error) {
|
||||
// Ignore connection errors
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Force garbage collection if available
|
||||
if (global.gc) {
|
||||
global.gc();
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
|
||||
const finalMemory = process.memoryUsage().heapUsed;
|
||||
const memoryIncrease = finalMemory - initialMemory;
|
||||
const memoryIncreaseMB = memoryIncrease / (1024 * 1024);
|
||||
|
||||
// Memory increase should be reasonable (less than 50MB for 10 connections)
|
||||
expect(memoryIncreaseMB).toBeLessThan(50);
|
||||
}, 60000);
|
||||
});
|
||||
|
||||
describe('Throughput', () => {
|
||||
it('should measure message throughput', async () => {
|
||||
const client = new TLSClient();
|
||||
const messageCount = 100;
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
await client.connect();
|
||||
|
||||
for (let i = 0; i < messageCount; i++) {
|
||||
const messageId = uuidv4();
|
||||
const paymentId = uuidv4();
|
||||
const uetr = uuidv4();
|
||||
const xmlContent = pacs008Template;
|
||||
|
||||
try {
|
||||
await client.sendMessage(messageId, paymentId, uetr, xmlContent);
|
||||
} catch (error) {
|
||||
// Expected if receiver unavailable
|
||||
}
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
const messagesPerSecond = (messageCount / duration) * 1000;
|
||||
|
||||
// Should handle at least 1 message per second
|
||||
expect(messagesPerSecond).toBeGreaterThan(1);
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
}, 120000);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user