Skip to content

Commit aac7925

Browse files
authored
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 ca76b39 commit aac7925

File tree

77 files changed

+1585
-1100
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
-1100
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
@@ -24,8 +24,14 @@ test-snapshot-incompatible: SKIP
2424
test-async-context-frame: PASS, FLAKY
2525
# https://github.com/nodejs/node/issues/54534
2626
test-runner-run-watch: PASS, FLAKY
27-
# https://github.com/nodejs/node/issues/56794
28-
test-fs-cp: PASS, FLAKY
27+
# https://github.com/nodejs/node/pull/59408#issuecomment-3170650933
28+
test-fs-cp-sync-error-on-exist: PASS, FLAKY
29+
test-fs-cp-sync-copy-symlink-not-pointing-to-folder: PASS, FLAKY
30+
test-fs-cp-sync-symlink-points-to-dest-error: PASS, FLAKY
31+
test-fs-cp-sync-resolve-relative-symlinks-false: PASS, FLAKY
32+
test-fs-cp-async-symlink-points-to-dest: PASS, FLAKY
33+
test-fs-cp-sync-unicode-folder-names: PASS, FLAKY
34+
test-fs-cp-sync-resolve-relative-symlinks-default: PASS, FLAKY
2935

3036
# https://github.com/nodejs/node/issues/56751
3137
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)