Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

teardown test #416

Closed
wants to merge 19 commits into from
180 changes: 90 additions & 90 deletions test/02-teardown.test.js
Original file line number Diff line number Diff line change
@@ -1,149 +1,149 @@
'use strict'
const { isWindows } = require('which-runtime')
const test = require('brittle')
const path = require('bare-path')
const os = require('bare-os')
const hypercoreid = require('hypercore-id-encoding')
const Helper = require('./helper')
const harness = path.join(Helper.localDir, 'test', 'fixtures', 'harness')
const teardownDir = path.join(Helper.localDir, 'test', 'fixtures', 'teardown')
const teardownOsKillDir = path.join(Helper.localDir, 'test', 'fixtures', 'teardown-os-kill')
const teardownExitCodeDir = path.join(Helper.localDir, 'test', 'fixtures', 'teardown-exit-code')

test('teardown', async function ({ is, ok, plan, comment, teardown, timeout }) {
timeout(180000)
test('teardown on pipe end', async function ({ ok, is, plan, comment, teardown, timeout }) {
if (isWindows) return
maidh91 marked this conversation as resolved.
Show resolved Hide resolved

plan(5)
timeout(180000)
plan(4)

const stager = new Helper()
teardown(() => stager.close(), { order: Infinity })
await stager.ready()
const dir = teardownDir

const dir = harness
const helper = new Helper()
teardown(() => helper.close(), { order: Infinity })
await helper.ready()

const id = Math.floor(Math.random() * 10000)

comment('staging')
const stage = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true })
const final = await Helper.pick(stage, { tag: 'final' })
ok(final.success, 'stage succeeded')
const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true })
teardown(() => Helper.teardownStream(staging))
const staged = await Helper.pick(staging, { tag: 'final' })
ok(staged.success, 'stage succeeded')

comment('seeding')
const seeder = new Helper()
teardown(() => seeder.close(), { order: Infinity })
await seeder.ready()
const seed = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir })
teardown(() => Helper.teardownStream(seed))
const until = await Helper.pick(seed, [{ tag: 'key' }, { tag: 'announced' }])
const key = await until.key
const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] })
teardown(() => Helper.teardownStream(seeding))
const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }])
const announced = await until.announced
ok(announced, 'seeding is announced')

const key = await until.key
ok(hypercoreid.isValid(key), 'app key is valid')
ok(announced, 'seeding is announced')

comment('running')
const link = 'pear://' + key
const running = await Helper.open(link, { tags: ['teardown', 'exit'] })
const link = `pear://${key}`
const run = await Helper.run({ link })
const { pipe } = run

await running.inspector.evaluate('Pear.teardown(() => console.log(\'teardown\'))')
await running.inspector.evaluate('Pear.shutdown()')
await running.inspector.close()
const teardownPromise = Helper.untilResult(pipe)

const td = await running.until.teardown
is(td, 'teardown', 'teardown has been triggered')
pipe.end()

const { code } = await running.until.exit
is(code, 0, 'exit code is 0')
const td = await teardownPromise
is(td, 'teardown', 'teardown executed')
})

test('teardown during teardown', async function ({ is, ok, plan, comment, teardown, timeout }) {
test('teardown on os kill', async function ({ ok, is, plan, comment, teardown, timeout }) {
if (isWindows) return
maidh91 marked this conversation as resolved.
Show resolved Hide resolved

timeout(180000)
plan(5)

const stager = new Helper()
teardown(() => stager.close(), { order: Infinity })
await stager.ready()
const dir = teardownOsKillDir

const dir = harness
const helper = new Helper()
teardown(() => helper.close(), { order: Infinity })
await helper.ready()

const id = Math.floor(Math.random() * 10000)

comment('staging')
const stage = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true })
const final = await Helper.pick(stage, { tag: 'final' })
ok(final.success, 'stage succeeded')
const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true })
teardown(() => Helper.teardownStream(staging))
const staged = await Helper.pick(staging, { tag: 'final' })
ok(staged.success, 'stage succeeded')

comment('seeding')
const seeder = new Helper()
teardown(() => seeder.close(), { order: Infinity })
await seeder.ready()
const seed = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir })
teardown(() => Helper.teardownStream(seed))
const until = await Helper.pick(seed, [{ tag: 'key' }, { tag: 'announced' }])
const key = await until.key
const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] })
teardown(() => Helper.teardownStream(seeding))
const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }])
const announced = await until.announced

ok(hypercoreid.isValid(key), 'app key is valid')
ok(announced, 'seeding is announced')

comment('running')
const link = 'pear://' + key
const running = await Helper.open(link, { tags: ['teardown', 'exit'] })
const key = await until.key
ok(hypercoreid.isValid(key), 'app key is valid')

await running.inspector.evaluate(
`(() => {
const { teardown } = Pear
const a = () => { b() }
const b = () => { teardown(() => console.log('teardown from b')) }
teardown( () => a() )
})()`)
const link = `pear://${key}`
const run = await Helper.run({ link })
const { pipe } = run

await running.inspector.evaluate('Pear.shutdown()')
await running.inspector.close()
const pid = +(await Helper.untilResult(pipe))
ok(pid > 0, 'worker pid is valid')

const td = await running.until.teardown
is(td, 'teardown from b', 'teardown from b has been triggered')
const teardownPromise = Helper.untilResult(pipe, 5000, () => os.kill(pid))

