Skip to content

Commit f39352b

Browse files
joyeecheungrichardlau
authored andcommitted
test: split test-fs-cp.js
This test previously squeezed 70+ test cases into one single file and has been constantly crashing on Windows with exit code 3221226505 and no stack trace. As it is already marked as flaky there is no way to understand which test case is failing and the Windows CI was constantly orange. This patch splits the test cases into different files so it's easier to find out which case is exactly failing and to be skipped. PR-URL: #59408 Refs: #56794 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Zeyu "Alex" Yang <[email protected]> Reviewed-By: Daeyeon Jeong <[email protected]> Reviewed-By: Filip Skokan <[email protected]>
1 parent 91fa83f commit f39352b

File tree

77 files changed

+1585
-1072
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1585
-1072
lines changed

test/common/fs.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'use strict';
2+
3+
const { mustNotMutateObjectDeep } = require('.');
4+
const { readdirSync } = require('node:fs');
5+
const { join } = require('node:path');
6+
const assert = require('node:assert');
7+
const tmpdir = require('./tmpdir.js');
8+
9+
let dirc = 0;
10+
function nextdir(dirname) {
11+
return tmpdir.resolve(dirname || `copy_%${++dirc}`);
12+
}
13+
14+
function assertDirEquivalent(dir1, dir2) {
15+
const dir1Entries = [];
16+
collectEntries(dir1, dir1Entries);
17+
const dir2Entries = [];
18+
collectEntries(dir2, dir2Entries);
19+
assert.strictEqual(dir1Entries.length, dir2Entries.length);
20+
for (const entry1 of dir1Entries) {
21+
const entry2 = dir2Entries.find((entry) => {
22+
return entry.name === entry1.name;
23+
});
24+
assert(entry2, `entry ${entry2.name} not copied`);
25+
if (entry1.isFile()) {
26+
assert(entry2.isFile(), `${entry2.name} was not file`);
27+
} else if (entry1.isDirectory()) {
28+
assert(entry2.isDirectory(), `${entry2.name} was not directory`);
29+
} else if (entry1.isSymbolicLink()) {
30+
assert(entry2.isSymbolicLink(), `${entry2.name} was not symlink`);
31+
}
32+
}
33+
}
34+
35+
function collectEntries(dir, dirEntries) {
36+
const newEntries = readdirSync(dir, mustNotMutateObjectDeep({ withFileTypes: true }));
37+
for (const entry of newEntries) {
38+
if (entry.isDirectory()) {
39+
collectEntries(join(dir, entry.name), dirEntries);
40+
}
41+
}
42+
dirEntries.push(...newEntries);
43+
}
44+
45+
module.exports = {
46+
nextdir,
47+
assertDirEquivalent,
48+
collectEntries,
49+
};

test/parallel/parallel.status

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,14 @@ test-runner-watch-mode-complex: PASS, FLAKY
3030
test-async-context-frame: PASS, FLAKY
3131
# https://github.com/nodejs/node/issues/54534
3232
test-runner-run-watch: PASS, FLAKY
33-
# https://github.com/nodejs/node/issues/56794
34-
test-fs-cp: PASS, FLAKY
33+
# https://github.com/nodejs/node/pull/59408#issuecomment-3170650933
34+
test-fs-cp-sync-error-on-exist: PASS, FLAKY
35+
test-fs-cp-sync-copy-symlink-not-pointing-to-folder: PASS, FLAKY
36+
test-fs-cp-sync-symlink-points-to-dest-error: PASS, FLAKY
37+
test-fs-cp-sync-resolve-relative-symlinks-false: PASS, FLAKY
38+
test-fs-cp-async-symlink-points-to-dest: PASS, FLAKY
39+
test-fs-cp-sync-unicode-folder-names: PASS, FLAKY
40+
test-fs-cp-sync-resolve-relative-symlinks-default: PASS, FLAKY
3541

