initial commit

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-06-14 00:46:35 +02:00
commit 7765367300
Se han modificado 12 ficheros con 2785 adiciones y 0 borrados

339
test/test-network.js Archivo normal
Ver fichero

@@ -0,0 +1,339 @@
#!/usr/bin/env node
import { RingNode } from '../src/ring-node.js';
import { OracleNode } from '../src/oracle-node.js';
import chalk from 'chalk';
console.log(chalk.blue.bold('🧪 Ring Network Test Suite\n'));
class NetworkTester {
constructor() {
this.nodes = [];
this.testResults = [];
}
async delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
log(message, type = 'info') {
const colors = {
info: chalk.blue,
success: chalk.green,
error: chalk.red,
warning: chalk.yellow
};
console.log(`${colors[type]}${message}`);
}
async runTest(name, testFn) {
this.log(`\n🔬 Running test: ${name}`, 'info');
try {
const startTime = Date.now();
await testFn();
const duration = Date.now() - startTime;
this.log(`✅ Test passed: ${name} (${duration}ms)`, 'success');
this.testResults.push({ name, status: 'passed', duration });
} catch (error) {
this.log(`❌ Test failed: ${name} - ${error.message}`, 'error');
this.testResults.push({ name, status: 'failed', error: error.message });
}
}
async setupBasicNetwork() {
this.log('🏗️ Setting up basic network with 1 Oracle and 2 regular nodes', 'info');
// Create Oracle node
const oracle = new OracleNode({
id: 'oracle-1',
port: 8080
});
this.nodes.push(oracle);
// Create regular nodes
const node1 = new RingNode({
id: 'node-1',
port: 8081
});
this.nodes.push(node1);
const node2 = new RingNode({
id: 'node-2',
port: 8082
});
this.nodes.push(node2);
// Allow nodes to initialize
await this.delay(2000);
return { oracle, node1, node2 };
}
async testNodeInitialization() {
const { oracle, node1, node2 } = await this.setupBasicNetwork();
// Verify nodes are properly initialized
if (!oracle.id || !oracle.isOracle) {
throw new Error('Oracle node not properly initialized');
}
if (!node1.id || node1.isOracle) {
throw new Error('Regular node 1 not properly initialized');
}
if (!node2.id || node2.isOracle) {
throw new Error('Regular node 2 not properly initialized');
}
this.log(`Oracle ID: ${oracle.id}`, 'info');
this.log(`Node 1 ID: ${node1.id}`, 'info');
this.log(`Node 2 ID: ${node2.id}`, 'info');
}
async testPeerConnections() {
const { oracle, node1, node2 } = this.nodes.length > 0 ?
{ oracle: this.nodes[0], node1: this.nodes[1], node2: this.nodes[2] } :
await this.setupBasicNetwork();
// Simulate peer connections
// In a real test, we would actually establish WebRTC connections
// For this test, we'll simulate the connection state
oracle.knownNodes.set(node1.id, { port: node1.port });
oracle.knownNodes.set(node2.id, { port: node2.port });
node1.knownNodes.set(oracle.id, { port: oracle.port, isOracle: true });
node1.knownNodes.set(node2.id, { port: node2.port });
node2.knownNodes.set(oracle.id, { port: oracle.port, isOracle: true });
node2.knownNodes.set(node1.id, { port: node1.port });
// Update oracle nodes list
node1.oracleNodes.add(oracle.id);
node2.oracleNodes.add(oracle.id);
this.log(`Oracle knows ${oracle.knownNodes.size} nodes`, 'info');
this.log(`Node 1 knows ${node1.knownNodes.size} nodes`, 'info');
this.log(`Node 2 knows ${node2.knownNodes.size} nodes`, 'info');
}
async testRingTopology() {
const { oracle, node1, node2 } = this.nodes.length > 0 ?
{ oracle: this.nodes[0], node1: this.nodes[1], node2: this.nodes[2] } :
await this.setupBasicNetwork();
// Simulate ring topology setup
// Oracle -> Node1 -> Node2 -> Oracle (inner ring)
oracle.rings.inner.right = node1.id;
oracle.rings.inner.left = node2.id;
node1.rings.inner.left = oracle.id;
node1.rings.inner.right = node2.id;
node2.rings.inner.left = node1.id;
node2.rings.inner.right = oracle.id;
// Oracle -> Node2 -> Node1 -> Oracle (outer ring - reversed)
oracle.rings.outer.right = node2.id;
oracle.rings.outer.left = node1.id;
node1.rings.outer.left = node2.id;
node1.rings.outer.right = oracle.id;
node2.rings.outer.left = oracle.id;
node2.rings.outer.right = node1.id;
// Verify ring integrity
const oracleHasValidRings = oracle.rings.inner.left && oracle.rings.inner.right &&
oracle.rings.outer.left && oracle.rings.outer.right;
if (!oracleHasValidRings) {
throw new Error('Oracle rings not properly configured');
}
this.log('Ring topology established successfully', 'success');
}
async testOracleServices() {
const oracle = this.nodes[0];
if (!oracle.isOracle) {
throw new Error('First node is not an Oracle');
}
// Test network analysis
const analysis = oracle.analyzeNetwork();
if (!analysis.networkSize || !analysis.ringTopology) {
throw new Error('Network analysis failed');
}
this.log(`Network analysis: ${analysis.networkSize} nodes`, 'info');
// Test data storage
const storeResult = oracle.handleDataStorage({
operation: 'set',
key: 'test-key',
value: 'test-value'
});
if (!storeResult.success) {
throw new Error('Data storage (set) failed');
}
const getResult = oracle.handleDataStorage({
operation: 'get',
key: 'test-key'
});
if (!getResult.success || getResult.value !== 'test-value') {
throw new Error('Data storage (get) failed');
}
this.log('Oracle data storage working correctly', 'success');
// Test consensus
const proposalId = 'test-proposal-' + Date.now();
const consensusResult = oracle.handleConsensus({
proposalId,
proposal: 'Test proposal for network upgrade'
});
if (!consensusResult.success) {
throw new Error('Consensus proposal creation failed');
}
this.log('Oracle consensus mechanism working', 'success');
// Test health check
const health = oracle.performHealthCheck();
if (!health.checks) {
throw new Error('Health check failed');
}
this.log(`Health check: ${health.healthy ? 'Healthy' : 'Issues detected'}`,
health.healthy ? 'success' : 'warning');
}
async testMessageRouting() {
// This test simulates message routing through the ring
// In a real implementation, this would test actual WebRTC communication
const oracle = this.nodes[0];
let messageReceived = false;
// Set up message handler
oracle.on('ringMessage', ({ from, payload }) => {
if (payload.type === 'test-message') {
messageReceived = true;
}
});
// Simulate sending a message
oracle.emit('ringMessage', {
from: 'test-sender',
payload: { type: 'test-message', content: 'Hello Ring!' }
});
await this.delay(100);
if (!messageReceived) {
throw new Error('Message routing failed');
}
this.log('Message routing test passed', 'success');
}
async testNetworkResilience() {
const { oracle, node1, node2 } = this.nodes.length > 0 ?
{ oracle: this.nodes[0], node1: this.nodes[1], node2: this.nodes[2] } :
await this.setupBasicNetwork();
// Simulate node disconnection
const originalPeerCount = oracle.knownNodes.size;
// Remove node2 from network
oracle.handlePeerDisconnection(node2.id);
node1.handlePeerDisconnection(node2.id);
if (oracle.knownNodes.has(node2.id)) {
throw new Error('Node not properly removed from network');
}
// Verify network adapted to disconnection
const newPeerCount = oracle.knownNodes.size;
if (newPeerCount >= originalPeerCount) {
throw new Error('Network did not adapt to peer disconnection');
}
this.log(`Network adapted to disconnection: ${originalPeerCount} -> ${newPeerCount} nodes`, 'success');
}
async cleanup() {
this.log('\n🧹 Cleaning up test environment', 'info');
for (const node of this.nodes) {
try {
await node.destroy();
} catch (error) {
this.log(`Warning: Error cleaning up node ${node.id}: ${error.message}`, 'warning');
}
}
this.nodes = [];
}
printResults() {
this.log('\n📊 Test Results Summary:', 'info');
const passed = this.testResults.filter(r => r.status === 'passed').length;
const failed = this.testResults.filter(r => r.status === 'failed').length;
this.log(`✅ Passed: ${passed}`, 'success');
this.log(`❌ Failed: ${failed}`, failed > 0 ? 'error' : 'info');
if (failed > 0) {
this.log('\nFailed tests:', 'error');
this.testResults
.filter(r => r.status === 'failed')
.forEach(r => {
this.log(` - ${r.name}: ${r.error}`, 'error');
});
}
const totalDuration = this.testResults.reduce((sum, r) => sum + (r.duration || 0), 0);
this.log(`\nTotal test duration: ${totalDuration}ms`, 'info');
return failed === 0;
}
async runAllTests() {
try {
await this.runTest('Node Initialization', () => this.testNodeInitialization());
await this.runTest('Peer Connections', () => this.testPeerConnections());
await this.runTest('Ring Topology', () => this.testRingTopology());
await this.runTest('Oracle Services', () => this.testOracleServices());
await this.runTest('Message Routing', () => this.testMessageRouting());
await this.runTest('Network Resilience', () => this.testNetworkResilience());
} finally {
await this.cleanup();
}
return this.printResults();
}
}
// Run tests if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
const tester = new NetworkTester();
tester.runAllTests()
.then(success => {
console.log(chalk.blue.bold('\n🏁 Test suite completed'));
process.exit(success ? 0 : 1);
})
.catch(error => {
console.error(chalk.red.bold(`\n💥 Test suite crashed: ${error.message}`));
process.exit(1);
});
}
export { NetworkTester };