ignore all rimraf errors to fix windows flakes

This commit is contained in:
Evan Wallace
2020-12-20 21:05:26 -08:00
parent 467124b71d
commit 9edbd8f0f0
8 changed files with 47 additions and 63 deletions

View File

@@ -13,8 +13,7 @@
}
const childProcess = await import('child_process')
const { default: { buildBinary, dirname } } = await import('./esbuild.js')
const { default: rimraf } = await import('rimraf')
const { default: { buildBinary, dirname, removeRecursiveSync } } = await import('./esbuild.js')
const assert = await import('assert')
const path = await import('path')
const util = await import('util')
@@ -2147,7 +2146,7 @@
}
// Clean up test output
rimraf.sync(thisTestDir, { disableGlob: true });
removeRecursiveSync(thisTestDir)
}
catch (e) {
@@ -2156,7 +2155,7 @@
assert.strictEqual(e.stderr, expectedStderr);
// Clean up test output
rimraf.sync(thisTestDir, { disableGlob: true });
removeRecursiveSync(thisTestDir)
continue;
} catch (e2) {
e = e2;
@@ -2193,7 +2192,7 @@
})
// Clean up test output
rimraf.sync(thisTestDir, { disableGlob: true })
removeRecursiveSync(thisTestDir)
} catch (e) {
console.error(`❌ test failed: ${e && e.message || e}
dir: ${path.relative(dirname, thisTestDir)}`)
@@ -2205,7 +2204,7 @@
}
// Create a fresh test directory
rimraf.sync(testDir, { disableGlob: true })
removeRecursiveSync(testDir)
await fs.mkdir(testDir, { recursive: true })
// Run all tests concurrently
@@ -2216,8 +2215,6 @@
process.exit(1)
} else {
console.log(`✅ end-to-end tests passed`)
// Clean up test output
rimraf.sync(testDir, { disableGlob: true })
removeRecursiveSync(testDir)
}
})().catch(e => setTimeout(() => { throw e }))

View File

@@ -16,8 +16,7 @@
return
}
const { default: { buildBinary, dirname } } = await import('./esbuild.js');
const { default: rimraf } = await import('rimraf');
const { default: { buildBinary, dirname, removeRecursiveSync } } = await import('./esbuild.js');
const childProcess = await import('child_process');
const util = await import('util');
const path = await import('path');
@@ -120,11 +119,11 @@
}
// Remove data for successful tests
rimraf.sync(testDir, { disableGlob: true });
removeRecursiveSync(testDir);
}
const parentDir = path.join(dirname, '.es6-fuzzer');
rimraf.sync(parentDir, { disableGlob: true });
removeRecursiveSync(parentDir);
fs.mkdirSync(parentDir);
// Run a set number of tests in parallel
@@ -140,6 +139,6 @@
// Remove everything if all tests passed
if (failureCount === 0) {
rimraf.sync(parentDir, { disableGlob: true });
removeRecursiveSync(parentDir);
}
})().catch(e => setTimeout(() => { throw e }));

View File

