feat(ipcclient): Add clientOnly mode to prevent clients from auto-starting servers and improve registration/reconnect behavior
This commit is contained in:
@@ -192,6 +192,61 @@ tap.test('Client retry should work with delayed server', async () => {
|
||||
await server.stop();
|
||||
});
|
||||
|
||||
// Test 7: clientOnly prevents client from auto-starting a server
|
||||
tap.test('clientOnly should prevent auto-start and fail fast', async () => {
|
||||
const uniqueSocketPath = path.join(os.tmpdir(), `smartipc-clientonly-${Date.now()}.sock`);
|
||||
|
||||
const client = smartipc.SmartIpc.createClient({
|
||||
id: 'clientonly-test',
|
||||
socketPath: uniqueSocketPath,
|
||||
clientId: 'co-client-1',
|
||||
clientOnly: true,
|
||||
connectRetry: { enabled: false }
|
||||
});
|
||||
|
||||
let failed = false;
|
||||
try {
|
||||
await client.connect();
|
||||
} catch (err: any) {
|
||||
failed = true;
|
||||
expect(err.message).toContain('clientOnly prevents auto-start');
|
||||
}
|
||||
expect(failed).toBeTrue();
|
||||
// Ensure no server-side socket was created
|
||||
expect(fs.existsSync(uniqueSocketPath)).toBeFalse();
|
||||
});
|
||||
|
||||
// Test 8: env SMARTIPC_CLIENT_ONLY enforces clientOnly behavior
|
||||
tap.test('SMARTIPC_CLIENT_ONLY=1 should enforce clientOnly', async () => {
|
||||
const uniqueSocketPath = path.join(os.tmpdir(), `smartipc-clientonly-env-${Date.now()}.sock`);
|
||||
const prev = process.env.SMARTIPC_CLIENT_ONLY;
|
||||
process.env.SMARTIPC_CLIENT_ONLY = '1';
|
||||
|
||||
const client = smartipc.SmartIpc.createClient({
|
||||
id: 'clientonly-test-env',
|
||||
socketPath: uniqueSocketPath,
|
||||
clientId: 'co-client-2',
|
||||
connectRetry: { enabled: false }
|
||||
});
|
||||
|
||||
let failed = false;
|
||||
try {
|
||||
await client.connect();
|
||||
} catch (err: any) {
|
||||
failed = true;
|
||||
expect(err.message).toContain('clientOnly prevents auto-start');
|
||||
}
|
||||
expect(failed).toBeTrue();
|
||||
expect(fs.existsSync(uniqueSocketPath)).toBeFalse();
|
||||
|
||||
// restore env
|
||||
if (prev === undefined) {
|
||||
delete process.env.SMARTIPC_CLIENT_ONLY;
|
||||
} else {
|
||||
process.env.SMARTIPC_CLIENT_ONLY = prev;
|
||||
}
|
||||
});
|
||||
|
||||
// Cleanup
|
||||
tap.test('Cleanup test socket', async () => {
|
||||
try {
|
||||
@@ -201,4 +256,4 @@ tap.test('Cleanup test socket', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
export default tap.start();
|
||||
|
21
test/test.ts
21
test/test.ts
@@ -2,6 +2,10 @@ import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as smartipc from '../ts/index.js';
|
||||
import * as smartdelay from '@push.rocks/smartdelay';
|
||||
import * as smartpromise from '@push.rocks/smartpromise';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
|
||||
const testSocketPath = path.join(os.tmpdir(), `test-smartipc-${Date.now()}.sock`);
|
||||
|
||||
let server: smartipc.IpcServer;
|
||||
let client1: smartipc.IpcClient;
|
||||
@@ -11,12 +15,13 @@ let client2: smartipc.IpcClient;
|
||||
tap.test('should create and start an IPC server', async () => {
|
||||
server = smartipc.SmartIpc.createServer({
|
||||
id: 'test-server',
|
||||
socketPath: '/tmp/test-smartipc.sock',
|
||||
socketPath: testSocketPath,
|
||||
autoCleanupSocketFile: true,
|
||||
heartbeat: true,
|
||||
heartbeatInterval: 2000
|
||||
});
|
||||
|
||||
await server.start();
|
||||
await server.start({ readyWhen: 'accepting' });
|
||||
expect(server.getStats().isRunning).toBeTrue();
|
||||
});
|
||||
|
||||
@@ -24,11 +29,12 @@ tap.test('should create and start an IPC server', async () => {
|
||||
tap.test('should create and connect a client', async () => {
|
||||
client1 = smartipc.SmartIpc.createClient({
|
||||
id: 'test-server',
|
||||
socketPath: '/tmp/test-smartipc.sock',
|
||||
socketPath: testSocketPath,
|
||||
clientId: 'client-1',
|
||||
metadata: { name: 'Test Client 1' },
|
||||
autoReconnect: true,
|
||||
heartbeat: true
|
||||
heartbeat: true,
|
||||
clientOnly: true
|
||||
});
|
||||
|
||||
await client1.connect();
|
||||
@@ -76,9 +82,10 @@ tap.test('should handle request/response pattern', async () => {
|
||||
tap.test('should handle multiple clients', async () => {
|
||||
client2 = smartipc.SmartIpc.createClient({
|
||||
id: 'test-server',
|
||||
socketPath: '/tmp/test-smartipc.sock',
|
||||
socketPath: testSocketPath,
|
||||
clientId: 'client-2',
|
||||
metadata: { name: 'Test Client 2' }
|
||||
metadata: { name: 'Test Client 2' },
|
||||
clientOnly: true
|
||||
});
|
||||
|
||||
await client2.connect();
|
||||
@@ -296,4 +303,4 @@ tap.test('should cleanup and close all connections', async () => {
|
||||
expect(client1.getIsConnected()).toBeFalse();
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
export default tap.start();
|
||||
|
Reference in New Issue
Block a user