Files
peardata/test/swarm-pull.test.js
T
Raven Scott 1d46b7b3ad
CI / test (push) Failing after 6s
Release rolling / release (push) Has been cancelled
updates
2026-07-18 19:11:32 -04:00

118 lines
3.3 KiB
JavaScript

/**
* Linked peer warm pull: replicate Corestore A → B, open remote bee by dbKeyHex,
* query metric points without re-scraping.
*/
import test from 'brittle'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import Corestore from 'corestore'
import { PearDataModel } from '../server/db/model.js'
import { MetricStore } from '../server/services/store.js'
import { openDb, closeDb } from '../server/db/index.js'
import { openRemoteDb, closeRemoteDbs, queryRemoteMetricPoints } from '../server/db/remote.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const TMP = path.join(__dirname, '..', 'tmp-swarm-pull-test')
function replicatePair(a, b) {
const s1 = a.replicate(true)
const s2 = b.replicate(false)
s1.pipe(s2).pipe(s1)
return () => {
try {
s1.destroy()
} catch {
// ignore
}
try {
s2.destroy()
} catch {
// ignore
}
}
}
test('linked peer pulls warm points over corestore replicate', async (t) => {
fs.rmSync(TMP, { recursive: true, force: true })
const dirA = path.join(TMP, 'a')
const dirB = path.join(TMP, 'b-local')
const storeA = new Corestore(path.join(dirA, 'corestore'))
await storeA.ready()
const coreA = storeA.get({ name: 'peardata-meta' })
const modelA = new PearDataModel(coreA, { autoUpdate: true })
await modelA.ready()
const now = Date.now()
await modelA.putMetricPoints([
{
chart: 'system.cpu',
context: 'system.cpu',
ts: now - 90_000,
values: { user: 15, system: 5, nice: 0, iowait: 0, irq: 0, softirq: 0, idle: 80 },
tier: 1,
},
{
chart: 'system.cpu',
context: 'system.cpu',
ts: now - 30_000,
values: { user: 25, system: 5, nice: 0, iowait: 0, irq: 0, softirq: 0, idle: 70 },
tier: 1,
},
])
const dbKeyHex = modelA.publicKeyHex
// B: local agent HyperDB + open A's core by key, then replicate
process.env.PEARDATA_DATA_DIR = dirB
delete process.env.PEARDATA_HYPERDB
await closeDb().catch(() => {})
await closeRemoteDbs().catch(() => {})
const localB = await openDb()
t.ok(localB)
const remote = await openRemoteDb(dbKeyHex)
t.ok(remote)
const storeB = (await import('../server/db/index.js')).getCorestore()
const stop = replicatePair(storeA, storeB)
// wait for remote core to download blocks
const deadline = Date.now() + 10_000
let rows = []
while (Date.now() < deadline) {
rows = await queryRemoteMetricPoints({
chart: 'system.cpu',
afterMs: now - 180_000,
beforeMs: now + 1000,
tier: 1,
limit: 100,
})
if (rows.length >= 2) break
await new Promise((r) => setTimeout(r, 100))
}
t.ok(rows.length >= 2, `expected warm rows, got ${rows.length}`)
// MetricStore query should surface hyperdb-remote when memory empty
const mem = new MetricStore()
const q = await mem.query({
chart: 'system.cpu',
after: Math.floor((now - 180_000) / 1000),
before: Math.floor(now / 1000),
points: 60,
tier: 1,
})
t.ok(q.source === 'hyperdb-remote' || q.source === 'hyperdb-warm')
t.ok(q.data.length >= 2)
stop()
await closeRemoteDbs()
await closeDb()
await modelA.close().catch(() => {})
await storeA.close().catch(() => {})
fs.rmSync(TMP, { recursive: true, force: true })
delete process.env.PEARDATA_DATA_DIR
})