/**
* @fileoverview Basic container smoke tests for VyOS MCP
*
* Lightweight container tests that can run quickly in CI environments.
* These tests focus on basic connectivity and core functionality.
*
* @author VyOS MCP Server Tests
* @version 1.0.0
* @since 2025-07-12
*/
import { describe, expect, it, beforeAll, afterAll } from 'bun:test';
import { GenericContainer, StartedTestContainer, Wait } from 'testcontainers';
import { VyOSClient } from '../src/vyos-client';
describe('VyOS MCP Basic Container Tests', () => {
let vyosContainer: StartedTestContainer;
let vyosClient: VyOSClient;
const API_KEY = 'basic-test-key';
const TIMEOUT = 180000; // 3 minutes for lighter tests
beforeAll(async () => {
console.log('Starting lightweight VyOS container for basic tests...');
vyosContainer = await new GenericContainer('docker.io/vyos/vyos-build:current')
.withPrivilegedMode()
.withExposedPorts(443, 22)
.withEnvironment({
VYOS_API_KEY: API_KEY,
})
.withWaitStrategy(Wait.forListeningPorts())
.withStartupTimeout(TIMEOUT)
.withCommand(['/sbin/init'])
.start();
console.log('VyOS container started, configuring API...');
// Wait for VyOS to initialize
await new Promise(resolve => setTimeout(resolve, 30000));
// Configure VyOS API
const configCommands = [
'/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper begin',
'/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper set system host-name vyos-basic-test',
`/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper set service https api keys id vyos-mcp key '${API_KEY}'`,
'/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper set service https port 443',
'/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper commit',
'/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper save',
'/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper end',
];
for (const cmd of configCommands) {
try {
await vyosContainer.exec(cmd.split(' '));
} catch (error) {
console.warn(`Command failed: ${cmd}`, error);
}
}
// Wait for API to be ready
await new Promise(resolve => setTimeout(resolve, 10000));
// Create VyOS client
const host = vyosContainer.getHost();
const port = vyosContainer.getMappedPort(443);
vyosClient = new VyOSClient({
host: `https://${host}:${port}`,
apiKey: API_KEY,
timeout: 30000,
verifySSL: false,
});
console.log('VyOS container ready for basic tests');
}, TIMEOUT);
afterAll(async () => {
if (vyosContainer) {
await vyosContainer.stop();
}
});
describe('Basic Connectivity', () => {
it('should connect to VyOS container', async () => {
expect(vyosContainer).toBeDefined();
expect(vyosClient).toBeDefined();
});
it('should retrieve system information', async () => {
// Wait for API to be ready with retries
let lastError;
for (let i = 0; i < 10; i++) {
try {
const systemInfo = await vyosClient.getSystemInfo();
expect(systemInfo).toBeDefined();
return; // Success
} catch (error) {
lastError = error;
console.log(`API not ready, attempt ${i + 1}/10`);
await new Promise(resolve => setTimeout(resolve, 3000));
}
}
throw lastError;
}, 60000);
it('should show configuration', async () => {
const config = await vyosClient.showConfig(['system']);
expect(config).toBeDefined();
expect(typeof config).toBe('object');
});
it('should get version information', async () => {
const version = await vyosClient.getVersion();
expect(version).toBeDefined();
});
});
describe('Basic Operations', () => {
it('should set and commit a simple configuration', async () => {
await vyosClient.setConfig(['system', 'domain-name'], 'basic-test.local');
await vyosClient.commit('Basic test configuration');
const config = await vyosClient.showConfig(['system', 'domain-name']);
expect(config).toBeDefined();
});
it('should ping localhost', async () => {
const result = await vyosClient.ping('127.0.0.1', { count: 1, timeout: 5 });
expect(result).toBeDefined();
});
it('should show operational data', async () => {
const result = await vyosClient.showOperational(['version']);
expect(result).toBeDefined();
});
});
describe('Error Handling', () => {
it('should handle invalid configuration gracefully', async () => {
await expect(
vyosClient.showConfig(['nonexistent', 'path'])
).rejects.toThrow();
});
it('should handle invalid operational commands gracefully', async () => {
await expect(
vyosClient.showOperational(['invalid', 'command'])
).rejects.toThrow();
});
});
});
// Set timeout for the entire test suite
process.env.BUN_TEST_TIMEOUT = String(TIMEOUT);