Skip to content

Commit 6850cd2

Browse files
committed
chore: add test setup for node tests and test for auto-relay
1 parent 61b89ae commit 6850cd2

File tree

8 files changed

+307
-4
lines changed

8 files changed

+307
-4
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,12 @@ jobs:
4646
- npm install
4747
- LIBP2P_JS=${TRAVIS_BUILD_DIR}/src/index.js npx aegir test -t node --bail
4848

49+
- stage: test
50+
name: example - auto-relay
51+
script:
52+
- cd examples
53+
- npm install
54+
- npm run test -- auto-relay
55+
4956
notifications:
5057
email: false

examples/auto-relay/test.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
'use strict'
2+
3+
const path = require('path')
4+
const execa = require('execa')
5+
const pDefer = require('p-defer')
6+
const uint8ArrayToString = require('uint8arrays/to-string')
7+
8+
function startProcess (name, args = []) {
9+
return execa('node', [path.join(__dirname, name), ...args], {
10+
cwd: path.resolve(__dirname),
11+
all: true
12+
})
13+
}
14+
15+
async function test () {
16+
let output1 = ''
17+
let output2 = ''
18+
let output3 = ''
19+
let relayAddr
20+
let autoRelayAddr
21+
22+
const proc1Ready = pDefer()
23+
const proc2Ready = pDefer()
24+
25+
// Step 1 process
26+
process.stdout.write('relay.js\n')
27+
28+
const proc1 = startProcess('relay.js')
29+
proc1.all.on('data', async (data) => {
30+
process.stdout.write(data)
31+
32+
output1 += uint8ArrayToString(data)
33+
34+
if (output1.includes('Listening on:') && output1.includes('/p2p/')) {
35+
relayAddr = output1.trim().split('Listening on:\n')[1].split('\n')[0]
36+
proc1Ready.resolve()
37+
}
38+
})
39+
40+
await proc1Ready.promise
41+
process.stdout.write('==================================================================\n')
42+
43+
// Step 2 process
44+
process.stdout.write('auto-relay.js\n')
45+
46+
const proc2 = startProcess('auto-relay.js', [relayAddr])
47+
proc2.all.on('data', async (data) => {
48+
process.stdout.write(data)
49+
50+
output2 += uint8ArrayToString(data)
51+
52+
if (output2.includes('Listening on:') && output2.includes('/p2p/')) {
53+
autoRelayAddr = output2.trim().split('Listening on:\n')[1]
54+
proc2Ready.resolve()
55+
}
56+
})
57+
58+
await proc2Ready.promise
59+
process.stdout.write('==================================================================\n')
60+
61+
// Step 3 process
62+
process.stdout.write('other-node.js\n')
63+
64+
const proc3 = startProcess('other-node.js', [autoRelayAddr])
65+
proc3.all.on('data', async (data) => {
66+
process.stdout.write(data)
67+
68+
output3 += uint8ArrayToString(data)
69+
70+
if (output3.includes('Connected to the auto relay node via')) {
71+
const remoteAddr = output3.trim().split('Connected to the auto relay node via ')[1]
72+
73+
if (remoteAddr === autoRelayAddr) {
74+
proc3.kill()
75+
proc2.kill()
76+
proc1.kill()
77+
} else {
78+
throw new Error('other-node did not dial through the relay')
79+
}
80+
}
81+
})
82+
83+
await Promise.all([
84+
proc1,
85+
proc2,
86+
proc3
87+
]).catch((err) => {
88+
if (err.signal !== 'SIGTERM') {
89+
throw err
90+
}
91+
})
92+
}
93+
94+
module.exports = test

examples/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "libp2p-examples",
3+
"version": "1.0.0",
4+
"description": "Examples of how to use libp2p",
5+
"scripts": {
6+
"test": "node ./test.js",
7+
"test:all": "node ./test-all.js"
8+
},
9+
"license": "MIT",
10+
"dependencies": {
11+
"execa": "^2.1.0",
12+
"fs-extra": "^8.1.0",
13+
"p-defer": "^3.0.0",
14+
"which": "^2.0.1"
15+
}
16+
}

examples/test-all.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict'
2+
3+
process.on('unhandedRejection', (err) => {
4+
console.error(err)
5+
6+
process.exit(1)
7+
})
8+
9+
const path = require('path')
10+
const fs = require('fs')
11+
const {
12+
waitForOutput
13+
} = require('./utils')
14+
15+
async function testAll () {
16+
for (const dir of fs.readdirSync(__dirname)) {
17+
if (dir === 'node_modules' || dir === 'tests_output') {
18+
continue
19+
}
20+
21+
const stats = fs.statSync(path.join(__dirname, dir))
22+
23+
if (!stats.isDirectory()) {
24+
continue
25+
}
26+
27+
await waitForOutput('npm info ok', 'npm', ['test', '--', dir], {
28+
cwd: __dirname
29+
})
30+
}
31+
}
32+
33+
testAll()

