Skip to content

Commit ea10da9

Browse files
authored
port test_sharedarraybuffer to CTS (#46)
* port test_sharedarraybuffer to CTS ports [test_sharedarraybuffer] from the Node.js test suite to the CTS. Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * use skipTest and version check for experimental features Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * remove redundant file Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * remove process module consumption Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com> * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts * Update implementors/node/tests.ts --------- Signed-off-by: Balakrishna Avulapati <ba@bavulapati.com>
1 parent 32311d1 commit ea10da9

7 files changed

Lines changed: 232 additions & 10 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ function(add_node_api_cts_addon ADDON_NAME)
4545
endfunction()
4646

4747
function(add_node_api_cts_experimental_addon ADDON_NAME)
48-
cmake_parse_arguments(PARSE_ARGV 1 ARG "" "" "SOURCES")
49-
add_node_api_cts_addon(${ADDON_NAME} ${ARG_SOURCES})
48+
add_node_api_cts_addon(${ADDON_NAME} ${ARGN})
5049
target_compile_definitions(${ADDON_NAME} PRIVATE NAPI_EXPERIMENTAL)
5150
if(MSVC)
5251
target_link_libraries(${ADDON_NAME} PRIVATE ${NODE_API_EXPERIMENTAL_LIB})

PORTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Tests covering the engine-specific part of Node-API, defined in `js_native_api.h
6868
| `test_properties` | Ported ✅ | Easy |
6969
| `test_reference` | Not ported | Medium |
7070
| `test_reference_double_free` | Ported ✅ | Easy |
71-
| `test_sharedarraybuffer` | Not ported | Medium |
71+
| `test_sharedarraybuffer` | Ported ✅ | Medium |
7272
| `test_string` | Ported ✅ | Medium |
7373
| `test_symbol` | Ported ✅ | Easy |
7474
| `test_typedarray` | Ported ✅ | Medium |

implementors/node/features.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
// Declares which experimental Node-API features this runtime supports.
22
// Each key corresponds to a NODE_API_EXPERIMENTAL_HAS_* compile-time macro.
33
// Other implementors should set unsupported features to false or omit them.
4+
5+
const [major, minor] = process.version.slice(1).split('.').map(Number);
6+
47
globalThis.experimentalFeatures = {
5-
sharedArrayBuffer: true,
8+
// node_api_is_sharedarraybuffer and node_api_create_sharedarraybuffer were
9+
// added in Node.js v24.9.0. Earlier versions do not export these symbols,
10+
// causing addons that reference them to fail at dlopen time.
11+
sharedArrayBuffer: major >= 25 || (major === 24 && minor >= 9),
612
createObjectWithProperties: true,
713
setPrototype: true,
814
postFinalizer: true,

implementors/node/tests.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,7 @@ const LOAD_ADDON_MODULE_PATH = path.join(
2828
"node",
2929
"load-addon.js"
3030
);
31-
const GC_MODULE_PATH = path.join(
32-
ROOT_PATH,
33-
"implementors",
34-
"node",
35-
"gc.js"
36-
);
31+
const GC_MODULE_PATH = path.join(ROOT_PATH, "implementors", "node", "gc.js");
3732
const MUST_CALL_MODULE_PATH = path.join(
3833
ROOT_PATH,
3934
"implementors",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_node_api_cts_experimental_addon(test_sharedarraybuffer test_sharedarraybuffer.c)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"use strict";
2+
3+
// SharedArrayBuffer support is an experimental feature.
4+
if (!experimentalFeatures.sharedArrayBuffer) {
5+
skipTest();
6+
}
7+
8+
const test_sharedarraybuffer = loadAddon("test_sharedarraybuffer");
9+
10+
{
11+
const sab = new SharedArrayBuffer(16);
12+
const ab = new ArrayBuffer(16);
13+
const obj = {};
14+
const arr = [];
15+
16+
assert.strictEqual(
17+
test_sharedarraybuffer.TestIsSharedArrayBuffer(sab),
18+
true,
19+
);
20+
assert.strictEqual(
21+
test_sharedarraybuffer.TestIsSharedArrayBuffer(ab),
22+
false,
23+
);
24+
assert.strictEqual(
25+
test_sharedarraybuffer.TestIsSharedArrayBuffer(obj),
26+
false,
27+
);
28+
assert.strictEqual(
29+
test_sharedarraybuffer.TestIsSharedArrayBuffer(arr),
30+
false,
31+
);
32+
assert.strictEqual(
33+
test_sharedarraybuffer.TestIsSharedArrayBuffer(null),
34+
false,
35+
);
36+
assert.strictEqual(
37+
test_sharedarraybuffer.TestIsSharedArrayBuffer(undefined),
38+
false,
39+
);
40+
}
41+
42+
// Test node_api_create_sharedarraybuffer
43+
{
44+
const sab = test_sharedarraybuffer.TestCreateSharedArrayBuffer(16);
45+
assert(sab instanceof SharedArrayBuffer);
46+
assert.strictEqual(sab.byteLength, 16);
47+
}
48+
49+
// Test node_api_create_get_sharedarraybuffer_info
50+
{
51+
const sab = new SharedArrayBuffer(32);
52+
const byteLength = test_sharedarraybuffer.TestGetSharedArrayBufferInfo(sab);
53+
assert.strictEqual(byteLength, 32);
54+
}
55+
56+
// Test data access
57+
{
58+
const sab = new SharedArrayBuffer(8);
59+
const result = test_sharedarraybuffer.TestSharedArrayBufferData(sab);
60+
assert.strictEqual(result, true);
61+
62+
// Check if data was written correctly
63+
const view = new Uint8Array(sab);
64+
for (let i = 0; i < 8; i++) {
65+
assert.strictEqual(view[i], i % 256);
66+
}
67+
}
68+
69+
// Test data pointer from existing SharedArrayBuffer
70+
{
71+
const sab = new SharedArrayBuffer(16);
72+
const result = test_sharedarraybuffer.TestSharedArrayBufferData(sab);
73+
assert.strictEqual(result, true);
74+
}
75+
76+
// Test zero-length SharedArrayBuffer
77+
{
78+
const sab = test_sharedarraybuffer.TestCreateSharedArrayBuffer(0);
79+
assert(sab instanceof SharedArrayBuffer);
80+
assert.strictEqual(sab.byteLength, 0);
81+
}
82+
83+
// Test invalid arguments
84+
{
85+
assert.throws(
86+
() => {
87+
test_sharedarraybuffer.TestGetSharedArrayBufferInfo({});
88+
},
89+
{ name: "Error", message: "Invalid argument" },
90+
);
91+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#define NAPI_EXPERIMENTAL
2+
#include <js_native_api.h>
3+
#include <string.h>
4+
#include "../common.h"
5+
#include "../entry_point.h"
6+
7+
static napi_value TestIsSharedArrayBuffer(napi_env env,
8+
napi_callback_info info) {
9+
size_t argc = 1;
10+
napi_value args[1];
11+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
12+
13+
NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments");
14+
15+
bool is_sharedarraybuffer;
16+
NODE_API_CALL(
17+
env, node_api_is_sharedarraybuffer(env, args[0], &is_sharedarraybuffer));
18+
19+
napi_value ret;
20+
NODE_API_CALL(env, napi_get_boolean(env, is_sharedarraybuffer, &ret));
21+
22+
return ret;
23+
}
24+
25+
static napi_value TestCreateSharedArrayBuffer(napi_env env,
26+
napi_callback_info info) {
27+
size_t argc = 1;
28+
napi_value args[1];
29+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
30+
31+
NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments");
32+
33+
napi_valuetype valuetype0;
34+
NODE_API_CALL(env, napi_typeof(env, args[0], &valuetype0));
35+
36+
NODE_API_ASSERT(
37+
env,
38+
valuetype0 == napi_number,
39+
"Wrong type of arguments. Expects a number as first argument.");
40+
41+
int32_t byte_length;
42+
NODE_API_CALL(env, napi_get_value_int32(env, args[0], &byte_length));
43+
44+
NODE_API_ASSERT(env,
45+
byte_length >= 0,
46+
"Invalid byte length. Expects a non-negative integer.");
47+
48+
napi_value ret;
49+
void* data;
50+
NODE_API_CALL(
51+
env, node_api_create_sharedarraybuffer(env, byte_length, &data, &ret));
52+
53+
return ret;
54+
}
55+
56+
static napi_value TestGetSharedArrayBufferInfo(napi_env env,
57+
napi_callback_info info) {
58+
size_t argc = 1;
59+
napi_value args[1];
60+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
61+
62+
NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments");
63+
64+
void* data;
65+
size_t byte_length;
66+
NODE_API_CALL(env,
67+
napi_get_arraybuffer_info(env, args[0], &data, &byte_length));
68+
69+
napi_value ret;
70+
NODE_API_CALL(env, napi_create_uint32(env, byte_length, &ret));
71+
72+
return ret;
73+
}
74+
75+
static void WriteTestDataToBuffer(void* data, size_t byte_length) {
76+
if (byte_length > 0 && data != NULL) {
77+
uint8_t* bytes = (uint8_t*)data;
78+
for (size_t i = 0; i < byte_length; i++) {
79+
bytes[i] = i % 256;
80+
}
81+
}
82+
}
83+
84+
static napi_value TestSharedArrayBufferData(napi_env env,
85+
napi_callback_info info) {
86+
size_t argc = 1;
87+
napi_value args[1];
88+
NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
89+
90+
NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments");
91+
92+
void* data;
93+
size_t byte_length;
94+
NODE_API_CALL(env,
95+
napi_get_arraybuffer_info(env, args[0], &data, &byte_length));
96+
97+
WriteTestDataToBuffer(data, byte_length);
98+
99+
// Return the same data pointer validity
100+
bool data_valid = (data != NULL) && (byte_length > 0);
101+
102+
napi_value ret;
103+
NODE_API_CALL(env, napi_get_boolean(env, data_valid, &ret));
104+
105+
return ret;
106+
}
107+
108+
EXTERN_C_START
109+
napi_value Init(napi_env env, napi_value exports) {
110+
napi_property_descriptor descriptors[] = {
111+
DECLARE_NODE_API_PROPERTY("TestIsSharedArrayBuffer",
112+
TestIsSharedArrayBuffer),
113+
DECLARE_NODE_API_PROPERTY("TestCreateSharedArrayBuffer",
114+
TestCreateSharedArrayBuffer),
115+
DECLARE_NODE_API_PROPERTY("TestGetSharedArrayBufferInfo",
116+
TestGetSharedArrayBufferInfo),
117+
DECLARE_NODE_API_PROPERTY("TestSharedArrayBufferData",
118+
TestSharedArrayBufferData),
119+
};
120+
121+
NODE_API_CALL(
122+
env,
123+
napi_define_properties(env,
124+
exports,
125+
sizeof(descriptors) / sizeof(*descriptors),
126+
descriptors));
127+
128+
return exports;
129+
}
130+
EXTERN_C_END

0 commit comments

Comments
 (0)