import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import os from 'node:os'
import { Registry } from '../lib/registry.js'
function createTestRegistry () {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), '7rnx-test-'))
const reg = new Registry(tmpDir)
reg.load()
return { reg, tmpDir }
}
describe('Registry multi-backend support', () => {
it('addService still works with single node (backwards compat)', () => {
const { reg } = createTestRegistry()
reg.addNode('node1', '10.0.0.1')
reg.addService('node1', 'web', 8080)
const services = reg.listServices()
assert.equal(services.length, 1)
assert.equal(services[0].name, 'web')
assert.equal(services[0].node, 'node1')
assert.equal(services[0].port, 8080)
assert.equal(services[0].backends, undefined)
})
it('addBackend adds a second backend', () => {
const { reg } = createTestRegistry()
reg.addNode('node1', '10.0.0.1')
reg.addNode('node2', '10.0.0.2')
reg.addService('node1', 'web', 8080)
reg.addBackend('web', 'node2', 9090, 'standby')
const services = reg.listServices()
const svc = services.find(s => s.name === 'web')
assert.ok(svc.backends)
assert.equal(svc.backends.length, 2)
assert.equal(svc.backends[0].node, 'node1')
assert.equal(svc.backends[0].port, 8080)
assert.equal(svc.backends[0].mode, 'active')
assert.equal(svc.backends[1].node, 'node2')
assert.equal(svc.backends[1].port, 9090)
assert.equal(svc.backends[1].mode, 'standby')
})
it('addBackend throws if service does not exist', () => {
const { reg } = createTestRegistry()
reg.addNode('node1', '10.0.0.1')
assert.throws(
() => reg.addBackend('nonexistent', 'node1', 8080),
{ message: 'Service "nonexistent" not found' }
)
})
it('addBackend throws if node does not exist', () => {
const { reg } = createTestRegistry()
reg.addNode('node1', '10.0.0.1')
reg.addService('node1', 'web', 8080)
assert.throws(
() => reg.addBackend('web', 'ghost', 9090),
{ message: 'Node "ghost" not found' }
)
})
it('removeBackend reverts to single-node if one backend left', () => {
const { reg } = createTestRegistry()
reg.addNode('node1', '10.0.0.1')
reg.addNode('node2', '10.0.0.2')
reg.addService('node1', 'web', 8080)
reg.addBackend('web', 'node2', 9090, 'standby')
reg.removeBackend('web', 'node2')
const svc = reg.listServices().find(s => s.name === 'web')
assert.equal(svc.backends, undefined)
assert.equal(svc.node, 'node1')
assert.equal(svc.port, 8080)
})
it('getServiceWithBackends returns resolved info', () => {
const { reg } = createTestRegistry()
reg.addNode('node1', '10.0.0.1')
reg.addNode('node2', '10.0.0.2')
reg.addService('node1', 'web', 8080)
reg.addBackend('web', 'node2', 9090, 'standby')
const result = reg.getServiceWithBackends('web')
assert.ok(result.resolvedBackends)
assert.equal(result.resolvedBackends.length, 2)
assert.equal(result.resolvedBackends[0].ip, '10.0.0.1')
assert.equal(result.resolvedBackends[0].node, 'node1')
assert.equal(result.resolvedBackends[0].port, 8080)
assert.equal(result.resolvedBackends[0].mode, 'active')
assert.equal(result.resolvedBackends[1].ip, '10.0.0.2')
assert.equal(result.resolvedBackends[1].node, 'node2')
assert.equal(result.resolvedBackends[1].port, 9090)
assert.equal(result.resolvedBackends[1].mode, 'standby')
})
it('getServiceWithBackends synthesizes array for single-node service', () => {
const { reg } = createTestRegistry()
reg.addNode('node1', '10.0.0.1')
reg.addService('node1', 'web', 8080)
const result = reg.getServiceWithBackends('web')
assert.ok(result.resolvedBackends)
assert.equal(result.resolvedBackends.length, 1)
assert.equal(result.resolvedBackends[0].ip, '10.0.0.1')
assert.equal(result.resolvedBackends[0].node, 'node1')
assert.equal(result.resolvedBackends[0].port, 8080)
assert.equal(result.resolvedBackends[0].mode, 'active')
})
})