examples/test.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
'use strict'
2+
3+
process.env.NODE_ENV = 'test'
4+
process.env.CI = true // needed for some "clever" build tools
5+
6+
const fs = require('fs-extra')
7+
const path = require('path')
8+
const execa = require('execa')
9+
const dir = path.join(__dirname, process.argv[2])
10+
11+
testExample(dir)
12+
.then(() => {}, (err) => {
13+
if (err.exitCode) {
14+
process.exit(err.exitCode)
15+
}
16+
17+
console.error(err)
18+
process.exit(1)
19+
})
20+
21+
async function testExample (dir) {
22+
await installDeps(dir)
23+
await build(dir)
24+
await runTest(dir)
25+
// TODO: add browser test setup
26+
}
27+
28+
async function installDeps (dir) {
29+
if (!fs.existsSync(path.join(dir, 'package.json'))) {
30+
console.info('Nothing to install in', dir)
31+
return
32+
}
33+
34+
if (fs.existsSync(path.join(dir, 'node_modules'))) {
35+
console.info('Dependencies already installed in', dir)
36+
return
37+
}
38+
39+
const proc = execa.command('npm install', {
40+
cwd: dir
41+
})
42+
proc.all.on('data', (data) => {
43+
process.stdout.write(data)
44+
})
45+
46+
await proc
47+
}
48+
49+
async function build (dir) {
50+
const pkgJson = path.join(dir, 'package.json')
51+
52+
if (!fs.existsSync(pkgJson)) {
53+
console.info('Nothing to build in', dir)
54+
return
55+
}
56+
57+
const pkg = require(pkgJson)
58+
let build
59+
60+
if (pkg.scripts.bundle) {
61+
build = 'bundle'
62+
}
63+
64+
if (pkg.scripts.build) {
65+
build = 'build'
66+
}
67+
68+
if (!build) {
69+
console.info('No "build" or "bundle" script in', pkgJson)
70+
return
71+
}
72+
73+
const proc = execa('npm', ['run', build], {
74+
cwd: dir
75+
})
76+
proc.all.on('data', (data) => {
77+
process.stdout.write(data)
78+
})
79+
80+
await proc
81+
}
82+
83+
async function runTest (dir) {
84+
console.info('Running node tests in', dir)
85+
const testFile = path.join(dir, 'test.js')
86+
87+
if (!fs.existsSync(testFile)) {
88+
console.info('Nothing to test in', dir)
89+
return
90+
}
91+
92+
const runTest = require(testFile)
93+
94+
await runTest()
95+
}

examples/utils.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict'
2+
3+
const execa = require('execa')
4+
const fs = require('fs-extra')
5+
const which = require('which')
6+
7+
async function isExecutable (command) {
8+
try {
9+
await fs.access(command, fs.constants.X_OK)
10+
11+
return true
12+
} catch (err) {
13+
if (err.code === 'ENOENT') {
14+
return isExecutable(await which(command))
15+
}
16+
17+
if (err.code === 'EACCES') {
18+
return false
19+
}
20+
21+
throw err
22+
}
23+
}
24+
25+
async function waitForOutput (expectedOutput, command, args = [], opts = {}) {
26+
if (!await isExecutable(command)) {
27+
args.unshift(command)
28+
command = 'node'
29+
}
30+
31+
const proc = execa(command, args, opts)
32+
let output = ''
33+
let time = 120000
34+
35+
let timeout = setTimeout(() => {
36+
throw new Error(`Did not see "${expectedOutput}" in output from "${[command].concat(args).join(' ')}" after ${time/1000}s`)
37+
}, time)
38+
39+
proc.all.on('data', (data) => {
40+
process.stdout.write(data)
41+
42+
output += data.toString('utf8')
43+
44+
if (output.includes(expectedOutput)) {
45+
clearTimeout(timeout)
46+
proc.kill()
47+
}
48+
})
49+
50+
try {
51+
await proc
52+
} catch (err) {
53+
if (!err.killed) {
54+
throw err
55+
}
56+
}
57+
}
58+
59+
module.exports = {
60+
waitForOutput
61+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"test": "npm run test:node && npm run test:browser",
1515
"test:node": "aegir test -t node -f \"./test/**/*.{node,spec}.js\"",
1616
"test:browser": "aegir test -t browser",
17+
"test:examples": "cd examples && npm run test:all",
1718
"release": "aegir release -t node -t browser",
1819
"release-minor": "aegir release --type minor -t node -t browser",
1920
"release-major": "aegir release --type major -t node -t browser",

src/circuit/transport.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,7 @@ class Circuit {
159159
*
160160
* @param {any} options
161161
* @param {Function} handler
162-
<<<<<<< HEAD
163162
* @returns {listener}
164-
=======
165-
* @return {listener}
166-
>>>>>>> feat: auto relay network query for new relays
167163
*/
168164
createListener (options, handler) {
169165
if (typeof options === 'function') {

0 commit comments

Comments
 (0)