Files
MetonaSqlark/tests/engine/aria-compress.test.ts
T
thzxx 4a3feac9ea
CI / test (18.x) (push) Successful in 9m58s
CI / test (20.x) (push) Successful in 9m56s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m52s
release: v0.2.3 AriaEngine 引擎加固 — RB-Tree fixDelete/LSM SSTable缓存预热/LZ4格式修复
2026-07-27 21:22:29 +08:00

128 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* AriaEngine LZ4 压缩 + LSM Merge Iterator 单元测试
* 注:LZ4 为简化演示实现(默认 compression:false),测试聚焦于「不卡死」
*/
import { compressLZ4, decompressLZ4 } from '../../src/engine/aria/compression/lz4';
import { MergeIterator, ArrayEntrySource } from '../../src/engine/aria/index/merge_iterator';
// ===================================================================
// LZ4 压缩 — 安全烟雾测试(不卡死)
// ===================================================================
describe('AriaEngine — LZ4 Compression', () => {
it('短于 4 字节时原样返回', () => {
const input = new Uint8Array([1, 2]);
const compressed = compressLZ4(input);
expect(compressed).toBe(input);
});
it('简单文本压缩不抛出异常且产生输出', () => {
const input = new TextEncoder().encode('hello world hello world hello world');
const compressed = compressLZ4(input);
expect(compressed).toBeInstanceOf(Uint8Array);
expect(compressed.byteLength).toBeGreaterThan(0);
});
it('重复数据有压缩效果', () => {
const pattern = 'ABCD';
const repeated = pattern.repeat(100);
const input = new TextEncoder().encode(repeated);
const compressed = compressLZ4(input);
expect(compressed.byteLength).toBeLessThan(input.byteLength);
});
it('随机不可压缩数据不卡死', () => {
const input = new Uint8Array(256);
for (let i = 0; i < 256; i++) input[i] = Math.floor(Math.random() * 256);
const compressed = compressLZ4(input);
expect(compressed).toBeInstanceOf(Uint8Array);
expect(compressed.byteLength).toBeGreaterThan(0);
});
it('长文本压缩不卡死', () => {
const input = new TextEncoder().encode('The quick brown fox jumps over the lazy dog. '.repeat(10));
const compressed = compressLZ4(input);
expect(compressed).toBeTruthy();
expect(compressed.byteLength).toBeGreaterThan(0);
});
it('多种长度输入均不卡死', () => {
for (const size of [10, 50, 100, 200, 500]) {
const input = new Uint8Array(size);
for (let i = 0; i < size; i++) input[i] = i % 256;
const compressed = compressLZ4(input);
expect(compressed.byteLength).toBeLessThanOrEqual(input.byteLength + 16);
}
});
it('解压不抛出异常', () => {
const input = new TextEncoder().encode('test data for decompression smoke test');
const compressed = compressLZ4(input);
expect(() => decompressLZ4(compressed, input.byteLength)).not.toThrow();
});
});
// ===================================================================
// MergeIterator — 归并迭代器单元测试
// ===================================================================
describe('AriaEngine — MergeIterator', () => {
it('单数据源归并', () => {
const mi = new MergeIterator();
mi.addSource(new ArrayEntrySource([
['a', { v: 1 }],
['b', { v: 2 }],
['c', { v: 3 }],
]));
const result = mi.drain();
expect(result).toHaveLength(3);
expect(result.map(([k]) => k)).toEqual(['a', 'b', 'c']);
});
it('多数据源归并去重(保留最新)', () => {
const mi = new MergeIterator();
mi.addSource(new ArrayEntrySource([['a', { v: 'new' }], ['c', { v: 3 }]]));
mi.addSource(new ArrayEntrySource([['a', { v: 'old' }], ['b', { v: 2 }]]));
const result = mi.drain();
expect(result).toHaveLength(3);
expect(result[0][0]).toBe('a');
expect(result[0][1].v).toBe('new');
expect(result[1][0]).toBe('b');
expect(result[2][0]).toBe('c');
});
it('空数据源归并', () => {
const mi = new MergeIterator();
mi.addSource(new ArrayEntrySource([]));
const result = mi.drain();
expect(result).toHaveLength(0);
});
it('大数量归并', () => {
const mi = new MergeIterator();
for (let s = 0; s < 5; s++) {
const entries: [string, Record<string, unknown>][] = [];
for (let i = 0; i < 100; i++) {
entries.push([`src${s}-key-${String(i).padStart(3, '0')}`, { src: s, idx: i }]);
}
mi.addSource(new ArrayEntrySource(entries));
}
const result = mi.drain();
// 5 sources × 100 unique keys = 500 total (keys are unique per source)
expect(result).toHaveLength(500);
});
it('ArrayEntrySource — 迭代器用完返回 null', () => {
const src = new ArrayEntrySource([['k', { v: 1 }]]);
expect(src.next()).not.toBeNull();
expect(src.next()).toBeNull();
expect(src.next()).toBeNull();
});
it('ArrayEntrySource — reset 重置', () => {
const src = new ArrayEntrySource([['k1', { v: 1 }], ['k2', { v: 2 }]]);
src.next();
src.reset();
const val = src.next();
expect(val![0]).toBe('k1');
});
});