mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
115 lines
3.5 KiB
TypeScript
115 lines
3.5 KiB
TypeScript
import { afterEach, beforeAll, describe, expect, test } from "bun:test";
|
|
import { bunEnv, bunExe, isWindows, makeTree, tempDirWithFiles } from "harness";
|
|
import path from "node:path";
|
|
import { symbols, test_skipped } from "../../src/bun.js/bindings/libuv/generate_uv_posix_stubs_constants";
|
|
import source from "./uv-stub-stuff/uv_impl.c";
|
|
|
|
const symbols_to_test = symbols.filter(s => !test_skipped.includes(s));
|
|
|
|
// We use libuv on Windows
|
|
describe.if(!isWindows)("uv stubs", () => {
|
|
const cwd = process.cwd();
|
|
let tempdir: string = "";
|
|
let outdir: string = "";
|
|
let nativeModule: any;
|
|
|
|
beforeAll(async () => {
|
|
const files = {
|
|
"uv_impl.c": await Bun.file(source).text(),
|
|
"package.json": JSON.stringify({
|
|
"name": "fake-plugin",
|
|
"module": "index.ts",
|
|
"type": "module",
|
|
"devDependencies": {
|
|
"@types/bun": "latest",
|
|
},
|
|
"peerDependencies": {
|
|
"typescript": "^5.0.0",
|
|
},
|
|
"scripts": {
|
|
"build:napi": "node-gyp configure && node-gyp build",
|
|
},
|
|
"dependencies": {
|
|
"node-gyp": "10.2.0",
|
|
},
|
|
}),
|
|
"binding.gyp": `{
|
|
"targets": [
|
|
{
|
|
"target_name": "uv_test",
|
|
"sources": [ "uv_impl.c" ],
|
|
"include_dirs": [ ".", "./libuv" ],
|
|
"cflags": ["-fPIC"],
|
|
"ldflags": ["-Wl,--export-dynamic"]
|
|
},
|
|
]
|
|
}`,
|
|
};
|
|
|
|
tempdir = tempDirWithFiles("uv-tests", files);
|
|
await makeTree(tempdir, files);
|
|
outdir = path.join(tempdir, "dist");
|
|
|
|
process.chdir(tempdir);
|
|
|
|
const libuvDir = path.join(__dirname, "../../src/bun.js/bindings/libuv");
|
|
await Bun.$`cp -R ${libuvDir} ${path.join(tempdir, "libuv")}`;
|
|
await Bun.$`${bunExe()} i && ${bunExe()} build:napi`.env(bunEnv).cwd(tempdir);
|
|
|
|
nativeModule = require(path.join(tempdir, "./build/Release/uv_test.node"));
|
|
});
|
|
|
|
afterEach(() => {
|
|
process.chdir(cwd);
|
|
});
|
|
|
|
test("mutex init and destroy", () => {
|
|
expect(() => nativeModule.testMutexInitDestroy()).not.toThrow();
|
|
});
|
|
|
|
test("recursive mutex", () => {
|
|
expect(() => nativeModule.testMutexRecursive()).not.toThrow();
|
|
});
|
|
|
|
test("mutex trylock", () => {
|
|
expect(() => nativeModule.testMutexTrylock()).not.toThrow();
|
|
});
|
|
|
|
test("process IDs", () => {
|
|
const result = nativeModule.testProcessIds();
|
|
expect(result).toHaveProperty("pid");
|
|
expect(result).toHaveProperty("ppid");
|
|
expect(result.pid).toBeGreaterThan(0);
|
|
expect(result.ppid).toBeGreaterThan(0);
|
|
// The process ID should match Node's process.pid
|
|
expect(result.pid).toBe(process.pid);
|
|
});
|
|
|
|
test("uv_once", () => {
|
|
expect(nativeModule.testUvOnce()).toBe(1);
|
|
expect(nativeModule.testUvOnce()).toBe(1);
|
|
expect(nativeModule.testUvOnce()).toBe(1);
|
|
});
|
|
|
|
test("hrtime", () => {
|
|
const result = nativeModule.testHrtime();
|
|
|
|
// Reconstruct the 64-bit values
|
|
const time1 = (BigInt(result.time1High) << 32n) | BigInt(result.time1Low >>> 0);
|
|
const time2 = (BigInt(result.time2High) << 32n) | BigInt(result.time2Low >>> 0);
|
|
|
|
// Verify that:
|
|
// 1. time2 is greater than time1 (time passed)
|
|
expect(time2 > time1).toBe(true);
|
|
|
|
// 2. The difference should be at least 1ms (we slept for 1ms)
|
|
// hrtime is in nanoseconds, so 1ms = 1,000,000 ns
|
|
const diff = time2 - time1;
|
|
expect(diff >= 1_000_000n).toBe(true);
|
|
|
|
// 3. The difference shouldn't be unreasonably large
|
|
// Let's say not more than 100ms (100,000,000 ns)
|
|
expect(diff <= 100_000_000n).toBe(true);
|
|
});
|
|
});
|