refactor(core): Centralize SSH Tunnel management (#9906)

Co-authored-by: Michael Kret <michael.k@radency.com>
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2024-07-04 12:29:44 +02:00
committed by GitHub
parent 86018aa6e0
commit 85aa560a5d
25 changed files with 525 additions and 630 deletions

View File

@@ -0,0 +1,67 @@
import { Client } from 'ssh2';
import type { SSHCredentials } from 'n8n-workflow';
import { SSHClientsManager } from '@/SSHClientsManager';
describe('SSHClientsManager', () => {
const credentials: SSHCredentials = {
sshAuthenticateWith: 'password',
sshHost: 'example.com',
sshPort: 22,
sshUser: 'username',
sshPassword: 'password',
};
let sshClientsManager: SSHClientsManager;
const connectSpy = jest.spyOn(Client.prototype, 'connect');
const endSpy = jest.spyOn(Client.prototype, 'end');
beforeEach(() => {
jest.clearAllMocks();
jest.useFakeTimers();
sshClientsManager = new SSHClientsManager();
connectSpy.mockImplementation(function (this: Client) {
this.emit('ready');
return this;
});
});
it('should create a new SSH client', async () => {
const client = await sshClientsManager.getClient(credentials);
expect(client).toBeInstanceOf(Client);
});
it('should not create a new SSH client when connect fails', async () => {
connectSpy.mockImplementation(function (this: Client) {
throw new Error('Failed to connect');
});
await expect(sshClientsManager.getClient(credentials)).rejects.toThrow('Failed to connect');
});
it('should reuse an existing SSH client', async () => {
const client1 = await sshClientsManager.getClient(credentials);
const client2 = await sshClientsManager.getClient(credentials);
expect(client1).toBe(client2);
});
it('should close all SSH connections on process exit', async () => {
await sshClientsManager.getClient(credentials);
sshClientsManager.onShutdown();
expect(endSpy).toHaveBeenCalledTimes(1);
});
it('should cleanup stale SSH connections', async () => {
await sshClientsManager.getClient({ ...credentials, sshHost: 'host1' });
await sshClientsManager.getClient({ ...credentials, sshHost: 'host2' });
await sshClientsManager.getClient({ ...credentials, sshHost: 'host3' });
jest.advanceTimersByTime(6 * 60 * 1000);
sshClientsManager.cleanupStaleConnections();
expect(endSpy).toHaveBeenCalledTimes(3);
expect(sshClientsManager.clients.size).toBe(0);
});
});