[6a3a178] | 1 | import Piscina from '..';
|
---|
| 2 | import { test } from 'tap';
|
---|
| 3 | import { version } from '../package.json';
|
---|
| 4 | import { pathToFileURL } from 'url';
|
---|
| 5 | import { resolve } from 'path';
|
---|
| 6 | import { EventEmitter } from 'events';
|
---|
| 7 |
|
---|
| 8 | test('Piscina is exposed on export', async ({ equal }) => {
|
---|
| 9 | equal(Piscina.version, version);
|
---|
| 10 | });
|
---|
| 11 |
|
---|
| 12 | test('Piscina is exposed on itself', async ({ equal }) => {
|
---|
| 13 | equal(Piscina.Piscina, Piscina);
|
---|
| 14 | });
|
---|
| 15 |
|
---|
| 16 | test('Piscina.isWorkerThread has the correct value', async ({ equal }) => {
|
---|
| 17 | equal(Piscina.isWorkerThread, false);
|
---|
| 18 | });
|
---|
| 19 |
|
---|
| 20 | test('Piscina.isWorkerThread has the correct value (worker)', async ({ equal }) => {
|
---|
| 21 | const worker = new Piscina({
|
---|
| 22 | filename: resolve(__dirname, 'fixtures/simple-isworkerthread.ts')
|
---|
| 23 | });
|
---|
| 24 | const result = await worker.runTask(null);
|
---|
| 25 | equal(result, 'done');
|
---|
| 26 | });
|
---|
| 27 |
|
---|
| 28 | test('Piscina instance is an EventEmitter', async ({ ok }) => {
|
---|
| 29 | const piscina = new Piscina();
|
---|
| 30 | ok(piscina instanceof EventEmitter);
|
---|
| 31 | });
|
---|
| 32 |
|
---|
| 33 | test('Piscina constructor options are correctly set', async ({ equal }) => {
|
---|
| 34 | const piscina = new Piscina({
|
---|
| 35 | minThreads: 10,
|
---|
| 36 | maxThreads: 20,
|
---|
| 37 | maxQueue: 30
|
---|
| 38 | });
|
---|
| 39 |
|
---|
| 40 | equal(piscina.options.minThreads, 10);
|
---|
| 41 | equal(piscina.options.maxThreads, 20);
|
---|
| 42 | equal(piscina.options.maxQueue, 30);
|
---|
| 43 | });
|
---|
| 44 |
|
---|
| 45 | test('trivial eval() handler works', async ({ equal }) => {
|
---|
| 46 | const worker = new Piscina({
|
---|
| 47 | filename: resolve(__dirname, 'fixtures/eval.js')
|
---|
| 48 | });
|
---|
| 49 | const result = await worker.runTask('42');
|
---|
| 50 | equal(result, 42);
|
---|
| 51 | });
|
---|
| 52 |
|
---|
| 53 | test('async eval() handler works', async ({ equal }) => {
|
---|
| 54 | const worker = new Piscina({
|
---|
| 55 | filename: resolve(__dirname, 'fixtures/eval.js')
|
---|
| 56 | });
|
---|
| 57 | const result = await worker.runTask('Promise.resolve(42)');
|
---|
| 58 | equal(result, 42);
|
---|
| 59 | });
|
---|
| 60 |
|
---|
| 61 | test('filename can be provided while posting', async ({ equal }) => {
|
---|
| 62 | const worker = new Piscina();
|
---|
| 63 | const result = await worker.runTask(
|
---|
| 64 | 'Promise.resolve(42)',
|
---|
| 65 | resolve(__dirname, 'fixtures/eval.js'));
|
---|
| 66 | equal(result, 42);
|
---|
| 67 | });
|
---|
| 68 |
|
---|
| 69 | test('filename can be null when initially provided', async ({ equal }) => {
|
---|
| 70 | const worker = new Piscina({ filename: null });
|
---|
| 71 | const result = await worker.runTask(
|
---|
| 72 | 'Promise.resolve(42)',
|
---|
| 73 | resolve(__dirname, 'fixtures/eval.js'));
|
---|
| 74 | equal(result, 42);
|
---|
| 75 | });
|
---|
| 76 |
|
---|
| 77 | test('filename must be provided while posting', async ({ rejects }) => {
|
---|
| 78 | const worker = new Piscina();
|
---|
| 79 | rejects(worker.runTask('doesn’t matter'),
|
---|
| 80 | /filename must be provided to run\(\) or in options object/);
|
---|
| 81 | });
|
---|
| 82 |
|
---|
| 83 | test('passing env to workers works', async ({ same }) => {
|
---|
| 84 | const pool = new Piscina({
|
---|
| 85 | filename: resolve(__dirname, 'fixtures/eval.js'),
|
---|
| 86 | env: { A: 'foo' }
|
---|
| 87 | });
|
---|
| 88 |
|
---|
| 89 | const env = await pool.runTask('({...process.env})');
|
---|
| 90 | same(env, { A: 'foo' });
|
---|
| 91 | });
|
---|
| 92 |
|
---|
| 93 | test('passing argv to workers works', async ({ same }) => {
|
---|
| 94 | const pool = new Piscina({
|
---|
| 95 | filename: resolve(__dirname, 'fixtures/eval.js'),
|
---|
| 96 | argv: ['a', 'b', 'c']
|
---|
| 97 | });
|
---|
| 98 |
|
---|
| 99 | const env = await pool.runTask('process.argv.slice(2)');
|
---|
| 100 | same(env, ['a', 'b', 'c']);
|
---|
| 101 | });
|
---|
| 102 |
|
---|
| 103 | test('passing execArgv to workers works', async ({ same }) => {
|
---|
| 104 | const pool = new Piscina({
|
---|
| 105 | filename: resolve(__dirname, 'fixtures/eval.js'),
|
---|
| 106 | execArgv: ['--no-warnings']
|
---|
| 107 | });
|
---|
| 108 |
|
---|
| 109 | const env = await pool.runTask('process.execArgv');
|
---|
| 110 | same(env, ['--no-warnings']);
|
---|
| 111 | });
|
---|
| 112 |
|
---|
| 113 | test('passing valid workerData works', async ({ equal }) => {
|
---|
| 114 | const pool = new Piscina({
|
---|
| 115 | filename: resolve(__dirname, 'fixtures/simple-workerdata.ts'),
|
---|
| 116 | workerData: 'ABC'
|
---|
| 117 | });
|
---|
| 118 | equal(Piscina.workerData, undefined);
|
---|
| 119 |
|
---|
| 120 | await pool.runTask(null);
|
---|
| 121 | });
|
---|
| 122 |
|
---|
| 123 | test('passing invalid workerData does not work', async ({ throws }) => {
|
---|
| 124 | throws(() => new Piscina(({
|
---|
| 125 | filename: resolve(__dirname, 'fixtures/simple-workerdata.ts'),
|
---|
| 126 | workerData: process.env
|
---|
| 127 | }) as any), /Cannot transfer object of unsupported type./);
|
---|
| 128 | });
|
---|
| 129 |
|
---|
| 130 | test('filename can be a file:// URL', async ({ equal }) => {
|
---|
| 131 | const worker = new Piscina({
|
---|
| 132 | filename: pathToFileURL(resolve(__dirname, 'fixtures/eval.js')).href
|
---|
| 133 | });
|
---|
| 134 | const result = await worker.runTask('42');
|
---|
| 135 | equal(result, 42);
|
---|
| 136 | });
|
---|
| 137 |
|
---|
| 138 | test('filename can be a file:// URL to an ESM module', {}, async ({ equal }) => {
|
---|
| 139 | const worker = new Piscina({
|
---|
| 140 | filename: pathToFileURL(resolve(__dirname, 'fixtures/esm-export.mjs')).href
|
---|
| 141 | });
|
---|
| 142 | const result = await worker.runTask('42');
|
---|
| 143 | equal(result, 42);
|
---|
| 144 | });
|
---|
| 145 |
|
---|
| 146 | test('duration and utilization calculations work', async ({ equal, ok }) => {
|
---|
| 147 | const worker = new Piscina({
|
---|
| 148 | filename: resolve(__dirname, 'fixtures/eval.js')
|
---|
| 149 | });
|
---|
| 150 |
|
---|
| 151 | // Initial utilization is always 0
|
---|
| 152 | equal(worker.utilization, 0);
|
---|
| 153 |
|
---|
| 154 | await Promise.all([
|
---|
| 155 | worker.runTask('42'),
|
---|
| 156 | worker.runTask('41'),
|
---|
| 157 | worker.runTask('40')
|
---|
| 158 | ]);
|
---|
| 159 |
|
---|
| 160 | // utilization is going to be some non-deterministic value
|
---|
| 161 | // between 0 and 1. It should not be zero at this point
|
---|
| 162 | // because tasks have run, but it should also never be 1
|
---|
| 163 | ok(worker.utilization > 0);
|
---|
| 164 | ok(worker.utilization < 1);
|
---|
| 165 |
|
---|
| 166 | // Duration must be non-zero.
|
---|
| 167 | ok(worker.duration > 0);
|
---|
| 168 | });
|
---|
| 169 |
|
---|
| 170 | test('run works also', async () => {
|
---|
| 171 | const worker = new Piscina({
|
---|
| 172 | filename: resolve(__dirname, 'fixtures/eval.js')
|
---|
| 173 | });
|
---|
| 174 |
|
---|
| 175 | await worker.run(42);
|
---|
| 176 | });
|
---|
| 177 |
|
---|
| 178 | test('named tasks work', async ({ equal }) => {
|
---|
| 179 | const worker = new Piscina({
|
---|
| 180 | filename: resolve(__dirname, 'fixtures/multiple.js')
|
---|
| 181 | });
|
---|
| 182 |
|
---|
| 183 | equal(await worker.run({}, { name: 'a' }), 'a');
|
---|
| 184 | equal(await worker.run({}, { name: 'b' }), 'b');
|
---|
| 185 | equal(await worker.run({}), 'a');
|
---|
| 186 | });
|
---|
| 187 |
|
---|
| 188 | test('named tasks work', async ({ equal }) => {
|
---|
| 189 | const worker = new Piscina({
|
---|
| 190 | filename: resolve(__dirname, 'fixtures/multiple.js'),
|
---|
| 191 | name: 'b'
|
---|
| 192 | });
|
---|
| 193 |
|
---|
| 194 | equal(await worker.run({}, { name: 'a' }), 'a');
|
---|
| 195 | equal(await worker.run({}, { name: 'b' }), 'b');
|
---|
| 196 | equal(await worker.run({}), 'b');
|
---|
| 197 | });
|
---|