const { code } = await running.until.exit
is(code, 0, 'exit code is 0')
const td = await teardownPromise
ok(td, 'teardown executed')
})

// TODO: fixme
test.skip('exit with non-zero code in teardown', async function ({ is, ok, plan, comment, teardown }) {
plan(4)
test('teardown on os kill with exit code', async function ({ ok, is, plan, comment, teardown, timeout }) {
if (isWindows) return

const stager = new Helper()
teardown(() => stager.close(), { order: Infinity })
await stager.ready()
timeout(180000)
plan(6)

const dir = teardownExitCodeDir

const dir = harness
const helper = new Helper()
teardown(() => helper.close(), { order: Infinity })
await helper.ready()

const id = Math.floor(Math.random() * 10000)

comment('staging')
const stage = stager.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true })
const final = await Helper.pick(stage, { tag: 'final' })
ok(final.success, 'stage succeeded')
const staging = helper.stage({ channel: `test-${id}`, name: `test-${id}`, dir, dryRun: false, bare: true })
teardown(() => Helper.teardownStream(staging))
const staged = await Helper.pick(staging, { tag: 'final' })
ok(staged.success, 'stage succeeded')

comment('seeding')
const seeder = new Helper()
teardown(() => seeder.close())
teardown(() => seeder.close(), { order: Infinity })
await seeder.ready()
const seed = seeder.seed({ channel: `test-${id}`, name: `test-${id}`, dir })
teardown(() => Helper.teardownStream(seed))
const until = await Helper.pick(seed, [{ tag: 'key' }, { tag: 'announced' }])
const key = await until.key
const seeding = helper.seed({ channel: `test-${id}`, name: `test-${id}`, dir, key: null, cmdArgs: [] })
teardown(() => Helper.teardownStream(seeding))
const until = await Helper.pick(seeding, [{ tag: 'key' }, { tag: 'announced' }])
const announced = await until.announced
ok(announced, 'seeding is announced')

const key = await until.key
ok(hypercoreid.isValid(key), 'app key is valid')
ok(announced, 'seeding is announced')

comment('running')
const link = 'pear://' + key
const running = await Helper.open(link, { tags: ['teardown', 'exit'] })
const link = `pear://${key}`
const run = await Helper.run({ link })
const { pipe } = run

const pid = +(await Helper.untilResult(pipe))
ok(pid > 0, 'worker pid is valid')

const exitCodePromise = new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => reject(new Error('timed out')), 5000)
pipe.on('crash', (data) => {
clearTimeout(timeoutId)
resolve(data.exitCode)
})
})

await running.inspector.evaluate('Pear.teardown(() => Pear.exit(124))')
const teardownPromise = Helper.untilResult(pipe, 5000, () => os.kill(pid))

await running.inspector.evaluate('__PEAR_TEST__.close()')
await running.inspector.close()
// running.subprocess.kill('SIGINT') <-- this was forcing the exit code, which false-positives the test
const td = await teardownPromise
ok(td, 'teardown executed')

const { code } = await running.until.exit
is(code, 124, 'exit code is 124')
const exitCode = await exitCodePromise
is(exitCode, 124, 'exit code is 124')
})
11 changes: 11 additions & 0 deletions test/fixtures/teardown-exit-code/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const program = global.Bare || global.process

const pipe = Pear.worker.pipe()
pipe.on('data', () => pipe.write(`${program.pid}`))

Pear.teardown(async () => {
await new Promise((resolve) => {
pipe.write('teardown', resolve)
})
Pear.exit(124)
})
8 changes: 8 additions & 0 deletions test/fixtures/teardown-exit-code/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "teardown-exit-code",
"main": "index.js",
"pear": {
"name": "teardown-exit-code",
"type": "terminal"
}
}
10 changes: 10 additions & 0 deletions test/fixtures/teardown-os-kill/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const program = global.Bare || global.process

const pipe = Pear.worker.pipe()
pipe.on('data', () => pipe.write(`${program.pid}`))

Pear.teardown(async () => {
await new Promise((resolve) => {
pipe.write('teardown', resolve)
})
})
8 changes: 8 additions & 0 deletions test/fixtures/teardown-os-kill/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "teardown-os-kill",
"main": "index.js",
"pear": {
"name": "teardown-os-kill",
"type": "terminal"
}
}
9 changes: 9 additions & 0 deletions test/fixtures/teardown/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const program = global.Bare || global.process

const pipe = Pear.worker.pipe()

Pear.teardown(async () => {
await new Promise((resolve) => {
pipe.write('teardown', resolve)
})
})
8 changes: 8 additions & 0 deletions test/fixtures/teardown/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "teardown",
"main": "index.js",
"pear": {
"name": "teardown",
"type": "terminal"
}
}
8 changes: 6 additions & 2 deletions test/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class Helper extends IPC {
return { pipe }
}

static async untilResult (pipe, timeout = 5000) {
static async untilResult (pipe, timeout = 5000, runFn) {
const res = new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => reject(new Error('timed out')), timeout)
pipe.on('data', (data) => {
Expand All @@ -173,7 +173,11 @@ class Helper extends IPC {
reject(new Error('unexpected ended'))
})
})
pipe.write('start')
if (runFn) {
await runFn()
} else {
pipe.write('start')
}
return res
}

Expand Down