/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/unit_node/v8_test.ts
261 строка
7 KB
em
fix(ext/node): trace v8 serializer delegate (#35132)
11 июн 2026, 19:49
Не верифицирован
11 июн 2026, 19:49
d9703a4
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. import * as v8 from "node:v8"; import { Buffer } from "node:buffer"; import { runInNewContext } from "node:vm"; import { assertEquals, assertThrows } from "@std/assert"; // https://github.com/nodejs/node/blob/a2bbe5ff216bc28f8dac1c36a8750025a93c3827/test/parallel/test-v8-version-tag.js#L6 Deno.test({ name: "cachedDataVersionTag success", fn() { const tag = v8.cachedDataVersionTag(); assertEquals(typeof tag, "number"); assertEquals(v8.cachedDataVersionTag(), tag); }, }); // https://github.com/nodejs/node/blob/a2bbe5ff216bc28f8dac1c36a8750025a93c3827/test/parallel/test-v8-stats.js#L6 Deno.test({ name: "getHeapStatistics success", fn() { const s = v8.getHeapStatistics(); const keys = [ "does_zap_garbage", "external_memory", "heap_size_limit", "malloced_memory", "number_of_detached_contexts", "number_of_native_contexts", "peak_malloced_memory", "total_allocated_bytes", "total_available_size", "total_global_handles_size", "total_heap_size", "total_heap_size_executable", "total_physical_size", "used_global_handles_size", "used_heap_size", ]; assertEquals(Object.keys(s).sort(), keys); for (const k of keys) { assertEquals( typeof (s as unknown as Record<string, unknown>)[k], "number", ); } }, }); Deno.test({ name: "setFlagsFromString", fn() { v8.setFlagsFromString("--allow_natives_syntax"); }, }); Deno.test({ name: "setFlagsFromString exposes gc to new vm contexts", fn() { v8.setFlagsFromString("--expose_gc"); const gc = runInNewContext("gc"); assertEquals(typeof gc, "function"); assertEquals(gc(), undefined); }, }); Deno.test({ name: "serialize deserialize", fn() { const s = v8.serialize({ a: 1 }); const d = v8.deserialize(s); assertEquals(d, { a: 1 }); }, }); // https://github.com/denoland/deno/issues/35113 Deno.test({ name: "serialize emits wire format version 15 for Node.js interop", fn() { const values = [ { a: 1 }, "string", 123n, new Uint8Array([1, 2, 3]), new Map([["a", new ArrayBuffer(16)]]), ]; for (const value of values) { const s = v8.serialize(value); assertEquals(s[0], 0xFF); assertEquals(s[1], 0x0F); assertEquals(v8.deserialize(s), value); } // A serializer without a header is left untouched. const ser = new v8.Serializer(); ser.writeUint32(42); const raw = ser.releaseBuffer(); assertEquals(raw[0], 42); }, }); Deno.test({ name: "Deserializer keeps delegate alive across GC", fn() { v8.setFlagsFromString("--expose_gc"); const gc = runInNewContext("gc"); const serialized = v8.serialize(Buffer.from([1, 2, 3, 4])); class HostObjectDeserializer extends v8.DefaultDeserializer { calls = 0; _readHostObject() { this.calls++; const defaultDeserializer = v8.DefaultDeserializer.prototype as & v8.DefaultDeserializer & { _readHostObject(): unknown }; return defaultDeserializer._readHostObject.call(this); } } const deserializer = new HostObjectDeserializer(serialized); assertEquals(deserializer.readHeader(), true); for (let i = 0; i < 10; i++) { gc(); } const value = deserializer.readValue(); assertEquals(value, Buffer.from([1, 2, 3, 4])); assertEquals(deserializer.calls, 1); }, }); Deno.test({ name: "Serializer keeps delegate alive across GC", fn() { v8.setFlagsFromString("--expose_gc"); const gc = runInNewContext("gc"); class HostObjectSerializer extends v8.DefaultSerializer { calls = 0; _writeHostObject(abView: unknown) { this.calls++; const defaultSerializer = v8.DefaultSerializer.prototype as & v8.DefaultSerializer & { _writeHostObject(abView: unknown): void }; return defaultSerializer._writeHostObject.call(this, abView); } } const serializer = new HostObjectSerializer(); serializer.writeHeader(); for (let i = 0; i < 10; i++) { gc(); } serializer.writeValue(Buffer.from([1, 2, 3, 4])); const serialized = serializer.releaseBuffer(); assertEquals(serializer.calls, 1); assertEquals(v8.deserialize(serialized), Buffer.from([1, 2, 3, 4])); }, }); Deno.test({ name: "writeHeapSnapshot requires write permission", permissions: { write: false }, fn() { assertThrows(() => { v8.writeHeapSnapshot("test.heapsnapshot"); }, Deno.errors.NotCapable); }, }); Deno.test({ name: "queryObjects counts instances by constructor", fn() { class QueryObjectsTestFixture {} const before = v8.queryObjects(QueryObjectsTestFixture, { format: "count", }); assertEquals(typeof before, "number"); const instances = []; for (let i = 0; i < 50; i++) { instances.push(new QueryObjectsTestFixture()); } const after = v8.queryObjects(QueryObjectsTestFixture, { format: "count", }); assertEquals(after - before >= 50, true); const summary = v8.queryObjects(QueryObjectsTestFixture, { format: "summary", }); assertEquals(Array.isArray(summary), true); assertEquals((summary as string[]).length, 1); assertEquals( (summary as string[])[0].includes("QueryObjectsTestFixture"), true, ); // Keep the instances reachable until after the snapshot. assertEquals(instances.length, 50); }, }); Deno.test({ name: "queryObjects validates the constructor argument", fn() { assertThrows(() => { // @ts-expect-error testing invalid input v8.queryObjects("not a function"); }); }, }); Deno.test({ name: "queryObjects validates the format option", fn() { class Anything {} assertThrows(() => { v8.queryObjects( Anything, // @ts-expect-error testing invalid input { format: "bogus" }, ); }); }, }); Deno.test({ name: "startupSnapshot exposes the documented API surface", fn() { assertEquals(typeof v8.startupSnapshot, "object"); assertEquals( typeof v8.startupSnapshot.setDeserializeMainFunction, "function", ); assertEquals(typeof v8.startupSnapshot.addSerializeCallback, "function"); assertEquals(typeof v8.startupSnapshot.addDeserializeCallback, "function"); assertEquals(typeof v8.startupSnapshot.isBuildingSnapshot, "function"); assertEquals(v8.startupSnapshot.isBuildingSnapshot(), false); }, }); Deno.test({ name: "startupSnapshot.addSerializeCallback and addDeserializeCallback accept callables", fn() { // Storing callbacks must not throw; Deno has no snapshot lifecycle so the // callbacks are never invoked. v8.startupSnapshot.addSerializeCallback(() => {}); v8.startupSnapshot.addDeserializeCallback(() => {}); assertThrows(() => { // @ts-expect-error testing invalid input v8.startupSnapshot.addSerializeCallback("not a function"); }); assertThrows(() => { // @ts-expect-error testing invalid input v8.startupSnapshot.addDeserializeCallback(123); }); }, });