mirror of
https://github.com/Microsoft/vscode
synced 2024-10-06 03:17:00 +00:00
Smoke-Test: Hot-exit / dataloss tests broken (#89905)
* smoke test - carefuly select untitled content based on file name to find it properly * Fileservice: mkdirp() logic is prone to errors from race conditions (fixes #89834)
This commit is contained in:
parent
39e290dbbc
commit
d6eb50caa4
|
@ -752,7 +752,22 @@ export class FileService extends Disposable implements IFileService {
|
|||
// Create directories as needed
|
||||
for (let i = directoriesToCreate.length - 1; i >= 0; i--) {
|
||||
directory = joinPath(directory, directoriesToCreate[i]);
|
||||
await provider.mkdir(directory);
|
||||
|
||||
try {
|
||||
await provider.mkdir(directory);
|
||||
} catch (error) {
|
||||
if (toFileSystemProviderErrorCode(error) !== FileSystemProviderErrorCode.FileExists) {
|
||||
// For mkdirp() we tolerate that the mkdir() call fails
|
||||
// in case the folder already exists. This follows node.js
|
||||
// own implementation of fs.mkdir({ recursive: true }) and
|
||||
// reduces the chances of race conditions leading to errors
|
||||
// if multiple calls try to create the same folders
|
||||
// As such, we only throw an error here if it is other than
|
||||
// the fact that the file already exists.
|
||||
// (see also https://github.com/microsoft/vscode/issues/89834)
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import { FileOperation, FileOperationEvent, IFileStat, FileOperationResult, File
|
|||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { isLinux, isWindows } from 'vs/base/common/platform';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { isEqual, joinPath } from 'vs/base/common/resources';
|
||||
import { VSBuffer, VSBufferReadable, streamToBufferReadableStream, VSBufferReadableStream, bufferToReadable, bufferToStream, streamToBuffer } from 'vs/base/common/buffer';
|
||||
import { find } from 'vs/base/common/arrays';
|
||||
|
||||
|
@ -1867,6 +1867,47 @@ suite('Disk File Service', function () {
|
|||
assert.ok(!error);
|
||||
});
|
||||
|
||||
test('writeFile - no error when writing to same non-existing folder multiple times different new files', async () => {
|
||||
const newFolder = URI.file(join(testDir, 'some', 'new', 'folder'));
|
||||
|
||||
const file1 = joinPath(newFolder, 'file-1');
|
||||
const file2 = joinPath(newFolder, 'file-2');
|
||||
const file3 = joinPath(newFolder, 'file-3');
|
||||
|
||||
// this essentially verifies that the mkdirp logic implemented
|
||||
// in the file service is able to receive multiple requests for
|
||||
// the same folder and will not throw errors if another racing
|
||||
// call succeeded first.
|
||||
const newContent = 'Updates to the small file';
|
||||
await Promise.all([
|
||||
service.writeFile(file1, VSBuffer.fromString(newContent)),
|
||||
service.writeFile(file2, VSBuffer.fromString(newContent)),
|
||||
service.writeFile(file3, VSBuffer.fromString(newContent))
|
||||
]);
|
||||
|
||||
assert.ok(service.exists(file1));
|
||||
assert.ok(service.exists(file2));
|
||||
assert.ok(service.exists(file3));
|
||||
});
|
||||
|
||||
test('writeFile - error when writing to folder that is a file', async () => {
|
||||
const existingFile = URI.file(join(testDir, 'my-file'));
|
||||
|
||||
await service.createFile(existingFile);
|
||||
|
||||
const newFile = joinPath(existingFile, 'file-1');
|
||||
|
||||
let error;
|
||||
const newContent = 'Updates to the small file';
|
||||
try {
|
||||
await service.writeFile(newFile, VSBuffer.fromString(newContent));
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
assert.ok(error);
|
||||
});
|
||||
|
||||
const runWatchTests = isLinux;
|
||||
|
||||
(runWatchTests ? test : test.skip)('watch - file', done => {
|
||||
|
|
|
@ -12,7 +12,7 @@ export function setup() {
|
|||
await app.workbench.editors.newUntitledFile();
|
||||
|
||||
const untitled = 'Untitled-1';
|
||||
const textToTypeInUntitled = 'Hello, Untitled Code';
|
||||
const textToTypeInUntitled = untitled;
|
||||
await app.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled);
|
||||
|
||||
const readmeMd = 'readme.md';
|
||||
|
|
|
@ -66,7 +66,7 @@ export function setup(stableCodePath: string, testDataPath: string) {
|
|||
await stableApp.workbench.editors.newUntitledFile();
|
||||
|
||||
const untitled = 'Untitled-1';
|
||||
const textToTypeInUntitled = 'Hello, Untitled Code';
|
||||
const textToTypeInUntitled = untitled;
|
||||
await stableApp.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled);
|
||||
|
||||
const readmeMd = 'readme.md';
|
||||
|
|
Loading…
Reference in a new issue