Files
core/tests/engine/sharded-cross-chain.test.js
T

115 lines
4.5 KiB
JavaScript
Raw Normal View History

import assert from 'node:assert/strict';
import { describe, test } from 'node:test';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { CondensedGraph } from '../../src/core/CondensedGraph.js';
import { ShardedSnapshotBuilder } from '../../src/core/shards/ShardedSnapshotBuilder.js';
import { ShardedSnapshot } from '../../src/core/shards/ShardedSnapshot.js';
import { FileShardStorage } from '../../src/core/shards/FileShardStorage.js';
function buildShardedSnapshot(bucketSize = 2) {
const graph = new CondensedGraph();
const user0 = graph._ensureNode('user:0');
const user1 = graph._ensureNode('user:1');
const user2 = graph._ensureNode('user:2');
const user3 = graph._ensureNode('user:3');
const group0 = graph._ensureNode('group:0');
const group1 = graph._ensureNode('group:1');
const doc0 = graph._ensureNode('doc:0');
graph.addEdge(user0, 'member', group0);
graph.addEdge(user3, 'member', group0);
graph.addEdge(user2, 'member', group1);
graph.addEdge(group0, 'viewer', doc0);
graph.addEdge(group1, 'viewer', doc0);
graph.addEdge(user0, 'risk', doc0, { value: 0.2, possibility: 1, reliability: 1 });
graph.addEdge(user3, 'risk', doc0, { value: 0.9, possibility: 1, reliability: 1 });
graph.addEdge(user2, 'risk', doc0, { value: 0.6, possibility: 1, reliability: 1 });
graph.finalizePerfectHash();
graph.finalizeWaveletAdjacency({ dropAdjacencyList: true });
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sharded-cross-chain-'));
const builder = new ShardedSnapshotBuilder({ bucketSize, includeDirections: ['out', 'in'] });
const manifest = builder.build(graph, dir);
const storage = new FileShardStorage(dir);
const snapshot = new ShardedSnapshot(manifest, storage, { cacheLimit: 8 });
snapshot.initializeSync();
return { graph, snapshot, dir, ids: { user0, user1, user2, user3, group0, group1, doc0 } };
}
function collectRiskPaths(snapshot, relationIds, docId) {
const viewerRel = relationIds.viewer;
const memberRel = relationIds.member;
const riskRel = relationIds.risk;
const paths = [];
const viewerEdges = snapshot.executeGetInEdgesSync(docId, viewerRel, new Set()) || [];
for (const viewer of viewerEdges) {
const groupId = viewer.src;
const memberEdges = snapshot.executeGetInEdgesSync(groupId, memberRel, new Set()) || [];
for (const member of memberEdges) {
const userId = member.src;
const riskEdge = snapshot.executeFindEdgeSync(userId, riskRel, docId, new Set());
if (riskEdge) {
paths.push({ userId, docId });
}
}
}
return paths;
}
// ADR-003: sharded snapshots are stubs in src/core/shards/ — tests are the spec for when the subsystem is implemented.
describe.skip('Sharded snapshot cross-chain aggregation', () => {
test('aggregates risk values across userset paths', () => {
const { graph, snapshot, dir, ids } = buildShardedSnapshot(2);
const relationIds = {
member: graph.getRelationId('member'),
viewer: graph.getRelationId('viewer'),
risk: graph.getRelationId('risk')
};
const plan = new Set();
snapshot.planInEdges(relationIds.viewer, ids.doc0, plan);
snapshot.planInEdges(relationIds.member, ids.group0, plan);
snapshot.planInEdges(relationIds.member, ids.group1, plan);
snapshot.planOutEdges(relationIds.risk, ids.user0, plan);
snapshot.planOutEdges(relationIds.risk, ids.user2, plan);
snapshot.planOutEdges(relationIds.risk, ids.user3, plan);
snapshot.prefetchPlanSync(plan);
const paths = collectRiskPaths(snapshot, relationIds, ids.doc0);
assert.strictEqual(paths.length, 3);
fs.rmSync(dir, { recursive: true, force: true });
});
test('cross-bucket paths resolve with inbound and outbound shards', () => {
const { graph, snapshot, dir, ids } = buildShardedSnapshot(2);
const relationIds = {
member: graph.getRelationId('member'),
viewer: graph.getRelationId('viewer'),
risk: graph.getRelationId('risk')
};
const plan = new Set();
snapshot.planInEdges(relationIds.viewer, ids.doc0, plan);
snapshot.planInEdges(relationIds.member, ids.group0, plan);
snapshot.planInEdges(relationIds.member, ids.group1, plan);
snapshot.planOutEdges(relationIds.risk, ids.user0, plan);
snapshot.planOutEdges(relationIds.risk, ids.user2, plan);
snapshot.planOutEdges(relationIds.risk, ids.user3, plan);
snapshot.prefetchPlanSync(plan);
const paths = collectRiskPaths(snapshot, relationIds, ids.doc0);
assert.strictEqual(paths.length, 3);
fs.rmSync(dir, { recursive: true, force: true });
});
});