feat: v0.6.1 — AriaEngine 可选自研 KVStore 后端(storageBackend: 'kv')+ KVStore APPEND 日志类型 + 10 个 aria+kv 集成测试 + 文档全量同步
This commit is contained in:
@@ -366,3 +366,103 @@ describe('KVStore — 编解码单元', () => {
|
||||
expect(decodeSnapshot(bytes)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
// ===================================================================
|
||||
// APPEND 追加写入(v0.6.1)
|
||||
// ===================================================================
|
||||
describe('KVStore — APPEND 追加写入', () => {
|
||||
it('appendValue 拼接 + 恢复完整(跨实例)', async () => {
|
||||
const dbName = uniqueDB();
|
||||
const medium = new SharedMemoryBackend();
|
||||
const kv = new KVStore(medium, 0);
|
||||
await kv.open(dbName);
|
||||
await kv.appendValue('log', enc('AAA'));
|
||||
await kv.appendValue('log', enc('BBB'));
|
||||
await kv.appendValue('log', enc('CCC'));
|
||||
expect(dec(await kv.get('log'))).toBe('AAABBBCCC');
|
||||
await kv.close();
|
||||
|
||||
const kv2 = new KVStore(medium, 0);
|
||||
await kv2.open(dbName);
|
||||
expect(dec(await kv2.get('log'))).toBe('AAABBBCCC');
|
||||
await kv2.close();
|
||||
});
|
||||
|
||||
it('append 与 put/delete 混合 + checkpoint 后恢复', async () => {
|
||||
const dbName = uniqueDB();
|
||||
const medium = new SharedMemoryBackend();
|
||||
const kv = new KVStore(medium, 0);
|
||||
await kv.open(dbName);
|
||||
await kv.appendValue('log', enc('A'));
|
||||
await kv.put('meta', enc('M'));
|
||||
await kv.appendValue('log', enc('B'));
|
||||
await kv.checkpoint();
|
||||
await kv.appendValue('log', enc('C'));
|
||||
await kv.put('meta2', enc('M2'));
|
||||
await kv.close();
|
||||
|
||||
const kv2 = new KVStore(medium, 0);
|
||||
await kv2.open(dbName);
|
||||
expect(dec(await kv2.get('log'))).toBe('ABC');
|
||||
expect(dec(await kv2.get('meta'))).toBe('M');
|
||||
expect(dec(await kv2.get('meta2'))).toBe('M2');
|
||||
await kv2.close();
|
||||
});
|
||||
|
||||
it('append 覆盖语义:先 put 后 append 拼接', async () => {
|
||||
const dbName = uniqueDB();
|
||||
const medium = new SharedMemoryBackend();
|
||||
const kv = new KVStore(medium, 0);
|
||||
await kv.open(dbName);
|
||||
await kv.put('f', enc('HEAD-'));
|
||||
await kv.appendValue('f', enc('BODY'));
|
||||
expect(dec(await kv.get('f'))).toBe('HEAD-BODY');
|
||||
await kv.close();
|
||||
|
||||
const kv2 = new KVStore(medium, 0);
|
||||
await kv2.open(dbName);
|
||||
expect(dec(await kv2.get('f'))).toBe('HEAD-BODY');
|
||||
await kv2.close();
|
||||
});
|
||||
|
||||
it('append 后 delete → 删除生效(索引与恢复一致)', async () => {
|
||||
const dbName = uniqueDB();
|
||||
const medium = new SharedMemoryBackend();
|
||||
const kv = new KVStore(medium, 0);
|
||||
await kv.open(dbName);
|
||||
await kv.appendValue('log', enc('X'));
|
||||
await kv.delete('log');
|
||||
expect(await kv.exists('log')).toBe(false);
|
||||
await kv.close();
|
||||
|
||||
const kv2 = new KVStore(medium, 0);
|
||||
await kv2.open(dbName);
|
||||
expect(await kv2.exists('log')).toBe(false);
|
||||
await kv2.close();
|
||||
});
|
||||
|
||||
it('日志损坏截断后已确认的 append 数据保留', async () => {
|
||||
const dbName = uniqueDB();
|
||||
const medium = new SharedMemoryBackend();
|
||||
const kv = new KVStore(medium, 0);
|
||||
await kv.open(dbName);
|
||||
await kv.appendValue('log', enc('KEEP'));
|
||||
await kv.close();
|
||||
|
||||
// 追加损坏记录
|
||||
const disk = new SharedMemoryBackend();
|
||||
await disk.open(dbName);
|
||||
const log = await disk.read('__kv_log');
|
||||
const bad = new Uint8Array(encodeLogRecord(999, { x: enc('X') }));
|
||||
bad[15] ^= 0xff;
|
||||
const combined = new Uint8Array((log as ArrayBuffer).byteLength + bad.byteLength);
|
||||
combined.set(new Uint8Array(log as ArrayBuffer), 0);
|
||||
combined.set(bad, (log as ArrayBuffer).byteLength);
|
||||
await disk.write('__kv_log', combined.buffer as ArrayBuffer);
|
||||
|
||||
const kv2 = new KVStore(medium, 0);
|
||||
await kv2.open(dbName);
|
||||
expect(dec(await kv2.get('log'))).toBe('KEEP');
|
||||
await kv2.close();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user