UNPKG

claude-flow

Version:

Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)

193 lines (155 loc) 7.21 kB
const { TestHarness } = require('../test-harness'); const assert = require('assert'); describe('Batch Operations Unit Tests', () => { let harness; beforeEach(() => { harness = new TestHarness(); harness.createMockProject('standard'); }); afterEach(() => { harness.reset(); }); describe('Parallel File Operations', () => { it('should read multiple files in parallel', async () => { const files = ['src/index.js', 'src/utils.js', 'package.json']; const results = await harness.batchReadFiles(files); assert.strictEqual(results.successful.length, 3); assert.strictEqual(results.failed.length, 0); assert.strictEqual(results.successRate, 1); }); it('should handle partial failures gracefully', async () => { const files = ['src/index.js', 'non-existent.js', 'package.json']; const results = await harness.batchReadFiles(files); assert.strictEqual(results.successful.length, 2); assert.strictEqual(results.failed.length, 1); assert.strictEqual(results.successRate, 2/3); assert(results.failed[0].error.message.includes('ENOENT')); }); it('should write multiple files concurrently', async () => { const filesToWrite = { 'src/new1.js': 'console.log("File 1");', 'src/new2.js': 'console.log("File 2");', 'src/new3.js': 'console.log("File 3");' }; const results = await harness.batchWriteFiles(filesToWrite); assert.strictEqual(results.successful.length, 3); // Verify files were written for (const [path, content] of Object.entries(filesToWrite)) { const readContent = await harness.mockReadFile(path); assert.strictEqual(readContent, content); } }); it('should respect concurrency limits', async () => { harness.concurrencyLimit = 2; harness.mockDelay = 100; // Increase delay to measure concurrency const files = Array.from({ length: 6 }, (_, i) => `file${i}.js`); files.forEach(f => harness.mockFS.set(f, `content of ${f}`)); const startTime = Date.now(); await harness.batchReadFiles(files); const duration = Date.now() - startTime; // With concurrency limit of 2, 6 files should take ~300ms (3 batches) assert(duration >= 300 && duration < 400, `Expected duration ~300ms, got ${duration}ms`); }); }); describe('Concurrent Search Operations', () => { it('should search multiple patterns concurrently', async () => { const patterns = ['console', 'export', 'describe']; const results = await harness.batchSearch(patterns); assert.strictEqual(results.successful.length, 3); assert(results.successful[0].length > 0); // Should find console.log assert(results.successful[1].length > 0); // Should find export assert(results.successful[2].length > 0); // Should find describe }); it('should search with path filtering', async () => { const patterns = ['test']; const results = await harness.batchSearch(patterns, 'test/'); assert(results.successful[0].every(r => r.file.includes('test/'))); }); it('should handle complex regex patterns', async () => { const patterns = [ 'module\\d+', // Match module followed by digits 'export\\s+const', // Match export const with whitespace '\\{[^}]+\\}' // Match content within braces ]; harness.createMockProject('large'); const results = await harness.batchSearch(patterns); assert.strictEqual(results.successful.length, 3); assert(results.successful[0].length > 0); // Should find module patterns }); }); describe('Batch Task Execution', () => { it('should execute multiple tasks with proper error handling', async () => { const tasks = [ async () => 'Task 1 complete', async () => { throw new Error('Task 2 failed'); }, async () => 'Task 3 complete', async () => 'Task 4 complete' ]; const results = await harness.executeBatch(tasks, async (task) => await task()); assert.strictEqual(results.successful.length, 3); assert.strictEqual(results.failed.length, 1); assert.strictEqual(results.failed[0].error.message, 'Task 2 failed'); }); it('should maintain task order in results', async () => { const tasks = Array.from({ length: 10 }, (_, i) => async () => i); const results = await harness.executeBatch(tasks, async (task) => await task()); results.successful.forEach((result, index) => { assert.strictEqual(result, index); }); }); }); describe('Performance Characteristics', () => { it('should demonstrate parallel speedup', async () => { harness.createMockProject('large'); const files = Array.from({ length: 20 }, (_, i) => `src/module${i}.js`); // Sequential simulation harness.concurrencyLimit = 1; const sequentialStart = Date.now(); await harness.batchReadFiles(files); const sequentialTime = Date.now() - sequentialStart; // Parallel execution harness.concurrencyLimit = 5; const parallelStart = Date.now(); await harness.batchReadFiles(files); const parallelTime = Date.now() - parallelStart; // Parallel should be significantly faster const speedup = sequentialTime / parallelTime; assert(speedup > 2, `Expected speedup > 2x, got ${speedup.toFixed(2)}x`); }); it('should track performance metrics accurately', async () => { const files = ['src/index.js', 'src/utils.js', 'package.json']; await harness.batchReadFiles(files); const report = harness.getPerformanceReport(); assert(report.batchReadFiles); assert.strictEqual(report.batchReadFiles.totalItemsProcessed, 3); assert(report.batchReadFiles.averageThroughput); }); }); describe('Resource Utilization', () => { it('should measure resource usage for batch operations', async () => { harness.createMockProject('large'); const files = Array.from({ length: 50 }, (_, i) => `src/module${i}.js`); const { metrics } = await harness.measureResourceUsage( async () => await harness.batchReadFiles(files) ); assert(metrics.duration > 0); assert(metrics.memory.heapUsed !== undefined); assert(metrics.cpu.user >= 0); }); it('should handle memory efficiently with large batches', async () => { const largeContent = 'x'.repeat(10000); // 10KB per file const files = Array.from({ length: 100 }, (_, i) => { const path = `large${i}.txt`; harness.mockFS.set(path, largeContent); return path; }); const { metrics } = await harness.measureResourceUsage( async () => await harness.batchReadFiles(files) ); // Memory usage should be reasonable (not loading all at once) const memoryMB = metrics.memory.heapUsed / 1024 / 1024; assert(memoryMB < 50, `Memory usage too high: ${memoryMB.toFixed(2)}MB`); }); }); });