Skip to content

Commit 2033dfb

Browse files
added unit test for showing that eviction is not working properly, its evicting keys not added to the list of safeEvictionKeys
1 parent fc541c1 commit 2033dfb

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

tests/unit/onyxCacheTest.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,5 +676,78 @@ describe('Onyx', () => {
676676
expect(cache.hasCacheForKey('key4')).toBe(true);
677677
});
678678
});
679+
680+
it('Should NOT evict keys that are not in safeEvictionKeys list when cache limit is reached', () => {
681+
// Given Onyx keys configuration
682+
const testKeys = {
683+
...ONYX_KEYS,
684+
SAFE_FOR_EVICTION: 'evictable_',
685+
NOT_SAFE_FOR_EVICTION: 'critical_',
686+
};
687+
688+
// Create specific test key instances
689+
const criticalKey1 = `${testKeys.NOT_SAFE_FOR_EVICTION}1`;
690+
const criticalKey2 = `${testKeys.NOT_SAFE_FOR_EVICTION}2`;
691+
const criticalKey3 = `${testKeys.NOT_SAFE_FOR_EVICTION}3`;
692+
const evictableKey1 = `${testKeys.SAFE_FOR_EVICTION}1`;
693+
const evictableKey2 = `${testKeys.SAFE_FOR_EVICTION}2`;
694+
const evictableKey3 = `${testKeys.SAFE_FOR_EVICTION}3`;
695+
696+
// Given storage with some data
697+
StorageMock.getItem.mockResolvedValue('"mockValue"');
698+
const allKeys = [
699+
// Keys that should be evictable
700+
evictableKey1,
701+
evictableKey2,
702+
evictableKey3,
703+
// Keys that should NOT be evictable
704+
criticalKey1,
705+
criticalKey2,
706+
criticalKey3,
707+
];
708+
StorageMock.getAllKeys.mockResolvedValue(allKeys);
709+
710+
// Given Onyx with a very small cache limit to force eviction
711+
return initOnyx({
712+
keys: testKeys,
713+
maxCachedKeysCount: 3, // Only allow 3 keys in cache
714+
safeEvictionKeys: [testKeys.SAFE_FOR_EVICTION],
715+
})
716+
.then(() => {
717+
// Connect to non-evictable keys first (oldest in LRU queue)
718+
Onyx.connect({key: criticalKey1, callback: jest.fn()});
719+
Onyx.connect({key: criticalKey2, callback: jest.fn()});
720+
Onyx.connect({key: criticalKey3, callback: jest.fn()});
721+
})
722+
.then(waitForPromisesToResolve)
723+
.then(() => {
724+
// Then connect to evictable keys (more recent in LRU queue)
725+
Onyx.connect({key: evictableKey1, callback: jest.fn()});
726+
Onyx.connect({key: evictableKey2, callback: jest.fn()});
727+
Onyx.connect({key: evictableKey3, callback: jest.fn()});
728+
})
729+
.then(waitForPromisesToResolve)
730+
.then(() => {
731+
// Force an eviction by directly calling removeLeastRecentlyUsedKeys
732+
cache.removeLeastRecentlyUsedKeys();
733+
})
734+
.then(waitForPromisesToResolve)
735+
.then(() => {
736+
// Get which keys were kept in cache
737+
const nonEvictableKeysInCache = [cache.hasCacheForKey(criticalKey1), cache.hasCacheForKey(criticalKey2), cache.hasCacheForKey(criticalKey3)];
738+
739+
const evictableKeysInCache = [cache.hasCacheForKey(evictableKey1), cache.hasCacheForKey(evictableKey2), cache.hasCacheForKey(evictableKey3)];
740+
741+
// Print results for debugging
742+
// eslint-disable-next-line no-console
743+
console.log('Non-evictable keys in cache:', nonEvictableKeysInCache);
744+
// eslint-disable-next-line no-console
745+
console.log('Evictable keys in cache:', evictableKeysInCache);
746+
747+
// Bug demonstration: This test should FAIL because critical keys are incorrectly evicted
748+
// The current implementation evicts based on LRU order, not respecting safeEvictionKeys
749+
expect(nonEvictableKeysInCache.every((inCache) => inCache)).toBe(true);
750+
});
751+
});
679752
});
680753
});

0 commit comments

Comments
 (0)