post-task.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { MessageChannel } from 'worker_threads';
  2. import Piscina from '..';
  3. import { test } from 'tap';
  4. import { resolve } from 'path';
  5. test('postTask() can transfer ArrayBuffer instances', async ({ equal }) => {
  6. const pool = new Piscina({
  7. filename: resolve(__dirname, 'fixtures/simple-isworkerthread.ts')
  8. });
  9. const ab = new ArrayBuffer(40);
  10. await pool.runTask({ ab }, [ab]);
  11. equal(pool.completed, 1);
  12. equal(ab.byteLength, 0);
  13. });
  14. test('postTask() can transfer ArrayBuffer instances', async ({ equal }) => {
  15. const pool = new Piscina({
  16. filename: resolve(__dirname, 'fixtures/simple-isworkerthread.ts')
  17. });
  18. const ab = new ArrayBuffer(40);
  19. await pool.run({ ab }, { transferList: [ab] });
  20. equal(pool.completed, 1);
  21. equal(ab.byteLength, 0);
  22. });
  23. test('postTask() cannot clone build-in objects', async ({ rejects }) => {
  24. const pool = new Piscina({
  25. filename: resolve(__dirname, 'fixtures/simple-isworkerthread.ts')
  26. });
  27. const obj = new MessageChannel().port1;
  28. rejects(pool.runTask({ obj }));
  29. });
  30. test('postTask() resolves with a rejection when the handler rejects', async ({ rejects }) => {
  31. const pool = new Piscina({
  32. filename: resolve(__dirname, 'fixtures/eval.js')
  33. });
  34. rejects(pool.runTask('Promise.reject(new Error("foo"))'), /foo/);
  35. });
  36. test('postTask() resolves with a rejection when the handler throws', async ({ rejects }) => {
  37. const pool = new Piscina({
  38. filename: resolve(__dirname, 'fixtures/eval.js')
  39. });
  40. rejects(pool.runTask('throw new Error("foo")'), /foo/);
  41. });
  42. test('postTask() validates transferList', async ({ rejects }) => {
  43. const pool = new Piscina({
  44. filename: resolve(__dirname, 'fixtures/eval.js')
  45. });
  46. rejects(pool.runTask('0', 42 as any),
  47. /transferList argument must be an Array/);
  48. rejects(pool.run('0', { transferList: 42 as any }),
  49. /transferList argument must be an Array/);
  50. });
  51. test('postTask() validates filename', async ({ rejects }) => {
  52. const pool = new Piscina({
  53. filename: resolve(__dirname, 'fixtures/eval.js')
  54. });
  55. rejects(pool.runTask('0', [], 42 as any),
  56. /filename argument must be a string/);
  57. rejects(pool.run('0', { filename: 42 as any }),
  58. /filename argument must be a string/);
  59. });
  60. test('postTask() validates name', async ({ rejects }) => {
  61. const pool = new Piscina({
  62. filename: resolve(__dirname, 'fixtures/eval.js')
  63. });
  64. rejects(pool.run('0', { name: 42 as any }),
  65. /name argument must be a string/);
  66. });
  67. test('postTask() validates abortSignal', async ({ rejects }) => {
  68. const pool = new Piscina({
  69. filename: resolve(__dirname, 'fixtures/eval.js')
  70. });
  71. rejects(pool.runTask('0', [], undefined, 42 as any),
  72. /signal argument must be an object/);
  73. rejects(pool.run('0', { signal: 42 as any }),
  74. /signal argument must be an object/);
  75. });
  76. test('Piscina emits drain', async ({ ok }) => {
  77. const pool = new Piscina({
  78. filename: resolve(__dirname, 'fixtures/eval.js')
  79. });
  80. let drained = false;
  81. pool.on('drain', () => {
  82. drained = true;
  83. });
  84. await Promise.all([pool.runTask('123'), pool.runTask('123')]);
  85. ok(drained);
  86. });
  87. test('Piscina can use async loaded workers', async ({ equal }) => {
  88. const pool = new Piscina({
  89. filename: resolve(__dirname, 'fixtures/eval-async.js')
  90. });
  91. equal(await pool.runTask('1'), 1);
  92. });
  93. test('Piscina can use async loaded esm workers', {}, async ({ equal }) => {
  94. const pool = new Piscina({
  95. filename: resolve(__dirname, 'fixtures/esm-async.mjs')
  96. });
  97. equal(await pool.runTask('1'), 1);
  98. });
  99. test('Piscina.run options is correct type', async ({ rejects }) => {
  100. const pool = new Piscina({
  101. filename: resolve(__dirname, 'fixtures/eval.js')
  102. });
  103. rejects(pool.run(42, 1 as any), /options must be an object/);
  104. });