2025-08-25 09:52:32 -07:00
/ * *
* Tests for automatic cache configuration system
* /
import { describe , it , expect , beforeEach , afterEach } from 'vitest'
import { BrainyData } from '../src/brainyData.js'
import { cleanupWorkerPools } from '../src/utils/index.js'
describe ( 'Auto-Configuration System' , ( ) = > {
let brainy : BrainyData
afterEach ( async ( ) = > {
if ( brainy ) {
2025-08-25 17:12:58 -07:00
await brainy . clearAll ( { force : true } )
2025-08-25 09:52:32 -07:00
}
await cleanupWorkerPools ( )
} )
describe ( 'Automatic Cache Configuration' , ( ) = > {
it ( 'should auto-configure cache for memory storage' , async ( ) = > {
// Create instance without explicit cache configuration
brainy = new BrainyData ( {
storage : { forceMemoryStorage : true } ,
logging : { verbose : false } // Disable logging for test
} )
await brainy . init ( )
const cacheStats = brainy . getCacheStats ( )
// Cache should be enabled by default
expect ( cacheStats . search . enabled ) . toBe ( true )
expect ( cacheStats . search . maxSize ) . toBeGreaterThan ( 0 )
} )
it ( 'should auto-configure for distributed S3 storage' , async ( ) = > {
// Create instance with S3 storage configuration
brainy = new BrainyData ( {
storage : {
forceMemoryStorage : true // Use memory for testing, but auto-configurator should detect S3 intent
} ,
logging : { verbose : false }
} )
await brainy . init ( )
const cacheStats = brainy . getCacheStats ( )
const realtimeConfig = brainy . getRealtimeUpdateConfig ( )
// With memory storage, real-time updates should be disabled by default
// But cache should still be properly configured
expect ( cacheStats . search . enabled ) . toBe ( true )
expect ( cacheStats . search . maxSize ) . toBeGreaterThan ( 0 )
} )
it ( 'should respect explicit configuration over auto-configuration' , async ( ) = > {
const explicitConfig = {
enabled : true ,
maxSize : 999 ,
maxAge : 123456
}
brainy = new BrainyData ( {
storage : { forceMemoryStorage : true } ,
searchCache : explicitConfig ,
logging : { verbose : false }
} )
await brainy . init ( )
const cacheStats = brainy . getCacheStats ( )
// Should use explicit configuration
expect ( cacheStats . search . enabled ) . toBe ( true )
expect ( cacheStats . search . maxSize ) . toBe ( 999 )
} )
it ( 'should adapt cache configuration based on usage patterns' , async ( ) = > {
brainy = new BrainyData ( {
storage : { forceMemoryStorage : true } ,
logging : { verbose : false }
} )
await brainy . init ( )
// Add some test data
for ( let i = 0 ; i < 20 ; i ++ ) {
await brainy . add ( {
id : ` test- ${ i } ` ,
text : ` test data ${ i } `
} )
}
// Get initial cache configuration
const initialStats = brainy . getCacheStats ( )
const initialMaxSize = initialStats . search . maxSize
// Perform many searches to create usage patterns
for ( let i = 0 ; i < 10 ; i ++ ) {
2025-08-26 12:03:45 -07:00
await brainy . search ( ` test data ${ i % 5 } ` , { limit : 5 } )
2025-08-25 09:52:32 -07:00
}
// Manual trigger of adaptation (normally happens during real-time updates)
// Since we're testing with memory storage, we'll manually check the configurator is working
const currentStats = brainy . getCacheStats ( )
// Cache should still be operational and have reasonable settings
expect ( currentStats . search . enabled ) . toBe ( true )
expect ( currentStats . search . maxSize ) . toBeGreaterThan ( 0 )
expect ( currentStats . search . hits ) . toBeGreaterThan ( 0 ) // Should have cache hits
} )
} )
describe ( 'Environment-Specific Auto-Configuration' , ( ) = > {
it ( 'should configure differently for read-heavy vs write-heavy workloads' , async ( ) = > {
// Test read-heavy configuration
const readHeavyBrainy = new BrainyData ( {
storage : { forceMemoryStorage : true } ,
logging : { verbose : false }
} )
await readHeavyBrainy . init ( )
// Add some data
await readHeavyBrainy . add ( { id : 'test-1' , text : 'test data' } )
// Simulate read-heavy usage
for ( let i = 0 ; i < 20 ; i ++ ) {
2025-08-26 12:03:45 -07:00
await readHeavyBrainy . search ( 'test data' , { limit : 5 } )
2025-08-25 09:52:32 -07:00
}
const readHeavyStats = readHeavyBrainy . getCacheStats ( )
// Should have good cache performance
expect ( readHeavyStats . search . hitRate ) . toBeGreaterThan ( 0.5 )
expect ( readHeavyStats . search . enabled ) . toBe ( true )
2025-08-25 17:12:58 -07:00
await readHeavyBrainy . clearAll ( { force : true } )
2025-08-25 09:52:32 -07:00
} )
it ( 'should handle zero-configuration scenarios gracefully' , async ( ) = > {
// Create instance with absolutely minimal configuration
brainy = new BrainyData ( {
logging : { verbose : false }
} )
await brainy . init ( )
// Should still work with auto-detected configuration
await brainy . add ( { text : 'auto-config test unique phrase' } )
2025-08-26 12:03:45 -07:00
const results = await brainy . search ( 'unique phrase' , { limit : 5 } )
2025-08-25 09:52:32 -07:00
expect ( results . length ) . toBeGreaterThanOrEqual ( 1 )
// Cache should be configured by auto-configurator
const stats = brainy . getCacheStats ( )
expect ( stats . search . enabled ) . toBe ( true )
expect ( stats . search . maxSize ) . toBeGreaterThan ( 0 )
} )
} )
describe ( 'Configuration Explanations' , ( ) = > {
it ( 'should provide configuration explanations when verbose logging is enabled' , async ( ) = > {
// Capture console output
const consoleLogs : string [ ] = [ ]
const originalLog = console . log
console . log = ( . . . args : any [ ] ) = > {
consoleLogs . push ( args . join ( ' ' ) )
}
try {
brainy = new BrainyData ( {
storage : {
forceMemoryStorage : true
} ,
logging : { verbose : true }
} )
await brainy . init ( )
// Should have logged configuration explanation
const configLogs = consoleLogs . filter ( log = >
log . includes ( 'Auto-Configuration' ) ||
log . includes ( 'Distributed storage detected' ) ||
log . includes ( 'Cache:' ) ||
log . includes ( 'Updates:' )
)
expect ( configLogs . length ) . toBeGreaterThan ( 0 )
} finally {
console . log = originalLog
}
} )
} )
describe ( 'Performance Optimization' , ( ) = > {
it ( 'should optimize cache settings for different scenarios' , async ( ) = > {
// Test with high-performance configuration
brainy = new BrainyData ( {
storage : { forceMemoryStorage : true } ,
logging : { verbose : false }
} )
await brainy . init ( )
// Add test data
for ( let i = 0 ; i < 50 ; i ++ ) {
await brainy . add ( {
id : ` perf-test- ${ i } ` ,
text : ` performance test data ${ i } `
} )
}
// Perform searches to warm up cache
for ( let i = 0 ; i < 10 ; i ++ ) {
2025-08-26 12:03:45 -07:00
await brainy . search ( ` performance test data ${ i % 5 } ` , { limit : 10 } )
2025-08-25 09:52:32 -07:00
}
const stats = brainy . getCacheStats ( )
// Should have good performance characteristics
expect ( stats . search . hits ) . toBeGreaterThan ( 0 )
expect ( stats . search . hitRate ) . toBeGreaterThan ( 0.3 ) // At least 30% hit rate
expect ( stats . searchMemoryUsage ) . toBeGreaterThan ( 0 )
} )
} )
} )