@joystick.js/db-canary
Version:
JoystickDB - A minimalist database server for the Joystick framework
351 lines (288 loc) • 12 kB
JavaScript
import test from 'ava';
import net from 'net';
import { create_server } from '../../../src/server/index.js';
import { encode_message, create_message_parser } from '../../../src/server/lib/tcp_protocol.js';
import { initialize_database } from '../../../src/server/lib/query_engine.js';
import { setup_initial_admin, reset_auth_state } from '../../../src/server/lib/user_auth_manager.js';
let server;
let port;
let admin_username = 'admin';
let admin_password = 'admin123';
test.before(async () => {
try {
// Reset auth state
await reset_auth_state();
// Initialize database for testing
initialize_database();
// Create server
server = await create_server();
// Start server on random port
await new Promise((resolve, reject) => {
server.listen(0, (error) => {
if (error) {
reject(error);
return;
}
port = server.address().port;
resolve();
});
});
// Set up initial admin user for all tests
await setup_initial_admin(admin_username, admin_password, 'admin@test.com');
} catch (error) {
throw error;
}
});
test.after.always(async () => {
if (server) {
await server.cleanup();
await new Promise((resolve) => {
server.close(resolve);
});
}
// Clean up auth state
await reset_auth_state();
});
const create_client = () => {
return new Promise((resolve, reject) => {
const client = net.createConnection(port, 'localhost');
const parser = create_message_parser();
let responses = [];
client.on('connect', () => {
resolve({
client,
send: (data) => {
const encoded = encode_message(data);
client.write(encoded);
},
receive: () => {
return new Promise((resolve) => {
const handler = (data) => {
try {
const messages = parser.parse_messages(data);
for (const message of messages) {
// Message is already decoded from MessagePack, no need to JSON.parse
responses.push(message);
client.off('data', handler);
resolve(message);
return;
}
} catch (error) {
// Continue listening
}
};
client.on('data', handler);
});
},
close: () => {
client.end();
}
});
});
client.on('error', reject);
});
};
test('production safety - ping operation returns ok: 1', async t => {
const { client, send, receive, close } = await create_client();
try {
send({ op: 'ping' });
const response = await receive();
t.is(response.ok, 1);
} finally {
close();
}
});
test('production safety - admin stats include comprehensive monitoring', async t => {
const { client, send, receive, close } = await create_client();
try {
// Authenticate using username and password
send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
const auth_response = await receive();
t.is(auth_response.ok, 1);
// Get admin stats
send({ op: 'admin', data: { admin_action: 'stats' } });
const stats_response = await receive();
t.is(stats_response.ok, 1);
// Check comprehensive stats structure
t.truthy(stats_response.server);
t.truthy(stats_response.memory);
t.truthy(stats_response.database);
t.truthy(stats_response.performance);
t.truthy(stats_response.system);
t.truthy(stats_response.connections);
t.truthy(stats_response.authentication);
// Check server stats
t.true(typeof stats_response.server.uptime === 'number');
t.true(typeof stats_response.server.uptime_formatted === 'string');
t.true(typeof stats_response.server.node_version === 'string');
t.true(typeof stats_response.server.platform === 'string');
t.true(typeof stats_response.server.arch === 'string');
t.true(typeof stats_response.server.pid === 'number');
// Check memory stats
t.true(typeof stats_response.memory.rss_mb === 'number');
t.true(typeof stats_response.memory.heap_total_mb === 'number');
t.true(typeof stats_response.memory.heap_used_mb === 'number');
t.true(typeof stats_response.memory.heap_used_percent === 'number');
t.true(typeof stats_response.memory.external_mb === 'number');
// Check database stats
t.true(typeof stats_response.database.map_size_mb === 'number');
t.true(typeof stats_response.database.used_space_mb === 'number');
t.true(typeof stats_response.database.usage_percent === 'number');
// Check performance stats
t.true(typeof stats_response.performance.ops_per_second === 'number');
t.true(typeof stats_response.performance.avg_response_time_ms === 'number');
// Check system stats
t.true(typeof stats_response.system.node_version === 'string');
t.true(typeof stats_response.system.platform === 'string');
t.true(typeof stats_response.system.arch === 'string');
t.true(typeof stats_response.system.pid === 'number');
// Check connection stats
t.true(typeof stats_response.connections.total_connections === 'number');
t.true(typeof stats_response.connections.max_connections === 'number');
// Check authentication stats
t.true(typeof stats_response.authentication.authenticated_clients === 'number');
} finally {
close();
}
});
test('production safety - request timeout handling', async t => {
const { client, send, receive, close } = await create_client();
try {
// Authenticate using username and password
send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
const auth_response = await receive();
t.is(auth_response.ok, 1);
// Send a normal operation that should complete quickly
send({ op: 'insert_one', data: { collection: 'test_timeout', document: { name: 'test' } } });
const response = await receive();
t.is(response.ok, 1);
t.truthy(response.inserted_id);
} finally {
close();
}
});
test('production safety - connection limits', async t => {
// This test verifies that connection management is working
// We can't easily test the actual limit without creating 1000+ connections
const { client, send, receive, close } = await create_client();
try {
send({ op: 'ping' });
const response = await receive();
t.is(response.ok, 1);
// Connection should be tracked
// We can verify this by checking that the connection was accepted
t.pass();
} finally {
close();
}
});
test('production safety - structured logging for operations', async t => {
const { client, send, receive, close } = await create_client();
try {
// Authenticate using username and password
send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
const auth_response = await receive();
t.is(auth_response.ok, 1);
// Perform database operation that should be logged
send({ op: 'insert_one', data: { collection: 'test_logging', document: { name: 'test_log' } } });
const response = await receive();
t.is(response.ok, 1);
t.truthy(response.inserted_id);
// The operation should have been logged with structured format
// We can't easily verify the log output in tests, but we can verify the operation succeeded
t.pass();
} finally {
close();
}
});
test('production safety - error handling and categorization', async t => {
const { client, send, receive, close } = await create_client();
try {
// Authenticate using username and password
send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
const auth_response = await receive();
t.is(auth_response.ok, 1);
// Try an operation that should fail
send({ op: 'insert_one', data: { collection: '', document: { name: 'test' } } });
const response = await receive();
t.is(response.ok, 0);
t.truthy(response.error);
t.true(response.error.includes('Collection name is required'));
} finally {
close();
}
});
test('production safety - performance metrics tracking', async t => {
const { client, send, receive, close } = await create_client();
try {
// Authenticate using username and password
send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
const auth_response = await receive();
t.is(auth_response.ok, 1);
// Perform several operations to generate metrics
for (let i = 0; i < 5; i++) {
send({ op: 'insert_one', data: { collection: 'test_metrics', document: { index: i } } });
await receive();
}
// Get stats to verify metrics are being tracked
send({ op: 'admin', data: { admin_action: 'stats' } });
const stats_response = await receive();
t.is(stats_response.ok, 1);
t.true(typeof stats_response.performance.ops_per_second === 'number');
t.true(typeof stats_response.performance.avg_response_time_ms === 'number');
} finally {
close();
}
});
test('production safety - memory and resource monitoring', async t => {
const { client, send, receive, close } = await create_client();
try {
// Authenticate using username and password
send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
const auth_response = await receive();
t.is(auth_response.ok, 1);
// Get stats to verify resource monitoring
send({ op: 'admin', data: { admin_action: 'stats' } });
const stats_response = await receive();
t.is(stats_response.ok, 1);
// Verify memory monitoring
t.true(stats_response.memory.rss_mb > 0);
t.true(stats_response.memory.heap_total_mb > 0);
t.true(stats_response.memory.heap_used_mb > 0);
t.true(stats_response.memory.heap_used_percent >= 0 && stats_response.memory.heap_used_percent <= 100);
// Verify database resource monitoring
t.true(stats_response.database.map_size_mb >= 0);
t.true(stats_response.database.used_space_mb >= 0);
t.true(stats_response.database.usage_percent >= 0 && stats_response.database.usage_percent <= 100);
// Verify system resource monitoring
t.true(stats_response.system.cpu_user_ms >= 0);
t.true(stats_response.system.cpu_system_ms >= 0);
} finally {
close();
}
});
test('production safety - connection management stats', async t => {
const { client, send, receive, close } = await create_client();
try {
// Authenticate using username and password
send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
const auth_response = await receive();
t.is(auth_response.ok, 1);
// Get stats to verify connection management
send({ op: 'admin', data: { admin_action: 'stats' } });
const stats_response = await receive();
t.is(stats_response.ok, 1);
// Verify connection stats
t.true(typeof stats_response.connections.total_connections === 'number');
t.true(typeof stats_response.connections.max_connections === 'number');
t.true(typeof stats_response.connections.total_requests === 'number');
t.true(typeof stats_response.connections.idle_timeout_ms === 'number');
t.true(typeof stats_response.connections.request_timeout_ms === 'number');
t.true(stats_response.connections.total_connections >= 1); // At least our connection
t.is(stats_response.connections.max_connections, 1000); // Default max
t.is(stats_response.connections.idle_timeout_ms, 10 * 60 * 1000); // 10 minutes
t.is(stats_response.connections.request_timeout_ms, 5 * 1000); // 5 seconds
} finally {
close();
}
});