@olane/o-node 0.7.13-alpha.0 → 0.7.13-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts +1 -0
- package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.d.ts +0 -1
- package/dist/src/connection/o-node-connection.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.js +0 -8
- package/dist/src/connection/o-node-connection.manager.d.ts +41 -4
- package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.manager.js +187 -45
- package/dist/src/connection/stream-handler.d.ts.map +1 -1
- package/dist/src/connection/stream-handler.js +0 -2
- package/dist/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -1
- package/dist/src/managers/o-connection-heartbeat.manager.js +15 -1
- package/dist/src/managers/o-reconnection.manager.d.ts.map +1 -1
- package/dist/src/managers/o-reconnection.manager.js +12 -7
- package/dist/src/o-node.d.ts +19 -0
- package/dist/src/o-node.d.ts.map +1 -1
- package/dist/src/o-node.js +89 -11
- package/dist/src/o-node.tool.d.ts.map +1 -1
- package/dist/src/o-node.tool.js +5 -0
- package/dist/src/router/o-node.router.d.ts.map +1 -1
- package/dist/src/router/o-node.router.js +16 -6
- package/dist/src/router/o-node.routing-policy.d.ts.map +1 -1
- package/dist/src/router/o-node.routing-policy.js +4 -0
- package/dist/test/connection-management.spec.d.ts +2 -0
- package/dist/test/connection-management.spec.d.ts.map +1 -0
- package/dist/test/connection-management.spec.js +370 -0
- package/dist/test/helpers/connection-spy.d.ts +124 -0
- package/dist/test/helpers/connection-spy.d.ts.map +1 -0
- package/dist/test/helpers/connection-spy.js +229 -0
- package/dist/test/helpers/index.d.ts +6 -0
- package/dist/test/helpers/index.d.ts.map +1 -0
- package/dist/test/helpers/index.js +12 -0
- package/dist/test/helpers/network-builder.d.ts +109 -0
- package/dist/test/helpers/network-builder.d.ts.map +1 -0
- package/dist/test/helpers/network-builder.js +309 -0
- package/dist/test/helpers/simple-node-builder.d.ts +50 -0
- package/dist/test/helpers/simple-node-builder.d.ts.map +1 -0
- package/dist/test/helpers/simple-node-builder.js +66 -0
- package/dist/test/helpers/test-environment.d.ts +140 -0
- package/dist/test/helpers/test-environment.d.ts.map +1 -0
- package/dist/test/helpers/test-environment.js +184 -0
- package/dist/test/helpers/test-node.tool.d.ts +31 -0
- package/dist/test/helpers/test-node.tool.d.ts.map +1 -1
- package/dist/test/helpers/test-node.tool.js +49 -0
- package/dist/test/leader-transport-validation.spec.d.ts +2 -0
- package/dist/test/leader-transport-validation.spec.d.ts.map +1 -0
- package/dist/test/leader-transport-validation.spec.js +177 -0
- package/dist/test/network-communication.spec.d.ts +2 -0
- package/dist/test/network-communication.spec.d.ts.map +1 -0
- package/dist/test/network-communication.spec.js +256 -0
- package/dist/test/o-node.spec.d.ts +2 -0
- package/dist/test/o-node.spec.d.ts.map +1 -0
- package/dist/test/o-node.spec.js +247 -0
- package/dist/test/parent-child-registration.spec.d.ts +2 -0
- package/dist/test/parent-child-registration.spec.d.ts.map +1 -0
- package/dist/test/parent-child-registration.spec.js +177 -0
- package/dist/test/search-resolver.spec.d.ts +2 -0
- package/dist/test/search-resolver.spec.d.ts.map +1 -0
- package/dist/test/search-resolver.spec.js +648 -0
- package/package.json +12 -7
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { oNode } from '../../src/o-node.js';
|
|
2
|
+
import { oNodeTool } from '../../src/o-node.tool.js';
|
|
3
|
+
import type { Connection, Stream } from '@libp2p/interface';
|
|
4
|
+
/**
|
|
5
|
+
* Connection event captured by the spy
|
|
6
|
+
*/
|
|
7
|
+
export interface ConnectionEvent {
|
|
8
|
+
type: 'peer:connect' | 'peer:disconnect' | 'connection:open' | 'connection:close' | 'stream:open' | 'stream:close';
|
|
9
|
+
timestamp: number;
|
|
10
|
+
peerId?: string;
|
|
11
|
+
remoteAddr?: string;
|
|
12
|
+
protocol?: string;
|
|
13
|
+
streamId?: string;
|
|
14
|
+
metadata?: Record<string, any>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Stream statistics
|
|
18
|
+
*/
|
|
19
|
+
export interface StreamStats {
|
|
20
|
+
protocol: string;
|
|
21
|
+
status: string;
|
|
22
|
+
writeStatus?: string;
|
|
23
|
+
readStatus?: string;
|
|
24
|
+
created: number;
|
|
25
|
+
closed?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Connection statistics
|
|
29
|
+
*/
|
|
30
|
+
export interface ConnectionStats {
|
|
31
|
+
peerId: string;
|
|
32
|
+
status: string;
|
|
33
|
+
remoteAddr: string;
|
|
34
|
+
streams: StreamStats[];
|
|
35
|
+
created: number;
|
|
36
|
+
closed?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Spy that monitors libp2p connections and streams for testing
|
|
40
|
+
*/
|
|
41
|
+
export declare class ConnectionSpy {
|
|
42
|
+
private events;
|
|
43
|
+
private node;
|
|
44
|
+
private listeners;
|
|
45
|
+
private isMonitoring;
|
|
46
|
+
constructor(node: oNode | oNodeTool);
|
|
47
|
+
/**
|
|
48
|
+
* Start monitoring connection events
|
|
49
|
+
*/
|
|
50
|
+
start(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Stop monitoring
|
|
53
|
+
*/
|
|
54
|
+
stop(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Clear all captured events
|
|
57
|
+
*/
|
|
58
|
+
clear(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get all captured events
|
|
61
|
+
*/
|
|
62
|
+
getEvents(): ConnectionEvent[];
|
|
63
|
+
/**
|
|
64
|
+
* Get events of a specific type
|
|
65
|
+
*/
|
|
66
|
+
getEventsByType(type: ConnectionEvent['type']): ConnectionEvent[];
|
|
67
|
+
/**
|
|
68
|
+
* Get events for a specific peer
|
|
69
|
+
*/
|
|
70
|
+
getEventsForPeer(peerId: string): ConnectionEvent[];
|
|
71
|
+
/**
|
|
72
|
+
* Get current connection statistics
|
|
73
|
+
*/
|
|
74
|
+
getConnectionStats(): ConnectionStats[];
|
|
75
|
+
/**
|
|
76
|
+
* Get total stream count across all connections
|
|
77
|
+
*/
|
|
78
|
+
getTotalStreamCount(): number;
|
|
79
|
+
/**
|
|
80
|
+
* Get stream count for a specific protocol
|
|
81
|
+
*/
|
|
82
|
+
getStreamCountByProtocol(protocol: string): number;
|
|
83
|
+
/**
|
|
84
|
+
* Check if a connection exists to a peer
|
|
85
|
+
*/
|
|
86
|
+
hasConnectionToPeer(peerId: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Get connection to a specific peer
|
|
89
|
+
*/
|
|
90
|
+
getConnectionToPeer(peerId: string): Connection | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Get all streams for a specific peer
|
|
93
|
+
*/
|
|
94
|
+
getStreamsForPeer(peerId: string): Stream[];
|
|
95
|
+
/**
|
|
96
|
+
* Wait for a specific event to occur
|
|
97
|
+
*/
|
|
98
|
+
waitForEvent(type: ConnectionEvent['type'], timeoutMs?: number): Promise<ConnectionEvent>;
|
|
99
|
+
/**
|
|
100
|
+
* Wait for connection to a specific peer
|
|
101
|
+
*/
|
|
102
|
+
waitForConnectionToPeer(peerId: string, timeoutMs?: number): Promise<Connection>;
|
|
103
|
+
/**
|
|
104
|
+
* Wait for stream count to reach expected value
|
|
105
|
+
*/
|
|
106
|
+
waitForStreamCount(expectedCount: number, timeoutMs?: number): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Get summary of connection activity
|
|
109
|
+
*/
|
|
110
|
+
getSummary(): {
|
|
111
|
+
totalEvents: number;
|
|
112
|
+
connectionOpens: number;
|
|
113
|
+
connectionCloses: number;
|
|
114
|
+
peerConnects: number;
|
|
115
|
+
peerDisconnects: number;
|
|
116
|
+
currentConnections: number;
|
|
117
|
+
currentStreams: number;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create a connection spy for a node
|
|
122
|
+
*/
|
|
123
|
+
export declare function createConnectionSpy(node: oNode | oNodeTool): ConnectionSpy;
|
|
124
|
+
//# sourceMappingURL=connection-spy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-spy.d.ts","sourceRoot":"","sources":["../../../test/helpers/connection-spy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spy that monitors libp2p connections and streams for testing
|
|
3
|
+
*/
|
|
4
|
+
export class ConnectionSpy {
|
|
5
|
+
constructor(node) {
|
|
6
|
+
this.events = [];
|
|
7
|
+
this.listeners = new Map();
|
|
8
|
+
this.isMonitoring = false;
|
|
9
|
+
this.node = node;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Start monitoring connection events
|
|
13
|
+
*/
|
|
14
|
+
start() {
|
|
15
|
+
if (this.isMonitoring) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.isMonitoring = true;
|
|
19
|
+
// Monitor peer events
|
|
20
|
+
const peerConnectListener = (event) => {
|
|
21
|
+
this.events.push({
|
|
22
|
+
type: 'peer:connect',
|
|
23
|
+
timestamp: Date.now(),
|
|
24
|
+
peerId: event.detail.toString(),
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
this.node.p2pNode.addEventListener('peer:connect', peerConnectListener);
|
|
28
|
+
this.listeners.set('peer:connect', peerConnectListener);
|
|
29
|
+
const peerDisconnectListener = (event) => {
|
|
30
|
+
this.events.push({
|
|
31
|
+
type: 'peer:disconnect',
|
|
32
|
+
timestamp: Date.now(),
|
|
33
|
+
peerId: event.detail.toString(),
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
this.node.p2pNode.addEventListener('peer:disconnect', peerDisconnectListener);
|
|
37
|
+
this.listeners.set('peer:disconnect', peerDisconnectListener);
|
|
38
|
+
// Monitor connection events
|
|
39
|
+
const connectionOpenListener = (event) => {
|
|
40
|
+
const connection = event.detail;
|
|
41
|
+
this.events.push({
|
|
42
|
+
type: 'connection:open',
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
peerId: connection.remotePeer.toString(),
|
|
45
|
+
remoteAddr: connection.remoteAddr.toString(),
|
|
46
|
+
metadata: {
|
|
47
|
+
status: connection.status,
|
|
48
|
+
direction: connection.direction,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
this.node.p2pNode.addEventListener('connection:open', connectionOpenListener);
|
|
53
|
+
this.listeners.set('connection:open', connectionOpenListener);
|
|
54
|
+
const connectionCloseListener = (event) => {
|
|
55
|
+
const connection = event.detail;
|
|
56
|
+
this.events.push({
|
|
57
|
+
type: 'connection:close',
|
|
58
|
+
timestamp: Date.now(),
|
|
59
|
+
peerId: connection.remotePeer.toString(),
|
|
60
|
+
remoteAddr: connection.remoteAddr.toString(),
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
this.node.p2pNode.addEventListener('connection:close', connectionCloseListener);
|
|
64
|
+
this.listeners.set('connection:close', connectionCloseListener);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Stop monitoring
|
|
68
|
+
*/
|
|
69
|
+
stop() {
|
|
70
|
+
if (!this.isMonitoring) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.isMonitoring = false;
|
|
74
|
+
for (const [event, listener] of this.listeners.entries()) {
|
|
75
|
+
this.node.p2pNode.removeEventListener(event, listener);
|
|
76
|
+
}
|
|
77
|
+
this.listeners.clear();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Clear all captured events
|
|
81
|
+
*/
|
|
82
|
+
clear() {
|
|
83
|
+
this.events = [];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get all captured events
|
|
87
|
+
*/
|
|
88
|
+
getEvents() {
|
|
89
|
+
return [...this.events];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get events of a specific type
|
|
93
|
+
*/
|
|
94
|
+
getEventsByType(type) {
|
|
95
|
+
return this.events.filter((e) => e.type === type);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get events for a specific peer
|
|
99
|
+
*/
|
|
100
|
+
getEventsForPeer(peerId) {
|
|
101
|
+
return this.events.filter((e) => e.peerId === peerId);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get current connection statistics
|
|
105
|
+
*/
|
|
106
|
+
getConnectionStats() {
|
|
107
|
+
const stats = [];
|
|
108
|
+
const connections = this.node.p2pNode.getConnections();
|
|
109
|
+
for (const conn of connections) {
|
|
110
|
+
const streamStats = conn.streams.map((stream) => ({
|
|
111
|
+
protocol: stream.protocol || 'unknown',
|
|
112
|
+
status: stream.status,
|
|
113
|
+
writeStatus: stream.writeStatus,
|
|
114
|
+
readStatus: stream.readStatus,
|
|
115
|
+
created: Date.now(), // Approximate
|
|
116
|
+
}));
|
|
117
|
+
stats.push({
|
|
118
|
+
peerId: conn.remotePeer.toString(),
|
|
119
|
+
status: conn.status,
|
|
120
|
+
remoteAddr: conn.remoteAddr.toString(),
|
|
121
|
+
streams: streamStats,
|
|
122
|
+
created: Date.now(), // Approximate
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return stats;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get total stream count across all connections
|
|
129
|
+
*/
|
|
130
|
+
getTotalStreamCount() {
|
|
131
|
+
const connections = this.node.p2pNode.getConnections();
|
|
132
|
+
return connections.reduce((sum, conn) => sum + conn.streams.length, 0);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get stream count for a specific protocol
|
|
136
|
+
*/
|
|
137
|
+
getStreamCountByProtocol(protocol) {
|
|
138
|
+
const connections = this.node.p2pNode.getConnections();
|
|
139
|
+
let count = 0;
|
|
140
|
+
for (const conn of connections) {
|
|
141
|
+
count += conn.streams.filter((s) => s.protocol === protocol).length;
|
|
142
|
+
}
|
|
143
|
+
return count;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check if a connection exists to a peer
|
|
147
|
+
*/
|
|
148
|
+
hasConnectionToPeer(peerId) {
|
|
149
|
+
const connections = this.node.p2pNode.getConnections();
|
|
150
|
+
return connections.some((conn) => conn.remotePeer.toString() === peerId);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get connection to a specific peer
|
|
154
|
+
*/
|
|
155
|
+
getConnectionToPeer(peerId) {
|
|
156
|
+
const connections = this.node.p2pNode.getConnections();
|
|
157
|
+
return connections.find((conn) => conn.remotePeer.toString() === peerId);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get all streams for a specific peer
|
|
161
|
+
*/
|
|
162
|
+
getStreamsForPeer(peerId) {
|
|
163
|
+
const connection = this.getConnectionToPeer(peerId);
|
|
164
|
+
return connection ? connection.streams : [];
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Wait for a specific event to occur
|
|
168
|
+
*/
|
|
169
|
+
async waitForEvent(type, timeoutMs = 5000) {
|
|
170
|
+
const startTime = Date.now();
|
|
171
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
172
|
+
const events = this.getEventsByType(type);
|
|
173
|
+
if (events.length > 0) {
|
|
174
|
+
return events[events.length - 1];
|
|
175
|
+
}
|
|
176
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
177
|
+
}
|
|
178
|
+
throw new Error(`Timeout waiting for event: ${type}`);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Wait for connection to a specific peer
|
|
182
|
+
*/
|
|
183
|
+
async waitForConnectionToPeer(peerId, timeoutMs = 5000) {
|
|
184
|
+
const startTime = Date.now();
|
|
185
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
186
|
+
const connection = this.getConnectionToPeer(peerId);
|
|
187
|
+
if (connection && connection.status === 'open') {
|
|
188
|
+
return connection;
|
|
189
|
+
}
|
|
190
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
191
|
+
}
|
|
192
|
+
throw new Error(`Timeout waiting for connection to peer: ${peerId}`);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Wait for stream count to reach expected value
|
|
196
|
+
*/
|
|
197
|
+
async waitForStreamCount(expectedCount, timeoutMs = 5000) {
|
|
198
|
+
const startTime = Date.now();
|
|
199
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
200
|
+
const currentCount = this.getTotalStreamCount();
|
|
201
|
+
if (currentCount === expectedCount) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
205
|
+
}
|
|
206
|
+
const actualCount = this.getTotalStreamCount();
|
|
207
|
+
throw new Error(`Timeout waiting for stream count. Expected: ${expectedCount}, Actual: ${actualCount}`);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get summary of connection activity
|
|
211
|
+
*/
|
|
212
|
+
getSummary() {
|
|
213
|
+
return {
|
|
214
|
+
totalEvents: this.events.length,
|
|
215
|
+
connectionOpens: this.getEventsByType('connection:open').length,
|
|
216
|
+
connectionCloses: this.getEventsByType('connection:close').length,
|
|
217
|
+
peerConnects: this.getEventsByType('peer:connect').length,
|
|
218
|
+
peerDisconnects: this.getEventsByType('peer:disconnect').length,
|
|
219
|
+
currentConnections: this.node.p2pNode.getConnections().length,
|
|
220
|
+
currentStreams: this.getTotalStreamCount(),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Create a connection spy for a node
|
|
226
|
+
*/
|
|
227
|
+
export function createConnectionSpy(node) {
|
|
228
|
+
return new ConnectionSpy(node);
|
|
229
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../test/helpers/index.ts"],"names":[],"mappings":"AAOA,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Test helpers barrel export
|
|
2
|
+
// These utilities are available for other packages during development and testing
|
|
3
|
+
// Core test environment and builders (moved from @olane/o-test)
|
|
4
|
+
// Note: Leader-related utilities have been removed to avoid circular dependencies
|
|
5
|
+
// with @olane/o-leader. Packages needing leader functionality should implement
|
|
6
|
+
// their own test utilities.
|
|
7
|
+
export * from './test-environment.js';
|
|
8
|
+
export * from './simple-node-builder.js';
|
|
9
|
+
// o-node specific helpers
|
|
10
|
+
export * from './network-builder.js';
|
|
11
|
+
export * from './connection-spy.js';
|
|
12
|
+
export * from './test-node.tool.js';
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { oNodeTool } from '../../src/o-node.tool.js';
|
|
2
|
+
import { oNodeAddress } from '../../src/router/o-node.address.js';
|
|
3
|
+
import { oNodeToolConfig } from '../../src/interfaces/o-node.tool-config.js';
|
|
4
|
+
import { oRequest } from '@olane/o-core';
|
|
5
|
+
import { Libp2pConfig } from '@olane/o-config';
|
|
6
|
+
/**
|
|
7
|
+
* Simple test tool for network communication testing
|
|
8
|
+
*/
|
|
9
|
+
export declare class TestTool extends oNodeTool {
|
|
10
|
+
callCount: number;
|
|
11
|
+
constructor(config: oNodeToolConfig & {
|
|
12
|
+
address: oNodeAddress;
|
|
13
|
+
});
|
|
14
|
+
configure(): Promise<Libp2pConfig>;
|
|
15
|
+
registerParent(): Promise<void>;
|
|
16
|
+
_tool_echo(request: oRequest): Promise<any>;
|
|
17
|
+
_tool_get_info(request: oRequest): Promise<any>;
|
|
18
|
+
_tool_stream(request: oRequest): AsyncGenerator<any>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for a node in the network
|
|
22
|
+
*/
|
|
23
|
+
export interface NodeConfig {
|
|
24
|
+
address: string;
|
|
25
|
+
parent?: string;
|
|
26
|
+
seed?: string;
|
|
27
|
+
disableHeartbeat?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Simplified network topology builder for testing node-to-node communication
|
|
31
|
+
* Focuses on peer connections and parent-child relationships without leader abstractions
|
|
32
|
+
*/
|
|
33
|
+
export declare class NetworkBuilder {
|
|
34
|
+
private nodes;
|
|
35
|
+
private startedNodes;
|
|
36
|
+
/**
|
|
37
|
+
* Add a node to the network
|
|
38
|
+
* If parentAddress is provided, the node will register as a child
|
|
39
|
+
*/
|
|
40
|
+
addNode(address: string, parentAddress?: string, config?: Partial<NodeConfig>): Promise<TestTool>;
|
|
41
|
+
/**
|
|
42
|
+
* Start a specific node
|
|
43
|
+
*/
|
|
44
|
+
startNode(address: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Stop a specific node
|
|
47
|
+
*/
|
|
48
|
+
stopNode(address: string): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Stop all nodes in the network
|
|
51
|
+
* Stops in reverse dependency order: children first, then parents
|
|
52
|
+
*/
|
|
53
|
+
stopAll(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Get a node by address
|
|
56
|
+
*/
|
|
57
|
+
getNode(address: string): TestTool | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Get all nodes
|
|
60
|
+
*/
|
|
61
|
+
getAllNodes(): Map<string, TestTool>;
|
|
62
|
+
/**
|
|
63
|
+
* Sort nodes by hierarchy depth (root nodes first)
|
|
64
|
+
*/
|
|
65
|
+
private getSortedNodesByDepth;
|
|
66
|
+
/**
|
|
67
|
+
* Wait for a node to have transports available
|
|
68
|
+
*/
|
|
69
|
+
private waitForTransports;
|
|
70
|
+
/**
|
|
71
|
+
* Clean up all nodes
|
|
72
|
+
*/
|
|
73
|
+
cleanup(): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Quick network topology builders for common test scenarios
|
|
77
|
+
* All topologies use simple parent-child relationships without leader abstractions
|
|
78
|
+
* Note: "leader" in address names is just a convention, not a special node type
|
|
79
|
+
*/
|
|
80
|
+
export declare class NetworkTopologies {
|
|
81
|
+
/**
|
|
82
|
+
* Create a simple two-node network (parent-child)
|
|
83
|
+
* Addresses: o://leader (root), o://child
|
|
84
|
+
*/
|
|
85
|
+
static twoNode(): Promise<NetworkBuilder>;
|
|
86
|
+
/**
|
|
87
|
+
* Create a three-node hierarchy (leader → parent → child)
|
|
88
|
+
* Addresses: o://leader (root), o://parent, o://child
|
|
89
|
+
*/
|
|
90
|
+
static threeNode(): Promise<NetworkBuilder>;
|
|
91
|
+
/**
|
|
92
|
+
* Create a five-node hierarchy with two branches
|
|
93
|
+
* Structure: leader → parent1 → child1, child2
|
|
94
|
+
* → parent2
|
|
95
|
+
*/
|
|
96
|
+
static fiveNode(): Promise<NetworkBuilder>;
|
|
97
|
+
/**
|
|
98
|
+
* Create two standalone nodes (peer-to-peer)
|
|
99
|
+
*/
|
|
100
|
+
static twoStandalone(): Promise<NetworkBuilder>;
|
|
101
|
+
/**
|
|
102
|
+
* Create a complex hierarchy for integration testing
|
|
103
|
+
* Structure: leader → parent1 → child1, child2
|
|
104
|
+
* → parent2 → child3, child4
|
|
105
|
+
* → parent3 → child5, child6
|
|
106
|
+
*/
|
|
107
|
+
static complex(): Promise<NetworkBuilder>;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=network-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-builder.d.ts","sourceRoot":"","sources":["../../../test/helpers/network-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;GAEG;AACH,qBAAa,QAAS,SAAQ,SAAS;IAC9B,SAAS,SAAK;gBAET,MAAM,EAAE,eAAe,GAAG;QAAE,OAAO,EAAE,YAAY,CAAA;KAAE;IAIzD,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAelC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC/B,UAAU,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAS3C,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAS9C,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC;CAY5D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,YAAY,CAA0B;IAE9C;;;OAGG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,MAAM,GAAE,OAAO,CAAC,UAAU,CAAM,GAC/B,OAAO,CAAC,QAAQ,CAAC;IAqCpB;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB/C;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9C;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9B;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI9C;;OAEG;IACH,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC;IAIpC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyC7B;;OAEG;YACW,iBAAiB;IAkB/B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B;;;OAGG;WACU,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IAO/C;;;OAGG;WACU,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IAQjD;;;;OAIG;WACU,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAUhD;;OAEG;WACU,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC;IAOrD;;;;;OAKG;WACU,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;CAmBhD"}
|