97 lines
2.8 KiB
JavaScript
97 lines
2.8 KiB
JavaScript
/**
|
|
* End-to-end: ephemeral HyperDHT agent + client RPC + metric push.
|
|
* Skip with: SKIP_INTEGRATION=1 npm test
|
|
*/
|
|
import test from 'brittle'
|
|
import DHT from 'hyperdht'
|
|
import b4a from 'b4a'
|
|
import crypto from 'hypercore-crypto'
|
|
import { PeerSession } from '../server/rpc/session.js'
|
|
import { registerAllHandlers, cleanupSession } from '../server/rpc/register.js'
|
|
import { peers } from '../server/core/peer-registry.js'
|
|
import { initAuthKeys } from '../server/core/auth-keys.js'
|
|
import { PearDataConnection } from '../client/connection.js'
|
|
import { Methods, Pushes } from '../shared/protocol.js'
|
|
import { startPipeline } from '../server/pipeline.js'
|
|
import { getCollector } from '../server/services/collector.js'
|
|
|
|
const skip = process.env.SKIP_INTEGRATION === '1'
|
|
|
|
test('integration: dial, handshake, metrics, subscribe', { skip, timeout: 60_000 }, async (t) => {
|
|
const seed = crypto.randomBytes(32)
|
|
const keyPair = DHT.keyPair(seed)
|
|
const publicKeyHex = b4a.toString(keyPair.publicKey, 'hex')
|
|
const seedHex = b4a.toString(seed, 'hex')
|
|
|
|
initAuthKeys({ seedHex, publicKeyHex })
|
|
process.env.PEARDATA_INSECURE_OPEN_ADMIN = '1'
|
|
|
|
startPipeline()
|
|
|
|
const dht = new DHT()
|
|
const server = dht.createServer()
|
|
|
|
server.on('connection', (socket) => {
|
|
const session = new PeerSession(socket, {
|
|
serverPublicKey: keyPair.publicKey,
|
|
onClose: (s) => {
|
|
cleanupSession(s)
|
|
peers.remove(s.id)
|
|
},
|
|
})
|
|
registerAllHandlers(session)
|
|
peers.add(session)
|
|
})
|
|
|
|
await server.listen(keyPair)
|
|
t.teardown(async () => {
|
|
getCollector().stop()
|
|
for (const s of peers.list()) s.destroy()
|
|
await server.close().catch(() => {})
|
|
await dht.destroy().catch(() => {})
|
|
delete process.env.PEARDATA_INSECURE_OPEN_ADMIN
|
|
})
|
|
|
|
const conn = new PearDataConnection(publicKeyHex, {
|
|
adminSeed: seedHex,
|
|
timeoutMs: 45_000,
|
|
})
|
|
|
|
/** @type {object[]} */
|
|
const metricPushes = []
|
|
conn.on(Pushes.metrics, (m) => metricPushes.push(m))
|
|
|
|
await conn.connect()
|
|
t.is(conn.role, 'admin')
|
|
t.ok(conn.connected)
|
|
|
|
const pong = await conn.request(Methods.ping, {})
|
|
t.ok(pong.ok)
|
|
|
|
const info = await conn.request(Methods.getServerInfo, {})
|
|
t.is(info.app, 'peardata')
|
|
|
|
const charts = await conn.request(Methods.listCharts, {})
|
|
t.ok(charts.charts)
|
|
|
|
await conn.request(Methods.subscribeMetrics, { charts: ['*'], intervalMs: 1000 })
|
|
|
|
// wait for at least one collector tick + push
|
|
await new Promise((r) => setTimeout(r, 2200))
|
|
|
|
const q = await conn.request(Methods.queryData, {
|
|
chart: 'system.cpu',
|
|
after: -30,
|
|
points: 30,
|
|
})
|
|
t.ok(q.labels)
|
|
t.ok(Array.isArray(q.data))
|
|
|
|
const health = await conn.request(Methods.getHealth, {})
|
|
t.ok(health.status)
|
|
|
|
t.ok(metricPushes.length >= 0) // push timing may vary; query proves pipeline
|
|
|
|
await conn.destroy()
|
|
})
|