176 lines
6.4 KiB
JavaScript
176 lines
6.4 KiB
JavaScript
// test/agent_geolocation_test.js
|
|
const mongoose = require('../backend/node_modules/mongoose');
|
|
const path = require('path');
|
|
|
|
// Load environment variables
|
|
require('dotenv').config({ path: path.join(__dirname, '../.env.local') });
|
|
|
|
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/backone_dpi';
|
|
|
|
const { CustomAgentLocation, DeviceStat, Flow } = require('../backend/models/Schemas');
|
|
|
|
let testCount = 0;
|
|
let passedCount = 0;
|
|
|
|
function assert(label, condition) {
|
|
testCount++;
|
|
if (condition) {
|
|
console.log(` ✓ PASSED: ${label}`);
|
|
passedCount++;
|
|
} else {
|
|
console.error(` ✗ FAILED: ${label}`);
|
|
}
|
|
}
|
|
|
|
async function runTests() {
|
|
console.log('\n=========================================');
|
|
console.log(' RUNNING TDD TESTS FOR GEOLOCATION & FLOWS');
|
|
console.log('=========================================\n');
|
|
|
|
try {
|
|
// 1. Connect to DB
|
|
await mongoose.connect(MONGODB_URI);
|
|
console.log('✓ Connected to MongoDB');
|
|
|
|
// 2. Validate Geolocation Seeding
|
|
const count = await CustomAgentLocation.countDocuments();
|
|
assert('CustomAgentLocation collection should have seeded documents', count >= 3);
|
|
|
|
const balarajaLoc = await CustomAgentLocation.findOne({ agent_uuid: 'F6-2V-DT-8A' });
|
|
assert('CPI Balaraja Agent location should exist', !!balarajaLoc);
|
|
if (balarajaLoc) {
|
|
assert('CPI Balaraja latitude matches', balarajaLoc.latitude === -6.2263304);
|
|
assert('CPI Balaraja longitude matches', balarajaLoc.longitude === 106.4247322);
|
|
assert('CPI Balaraja belongs to SIAB site', balarajaLoc.site_uuid === '6681452d_9cae_4ff4_8ae8_0d504774265e');
|
|
}
|
|
|
|
const cibuburLoc = await CustomAgentLocation.findOne({ agent_uuid: '2F-TF-1D-GK' });
|
|
assert('JRP Cibubur Agent location should exist', !!cibuburLoc);
|
|
if (cibuburLoc) {
|
|
assert('JRP Cibubur latitude matches', cibuburLoc.latitude === -6.3763318);
|
|
assert('JRP Cibubur longitude matches', cibuburLoc.longitude === 106.8983017);
|
|
}
|
|
|
|
const ifgLoc = await CustomAgentLocation.findOne({ agent_uuid: '8A-V3-PB-85' });
|
|
assert('IFG LT.18 Agent location should exist', !!ifgLoc);
|
|
if (ifgLoc) {
|
|
assert('IFG LT.18 latitude matches', ifgLoc.latitude === -6.2253265);
|
|
assert('IFG LT.18 longitude matches', ifgLoc.longitude === 106.8061484);
|
|
}
|
|
|
|
// 3. Test Location Updates (Simulation of POST API)
|
|
const testUuid = 'TEST-AGENT-UUID';
|
|
const testSite = 'test-site-uuid';
|
|
|
|
// Remove if exists
|
|
await CustomAgentLocation.deleteOne({ agent_uuid: testUuid });
|
|
|
|
const updated = await CustomAgentLocation.findOneAndUpdate(
|
|
{ agent_uuid: testUuid },
|
|
{
|
|
agent_uuid: testUuid,
|
|
site_uuid: testSite,
|
|
latitude: -6.1234,
|
|
longitude: 106.1234,
|
|
label: 'Test Location Label'
|
|
},
|
|
{ new: true, upsert: true }
|
|
);
|
|
assert('Location upsert should return the saved document', !!updated);
|
|
assert('Upserted latitude matches', updated.latitude === -6.1234);
|
|
assert('Upserted longitude matches', updated.longitude === 106.1234);
|
|
assert('Upserted label matches', updated.label === 'Test Location Label');
|
|
|
|
// 4. Test Location Reset (Simulation of DELETE API)
|
|
const delRes = await CustomAgentLocation.deleteOne({ agent_uuid: testUuid });
|
|
assert('Location delete should succeed', delRes.deletedCount > 0);
|
|
|
|
const checkedDel = await CustomAgentLocation.findOne({ agent_uuid: testUuid });
|
|
assert('Location should no longer exist after delete', !checkedDel);
|
|
|
|
// 5. Test Inter-Agent Flow Aggregation Logic
|
|
// Let's seed a mock device belonging to Cibubur agent and a flow from Balaraja to Cibubur's device IP.
|
|
const mockDestIp = '192.168.99.123';
|
|
|
|
// Cleanup if existing
|
|
await DeviceStat.deleteOne({ ip_address: mockDestIp });
|
|
await Flow.deleteMany({ dst_ip: mockDestIp });
|
|
|
|
// Seed mock device monitored by Cibubur agent (2F-TF-1D-GK)
|
|
await DeviceStat.create({
|
|
timestamp: new Date(),
|
|
ip_address: mockDestIp,
|
|
agent_uuid: '2F-TF-1D-GK',
|
|
site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e',
|
|
mac_address: '00:11:22:33:44:55',
|
|
});
|
|
|
|
// Seed mock flow from Balaraja agent (F6-2V-DT-8A) to mockDestIp
|
|
await Flow.create({
|
|
timestamp: new Date(),
|
|
agent_uuid: 'F6-2V-DT-8A',
|
|
site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e',
|
|
src_ip: '192.168.10.50',
|
|
dst_ip: mockDestIp,
|
|
download: 15000000,
|
|
upload: 5000000,
|
|
});
|
|
|
|
// Run the aggregation logic
|
|
const devices = await DeviceStat.find({ site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' }).select('ip_address agent_uuid').lean();
|
|
const deviceIpToAgent = {};
|
|
for (const dev of devices) {
|
|
if (dev.ip_address && dev.agent_uuid) {
|
|
deviceIpToAgent[dev.ip_address] = dev.agent_uuid;
|
|
}
|
|
}
|
|
|
|
const flows = await Flow.find({ site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' }).select('agent_uuid src_ip dst_ip download upload').lean();
|
|
|
|
const flowMap = {};
|
|
for (const flow of flows) {
|
|
const srcAgent = flow.agent_uuid;
|
|
const dstAgent = deviceIpToAgent[flow.dst_ip];
|
|
|
|
if (srcAgent && dstAgent && srcAgent !== dstAgent) {
|
|
const key = `${srcAgent}->${dstAgent}`;
|
|
if (!flowMap[key]) {
|
|
flowMap[key] = {
|
|
source: srcAgent,
|
|
target: dstAgent,
|
|
bytes: 0,
|
|
flowsCount: 0
|
|
};
|
|
}
|
|
flowMap[key].bytes += ((flow.download || 0) + (flow.upload || 0));
|
|
flowMap[key].flowsCount += 1;
|
|
}
|
|
}
|
|
|
|
const result = Object.values(flowMap);
|
|
assert('Inter-agent flows aggregation should detect flows', result.length > 0);
|
|
|
|
const detectedFlow = result.find(f => f.source === 'F6-2V-DT-8A' && f.target === '2F-TF-1D-GK');
|
|
assert('Mock flow from Balaraja to Cibubur should be detected', !!detectedFlow);
|
|
if (detectedFlow) {
|
|
assert('Mock flow bytes matches (15MB down + 5MB up = 20MB)', detectedFlow.bytes >= 20000000);
|
|
assert('Mock flow connection count is correct', detectedFlow.flowsCount >= 1);
|
|
}
|
|
|
|
// Cleanup mock telemetry
|
|
await DeviceStat.deleteOne({ ip_address: mockDestIp });
|
|
await Flow.deleteMany({ dst_ip: mockDestIp });
|
|
|
|
console.log('\n=========================================');
|
|
console.log(` RESULT: ${passedCount} / ${testCount} tests passed.`);
|
|
console.log('=========================================\n');
|
|
|
|
await mongoose.disconnect();
|
|
} catch (err) {
|
|
console.error('TDD Test run error:', err);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
runTests();
|