Skip to content

Commit

Permalink
Add tests for running workers in terminal apps (#427)
Browse files Browse the repository at this point in the history
* Add tests for running workers in terminal apps

* Use a separate runner instead of harness and use new helper methods

* Remove unnecessary package.json fields

* Use simpler workers

* Add test for passing passing args to worker

* Update wrong name in package.json

* Switch worker runner to use args

* Cleanup unused message argument
  • Loading branch information
jkcdarunday authored Nov 7, 2024
1 parent 2409eb8 commit 13758e4
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 3 deletions.
72 changes: 71 additions & 1 deletion test/03-worker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ const test = require('brittle')
const path = require('bare-path')
const Helper = require('./helper')
const worker = path.join(Helper.localDir, 'test', 'fixtures', 'worker')
const helloWorld = path.join(Helper.localDir, 'test', 'fixtures', 'hello-world')
const printArgs = path.join(Helper.localDir, 'test', 'fixtures', 'print-args')
const workerRunner = path.join(Helper.localDir, 'test', 'fixtures', 'worker-runner')

test('worker pipe', async function ({ is, plan, comment, teardown }) {
test('worker pipe', async function ({ is, plan, teardown }) {
plan(1)
const helper = new Helper()
teardown(() => helper.close())
Expand All @@ -29,3 +32,70 @@ test('worker pipe', async function ({ is, plan, comment, teardown }) {

pipe.write('exit')
})

test('worker should receive args from the parent', async function ({ is, plan }) {
plan(1)

const args = ['hello', 'world']
const { pipe } = await Helper.run({ link: printArgs, args })
const result = await Helper.untilResult(pipe)

is(result, JSON.stringify(args), 'worker should receive args from the parent')

await Helper.untilClose(pipe)
})

test('worker should run directly in a terminal app', async function ({ is, plan, comment, teardown }) {
plan(1)

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

const testId = Math.floor(Math.random() * 100000)
comment('Staging worker-runner...')
const staging = helper.stage({ channel: `test-${testId}`, name: `test-${testId}`, key: null, dir: workerRunner, cmdArgs: [], dryRun: false, bare: true, ignore: [] })
teardown(() => Helper.teardownStream(staging))
const until = await Helper.pick(staging, [{ tag: 'staging' }, { tag: 'final' }])
const { link } = await until.staging
await until.final

comment('Running worker using worker-runner...')
const { pipe } = await Helper.run({ link, args: [helloWorld] })
const response = await Helper.untilResult(pipe)

is(response, 'hello world', 'worker should send expected response')

await Helper.untilClose(pipe)
})

test('worker should run as a link in a terminal app', async function ({ is, plan, comment, teardown }) {
plan(1)

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

const testId = Math.floor(Math.random() * 100000)
comment('Staging worker-runner...')
const staging1 = helper.stage({ channel: `test-${testId}`, name: `test-${testId}`, key: null, dir: workerRunner, cmdArgs: [], dryRun: false, bare: true, ignore: [] })
teardown(() => Helper.teardownStream(staging1))
const until1 = await Helper.pick(staging1, [{ tag: 'staging' }, { tag: 'final' }])
const { link: runnerLink } = await until1.staging
await until1.final

comment('Staging worker...')
const staging2 = helper.stage({ channel: `test-worker-${testId}`, name: `test-worker-${testId}`, key: null, dir: helloWorld, cmdArgs: [], dryRun: false, bare: true, ignore: [] })
teardown(() => Helper.teardownStream(staging2))
const until2 = await Helper.pick(staging2, [{ tag: 'staging' }, { tag: 'final' }])
const { link: workerLink } = await until2.staging
await until2.final

comment('Running worker using worker-runner...')
const { pipe } = await Helper.run({ link: runnerLink, args: [workerLink] })
const response = await Helper.untilResult(pipe)

is(response, 'hello world', 'worker should send expected response')

await Helper.untilClose(pipe)
})
9 changes: 9 additions & 0 deletions test/fixtures/hello-world/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const pipe = Pear.worker.pipe()
pipe.on('data', () => {
try {
pipe.write('hello world')
} catch (err) {
console.error(err)
Pear.exit()
}
})
8 changes: 8 additions & 0 deletions test/fixtures/hello-world/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "hello-world",
"main": "index.js",
"pear": {
"name": "hello-world",
"type": "terminal"
}
}
9 changes: 9 additions & 0 deletions test/fixtures/print-args/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const pipe = Pear.worker.pipe()
pipe.on('data', () => {
try {
pipe.write(JSON.stringify(Pear.config.args))
} catch (err) {
console.error(err)
Pear.exit()
}
})
8 changes: 8 additions & 0 deletions test/fixtures/print-args/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "print-args",
"main": "index.js",
"pear": {
"name": "print-args",
"type": "terminal"
}
}
10 changes: 10 additions & 0 deletions test/fixtures/worker-runner/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const pipe = Pear.worker.pipe()

const [workerPath] = Pear.config.args
const workerPipe = Pear.worker.run(workerPath)
workerPipe.on('data', (data) => {
pipe.write(data)
workerPipe.end()
})

workerPipe.write('start')
8 changes: 8 additions & 0 deletions test/fixtures/worker-runner/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "worker-runner",
"main": "index.js",
"pear": {
"name": "worker-runner",
"type": "terminal"
}
}
4 changes: 2 additions & 2 deletions test/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ class Helper extends IPC {
// ONLY ADD STATICS, NEVER ADD PUBLIC METHODS OR PROPERTIES (see pear-ipc)
static localDir = isWindows ? path.normalize(pathname.slice(1)) : pathname

static async run ({ link, encryptionKey, platformDir }) {
static async run ({ link, encryptionKey, platformDir, args = [] }) {
if (encryptionKey) program.argv.splice(2, 0, '--encryption-key', encryptionKey)
if (platformDir) Pear.worker.constructor.RUNTIME = path.join(platformDir, 'current', BY_ARCH)

const pipe = Pear.worker.run(link)
const pipe = Pear.worker.run(link, args)

if (platformDir) Pear.worker.constructor.RUNTIME = RUNTIME
if (encryptionKey) program.argv.splice(2, 2)
Expand Down

0 comments on commit 13758e4

Please sign in to comment.