@@ -112,6 +112,26 @@ exports.buildBinary = () => {
return path.join(repoDir, process.platform === 'win32' ? 'esbuild.exe' : 'esbuild')
}
exports.removeRecursiveSync = path => {
try {
// Strangely node doesn't have a function to remove a directory tree.
// Using "rm -fr" will never work on Windows because the "rm" command
// doesn't exist. Using the "rimraf" should be cross-platform and even
// works on Windows some of the time.
rimraf.sync(testDir, { disableGlob: true })
} catch (e) {
// Removing stuff on Windows is flaky and unreliable. Don't fail tests
// on CI if Windows is just being a pain. Common causes of flakes include
// random EPERM and ENOTEMPTY errors.
//
// The general "solution" to this is to try asking Windows to redo the
// failing operation repeatedly until eventually giving up after a
// timeout. But that doesn't guarantee that flakes will be fixed so we
// just give up instead. People that want reasonable file system
// behavior on Windows should use WSL instead.
}
}
exports.installForTests = () => {
// Build the "esbuild" binary and library
const esbuildPath = exports.buildBinary()

View File

@@ -1,6 +1,5 @@
const { installForTests } = require('./esbuild')
const { installForTests, removeRecursiveSync } = require('./esbuild')
const { SourceMapConsumer } = require('source-map')
const rimraf = require('rimraf')
const assert = require('assert')
const path = require('path')
const http = require('http')
@@ -2299,7 +2298,7 @@ async function main() {
const esbuild = installForTests()
// Create a fresh test directory
rimraf.sync(rootTestDir, { disableGlob: true })
removeRecursiveSync(rootTestDir)
fs.mkdirSync(rootTestDir)
// Time out these tests after 5 minutes. This exists to help debug test hangs in CI.
@@ -2318,7 +2317,7 @@ async function main() {
try {
await mkdirAsync(testDir)
await fn({ esbuild, service, testDir })
rimraf.sync(testDir, { disableGlob: true })
removeRecursiveSync(testDir)
return true
} catch (e) {
console.error(`${name}: ${e && e.message || e}`)
@@ -2346,24 +2345,7 @@ async function main() {
process.exit(1)
} else {
console.log(`✅ js api tests passed`)
// This randomly fails with EPERM on Windows in CI (GitHub Actions):
//
// Error: EPERM: operation not permitted: unlink 'esbuild\scripts\.js-api-tests\node_modules\esbuild\esbuild.exe'
// at Object.unlinkSync (fs.js)
// at fixWinEPERMSync (esbuild\scripts\node_modules\rimraf\rimraf.js)
// at rimrafSync (esbuild\scripts\node_modules\rimraf\rimraf.js)
//
// From searching related issues on GitHub it looks like apparently this is
// just how Windows works? It's kind of hard to believe something as
// fundamental as file operations is broken on Windows. It sounds like the
// file system implementation on Windows has race conditions or something.
// Anyway, deleting this is not important for the success of the test so
// just ignore errors here.
try {
rimraf.sync(rootTestDir, { disableGlob: true })
} catch (e) {
}
removeRecursiveSync(rootTestDir)
}
clearTimeout(timeout);

View File

@@ -1,5 +1,4 @@
const { installForTests } = require('./esbuild')
const rimraf = require('rimraf')
const { installForTests, removeRecursiveSync } = require('./esbuild')
const assert = require('assert')
const path = require('path')
const util = require('util')
@@ -966,7 +965,7 @@ async function main() {
const esbuild = installForTests()
// Create a fresh test directory
rimraf.sync(rootTestDir, { disableGlob: true })
removeRecursiveSync(rootTestDir)
fs.mkdirSync(rootTestDir)
// Time out these tests after 5 minutes. This exists to help debug test hangs in CI.
@@ -985,7 +984,7 @@ async function main() {
try {
await mkdirAsync(testDir)
await fn({ esbuild, service, testDir })
rimraf.sync(testDir, { disableGlob: true })
removeRecursiveSync(testDir)
return true
} catch (e) {
console.error(`${name}: ${e && e.message || e}`)
@@ -1003,13 +1002,7 @@ async function main() {
process.exit(1)
} else {
console.log(`✅ plugin tests passed`)
try {
rimraf.sync(rootTestDir, { disableGlob: true })
} catch (e) {
// This doesn't work on Windows due to "EPERM: operation not permitted"
// but that's ok for CI because the VM will just be thrown away anyway.
}
removeRecursiveSync(rootTestDir)
}
clearTimeout(timeout);

View File

@@ -1,14 +1,13 @@
const { installForTests } = require('./esbuild')
const { installForTests, removeRecursiveSync } = require('./esbuild')
const child_process = require('child_process')
const path = require('path')
const fs = require('fs')
const rimraf = require('rimraf')
const assert = require('assert')
const esbuild = installForTests()
// Create a fresh test directory
const rootTestDir = path.join(__dirname, '.register-test')
rimraf.sync(rootTestDir, { disableGlob: true })
removeRecursiveSync(rootTestDir)
fs.mkdirSync(rootTestDir)
const entry = path.join(rootTestDir, 'entry.ts')
@@ -49,12 +48,7 @@ async function main() {
main().then(
() => {
console.log(`✅ register test passed`)
try {
rimraf.sync(rootTestDir, { disableGlob: true })
} catch (e) {
// This doesn't work on Windows due to "EPERM: operation not permitted"
// but that's ok for CI because the VM will just be thrown away anyway.
}
removeRecursiveSync(rootTestDir)
},
e => {
console.error(`❌ register test failed: ${e && e.message || e}`)

View File

@@ -1,5 +1,5 @@
const { removeRecursiveSync } = require('./esbuild')
const child_process = require('child_process')
const rimraf = require('rimraf')
const path = require('path')
const fs = require('fs')
@@ -318,7 +318,7 @@ const tests = {
async function main() {
let testDir = path.join(__dirname, '.ts-types-test')
rimraf.sync(testDir, { disableGlob: true })
removeRecursiveSync(testDir)
fs.mkdirSync(testDir, { recursive: true })
fs.writeFileSync(path.join(testDir, 'tsconfig.json'), JSON.stringify(tsconfigJson))
@@ -349,7 +349,7 @@ async function main() {
process.exit(1)
} else {
console.log(`✅ typescript type tests passed`)
rimraf.sync(testDir, { disableGlob: true })
removeRecursiveSync(testDir)
}
}

View File

@@ -1,7 +1,6 @@
const { SourceMapConsumer } = require('source-map')
const { buildBinary } = require('./esbuild')
const { buildBinary, removeRecursiveSync } = require('./esbuild')
const childProcess = require('child_process')
const rimraf = require('rimraf')
const path = require('path')
const util = require('util')
const fs = require('fs').promises
@@ -341,7 +340,7 @@ async function check(kind, testCase, toSearch, { flags, entryPoints, crlf }) {
checkMap(out2Js, out2Map, tempDir)
}
if (!failed) rimraf.sync(tempDir, { disableGlob: true })
if (!failed) removeRecursiveSync(tempDir)
}
catch (e) {
@@ -424,7 +423,7 @@ async function main() {
process.exit(1)
} else {
console.log(`✅ verify source map passed`)
rimraf.sync(testDir, { disableGlob: true })
removeRecursiveSync(testDir)
}
}