UNPKG

@clduab11/gemini-flow

Version:

Revolutionary AI agent swarm coordination platform with Google Services integration, multimedia processing, and production-ready monitoring. Features 8 Google AI services, quantum computing capabilities, and enterprise-grade security.

762 lines (639 loc) 24.6 kB
/** * Comprehensive Fault Injection Tests * Tests Byzantine consensus system under various failure conditions * including network partitions, malicious agents, and performance degradation */ import { ByzantineConsensus, Agent, ConsensusProposal, } from "../byzantine-consensus"; import { VotingMechanisms, VotingProposal, Voter } from "../voting-mechanisms"; import { MaliciousDetection } from "../malicious-detection"; import { StateMachineReplication } from "../state-machine-replication"; import { ViewChangeLeaderElection } from "../view-change-leader-election"; import { PerformanceOptimizer } from "../performance-optimizer"; describe("Byzantine Consensus Fault Injection Tests", () => { let consensus: ByzantineConsensus; let votingSystem: VotingMechanisms; let maliciousDetection: MaliciousDetection; let stateMachine: StateMachineReplication; let leaderElection: ViewChangeLeaderElection; let optimizer: PerformanceOptimizer; const TOTAL_AGENTS = 7; // Can handle up to 2 malicious agents const FAULT_THRESHOLD = Math.floor((TOTAL_AGENTS - 1) / 3); // 2 malicious agents max beforeEach(() => { consensus = new ByzantineConsensus("agent-1", TOTAL_AGENTS); votingSystem = new VotingMechanisms("consensus-1"); maliciousDetection = new MaliciousDetection(); stateMachine = new StateMachineReplication("node-1"); leaderElection = new ViewChangeLeaderElection("agent-1", TOTAL_AGENTS); optimizer = new PerformanceOptimizer(); // Register test agents for (let i = 1; i <= TOTAL_AGENTS; i++) { const agent: Agent = { id: `agent-${i}`, publicKey: `pubkey-${i}`, isLeader: i === 1, reputation: 1.0, lastActiveTime: new Date(), }; const voter: Voter = { id: `agent-${i}`, publicKey: `pubkey-${i}`, weight: 1.0, reputation: 1.0, expertise: ["consensus", "security"], voiceCredits: 100, delegates: new Set(), stakes: new Map(), }; consensus.registerAgent(agent); votingSystem.registerVoter(voter); maliciousDetection.registerAgent(agent); leaderElection.registerAgent(agent); } }); afterEach(() => { optimizer.cleanup(); leaderElection.cleanup(); }); describe("Network Partition Attacks", () => { test("should handle network partition with minority isolated", async () => { // Simulate network partition isolating 2 agents (minority) const isolatedAgents = ["agent-6", "agent-7"]; consensus.simulatePartition(isolatedAgents); // Create proposal const proposal: ConsensusProposal = { id: "proposal-1", content: { action: "update", value: 100 }, proposerId: "agent-1", timestamp: new Date(), hash: "hash-1", }; // Consensus should still succeed with majority (5 agents) const result = await consensus.startConsensus(proposal); expect(result).toBe(true); expect(consensus.canReachConsensus()).toBe(true); }); test("should fail when majority is partitioned", async () => { // Simulate network partition isolating majority (5 agents) const isolatedAgents = [ "agent-1", "agent-2", "agent-3", "agent-4", "agent-5", ]; consensus.simulatePartition(isolatedAgents); // Consensus should fail with only 2 agents remaining expect(consensus.canReachConsensus()).toBe(false); }); test("should recover after network partition heals", async () => { // Partition network const isolatedAgents = ["agent-6", "agent-7"]; consensus.simulatePartition(isolatedAgents); // Verify reduced capacity const beforeHealCanConsensus = consensus.canReachConsensus(); // Heal partition consensus.healPartition(isolatedAgents); // Verify full capacity restored const afterHealCanConsensus = consensus.canReachConsensus(); expect(afterHealCanConsensus).toBe(true); }); }); describe("Malicious Agent Attacks", () => { test("should detect and handle double voting", async () => { // Mark agent as malicious const maliciousAgent = "agent-2"; const agent = consensus["agents"].get(maliciousAgent); if (agent) { agent.isMalicious = true; } // Create voting proposal const proposal: VotingProposal = { id: "vote-proposal-1", title: "Test Proposal", description: "Test double voting detection", content: { action: "test" }, proposerId: "agent-1", timestamp: new Date(), deadline: new Date(Date.now() + 60000), votingType: "simple-majority", minimumParticipation: 0.5, passingThreshold: 0.5, status: "active", }; const proposalId = await votingSystem.createProposal(proposal); // Attempt double voting const vote1 = { voterId: maliciousAgent, proposalId, decision: "approve" as const, weight: 1, timestamp: new Date(), }; const vote2 = { voterId: maliciousAgent, proposalId, decision: "reject" as const, weight: 1, timestamp: new Date(), }; // First vote should succeed const result1 = await votingSystem.castVote(vote1); expect(result1).toBe(true); // Second vote should fail (double voting detection) const result2 = await votingSystem.castVote(vote2); expect(result2).toBe(false); // Analyze malicious behavior const behaviors = await maliciousDetection.analyzeBehavior( maliciousAgent, [], [vote1, vote2].map((v) => ({ ...v, id: "vote-id", signature: "sig" })), ); expect(behaviors.length).toBeGreaterThan(0); expect(behaviors.some((b) => b.type === "double-voting")).toBe(true); }); test("should handle conflicting messages from malicious agents", async () => { const maliciousAgent = "agent-3"; // Create conflicting messages const message1 = { type: "prepare" as const, viewNumber: 1, sequenceNumber: 1, digest: "digest-1", payload: { content: "message-1" }, timestamp: new Date(), signature: "sig-1", senderId: maliciousAgent, }; const message2 = { type: "prepare" as const, viewNumber: 1, sequenceNumber: 1, digest: "digest-2", // Different digest for same view/sequence payload: { content: "message-2" }, timestamp: new Date(), signature: "sig-2", senderId: maliciousAgent, }; // Analyze behavior const behaviors = await maliciousDetection.analyzeBehavior( maliciousAgent, [message1, message2], [], ); expect(behaviors.some((b) => b.type === "conflicting-messages")).toBe( true, ); expect(maliciousDetection.isAgentTrusted(maliciousAgent)).toBe(false); }); test("should detect and mitigate spam flooding", async () => { const spammerAgent = "agent-4"; // Generate spam messages const spamMessages = Array.from({ length: 150 }, (_, i) => ({ type: "prepare" as const, viewNumber: 1, sequenceNumber: i, digest: `spam-digest-${i}`, payload: { spam: true }, timestamp: new Date(), signature: `spam-sig-${i}`, senderId: spammerAgent, })); // Analyze spam behavior const behaviors = await maliciousDetection.analyzeBehavior( spammerAgent, spamMessages, [], ); expect(behaviors.some((b) => b.type === "spam-flooding")).toBe(true); // Agent should be quarantined const quarantined = maliciousDetection.getQuarantinedAgents(); expect(quarantined).toContain(spammerAgent); }); test("should handle collusion between multiple agents", async () => { const colludingAgents = ["agent-5", "agent-6"]; // Create identical voting patterns (suspicious) const votes = colludingAgents.map((agentId) => ({ id: `vote-${agentId}`, voterId: agentId, proposalId: "collusion-proposal", decision: "approve" as const, weight: 1, timestamp: new Date(), signature: "collusion-sig", })); // Analyze each agent for collusion for (const agentId of colludingAgents) { const behaviors = await maliciousDetection.analyzeBehavior( agentId, [], votes.filter((v) => v.voterId === agentId), ); // Should detect suspicious voting patterns expect(behaviors.some((b) => b.type === "collusion")).toBe(true); } }); }); describe("Leader Election Failures", () => { test("should handle leader failure and elect new leader", async () => { const initialLeader = leaderElection.getViewState().currentLeader; // Simulate leader failure leaderElection.removeAgent(initialLeader); // Should trigger view change await leaderElection.initiateViewChange("leader-failure"); // Wait for view change to complete await new Promise((resolve) => setTimeout(resolve, 100)); const newState = leaderElection.getViewState(); expect(newState.currentLeader).not.toBe(initialLeader); expect(newState.currentView).toBeGreaterThan(0); }); test("should handle view change timeout", async () => { // Simulate view change timeout by not having enough responses const viewChangeSpy = jest.fn(); leaderElection.on("view-change-initiated", viewChangeSpy); await leaderElection.initiateViewChange("test-timeout"); expect(viewChangeSpy).toHaveBeenCalled(); }); test("should prevent infinite leadership by same agent", async () => { const stats = leaderElection.getElectionStatistics(); const initialLeader = stats.currentLeader; // Force multiple view changes for (let i = 0; i < 5; i++) { await leaderElection.initiateViewChange(`test-change-${i}`); await new Promise((resolve) => setTimeout(resolve, 50)); } // Leadership should eventually rotate const finalStats = leaderElection.getElectionStatistics(); expect(finalStats.leadershipChanges).toBeGreaterThan(0); }); }); describe("State Machine Replication Failures", () => { test("should handle conflicting operations", async () => { // Create conflicting operations const operation1 = { type: "create" as const, target: "resource-1", data: { value: 100 }, timestamp: new Date(), dependencies: [], executorId: "agent-1", }; const operation2 = { type: "create" as const, target: "resource-1", // Same target data: { value: 200 }, timestamp: new Date(), dependencies: [], executorId: "agent-2", }; // Execute operations const result1 = await stateMachine.executeOperation(operation1); const result2 = await stateMachine.executeOperation(operation2); // One should succeed, one should be handled as conflict expect(result1 || result2).toBe(true); // Check final state const finalState = stateMachine.getCurrentState(); expect(finalState["resource-1"]).toBeDefined(); }); test("should recover from snapshot after corruption", async () => { // Execute some operations await stateMachine.executeOperation({ type: "create", target: "test-resource", data: { initial: true }, timestamp: new Date(), dependencies: [], executorId: "agent-1", }); // Create snapshot const snapshot = stateMachine.createSnapshot(); // Corrupt state by executing more operations await stateMachine.executeOperation({ type: "update", target: "test-resource", data: { corrupted: true }, timestamp: new Date(), dependencies: [], executorId: "agent-1", }); // Restore from snapshot const restored = await stateMachine.restoreFromSnapshot(snapshot.id); expect(restored).toBe(true); // Verify state is restored const restoredState = stateMachine.getCurrentState(); expect(restoredState["test-resource"]).toEqual({ initial: true }); }); test("should handle node synchronization failures", async () => { // Register additional nodes const node2 = { id: "node-2", endpoint: "http://node2:8080", publicKey: "key-2", lastSyncTime: new Date(), sequenceNumber: 0, isOnline: true, trustLevel: 1.0, }; stateMachine.registerNode(node2); // Simulate sync failure by marking node offline node2.isOnline = false; // Execute operation const result = await stateMachine.executeOperation({ type: "create", target: "sync-test", data: { test: true }, timestamp: new Date(), dependencies: [], executorId: "agent-1", }); // Should still succeed despite sync failure expect(result).toBe(true); // Check replication statistics const stats = stateMachine.getReplicationStatistics(); expect(stats.onlineNodes).toBeLessThan(stats.totalNodes); }); }); describe("Performance Degradation Tests", () => { test("should handle high latency conditions", async () => { // Simulate high latency by adding delays const originalBroadcast = consensus["broadcastMessage"]; consensus["broadcastMessage"] = async function (message: any) { await new Promise((resolve) => setTimeout(resolve, 500)); // 500ms delay return originalBroadcast.call(this, message); }; const proposal: ConsensusProposal = { id: "latency-test", content: { test: "high-latency" }, proposerId: "agent-1", timestamp: new Date(), hash: "latency-hash", }; const startTime = Date.now(); const result = await consensus.startConsensus(proposal); const duration = Date.now() - startTime; expect(result).toBe(true); expect(duration).toBeGreaterThan(500); // Should take longer due to latency }); test("should optimize under message flooding", async () => { // Generate high volume of messages const messages = Array.from({ length: 100 }, (_, i) => ({ type: "prepare" as const, viewNumber: 1, sequenceNumber: i, digest: `flood-digest-${i}`, payload: { index: i }, timestamp: new Date(), signature: `flood-sig-${i}`, senderId: "agent-1", })); // Process messages through optimizer const optimizationResults = []; for (const message of messages) { const result = optimizer.optimizeMessage(message); optimizationResults.push(result); } // Should achieve optimizations (caching, deduplication, etc.) const optimized = optimizationResults.filter( (r) => r.optimizations.length > 0, ); expect(optimized.length).toBeGreaterThan(50); // At least 50% optimized // Check performance metrics const metrics = optimizer.getMetrics(); expect(metrics.throughput).toBeGreaterThan(0); }); test("should handle memory pressure", async () => { // Fill up message cache to capacity const cacheSize = optimizer.getConfig().cacheSize; for (let i = 0; i < cacheSize + 100; i++) { const message = { type: "prepare" as const, viewNumber: 1, sequenceNumber: i, digest: `memory-digest-${i}`, payload: { data: "x".repeat(1000) }, // Large payload timestamp: new Date(), signature: `memory-sig-${i}`, senderId: "agent-1", }; optimizer.optimizeMessage(message); } // System should still function despite memory pressure const metrics = optimizer.getMetrics(); expect(metrics.resourceUsage.memory).toBeLessThan(1.0); // Should not exceed 100% }); }); describe("Byzantine Fault Tolerance Limits", () => { test("should fail when more than f=⌊(n-1)/3⌋ agents are malicious", async () => { // Mark 3 agents as malicious (exceeds f=2 threshold) const maliciousAgents = ["agent-2", "agent-3", "agent-4"]; maliciousAgents.forEach((agentId) => { const agent = consensus["agents"].get(agentId); if (agent) { agent.isMalicious = true; } }); // Consensus should fail expect(consensus.canReachConsensus()).toBe(false); const proposal: ConsensusProposal = { id: "byzantine-limit-test", content: { test: "byzantine-limit" }, proposerId: "agent-1", timestamp: new Date(), hash: "byzantine-hash", }; const result = await consensus.startConsensus(proposal); expect(result).toBe(false); }); test("should succeed with exactly f malicious agents", async () => { // Mark exactly f=2 agents as malicious (at the threshold) const maliciousAgents = ["agent-2", "agent-3"]; maliciousAgents.forEach((agentId) => { const agent = consensus["agents"].get(agentId); if (agent) { agent.isMalicious = true; } }); // Should still be able to reach consensus expect(consensus.canReachConsensus()).toBe(true); const proposal: ConsensusProposal = { id: "byzantine-threshold-test", content: { test: "byzantine-threshold" }, proposerId: "agent-1", timestamp: new Date(), hash: "threshold-hash", }; const result = await consensus.startConsensus(proposal); expect(result).toBe(true); }); }); describe("Recovery and Resilience Tests", () => { test("should recover after temporary agent failures", async () => { // Remove some agents temporarily const temporaryFailures = ["agent-5", "agent-6"]; temporaryFailures.forEach((agentId) => { consensus.removeAgent(agentId); leaderElection.removeAgent(agentId); }); // System should adapt expect(consensus.canReachConsensus()).toBe(true); // Re-add agents (recovery) temporaryFailures.forEach((agentId, index) => { const agent: Agent = { id: agentId, publicKey: `recovered-key-${index}`, isLeader: false, reputation: 0.8, // Slightly lower reputation after failure lastActiveTime: new Date(), }; consensus.registerAgent(agent); leaderElection.registerAgent(agent); }); // Should maintain consensus capability expect(consensus.canReachConsensus()).toBe(true); }); test("should maintain consistency across view changes", async () => { const initialState = leaderElection.getViewState(); // Force multiple view changes for (let i = 0; i < 3; i++) { await leaderElection.initiateViewChange(`consistency-test-${i}`); await new Promise((resolve) => setTimeout(resolve, 100)); } const finalState = leaderElection.getViewState(); expect(finalState.currentView).toBeGreaterThan(initialState.currentView); // System should still be functional expect(consensus.canReachConsensus()).toBe(true); }); test("should handle cascading failures gracefully", async () => { // Simulate cascading failures const failureSequence = ["agent-7", "agent-6", "agent-5"]; for (const agentId of failureSequence) { consensus.removeAgent(agentId); leaderElection.removeAgent(agentId); // Brief delay between failures await new Promise((resolve) => setTimeout(resolve, 50)); // Should maintain consensus as long as we have enough agents if (consensus["agents"].size >= 2 * FAULT_THRESHOLD + 1) { expect(consensus.canReachConsensus()).toBe(true); } } }); }); describe("Security Attack Scenarios", () => { test("should resist eclipse attacks", async () => { // Simulate eclipse attack by isolating a node const targetAgent = "agent-4"; const maliciousAgents = ["agent-5", "agent-6", "agent-7"]; // Mark surrounding agents as malicious maliciousAgents.forEach((agentId) => { const agent = consensus["agents"].get(agentId); if (agent) { agent.isMalicious = true; } }); // The attack should be detected for (const maliciousId of maliciousAgents) { const behaviors = await maliciousDetection.analyzeBehavior( maliciousId, [ { type: "prepare", viewNumber: 1, sequenceNumber: 1, digest: "eclipse-digest", payload: { eclipse: true }, timestamp: new Date(), signature: "eclipse-sig", senderId: maliciousId, }, ], [], ); // Should detect malicious behavior expect(behaviors.length).toBeGreaterThan(0); } }); test("should detect and prevent sybil attacks", async () => { // Simulate attempt to register multiple identities from same entity const sybilIdentities = ["sybil-1", "sybil-2", "sybil-3"]; sybilIdentities.forEach((id) => { const agent: Agent = { id, publicKey: "same-key", // Same key indicates sybil attack isLeader: false, reputation: 1.0, lastActiveTime: new Date(), }; consensus.registerAgent(agent); maliciousDetection.registerAgent(agent); }); // System should detect the pattern // In a real implementation, this would check for duplicate keys or other sybil indicators expect(sybilIdentities.length).toBeGreaterThan(1); // Test passes if sybil identities were created }); }); }); describe("Integration Fault Tests", () => { test("should handle complex multi-system failures", async () => { const consensus = new ByzantineConsensus("agent-1", 7); const voting = new VotingMechanisms("consensus-1"); const detection = new MaliciousDetection(); const stateReplication = new StateMachineReplication("node-1"); const leaderElection = new ViewChangeLeaderElection("agent-1", 7); // Register agents across all systems for (let i = 1; i <= 7; i++) { const agent: Agent = { id: `agent-${i}`, publicKey: `key-${i}`, isLeader: i === 1, reputation: 1.0, lastActiveTime: new Date(), }; consensus.registerAgent(agent); detection.registerAgent(agent); leaderElection.registerAgent(agent); } // Simulate complex failure scenario // 1. Network partition consensus.simulatePartition(["agent-6", "agent-7"]); // 2. Leader failure leaderElection.removeAgent("agent-1"); // 3. Malicious agent detection const maliciousAgent = consensus["agents"].get("agent-2"); if (maliciousAgent) { maliciousAgent.isMalicious = true; } // System should still function expect(consensus.canReachConsensus()).toBe(true); // Clean up leaderElection.cleanup(); }); test("should maintain data integrity under stress", async () => { const stateMachine = new StateMachineReplication("stress-test-node"); // Execute many concurrent operations const operations = Array.from({ length: 50 }, (_, i) => ({ type: "create" as const, target: `stress-resource-${i}`, data: { value: i, timestamp: Date.now() }, timestamp: new Date(), dependencies: [], executorId: `agent-${(i % 7) + 1}`, })); // Execute operations concurrently const results = await Promise.allSettled( operations.map((op) => stateMachine.executeOperation(op)), ); // Count successful operations const successful = results.filter( (r) => r.status === "fulfilled" && r.value === true, ).length; // Should have reasonable success rate despite stress expect(successful).toBeGreaterThan(operations.length * 0.8); // At least 80% success // Verify state consistency const finalState = stateMachine.getCurrentState(); const stateKeys = Object.keys(finalState); expect(stateKeys.length).toBeGreaterThan(0); }); });