@libp2p/interop 2.1.0 → 3.0.0

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.
@@ -1,6 +1,7 @@
1
1
  import { connectTests } from './connect.js';
2
2
  import { dhtTests } from './dht/index.js';
3
3
  import { pubsubTests } from './pubsub/index.js';
4
+ import { streamTests } from './streams/index.js';
4
5
  import type { DaemonClient } from '@libp2p/daemon-client';
5
6
  export interface Daemon {
6
7
  stop: () => Promise<void>;
@@ -8,17 +9,20 @@ export interface Daemon {
8
9
  }
9
10
  export declare type NodeType = 'js' | 'go';
10
11
  export declare type PeerIdType = 'rsa' | 'ed25519' | 'secp256k1';
12
+ export declare type PubSubRouter = 'gossipsub' | 'floodsub';
13
+ export declare type Muxer = 'mplex' | 'yamux';
11
14
  export interface SpawnOptions {
12
15
  type: NodeType;
13
16
  key?: string;
14
17
  noise?: true;
15
18
  dht?: boolean;
16
19
  pubsub?: boolean;
17
- pubsubRouter?: 'gossipsub' | 'floodsub';
20
+ pubsubRouter?: PubSubRouter;
21
+ muxer?: Muxer;
18
22
  }
19
23
  export interface DaemonFactory {
20
24
  spawn: (options: SpawnOptions) => Promise<Daemon>;
21
25
  }
22
26
  export declare function interopTests(factory: DaemonFactory): Promise<void>;
23
- export { connectTests as connectInteropTests, dhtTests as dhtInteropTests, pubsubTests as pubsubInteropTests };
27
+ export { connectTests as connectInteropTests, dhtTests as dhtInteropTests, pubsubTests as pubsubInteropTests, streamTests as streamInteropTests };
24
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,MAAM,EAAE,YAAY,CAAA;CACrB;AAED,oBAAY,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAA;AAClC,oBAAY,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,CAAA;AAExD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,WAAW,GAAG,UAAU,CAAA;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAClD;AAED,wBAAsB,YAAY,CAAE,OAAO,EAAE,aAAa,iBAIzD;AAED,OAAO,EACL,YAAY,IAAI,mBAAmB,EACnC,QAAQ,IAAI,eAAe,EAC3B,WAAW,IAAI,kBAAkB,EAClC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,MAAM,EAAE,YAAY,CAAA;CACrB;AAED,oBAAY,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAA;AAClC,oBAAY,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,CAAA;AACxD,oBAAY,YAAY,GAAG,WAAW,GAAG,UAAU,CAAA;AACnD,oBAAY,KAAK,GAAG,OAAO,GAAG,OAAO,CAAA;AAErC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAClD;AAED,wBAAsB,YAAY,CAAE,OAAO,EAAE,aAAa,iBAKzD;AAED,OAAO,EACL,YAAY,IAAI,mBAAmB,EACnC,QAAQ,IAAI,eAAe,EAC3B,WAAW,IAAI,kBAAkB,EACjC,WAAW,IAAI,kBAAkB,EAClC,CAAA"}
package/dist/src/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { connectTests } from './connect.js';
2
2
  import { dhtTests } from './dht/index.js';
3
3
  import { pubsubTests } from './pubsub/index.js';
4
+ import { streamTests } from './streams/index.js';
4
5
  export async function interopTests(factory) {
5
6
  await connectTests(factory);
6
7
  await dhtTests(factory);
7
8
  await pubsubTests(factory);
9
+ await streamTests(factory);
8
10
  }
9
- export { connectTests as connectInteropTests, dhtTests as dhtInteropTests, pubsubTests as pubsubInteropTests };
11
+ export { connectTests as connectInteropTests, dhtTests as dhtInteropTests, pubsubTests as pubsubInteropTests, streamTests as streamInteropTests };
10
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAwB/C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAE,OAAsB;IACxD,MAAM,YAAY,CAAC,OAAO,CAAC,CAAA;IAC3B,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;IACvB,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED,OAAO,EACL,YAAY,IAAI,mBAAmB,EACnC,QAAQ,IAAI,eAAe,EAC3B,WAAW,IAAI,kBAAkB,EAClC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AA2BhD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAE,OAAsB;IACxD,MAAM,YAAY,CAAC,OAAO,CAAC,CAAA;IAC3B,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;IACvB,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,WAAW,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED,OAAO,EACL,YAAY,IAAI,mBAAmB,EACnC,QAAQ,IAAI,eAAe,EAC3B,WAAW,IAAI,kBAAkB,EACjC,WAAW,IAAI,kBAAkB,EAClC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { DaemonFactory, Muxer } from '../index.js';
2
+ export declare function echoStreamTests(factory: DaemonFactory, muxer: Muxer): void;
3
+ //# sourceMappingURL=echo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../../../src/streams/echo.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,aAAa,EAAE,KAAK,EAA0B,MAAM,aAAa,CAAA;AAMvF,wBAAgB,eAAe,CAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,QAapE"}
@@ -0,0 +1,65 @@
1
+ /* eslint-env mocha */
2
+ import { expect } from 'aegir/chai';
3
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
4
+ import { pipe } from 'it-pipe';
5
+ import all from 'it-all';
6
+ import defer from 'p-defer';
7
+ export function echoStreamTests(factory, muxer) {
8
+ const nodeTypes = ['js', 'go'];
9
+ for (const typeA of nodeTypes) {
10
+ for (const typeB of nodeTypes) {
11
+ runEchoStreamTests(factory, muxer, { type: typeA, muxer }, { type: typeB, muxer });
12
+ }
13
+ }
14
+ }
15
+ function runEchoStreamTests(factory, muxer, optionsA, optionsB) {
16
+ describe(`echo streams - ${muxer}`, () => {
17
+ let daemons;
18
+ // Start Daemons
19
+ before(async function () {
20
+ this.timeout(20 * 1000);
21
+ daemons = await Promise.all([
22
+ factory.spawn(optionsA),
23
+ factory.spawn(optionsB)
24
+ ]);
25
+ // connect them
26
+ const identify0 = await daemons[0].client.identify();
27
+ await daemons[1].client.connect(identify0.peerId, identify0.addrs);
28
+ // jsDaemon1 will take some time to get the peers
29
+ await new Promise(resolve => setTimeout(resolve, 1000));
30
+ });
31
+ // Stop daemons
32
+ after(async function () {
33
+ if (daemons != null) {
34
+ await Promise.all(daemons.map(async (daemon) => await daemon.stop()));
35
+ }
36
+ });
37
+ it(`${optionsA.type} sender to ${optionsB.type} listener`, async function () {
38
+ this.timeout(10 * 1000);
39
+ const receivingIdentity = await daemons[1].client.identify();
40
+ const protocol = '/echo/1.0.0';
41
+ const input = [uint8ArrayFromString('hello world')];
42
+ await daemons[1].client.registerStreamHandler(protocol, async (stream) => {
43
+ await pipe(stream, async function* (source) {
44
+ for await (const buf of source) {
45
+ yield buf.subarray();
46
+ }
47
+ }, stream);
48
+ });
49
+ const stream = await daemons[0].client.openStream(receivingIdentity.peerId, protocol);
50
+ // without this the socket can close before we receive a response
51
+ const responseReceived = defer();
52
+ const output = await pipe(input, async function* (source) {
53
+ yield* source;
54
+ await responseReceived.promise;
55
+ }, stream, async function* (source) {
56
+ for await (const buf of source) {
57
+ yield buf.subarray();
58
+ responseReceived.resolve();
59
+ }
60
+ }, async (source) => await all(source));
61
+ expect(output).to.deep.equal(input);
62
+ });
63
+ });
64
+ }
65
+ //# sourceMappingURL=echo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"echo.js","sourceRoot":"","sources":["../../../src/streams/echo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DaemonFactory } from '../index.js';
2
+ export declare function streamTests(factory: DaemonFactory): Promise<void>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/streams/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,wBAAsB,WAAW,CAAE,OAAO,EAAE,aAAa,iBAGxD"}
@@ -0,0 +1,6 @@
1
+ import { echoStreamTests } from './echo.js';
2
+ export async function streamTests(factory) {
3
+ await echoStreamTests(factory, 'mplex');
4
+ await echoStreamTests(factory, 'yamux');
5
+ }
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/streams/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAG3C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAE,OAAsB;IACvD,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACvC,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/interop",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Interoperability Tests for libp2p",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/interop#readme",
@@ -128,14 +128,16 @@
128
128
  "release": "aegir release"
129
129
  },