3642
# https://github.com/nodejs/node/issues/56751
3743
test-without-async-context-frame: PASS, FLAKY
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// This tests that cp() supports async filter function.
2+
3+
import { mustCall } from '../common/index.mjs';
4+
import { nextdir, collectEntries } from '../common/fs.js';
5+
import assert from 'node:assert';
6+
import { cp, statSync } from 'node:fs';
7+
import { setTimeout } from 'node:timers/promises';
8+
import tmpdir from '../common/tmpdir.js';
9+
import fixtures from '../common/fixtures.js';
10+
tmpdir.refresh();
11+
12+
const src = fixtures.path('copy/kitchen-sink');
13+
const dest = nextdir();
14+
cp(src, dest, {
15+
filter: async (path) => {
16+
await setTimeout(5, 'done');
17+
const pathStat = statSync(path);
18+
return pathStat.isDirectory() || path.endsWith('.js');
19+
},
20+
dereference: true,
21+
recursive: true,
22+
}, mustCall((err) => {
23+
assert.strictEqual(err, null);
24+
const destEntries = [];
25+
collectEntries(dest, destEntries);
26+
for (const entry of destEntries) {
27+
assert.strictEqual(
28+
entry.isDirectory() || entry.name.endsWith('.js'),
29+
true
30+
);
31+
}
32+
}));
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// This tests that cp() copies link if it does not point to folder in src.
2+
3+
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
4+
import { nextdir } from '../common/fs.js';
5+
import assert from 'node:assert';
6+
import { cp, mkdirSync, readlinkSync, symlinkSync } from 'node:fs';
7+
import { join } from 'node:path';
8+
import tmpdir from '../common/tmpdir.js';
9+
10+
tmpdir.refresh();
11+
12+
const src = nextdir();
13+
mkdirSync(join(src, 'a', 'b'), mustNotMutateObjectDeep({ recursive: true }));
14+
symlinkSync(src, join(src, 'a', 'c'));
15+
const dest = nextdir();
16+
mkdirSync(join(dest, 'a'), mustNotMutateObjectDeep({ recursive: true }));
17+
symlinkSync(dest, join(dest, 'a', 'c'));
18+
cp(src, dest, mustNotMutateObjectDeep({ recursive: true }), mustCall((err) => {
19+
assert.strictEqual(err, null);
20+
const link = readlinkSync(join(dest, 'a', 'c'));
21+
assert.strictEqual(link, src);
22+
}));
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This tests that it does not fail if the same directory is copied to dest
2+
// twice, when dereference is true, and force is false (fails silently).
3+
4+
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
5+
import assert from 'node:assert';
6+
import { cp, cpSync, lstatSync } from 'node:fs';
7+
import { join } from 'node:path';
8+
import { nextdir } from '../common/fs.js';
9+
import tmpdir from '../common/tmpdir.js';
10+
import fixtures from '../common/fixtures.js';
11+
12+
tmpdir.refresh();
13+
14+
const src = fixtures.path('copy/kitchen-sink');
15+
const dest = nextdir();
16+
const destFile = join(dest, 'a/b/README2.md');
17+
cpSync(src, dest, mustNotMutateObjectDeep({ dereference: true, recursive: true }));
18+
cp(src, dest, {
19+
dereference: true,
20+
recursive: true
21+
}, mustCall((err) => {
22+
assert.strictEqual(err, null);
23+
const stat = lstatSync(destFile);
24+
assert(stat.isFile());
25+
}));
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// This tests that cp() copies file itself, rather than symlink, when dereference is true.
2+
3+
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
4+
import { nextdir } from '../common/fs.js';
5+
import assert from 'node:assert';
6+
import { cp, lstatSync, mkdirSync, symlinkSync, writeFileSync } from 'node:fs';
7+
import { join } from 'node:path';
8+
import tmpdir from '../common/tmpdir.js';
9+
10+
tmpdir.refresh();
11+
12+
const src = nextdir();
13+
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
14+
writeFileSync(join(src, 'foo.js'), 'foo', 'utf8');
15+
symlinkSync(join(src, 'foo.js'), join(src, 'bar.js'));
16+
17+
const dest = nextdir();
18+
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
19+
const destFile = join(dest, 'foo.js');
20+
21+
cp(join(src, 'bar.js'), destFile, mustNotMutateObjectDeep({ dereference: true }),
22+
mustCall((err) => {
23+
assert.strictEqual(err, null);
24+
const stat = lstatSync(destFile);
25+
assert(stat.isFile());
26+
})
27+
);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// This tests that cp() returns error if parent directory of symlink in dest points to src.
2+
3+
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
4+
import { nextdir } from '../common/fs.js';
5+
import assert from 'node:assert';
6+
import { cp, mkdirSync, symlinkSync } from 'node:fs';
7+
import { join } from 'node:path';
8+
import tmpdir from '../common/tmpdir.js';
9+
10+
tmpdir.refresh();
11+
12+
const src = nextdir();
13+
mkdirSync(join(src, 'a'), mustNotMutateObjectDeep({ recursive: true }));
14+
const dest = nextdir();
15+
// Create symlink in dest pointing to src.
16+
const destLink = join(dest, 'b');
17+
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
18+
symlinkSync(src, destLink);
19+
cp(src, join(dest, 'b', 'c'), mustCall((err) => {
20+
assert.strictEqual(err.code, 'ERR_FS_CP_EINVAL');
21+
}));
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// This tests that cp() returns error if attempt is made to copy directory to file.
2+
3+
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
4+
import { nextdir } from '../common/fs.js';
5+
import assert from 'node:assert';
6+
import { cp, mkdirSync } from 'node:fs';
7+
import tmpdir from '../common/tmpdir.js';
8+
import fixtures from '../common/fixtures.js';
9+
10+
tmpdir.refresh();
11+
12+
const src = nextdir();
13+
mkdirSync(src, mustNotMutateObjectDeep({ recursive: true }));
14+
const dest = fixtures.path('copy/kitchen-sink/README.md');
15+
cp(src, dest, mustCall((err) => {
16+
assert.strictEqual(err.code, 'ERR_FS_CP_DIR_TO_NON_DIR');
17+
}));
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// This tests that cp() returns error if errorOnExist is true, force is false, and file or folder copied over.
2+
3+
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
4+
import { nextdir } from '../common/fs.js';
5+
import assert from 'node:assert';
6+
import { cp, cpSync } from 'node:fs';
7+
import tmpdir from '../common/tmpdir.js';
8+
import fixtures from '../common/fixtures.js';
9+
10+
tmpdir.refresh();
11+
12+
const src = fixtures.path('copy/kitchen-sink');
13+
const dest = nextdir();
14+
cpSync(src, dest, mustNotMutateObjectDeep({ recursive: true }));
15+
cp(src, dest, {
16+
dereference: true,
17+
errorOnExist: true,
18+
force: false,
19+
recursive: true,
20+
}, mustCall((err) => {
21+
assert.strictEqual(err.code, 'ERR_FS_CP_EEXIST');
22+
}));
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// This tests that cp() returns error if attempt is made to copy file to directory.
2+
3+
import { mustCall, mustNotMutateObjectDeep } from '../common/index.mjs';
4+
import { nextdir } from '../common/fs.js';
5+
import assert from 'node:assert';
6+
import { cp, mkdirSync } from 'node:fs';
7+
import tmpdir from '../common/tmpdir.js';
8+
import fixtures from '../common/fixtures.js';
9+
10+
tmpdir.refresh();
11+
12+
const src = fixtures.path('copy/kitchen-sink/README.md');
13+
const dest = nextdir();
14+
mkdirSync(dest, mustNotMutateObjectDeep({ recursive: true }));
15+
cp(src, dest, mustCall((err) => {
16+
assert.strictEqual(err.code, 'ERR_FS_CP_NON_DIR_TO_DIR');
17+
}));

0 commit comments

Comments
 (0)