mirror of
https://github.com/ptarmiganlabs/butler-sos.git
synced 2025-12-19 17:58:18 -05:00
238 lines
8.4 KiB
JavaScript
238 lines
8.4 KiB
JavaScript
// filepath: /Users/goran/code/butler-sos/src/lib/__tests__/proxysessionmetrics.test.js
|
|
import { jest, describe, test, expect, beforeEach } from '@jest/globals';
|
|
|
|
// Mock dependencies
|
|
const mockHttpsAgent = jest.fn();
|
|
jest.unstable_mockModule('https', () => ({
|
|
default: {
|
|
Agent: jest.fn().mockImplementation(() => mockHttpsAgent),
|
|
},
|
|
}));
|
|
|
|
jest.unstable_mockModule('fs', () => ({
|
|
default: {
|
|
readFileSync: jest.fn().mockImplementation(() => 'dummy-cert-content'),
|
|
},
|
|
}));
|
|
|
|
jest.unstable_mockModule('path', () => ({
|
|
default: {
|
|
resolve: jest.fn().mockImplementation((...args) => args.join('/')),
|
|
},
|
|
}));
|
|
|
|
const mockRequest = jest.fn();
|
|
jest.unstable_mockModule('axios', () => ({
|
|
default: {
|
|
create: jest.fn().mockReturnValue({
|
|
get: jest.fn(),
|
|
}),
|
|
request: mockRequest,
|
|
},
|
|
}));
|
|
|
|
// Mock InfluxDB client
|
|
jest.unstable_mockModule('@influxdata/influxdb-client', () => ({
|
|
Point: jest.fn().mockImplementation(() => ({
|
|
tag: jest.fn().mockReturnThis(),
|
|
floatField: jest.fn().mockReturnThis(),
|
|
intField: jest.fn().mockReturnThis(),
|
|
uintField: jest.fn().mockReturnThis(),
|
|
stringField: jest.fn().mockReturnThis(),
|
|
timestamp: jest.fn().mockReturnThis(),
|
|
})),
|
|
}));
|
|
|
|
// Mock globals
|
|
jest.unstable_mockModule('../../globals.js', () => ({
|
|
default: {
|
|
logger: {
|
|
info: jest.fn(),
|
|
verbose: jest.fn(),
|
|
debug: jest.fn(),
|
|
error: jest.fn(),
|
|
},
|
|
errorTracker: {
|
|
incrementError: jest.fn(),
|
|
},
|
|
config: {
|
|
get: jest.fn().mockImplementation((path) => {
|
|
if (path === 'Butler-SOS.cert.clientCert') return '/path/to/cert.pem';
|
|
if (path === 'Butler-SOS.cert.clientCertKey') return '/path/to/key.pem';
|
|
if (path === 'Butler-SOS.cert.clientCertCA') return '/path/to/ca.pem';
|
|
if (path === 'Butler-SOS.serversToMonitor.rejectUnauthorized') return false;
|
|
if (path === 'Butler-SOS.mqttConfig.enable') return false;
|
|
if (path === 'Butler-SOS.influxdbConfig.enable') return true;
|
|
if (path === 'Butler-SOS.influxdbConfig.version') return 2;
|
|
if (path === 'Butler-SOS.newRelic.enable') return true;
|
|
if (path === 'Butler-SOS.newRelic.metric.dynamic.proxy.sessions.enable')
|
|
return true;
|
|
if (path === 'Butler-SOS.prometheus.enable') return true;
|
|
if (path === 'Butler-SOS.userSessions.pollingInterval') return 10000;
|
|
if (path === 'Butler-SOS.userSessions.excludeUser') return [];
|
|
return undefined;
|
|
}),
|
|
has: jest.fn().mockReturnValue(true),
|
|
},
|
|
getErrorMessage: jest.fn().mockImplementation((err) => err.toString()),
|
|
serverList: [
|
|
{
|
|
serverName: 'server1',
|
|
host: 'host1.example.com',
|
|
userSessions: {
|
|
enable: true,
|
|
host: 'host1.example.com',
|
|
virtualProxies: [{ virtualProxy: 'vproxy1' }, { virtualProxy: 'vproxy2' }],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}));
|
|
|
|
// Mock dependent modules
|
|
const mockPostProxySessionsToInfluxdb = jest.fn().mockResolvedValue();
|
|
jest.unstable_mockModule('../influxdb/index.js', () => ({
|
|
postProxySessionsToInfluxdb: mockPostProxySessionsToInfluxdb,
|
|
}));
|
|
|
|
const mockPostProxySessionsToNewRelic = jest.fn().mockResolvedValue();
|
|
jest.unstable_mockModule('../post-to-new-relic.js', () => ({
|
|
postProxySessionsToNewRelic: mockPostProxySessionsToNewRelic,
|
|
}));
|
|
|
|
const mockPostUserSessionsToMQTT = jest.fn().mockResolvedValue();
|
|
jest.unstable_mockModule('../post-to-mqtt.js', () => ({
|
|
postUserSessionsToMQTT: mockPostUserSessionsToMQTT,
|
|
}));
|
|
|
|
const mockGetServerTags = jest.fn().mockReturnValue({
|
|
server_name: 'server1',
|
|
server_environment: 'production',
|
|
});
|
|
jest.unstable_mockModule('../servertags.js', () => ({
|
|
getServerTags: mockGetServerTags,
|
|
}));
|
|
|
|
const mockSaveUserSessionMetricsToPrometheus = jest.fn().mockResolvedValue();
|
|
jest.unstable_mockModule('../prom-client.js', () => ({
|
|
saveUserSessionMetricsToPrometheus: mockSaveUserSessionMetricsToPrometheus,
|
|
}));
|
|
|
|
// Import the module under test
|
|
const { setupUserSessionsTimer, getProxySessionStatsFromSense } =
|
|
await import('../proxysessionmetrics.js');
|
|
|
|
describe('proxysessionmetrics', () => {
|
|
let proxysessionmetrics;
|
|
let axios;
|
|
let globals;
|
|
let influxdb;
|
|
let newRelic;
|
|
let mqtt;
|
|
let servertags;
|
|
let promClient;
|
|
|
|
beforeEach(async () => {
|
|
jest.clearAllMocks();
|
|
|
|
// Get mocked modules
|
|
axios = (await import('axios')).default;
|
|
globals = (await import('../../globals.js')).default;
|
|
influxdb = await import('../influxdb/index.js');
|
|
newRelic = await import('../post-to-new-relic.js');
|
|
mqtt = await import('../post-to-mqtt.js');
|
|
servertags = await import('../servertags.js');
|
|
promClient = await import('../prom-client.js');
|
|
|
|
// Reset mockRequest for each test
|
|
mockRequest.mockReset();
|
|
});
|
|
|
|
describe('getProxySessionStatsFromSense', () => {
|
|
test('should get session stats from Sense and post to backends', async () => {
|
|
// Setup
|
|
const serverName = 'server1';
|
|
const host = 'host1.example.com';
|
|
const virtualProxy = 'vproxy1';
|
|
const tags = { server_name: serverName, server_environment: 'production' };
|
|
|
|
// Set up mock response with data that will actually make the backend calls
|
|
const mockResponse = {
|
|
data: [
|
|
{
|
|
UserDirectory: 'DOMAIN',
|
|
UserId: 'user1',
|
|
Attributes: [],
|
|
SessionId: 'session1',
|
|
},
|
|
{
|
|
UserDirectory: 'DOMAIN',
|
|
UserId: 'user2',
|
|
Attributes: [],
|
|
SessionId: 'session2',
|
|
},
|
|
],
|
|
status: 200,
|
|
config: {
|
|
url: `https://${host}/qps${virtualProxy}/session?Xrfkey=abcdefghij987654`,
|
|
},
|
|
};
|
|
|
|
mockRequest.mockResolvedValueOnce(mockResponse);
|
|
|
|
// Execute
|
|
await getProxySessionStatsFromSense(serverName, host, virtualProxy, tags);
|
|
|
|
// Verify
|
|
expect(mockRequest).toHaveBeenCalled();
|
|
expect(mockPostProxySessionsToInfluxdb).toHaveBeenCalled();
|
|
expect(mockPostProxySessionsToNewRelic).toHaveBeenCalled();
|
|
expect(mockSaveUserSessionMetricsToPrometheus).toHaveBeenCalled();
|
|
});
|
|
|
|
test('should handle error from Sense API', async () => {
|
|
// Setup
|
|
const serverName = 'server1';
|
|
const host = 'host1.example.com';
|
|
const virtualProxy = 'vproxy1';
|
|
const tags = { server_name: serverName, server_environment: 'production' };
|
|
|
|
mockRequest.mockRejectedValueOnce(new Error('API error'));
|
|
|
|
// Execute
|
|
await getProxySessionStatsFromSense(serverName, host, virtualProxy, tags);
|
|
|
|
// Verify
|
|
expect(mockRequest).toHaveBeenCalled();
|
|
expect(globals.logger.error).toHaveBeenCalledWith(
|
|
expect.stringContaining(
|
|
"PROXY SESSIONS: Error when calling proxy session API for server 'server1' (host1.example.com), virtual proxy 'vproxy1':"
|
|
)
|
|
);
|
|
expect(mockPostProxySessionsToInfluxdb).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('setupUserSessionsTimer', () => {
|
|
test('should set up timer for polling user sessions', () => {
|
|
// Mock setInterval
|
|
jest.useFakeTimers();
|
|
const originalSetInterval = global.setInterval;
|
|
global.setInterval = jest.fn().mockImplementation((callback, interval) => {
|
|
return originalSetInterval(callback, interval);
|
|
});
|
|
|
|
// Execute
|
|
setupUserSessionsTimer();
|
|
|
|
// Verify
|
|
expect(global.setInterval).toHaveBeenCalled();
|
|
expect(global.setInterval).toHaveBeenCalledWith(expect.any(Function), 10000);
|
|
|
|
// Restore setInterval
|
|
global.setInterval = originalSetInterval;
|
|
jest.useRealTimers();
|
|
});
|
|
});
|
|
});
|