Skip to content
File

Blob: src/workerd/api/node/tests/fs-misc-test.js

javascript241 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4import { notStrictEqual, strictEqual, throws } from 'node:assert';
5 
6// sync and datasync are generally non-ops. The most they do is
7// verify that the file descriptor is valid.
8 
9import {
10 openSync,
11 closeSync,
12 fsyncSync,
13 fdatasyncSync,
14 fdatasync,
15 fsync,
16 statfs,
17 statfsSync,
18 openAsBlob,
19 WriteStream,
20 FileWriteStream,
21 ReadStream,
22 FileReadStream,
23 constants,
24 F_OK,
25 R_OK,
26 W_OK,
27 X_OK,
28 writeFileSync,
29 writeSync,
30} from 'node:fs';
31 
32strictEqual(typeof openSync, 'function');
33strictEqual(typeof closeSync, 'function');
34strictEqual(typeof fdatasyncSync, 'function');
35strictEqual(typeof fsyncSync, 'function');
36strictEqual(typeof fdatasync, 'function');
37strictEqual(typeof fsync, 'function');
38 
39const kInvalidArgTypeError = { code: 'ERR_INVALID_ARG_TYPE' };
40const kBadFError = { code: 'EBADF' };
41 
42export const miscTest = {
43 async test() {
44 throws(() => fsyncSync(), kInvalidArgTypeError);
45 throws(() => fdatasyncSync(), kInvalidArgTypeError);
46 throws(() => fsyncSync('hello'), kInvalidArgTypeError);
47 throws(() => fdatasyncSync('hello'), kInvalidArgTypeError);
48 throws(() => fsync(), kInvalidArgTypeError);
49 throws(() => fdatasync(), kInvalidArgTypeError);
50 throws(() => fsync('hello'), kInvalidArgTypeError);
51 throws(() => fdatasync('hello'), kInvalidArgTypeError);
52 throws(() => fsyncSync(123), kBadFError);
53 throws(() => fdatasyncSync(123), kBadFError);
54 
55 const fd = openSync('/dev/null', 'r');
56 fsyncSync(fd);
57 fdatasyncSync(fd);
58 
59 {
60 const { promise, resolve, reject } = Promise.withResolvers();
61 fsync(fd, (err) => {
62 if (err) {
63 reject(err);
64 return;
65 }
66 resolve();
67 });
68 await promise;
69 }
70 
71 {
72 const { promise, resolve, reject } = Promise.withResolvers();
73 fdatasync(fd, (err) => {
74 if (err) {
75 reject(err);
76 return;
77 }
78 resolve();
79 });
80 await promise;
81 }
82 
83 {
84 const { promise, resolve, reject } = Promise.withResolvers();
85 fsync(123, (err) => {
86 if (!err) {
87 reject(new Error('Expected an error'));
88 return;
89 }
90 strictEqual(err.code, 'EBADF');
91 resolve();
92 });
93 await promise;
94 }
95 
96 {
97 const { promise, resolve, reject } = Promise.withResolvers();
98 fdatasync(123, (err) => {
99 if (!err) {
100 reject(new Error('Expected an error'));
101 return;
102 }
103 strictEqual(err.code, 'EBADF');
104 resolve();
105 });
106 await promise;
107 }
108 
109 closeSync(fd);
110 },
111};
112 
113export const statFsTest = {
114 async test() {
115 const stat = statfsSync('/');
116 strictEqual(typeof stat, 'object');
117 strictEqual(stat.type, 0);
118 strictEqual(stat.bsize, 0);
119 strictEqual(stat.blocks, 0);
120 strictEqual(stat.bfree, 0);
121 strictEqual(stat.bavail, 0);
122 strictEqual(stat.files, 0);
123 strictEqual(stat.ffree, 0);
124 
125 throws(() => statfsSync(123), {
126 code: 'ERR_INVALID_ARG_TYPE',
127 });
128 
129 throws(() => statfsSync('/does/not/exist', { bigint: 123 }), {
130 code: 'ERR_INVALID_ARG_TYPE',
131 });
132 
133 const { promise, resolve, reject } = Promise.withResolvers();
134 statfs('/', (err, stat) => {
135 if (err) reject(err);
136 else {
137 strictEqual(typeof stat, 'object');
138 strictEqual(stat.type, 0);
139 strictEqual(stat.bsize, 0);
140 strictEqual(stat.blocks, 0);
141 strictEqual(stat.bfree, 0);
142 strictEqual(stat.bavail, 0);
143 strictEqual(stat.files, 0);
144 strictEqual(stat.ffree, 0);
145 resolve();
146 }
147 });
148 await promise;
149 
150 throws(() => statfs(123, () => {}), {
151 code: 'ERR_INVALID_ARG_TYPE',
152 });
153 
154 throws(() => statfs('/does/not/exist', { bigint: 123 }), {
155 code: 'ERR_INVALID_ARG_TYPE',
156 });
157 },
158};
159 
160export const pathLimitTest = {
161 test() {
162 // Trying to open a path longer than 4096 characters should throw an error.
163 const longPath = '/tmp/a'.repeat(4097);
164 throws(() => openSync(longPath, 'r'), {
165 message: /File path is too long/,
166 });
167 
168 // Trying to open a path with more than 48 segments should throw an error.
169 const tooManySegments = '/a'.repeat(49);
170 throws(() => openSync(tooManySegments, 'r'), {
171 message: /File path has too many segments/,
172 });
173 },
174};
175 
176export const openAsBlobTest = {
177 async test() {
178 // We currently do not implement openAsBlob, but let's verify arg validation.
179 throws(() => openAsBlob(), {
180 code: 'ERR_INVALID_ARG_TYPE',
181 });
182 throws(() => openAsBlob(1), {
183 code: 'ERR_INVALID_ARG_TYPE',
184 });
185 throws(() => openAsBlob('/', 123), {
186 code: 'ERR_INVALID_ARG_TYPE',
187 });
188 throws(() => openAsBlob('/', { type: 123 }), {
189 code: 'ERR_INVALID_ARG_TYPE',
190 });
191 
192 writeFileSync('/tmp/abc', '123');
193 throws(() => openAsBlob('/'), {
194 message: /illegal operation on a directory/,
195 });
196 throws(() => openAsBlob(new URL('file:///')), {
197 message: /illegal operation on a directory/,
198 });
199 
200 const blob = openAsBlob('/tmp/abc', { type: 'text/plain' });
201 strictEqual(blob instanceof Blob, true);
202 strictEqual(blob.size, 3);
203 strictEqual(blob.type, 'text/plain');
204 strictEqual(await blob.text(), '123');
205 },
206};
207 
208export const otherExportsTest = {
209 test() {
210 strictEqual(WriteStream, FileWriteStream);
211 strictEqual(ReadStream, FileReadStream);
212 strictEqual(constants.F_OK, F_OK);
213 strictEqual(constants.R_OK, R_OK);
214 strictEqual(constants.W_OK, W_OK);
215 strictEqual(constants.X_OK, X_OK);
216 notStrictEqual(F_OK, undefined);
217 notStrictEqual(R_OK, undefined);
218 notStrictEqual(W_OK, undefined);
219 notStrictEqual(X_OK, undefined);
220 notStrictEqual(WriteStream, undefined);
221 notStrictEqual(ReadStream, undefined);
222 },
223};
224 
225export const oobWriteTest = {
226 test() {
227 const v3 = Buffer.from('Test data for write operations');
228 const fd = openSync('/tmp/write-test.bin');
229 throws(
230 () => {
231 strictEqual(writeSync(fd, v3, 10, 10, 4294967295), 0);
232 },
233 {
234 message: /File size limit exceeded/,
235 }
236 );
237 
238 strictEqual(writeSync(fd, v3, 10, 10, 134217718), 10);
239 },
240};