Files
bun.sh/test/js/web/worker.test.ts
Jarred Sumner 7a4e0158d6 Lots of stuff (#7027)
* Use debug mode by default

* Enable build with assertions enabled

* Update cli.zig

* Update bun-linux-build.yml

* Fixes

* Fix `ASSERT_ENABLED`

* try this

* Update Dockerfile

* mimalloc debug

* Update CMakeLists.txt

* `Bun.deepMatch` - fix assertion failures

cc @dylan-conway, looks like we need to use `putDirectMayBeIndex` and check for `isCell` more carefully.

* Object.create support in code generator and callbacks wrapper

* Remove unused file

* zig upgrade

* zls

* Fix various errors

* Support `BuiltinAccessor` in create_hash_table script

* Fix assertion failure in `process.mainModule`

* Fix assertion failure in `onerror`

* Fix assertion failure when creating a Worker

* Fix asssertion failure when loading lots of files in bun test

* Fix assertion failure when termating a `Worker`

* Add helper for converting BunString to a WTFString

* Fix assertion failure in notifyNeedTermination

* Add more debug logs in `bun test`

* Fix compiler warning in usockets

* Fix assertion failure with `Worker` termination (another)

* Fix assertion failure in `coerceToInt64`

* Fix assertion failure in `BroadcastChannel`

* Fix assertion failure in `Headers.prototype.getAll`

* Fixes #7067

* Add heap analyzer label for CommonJS modules

* Fix assertion failure in module.require && module.require.resolve

* Remove unused code

* Fix assertion failure in debugger

* Fix crash in debugger

* Fix assertion failures in bun:sqlite

* Bump zig

* Bump WebKit

* Fix assertion failure in JSPromise::reject && JSInternalPromise::reject

* Fix assertion failure in ReadableStream::cancel

* Fix assertion failure in AsyncContextFrame::create

* Fix assertion failure in bun:sqlite

* Fix assertion failure in mocks

* Fix assertion failure in ServerWebSocket.close

* Fix assertion failure in N-API with subclasses

* [napi] Make promises cheaper

* undo

* Don't check for exceptions in ObjectInitializationScope

* Add separate entry point for test runner that doesn't generate code

* Don't deref builtin code

* Fix preload test

* Fix assertion failure in memoryUsage()

* Fix preload test, part 2

* Ensure that the env map for a Worker is empty after it is used

* The pointer for the Arena allocator used in parsing should not change

* Terminate thread on exit

* Start to implement scriptExecutionStatus

* Update worker.test.ts

* Fix Dirent.name setter

* Update settings.json

* Fix assertion failure in node:http

* Use correct value for `JSFinalObject::maxInlineCapacity`

* JSFinalObject::maxInlineCapacity x2

* Don't strip when assertions are enabled

* Make `m_wasTerminated` atomic

* Preserve directives in the transpiler

cc @ctjlewis

* Workaround assertion failure in ServerWebSocket.sendBinary and ServerWebSocket.sendText

* windows

* Buffer lockfile serialization in-memory

* PR feedback

* PR feedback

* PR feedback

* Windows

* quotes

* Update CMakeLists.txt

* Update bun-linux-build.yml

* Update bun-linux-build.yml

* Move this code to BunString.cpp

* Update BunString.cpp

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-11-13 22:10:09 -08:00

211 lines
5.0 KiB
TypeScript

import { expect, test } from "bun:test";
import { bunEnv, bunExe } from "harness";
import path from "path";
import wt from "worker_threads";
test("worker", done => {
const worker = new Worker(new URL("worker-fixture.js", import.meta.url).href, {
smol: true,
});
expect(worker.threadId).toBe(1);
worker.postMessage("hello");
worker.onerror = e => {
done(e.error);
};
worker.onmessage = e => {
try {
expect(e.data).toEqual("initial message");
} catch (e) {
done(e);
} finally {
worker.terminate();
done();
}
worker.terminate();
done();
};
});
test("worker-env", done => {
const worker = new Worker(new URL("worker-fixture-env.js", import.meta.url).href, {
env: {
hello: "world",
another_key: 123 as any,
},
});
worker.postMessage("hello");
worker.onerror = e => {
done(e.error);
};
worker.onmessage = e => {
try {
expect(e.data).toEqual({
env: {
hello: "world",
another_key: "123",
},
hello: "world",
});
} catch (e) {
done(e);
} finally {
worker.terminate();
done();
}
};
});
test("worker-env with a lot of properties", done => {
const obj: any = {};
for (let i = 0; i < 1000; i++) {
obj["prop " + i] = Math.random().toString();
}
const worker = new Worker(new URL("worker-fixture-env.js", import.meta.url).href, {
env: obj,
});
worker.postMessage("hello");
worker.onerror = e => {
done(e.error);
};
worker.onmessage = e => {
try {
expect(e.data).toEqual({
env: obj,
hello: undefined,
});
} catch (e) {
done(e);
} finally {
worker.terminate();
done();
}
};
});
test("sending 50 messages should just work", done => {
const worker = new Worker(new URL("worker-fixture-many-messages.js", import.meta.url).href, {});
worker.postMessage("initial message");
worker.addEventListener("message", ({ data }) => {
if (data.done) {
worker.terminate();
done();
} else {
worker.postMessage({ i: data.i + 1 });
}
});
});
test("worker with event listeners doesn't close event loop", done => {
const x = Bun.spawn({
cmd: [bunExe(), path.join(import.meta.dir, "many-messages-event-loop.mjs"), "worker-fixture-many-messages.js"],
env: bunEnv,
stdio: ["inherit", "pipe", "inherit"],
});
const timer = setTimeout(() => {
x.kill();
done(new Error("timeout"));
}, 1000);
x.exited.then(async code => {
clearTimeout(timer);
if (code !== 0) {
done(new Error("exited with non-zero code"));
} else {
const text = await new Response(x.stdout).text();
if (!text.includes("done")) {
console.log({ text });
done(new Error("event loop killed early"));
} else {
done();
}
}
});
});
test("worker with event listeners doesn't close event loop 2", done => {
const x = Bun.spawn({
cmd: [bunExe(), path.join(import.meta.dir, "many-messages-event-loop.mjs"), "worker-fixture-many-messages2.js"],
env: bunEnv,
stdio: ["inherit", "pipe", "inherit"],
});
const timer = setTimeout(() => {
x.kill();
done(new Error("timeout"));
}, 1000);
x.exited.then(async code => {
clearTimeout(timer);
if (code !== 0) {
done(new Error("exited with non-zero code"));
} else {
const text = await new Response(x.stdout).text();
if (!text.includes("done")) {
console.log({ text });
done(new Error("event loop killed early"));
} else {
done();
}
}
});
});
test("worker with process.exit", done => {
const worker = new Worker(new URL("worker-fixture-process-exit.js", import.meta.url).href, {
smol: true,
});
worker.addEventListener("close", e => {
try {
expect(e.code).toBe(2);
} catch (e) {
done(e);
}
done();
});
});
test("worker_threads with process.exit", done => {
const worker = new wt.Worker(new URL("worker-fixture-process-exit.js", import.meta.url).href, {
smol: true,
});
worker.on("exit", event => {
try {
expect(event).toBe(2);
} catch (e) {
done(e);
return;
}
done();
});
});
test("worker_threads terminate", async () => {
const worker = new wt.Worker(new URL("worker-fixture-hang.js", import.meta.url).href, {
smol: true,
});
const code = await worker.terminate();
expect(code).toBe(0);
});
test("worker_threads with process.exit (delay) and terminate", async () => {
const worker2 = new wt.Worker(new URL("worker-fixture-process-exit.js", import.meta.url).href, {
smol: true,
});
await Bun.sleep(200);
const code2 = await worker2.terminate();
expect(code2).toBe(2);
});
test.todo("terminating forcefully properly interrupts", async () => {
const worker2 = new wt.Worker(new URL("worker-fixture-while-true.js", import.meta.url).href, {});
await new Promise<void>(done => {
worker2.on("message", () => done());
});
const code2 = await worker2.terminate();
expect(code2).toBe(0);
});