/** * Integration tests for Memory Enhancements (v5.11.0) * * End-to-end tests verifying: * - Container detection works correctly * - Memory limits are applied correctly * - getMemoryStats() provides accurate information * - All features work together seamlessly */ import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { Brainy } from '../../src/brainy.js' import { mkdtempSync, rmSync } from 'fs' import { tmpdir } from 'os' import { join } from 'path' describe('Memory Enhancements Integration (v5.11.0)', () => { let testDir: string let originalEnv: Record beforeEach(() => { testDir = mkdtempSync(join(tmpdir(), 'brainy-memory-integration-')) originalEnv = { CLOUD_RUN_MEMORY: process.env.CLOUD_RUN_MEMORY, MEMORY_LIMIT: process.env.MEMORY_LIMIT } }) afterEach(() => { rmSync(testDir, { recursive: true, force: true }) Object.keys(originalEnv).forEach(key => { if (originalEnv[key] === undefined) { delete process.env[key] } else { process.env[key] = originalEnv[key] } }) }) describe('Production Workflow: Cloud Run Deployment', () => { it('should detect 4GB Cloud Run container and set optimal limits', async () => { process.env.CLOUD_RUN_MEMORY = '4Gi' const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true }) await brain.init() const stats = brain.getMemoryStats() // Verify container detected expect(stats.memory.containerLimit).toBe(4 * 1024 * 1024 * 1024) // Verify optimal limits expect(stats.limits.basis).toBe('containerMemory') expect(stats.limits.maxQueryLimit).toBe(10000) // 25% of 4GB // Verify can query with these limits for (let i = 0; i < 100; i++) { await brain.add({ type: 'document', data: `Entity ${i}` }) } const results = await brain.find({ limit: 10000 }) // Should not throw expect(results.length).toBe(100) await brain.close() }) it('should allow manual override for power users in containers', async () => { process.env.CLOUD_RUN_MEMORY = '4Gi' const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, maxQueryLimit: 50000, // Override auto-detection silent: true }) await brain.init() const stats = brain.getMemoryStats() // Container detected but override used expect(stats.memory.containerLimit).toBe(4 * 1024 * 1024 * 1024) expect(stats.limits.basis).toBe('override') expect(stats.limits.maxQueryLimit).toBe(50000) await brain.close() }) it('should use reservedQueryMemory for fine-grained control', async () => { const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, reservedQueryMemory: 2 * 1024 * 1024 * 1024, // Reserve 2GB silent: true }) await brain.init() const stats = brain.getMemoryStats() expect(stats.limits.basis).toBe('reservedMemory') expect(stats.limits.maxQueryLimit).toBe(20000) // 2GB / 100MB * 1000 await brain.close() }) }) describe('Memory Stats API', () => { it('should provide actionable recommendations', async () => { process.env.CLOUD_RUN_MEMORY = '4Gi' const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true }) await brain.init() const stats = brain.getMemoryStats() // Should have recommendations array expect(stats.recommendations).toBeDefined() expect(Array.isArray(stats.recommendations)).toBe(true) // Should not have error recommendations for well-configured system const errorRecommendations = stats.recommendations?.filter(r => r.toLowerCase().includes('error') || r.toLowerCase().includes('warning') ) expect(errorRecommendations?.length || 0).toBe(0) await brain.close() }) it('should help debug low limits in production', async () => { // Simulate production issue: container detected but low free memory process.env.CLOUD_RUN_MEMORY = '4Gi' const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true }) await brain.init() const stats = brain.getMemoryStats() // User can see why limits are what they are expect(stats.limits.basis).toBeDefined() expect(stats.memory.containerLimit).toBeDefined() expect(stats.config).toBeDefined() // Can debug: "Why is my limit only 10k?" // Answer: basis='containerMemory', container=4GB, 4GB * 0.25 = 1GB -> 10k await brain.close() }) }) describe('Zero-Config Behavior', () => { it('should work optimally with no configuration', async () => { process.env.CLOUD_RUN_MEMORY = '4Gi' const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true }) await brain.init() // Zero config, optimal behavior const stats = brain.getMemoryStats() expect(stats.limits.maxQueryLimit).toBe(10000) expect(stats.limits.basis).toBe('containerMemory') // Should work without issues for (let i = 0; i < 100; i++) { await brain.add({ type: 'note', data: `Test ${i}` }) } const results = await brain.find({ limit: 100 }) expect(results.length).toBe(100) await brain.close() }) it('should work on bare metal without containers', async () => { // No container env vars const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true }) await brain.init() const stats = brain.getMemoryStats() expect(stats.memory.containerLimit).toBeNull() expect(stats.limits.basis).toBe('freeMemory') expect(stats.limits.maxQueryLimit).toBeGreaterThan(0) await brain.close() }) }) describe('Backward Compatibility', () => { it('should not break existing code', async () => { const brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true }) await brain.init() // Existing APIs work await brain.add({ type: 'document', data: 'Test' }) const results = await brain.find({ limit: 10 }) expect(results.length).toBe(1) await brain.close() }) }) })