Skip to content

Commit 78921b9

Browse files
chore: add interop tests (#194)
* chore: add interop tests * chore: update @libp2p/interop version * fix depcheck Co-authored-by: Cayman <caymannava@gmail.com>
1 parent aa85698 commit 78921b9

3 files changed

Lines changed: 138 additions & 2 deletions

File tree

.github/workflows/js-test-and-release.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,19 @@ jobs:
130130
directory: ./.nyc_output
131131
flags: electron-renderer
132132

133+
test-interop:
134+
needs: check
135+
runs-on: ubuntu-latest
136+
steps:
137+
- uses: actions/checkout@v2
138+
- uses: actions/setup-node@v2
139+
with:
140+
node-version: lts/*
141+
- uses: ipfs/aegir/actions/cache-node-modules@master
142+
- run: npm run test:interop -- --bail
143+
133144
release:
134-
needs: [test-node, test-chrome, test-chrome-webworker, test-firefox, test-firefox-webworker, test-electron-main, test-electron-renderer]
145+
needs: [test-node, test-chrome, test-chrome-webworker, test-firefox, test-firefox-webworker, test-electron-main, test-electron-renderer, test-interop]
135146
runs-on: ubuntu-latest
136147
if: github.event_name == 'push' && github.ref == 'refs/heads/master' # with #262 - 'refs/heads/${{{ github.default_branch }}}'
137148
steps:

package.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"test:node": "aegir test -t node",
6262
"test:browser": "aegir test -t browser -t webworker",
6363
"test:electron-main": "aegir test -t electron-main",
64+
"test:interop": "aegir test -t node -f dist/test/interop.js",
6465
"docs": "aegir docs",
6566
"proto:gen": "protons ./src/proto/payload.proto",
6667
"prepublish": "npm run build"
@@ -78,20 +79,30 @@
7879
"@stablelib/x25519": "^1.0.1",
7980
"it-length-prefixed": "^8.0.2",
8081
"it-pair": "^2.0.2",
81-
"it-stream-types": "^1.0.4",
8282
"it-pb-stream": "^2.0.2",
8383
"it-pipe": "^2.0.3",
84+
"it-stream-types": "^1.0.4",
8485
"protons-runtime": "^3.1.0",
8586
"uint8arraylist": "^2.3.2",
8687
"uint8arrays": "^3.1.0"
8788
},
8889
"devDependencies": {
90+
"@libp2p/daemon-client": "2.0.3",
91+
"@libp2p/daemon-server": "^2.0.4",
8992
"@libp2p/interface-connection-encrypter-compliance-tests": "^2.0.1",
93+
"@libp2p/interop": "^2.1.0",
94+
"@libp2p/mplex": "^5.0.0",
9095
"@libp2p/peer-id-factory": "^1.0.8",
96+
"@libp2p/tcp": "^3.0.3",
97+
"@multiformats/multiaddr": "^10.3.3",
9198
"aegir": "^37.3.0",
9299
"benchmark": "^2.1.4",
100+
"execa": "^6.1.0",
101+
"go-libp2p": "^0.0.6",
93102
"iso-random-stream": "^2.0.2",
103+
"libp2p": "0.37.3-f439d9b",
94104
"mkdirp": "^1.0.4",
105+
"p-defer": "^4.0.0",
95106
"protons": "^5.1.0",
96107
"sinon": "^14.0.0",
97108
"util": "^0.12.4"

test/interop.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { connectInteropTests } from '@libp2p/interop'
2+
import type { SpawnOptions, Daemon, DaemonFactory } from '@libp2p/interop'
3+
import { createServer } from '@libp2p/daemon-server'
4+
import { createClient } from '@libp2p/daemon-client'
5+
import { createLibp2p, Libp2pOptions } from 'libp2p'
6+
import { TCP } from '@libp2p/tcp'
7+
import { Multiaddr } from '@multiformats/multiaddr'
8+
import { path as p2pd } from 'go-libp2p'
9+
import { execa } from 'execa'
10+
import pDefer from 'p-defer'
11+
import { logger } from '@libp2p/logger'
12+
import { Mplex } from '@libp2p/mplex'
13+
import fs from 'fs'
14+
import { unmarshalPrivateKey } from '@libp2p/crypto/keys'
15+
import type { PeerId } from '@libp2p/interface-peer-id'
16+
import { peerIdFromKeys } from '@libp2p/peer-id'
17+
import { Noise } from '../src/index.js'
18+
19+
async function createGoPeer (options: SpawnOptions): Promise<Daemon> {
20+
const controlPort = Math.floor(Math.random() * (50000 - 10000 + 1)) + 10000
21+
const apiAddr = new Multiaddr(`/ip4/0.0.0.0/tcp/${controlPort}`)
22+
23+
const log = logger(`go-libp2p:${controlPort}`)
24+
25+
const opts = [
26+
`-listen=${apiAddr.toString()}`,
27+
'-hostAddrs=/ip4/0.0.0.0/tcp/0'
28+
]
29+
30+
if (options.noise === true) {
31+
opts.push('-noise=true')
32+
}
33+
34+
if (options.key != null) {
35+
opts.push(`-id=${options.key}`)
36+
}
37+
38+
const deferred = pDefer()
39+
const proc = execa(p2pd(), opts)
40+
41+
proc.stdout?.on('data', (buf: Buffer) => {
42+
const str = buf.toString()
43+
log(str)
44+
45+
// daemon has started
46+
if (str.includes('Control socket:')) {
47+
deferred.resolve()
48+
}
49+
})
50+
51+
proc.stderr?.on('data', (buf) => {
52+
log.error(buf.toString())
53+
})
54+
55+
await deferred.promise
56+
57+
return {
58+
client: createClient(apiAddr),
59+
stop: async () => {
60+
await proc.kill()
61+
}
62+
}
63+
}
64+
65+
async function createJsPeer (options: SpawnOptions): Promise<Daemon> {
66+
let peerId: PeerId | undefined
67+
68+
if (options.key != null) {
69+
const keyFile = fs.readFileSync(options.key)
70+
const privateKey = await unmarshalPrivateKey(keyFile)
71+
peerId = await peerIdFromKeys(privateKey.public.bytes, privateKey.bytes)
72+
}
73+
74+
const opts: Libp2pOptions = {
75+
peerId,
76+
addresses: {
77+
listen: ['/ip4/0.0.0.0/tcp/0']
78+
},
79+
transports: [new TCP()],
80+
streamMuxers: [new Mplex()],
81+
connectionEncryption: [new Noise()]
82+
}
83+
84+
const node = await createLibp2p(opts)
85+
const server = await createServer(new Multiaddr('/ip4/0.0.0.0/tcp/0'), node as any)
86+
await server.start()
87+
88+
return {
89+
client: createClient(server.getMultiaddr()),
90+
stop: async () => {
91+
await server.stop()
92+
await node.stop()
93+
}
94+
}
95+
}
96+
97+
async function main (): Promise<void> {
98+
const factory: DaemonFactory = {
99+
async spawn (options: SpawnOptions) {
100+
if (options.type === 'go') {
101+
return await createGoPeer(options)
102+
}
103+
104+
return await createJsPeer(options)
105+
}
106+
}
107+
108+
await connectInteropTests(factory)
109+
}
110+
111+
main().catch(err => {
112+
console.error(err) // eslint-disable-line no-console
113+
process.exit(1)
114+
})

0 commit comments

Comments
 (0)