wifi-densepose/vendor/midstream/AIMDS/tests/integration/gateway.test.ts

231 lines
6.3 KiB
TypeScript

/**
* Integration Tests for AIMDS Gateway
*/
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import request from 'supertest';
import { AIMDSGateway } from '../../src/gateway/server';
import { Config } from '../../src/utils/config';
import { ThreatLevel } from '../../src/types';
describe('AIMDS Gateway Integration Tests', () => {
let gateway: AIMDSGateway;
let app: any;
beforeAll(async () => {
// Create test configuration
const config = Config.getInstance();
const gatewayConfig = {
...config.getGatewayConfig(),
port: 3001 // Use different port for tests
};
gateway = new AIMDSGateway(
gatewayConfig,
config.getAgentDBConfig(),
config.getLeanAgenticConfig()
);
await gateway.initialize();
await gateway.start();
// Get Express app for supertest
app = (gateway as any).app;
});
afterAll(async () => {
await gateway.shutdown();
});
describe('Health Checks', () => {
it('should return healthy status', async () => {
const response = await request(app)
.get('/health')
.expect(200);
expect(response.body.status).toBe('healthy');
expect(response.body.components.gateway.status).toBe('up');
expect(response.body.components.agentdb.status).toBe('up');
expect(response.body.components.verifier.status).toBe('up');
});
it('should return metrics', async () => {
const response = await request(app)
.get('/metrics')
.expect(200);
expect(response.text).toContain('aimds_requests_total');
});
});
describe('Defense Endpoint', () => {
it('should process a benign request (fast path)', async () => {
const testRequest = {
action: {
type: 'read',
resource: '/api/users',
method: 'GET'
},
source: {
ip: '192.168.1.1',
userAgent: 'test-client'
}
};
const response = await request(app)
.post('/api/v1/defend')
.send(testRequest)
.expect(200);
expect(response.body.allowed).toBeDefined();
expect(response.body.confidence).toBeGreaterThan(0);
expect(response.body.latency).toBeLessThan(100); // Should be fast
expect(response.body.metadata.pathTaken).toBe('fast');
});
it('should detect and block suspicious request (deep path)', async () => {
const testRequest = {
action: {
type: 'admin',
resource: '/api/admin/delete-all',
method: 'DELETE',
payload: { force: true }
},
source: {
ip: '10.0.0.1',
userAgent: 'suspicious-bot'
}
};
const response = await request(app)
.post('/api/v1/defend')
.send(testRequest)
.expect(200); // Still returns 200, but with allowed: false
expect(response.body.latency).toBeLessThan(1000); // Within performance target
});
it('should validate request schema', async () => {
const invalidRequest = {
// Missing required fields
action: {
type: 'read'
// Missing resource and method
}
};
await request(app)
.post('/api/v1/defend')
.send(invalidRequest)
.expect(400);
});
it('should handle batch requests', async () => {
const batchRequest = {
requests: [
{
id: 'req1',
timestamp: Date.now(),
action: { type: 'read', resource: '/api/data', method: 'GET' },
source: { ip: '192.168.1.1' }
},
{
id: 'req2',
timestamp: Date.now(),
action: { type: 'write', resource: '/api/data', method: 'POST' },
source: { ip: '192.168.1.2' }
}
]
};
const response = await request(app)
.post('/api/v1/defend/batch')
.send(batchRequest)
.expect(200);
expect(response.body.results).toHaveLength(2);
expect(response.body.results[0].allowed).toBeDefined();
expect(response.body.results[1].allowed).toBeDefined();
});
it('should reject oversized batch requests', async () => {
const largeBatch = {
requests: Array(101).fill({
action: { type: 'read', resource: '/api/data', method: 'GET' },
source: { ip: '192.168.1.1' }
})
};
await request(app)
.post('/api/v1/defend/batch')
.send(largeBatch)
.expect(400);
});
});
describe('Performance', () => {
it('should meet latency targets for fast path (<35ms avg)', async () => {
const latencies: number[] = [];
// Run 100 requests
for (let i = 0; i < 100; i++) {
const response = await request(app)
.post('/api/v1/defend')
.send({
action: { type: 'read', resource: '/api/data', method: 'GET' },
source: { ip: '192.168.1.1' }
});
latencies.push(response.body.latency);
}
const avgLatency = latencies.reduce((a, b) => a + b, 0) / latencies.length;
expect(avgLatency).toBeLessThan(35); // Target: <35ms
});
it('should handle concurrent requests', async () => {
const promises = Array(50).fill(null).map(() =>
request(app)
.post('/api/v1/defend')
.send({
action: { type: 'read', resource: '/api/data', method: 'GET' },
source: { ip: '192.168.1.1' }
})
);
const responses = await Promise.all(promises);
const allSuccessful = responses.every(r => r.status === 200);
expect(allSuccessful).toBe(true);
});
});
describe('Stats Endpoint', () => {
it('should return statistics', async () => {
const response = await request(app)
.get('/api/v1/stats')
.expect(200);
expect(response.body.timestamp).toBeDefined();
expect(response.body.requests).toBeDefined();
expect(response.body.latency).toBeDefined();
expect(response.body.threats).toBeDefined();
});
});
describe('Error Handling', () => {
it('should handle 404 errors', async () => {
await request(app)
.get('/nonexistent')
.expect(404);
});
it('should handle malformed JSON', async () => {
await request(app)
.post('/api/v1/defend')
.set('Content-Type', 'application/json')
.send('invalid json{')
.expect(400);
});
});
});