nip/tests/test_optimizations.nim

117 lines
3.7 KiB
Nim

import unittest, os, strutils, tables, options, json
import ../src/nimpak/cas
import ../src/nip/types
suite "CAS Performance Optimizations Tests":
var
cas: CasManager
testRoot = getTempDir() / "nip_optim_test_" & $getCurrentProcessId()
testFile = testRoot / "large_file.dat"
setup:
createDir(testRoot)
cas = initCasManager(testRoot)
# Create a dummy large file (larger than 1MB to trigger chunking)
var f = open(testFile, fmWrite)
# Write 1.5MB
let chunk = newString(1024 * 64) # 64KB
for i in 0..<24:
f.write(chunk)
f.close()
teardown:
removeDir(testRoot)
test "Index Caching":
# Initial state
check cas.indexCache.isNone
# Load index (should create empty one)
discard cas.loadIndex()
check cas.indexCache.isSome
let idx = cas.indexCache.get()
check idx.totalChunks == 0
# Update index
cas.updateIndex(100, 1)
check cas.indexCache.get().totalChunks == 1
check cas.indexCache.get().totalSize == 100
# Save and reload
discard cas.saveIndex()
# Reset manager to clear cache
var newCas = initCasManager(testRoot)
discard newCas.loadIndex()
check newCas.indexCache.get().totalChunks == 1
check newCas.indexCache.get().totalSize == 100
test "Existence Caching":
let data = "test data"
let res = cas.storeObject(data.toOpenArrayByte(0, data.len-1))
let hash = res.get().hash
# Cache should be empty initially (or populated by storeObject? storeObject doesn't update existenceCache currently)
# Wait, storeObject calls objectExists.
# But objectExists updates cache ONLY if found.
# When we store a NEW object, objectExists returns false.
# Then we write file.
# So cache is NOT updated for the new object yet.
check not cas.existenceCache.hasKey(hash)
# First check - should hit disk and populate cache
check cas.objectExists(hash)
check cas.existenceCache.hasKey(hash)
check cas.existenceCache[hash].endsWith(hash.split('-')[1])
# Second check - should hit cache
# Since our cache verifies file existence, deleting the file invalidates the cache.
# So we just verify the cache is populated.
check cas.existenceCache.hasKey(hash)
check cas.existenceCache[hash].endsWith(hash.split('-')[1])
# Invalidate cache manually
cas.existenceCache.del(hash)
check not cas.existenceCache.hasKey(hash)
test "Parallel Store Correctness":
# We test storeFileParallel for correctness
let res = cas.storeFileParallel(testFile)
if not res.isOk:
echo "Store failed: ", res.getError().msg
check res.isOk
let obj = res.get()
check obj.chunks.len > 0
# Verify we can retrieve it
let outFile = testRoot / "retrieved.dat"
let retRes = cas.retrieveFile(obj.hash, outFile)
if not retRes.isOk:
echo "Retrieve failed: ", retRes.errValue.msg
check retRes.isOk
if retRes.isOk:
check getFileInfo(outFile).size == getFileInfo(testFile).size
else:
# Debug: check if it wrote a manifest file
if fileExists(outFile):
echo "Output file size: ", getFileInfo(outFile).size
echo "Output content preview: ", readFile(outFile)[0..100]
test "Manifest Caching":
# Store a file (creates manifest)
let res = cas.storeFile(testFile)
let hash = res.get().hash
check not cas.manifestCache.hasKey(hash)
# Retrieve file - should populate manifest cache
let outFile = testRoot / "retrieved_manifest.dat"
discard cas.retrieveFile(hash, outFile)
check cas.manifestCache.hasKey(hash)
check cas.manifestCache[hash].kind == JObject
check cas.manifestCache[hash].hasKey("chunks")