130
130
  "dependencies": {
131
- "@libp2p/daemon-client": "^2.0.1",
131
+ "@libp2p/daemon-client": "^3.0.0",
132
132
  "@libp2p/interface-peer-info": "^1.0.1",
133
133
  "@libp2p/logger": "^2.0.0",
134
134
  "@libp2p/peer-id": "^1.1.8",
135
135
  "@multiformats/multiaddr": "^10.1.8",
136
136
  "it-all": "^1.0.6",
137
137
  "it-first": "^1.0.7",
138
+ "it-pipe": "^2.0.4",
138
139
  "multiformats": "^9.4.5",
140
+ "p-defer": "^4.0.0",
139
141
  "p-retry": "^5.1.0",
140
142
  "uint8arrays": "^3.0.0"
141
143
  },
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { connectTests } from './connect.js'
2
2
  import { dhtTests } from './dht/index.js'
3
3
  import { pubsubTests } from './pubsub/index.js'
4
+ import { streamTests } from './streams/index.js'
4
5
  import type { DaemonClient } from '@libp2p/daemon-client'
5
6
 
6
7
  export interface Daemon {
@@ -10,6 +11,8 @@ export interface Daemon {
10
11
 
11
12
  export type NodeType = 'js' | 'go'
12
13
  export type PeerIdType = 'rsa' | 'ed25519' | 'secp256k1'
14
+ export type PubSubRouter = 'gossipsub' | 'floodsub'
15
+ export type Muxer = 'mplex' | 'yamux'
13
16
 
14
17
  export interface SpawnOptions {
15
18
  type: NodeType
@@ -17,7 +20,8 @@ export interface SpawnOptions {
17
20
  noise?: true
18
21
  dht?: boolean
19
22
  pubsub?: boolean
20
- pubsubRouter?: 'gossipsub' | 'floodsub'
23
+ pubsubRouter?: PubSubRouter
24
+ muxer?: Muxer
21
25
  }
22
26
 
23
27
  export interface DaemonFactory {
@@ -28,10 +32,12 @@ export async function interopTests (factory: DaemonFactory) {
28
32
  await connectTests(factory)
29
33
  await dhtTests(factory)
30
34
  await pubsubTests(factory)
35
+ await streamTests(factory)
31
36
  }
32
37
 
33
38
  export {
34
39
  connectTests as connectInteropTests,
35
40
  dhtTests as dhtInteropTests,
36
- pubsubTests as pubsubInteropTests
41
+ pubsubTests as pubsubInteropTests,
42
+ streamTests as streamInteropTests
37
43
  }
@@ -0,0 +1,99 @@
1
+ /* eslint-env mocha */
2
+
3
+ import { expect } from 'aegir/chai'
4
+ import type { Daemon, DaemonFactory, Muxer, NodeType, SpawnOptions } from '../index.js'
5
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
6
+ import { pipe } from 'it-pipe'
7
+ import all from 'it-all'
8
+ import defer from 'p-defer'
9
+
10
+ export function echoStreamTests (factory: DaemonFactory, muxer: Muxer) {
11
+ const nodeTypes: NodeType[] = ['js', 'go']
12
+
13
+ for (const typeA of nodeTypes) {
14
+ for (const typeB of nodeTypes) {
15
+ runEchoStreamTests(
16
+ factory,
17
+ muxer,
18
+ { type: typeA, muxer },
19
+ { type: typeB, muxer }
20
+ )
21
+ }
22
+ }
23
+ }
24
+
25
+ function runEchoStreamTests (factory: DaemonFactory, muxer: Muxer, optionsA: SpawnOptions, optionsB: SpawnOptions) {
26
+ describe(`echo streams - ${muxer}`, () => {
27
+ let daemons: Daemon[]
28
+
29
+ // Start Daemons
30
+ before(async function () {
31
+ this.timeout(20 * 1000)
32
+
33
+ daemons = await Promise.all([
34
+ factory.spawn(optionsA),
35
+ factory.spawn(optionsB)
36
+ ])
37
+
38
+ // connect them
39
+ const identify0 = await daemons[0].client.identify()
40
+
41
+ await daemons[1].client.connect(identify0.peerId, identify0.addrs)
42
+
43
+ // jsDaemon1 will take some time to get the peers
44
+ await new Promise(resolve => setTimeout(resolve, 1000))
45
+ })
46
+
47
+ // Stop daemons
48
+ after(async function () {
49
+ if (daemons != null) {
50
+ await Promise.all(
51
+ daemons.map(async (daemon) => await daemon.stop())
52
+ )
53
+ }
54
+ })
55
+
56
+ it(`${optionsA.type} sender to ${optionsB.type} listener`, async function () {
57
+ this.timeout(10 * 1000)
58
+
59
+ const receivingIdentity = await daemons[1].client.identify()
60
+ const protocol = '/echo/1.0.0'
61
+ const input = [uint8ArrayFromString('hello world')]
62
+
63
+ await daemons[1].client.registerStreamHandler(protocol, async (stream) => {
64
+ await pipe(
65
+ stream,
66
+ async function * (source) {
67
+ for await (const buf of source) {
68
+ yield buf.subarray()
69
+ }
70
+ },
71
+ stream
72
+ )
73
+ })
74
+
75
+ const stream = await daemons[0].client.openStream(receivingIdentity.peerId, protocol)
76
+
77
+ // without this the socket can close before we receive a response
78
+ const responseReceived = defer()
79
+
80
+ const output = await pipe(
81
+ input,
82
+ async function * (source) {
83
+ yield * source
84
+ await responseReceived.promise
85
+ },
86
+ stream,
87
+ async function * (source) {
88
+ for await (const buf of source) {
89
+ yield buf.subarray()
90
+ responseReceived.resolve()
91
+ }
92
+ },
93
+ async (source) => await all(source)
94
+ )
95
+
96
+ expect(output).to.deep.equal(input)
97
+ })
98
+ })
99
+ }
@@ -0,0 +1,7 @@
1
+ import { echoStreamTests } from './echo.js'
2
+ import type { DaemonFactory } from '../index.js'
3
+
4
+ export async function streamTests (factory: DaemonFactory) {
5
+ await echoStreamTests(factory, 'mplex')
6
+ await echoStreamTests(factory, 'yamux')
7
+ }