Skip to content
File

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

javascript171 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 { ok, notStrictEqual, strictEqual, rejects } 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 { promises } from 'node:fs';
10 
11export const openCloseTest = {
12 async test() {
13 const fileHandle = await promises.open('/tmp/test.txt', 'w+');
14 strictEqual(fileHandle.constructor.name, 'FileHandle');
15 
16 // If the FileHandle is opened successfully, stat should work.
17 const stat = await fileHandle.stat();
18 ok(stat.isFile());
19 
20 // Close the file handle
21 await fileHandle.close();
22 
23 // Verify that the file handle is closed
24 await rejects(fileHandle.stat(), {
25 code: 'EBADF',
26 });
27 },
28};
29 
30export const chmodChownTest = {
31 async test() {
32 await using fileHandle = await promises.open('/tmp/test.txt', 'w+');
33 
34 const stat = await fileHandle.stat();
35 ok(stat.isFile());
36 
37 // Change the file mode
38 await fileHandle.chmod(0o644);
39 
40 // Verify the mode has not changed since chmod is a no-op
41 const newStat = await fileHandle.stat();
42 strictEqual(newStat.mode, stat.mode);
43 
44 // Change the file ownership
45 await fileHandle.chown(1000, 1000);
46 // Verify the ownership has not changed since chown is a no-op
47 const newStat2 = await fileHandle.stat();
48 strictEqual(newStat2.uid, stat.uid);
49 strictEqual(newStat2.gid, stat.gid);
50 },
51};
52 
53export const syncTest = {
54 async test() {
55 await using fileHandle = await promises.open('/tmp/test.txt', 'w+');
56 strictEqual(fileHandle.constructor.name, 'FileHandle');
57 
58 // If the FileHandle is opened successfully, stat should work.
59 const stat = await fileHandle.stat();
60 ok(stat.isFile());
61 
62 // These are non-ops with no testable side effect. Just make
63 // sure they don't reject.
64 await fileHandle.sync();
65 await fileHandle.datasync();
66 },
67};
68 
69export const writeAppendReadFileTest = {
70 async test() {
71 await using fileHandle = await promises.open('/tmp/test.txt', 'a+');
72 strictEqual(fileHandle.constructor.name, 'FileHandle');
73 
74 await fileHandle.writeFile('Hello, World');
75 
76 // Append some data to the file
77 await fileHandle.appendFile('!!!!\n');
78 
79 // Read the file back
80 const data = await fileHandle.readFile('utf8');
81 strictEqual(data, 'Hello, World!!!!\n');
82 },
83};
84 
85export const writeReadTest = {
86 async test() {
87 // Note that we're opening the file in append mode...
88 await using fileHandle = await promises.open('/tmp/test.txt', 'a+');
89 strictEqual(fileHandle.constructor.name, 'FileHandle');
90 
91 // Write some data to the file
92 await fileHandle.write('Hello, World');
93 
94 // Append some data to the file
95 await fileHandle.write('!!!!\n');
96 
97 // Read the file back
98 const buffer = Buffer.alloc(100);
99 const { bytesRead } = await fileHandle.read(buffer, 0, buffer.length, 0);
100 strictEqual(bytesRead, 17);
101 strictEqual(buffer.toString('utf8', 0, bytesRead), 'Hello, World!!!!\n');
102 
103 // Use readv
104 const buffer2 = Buffer.alloc(10);
105 const buffer3 = Buffer.alloc(10);
106 const { bytesRead: bytesRead2 } = await fileHandle.readv(
107 [buffer2, buffer3],
108 0
109 );
110 strictEqual(bytesRead2, 17);
111 const buffer4 = Buffer.concat([buffer2, buffer3]);
112 strictEqual(buffer4.toString('utf8', 0, bytesRead2), 'Hello, World!!!!\n');
113 
114 await fileHandle.writev(
115 [Buffer.from('More data'), Buffer.from(' to write\n')],
116 0
117 );
118 // Read the file back again
119 const buffer5 = Buffer.alloc(100);
120 const { bytesRead: bytesRead3 } = await fileHandle.read(
121 buffer5,
122 0,
123 buffer5.length,
124 0
125 );
126 strictEqual(bytesRead3, 36);
127 strictEqual(
128 buffer5.toString('utf8', 0, bytesRead3),
129 'Hello, World!!!!\nMore data to write\n'
130 );
131 },
132};
133 
134export const truncateTest = {
135 async test() {
136 await using fileHandle = await promises.open('/tmp/test.txt', 'w+');
137 strictEqual(fileHandle.constructor.name, 'FileHandle');
138 
139 // Write some data to the file
140 await fileHandle.writeFile('Hello, World');
141 
142 // Truncate the file to 5 bytes
143 await fileHandle.truncate(5);
144 
145 // Read the file back
146 const data = await fileHandle.readFile('utf8');
147 strictEqual(data, 'Hello');
148 },
149};
150 
151export const utimesTest = {
152 async test() {
153 await using fileHandle = await promises.open('/tmp/test.txt', 'w+');
154 strictEqual(fileHandle.constructor.name, 'FileHandle');
155 
156 // If the FileHandle is opened successfully, stat should work.
157 const stat = await fileHandle.stat();
158 ok(stat.isFile());
159 
160 // Update the access and modification times
161 const now = new Date();
162 await fileHandle.utimes(now, now);
163 
164 const newStat = await fileHandle.stat();
165 
166 // atime should not be changed, mtime should.
167 strictEqual(newStat.atime.getTime(), stat.atime.getTime());
168 notStrictEqual(newStat.mtime.getTime(), stat.mtime.getTime());
169 },
170};