test('simple file operations, ignore', async () => { let request: IWatcherRequest = { basePath: testDir, ignored: ['**/b/**', '**/*.js', '.git/**'] }; service.setRoots([request]); await wait(300); assert.equal(service.wacherCount, 1); // create various ignored files let file1 = path.join(bFolder, 'file1.txt'); // hidden await pfs.writeFile(file1, 'Hello'); let file2 = path.join(b2Folder, 'file2.txt'); // hidden await pfs.writeFile(file2, 'Hello'); let folder1 = path.join(bFolder, 'folder1'); // hidden await pfs.mkdirp(folder1); let folder2 = path.join(aFolder, 'b'); // hidden await pfs.mkdirp(folder2); let folder3 = path.join(testDir, '.git'); // hidden await pfs.mkdirp(folder3); let folder4 = path.join(testDir, '.git1'); await pfs.mkdirp(folder4); let folder5 = path.join(aFolder, '.git'); await pfs.mkdirp(folder5); let file3 = path.join(aFolder, 'file3.js'); // hidden await pfs.writeFile(file3, 'var x;'); let file4 = path.join(aFolder, 'file4.txt'); await pfs.writeFile(file4, 'Hello'); await assertFileEvents(result, [{ path: file4, type: FileChangeType.ADDED }, { path: folder4, type: FileChangeType.ADDED }, { path: folder5, type: FileChangeType.ADDED }]); // move some files let movedFile1 = path.join(folder2, 'file1.txt'); // from ignored to ignored await pfs.rename(file1, movedFile1); let movedFile2 = path.join(aFolder, 'file2.txt'); // from ignored to visible await pfs.rename(file2, movedFile2); let movedFile3 = path.join(aFolder, 'file3.txt'); // from ignored file ext to visible await pfs.rename(file3, movedFile3); await assertFileEvents(result, [{ path: movedFile2, type: FileChangeType.ADDED }, { path: movedFile3, type: FileChangeType.ADDED }]); // delete all files await pfs.del(movedFile1); // hidden await pfs.del(movedFile2); await pfs.del(movedFile3); await pfs.del(folder1); // hidden await pfs.del(folder2); // hidden await pfs.del(folder3); // hidden await pfs.del(folder4); await pfs.del(folder5); await pfs.del(file4); await assertFileEvents(result, [{ path: movedFile2, type: FileChangeType.DELETED }, { path: movedFile3, type: FileChangeType.DELETED }, { path: file4, type: FileChangeType.DELETED }, { path: folder4, type: FileChangeType.DELETED }, { path: folder5, type: FileChangeType.DELETED }]); });
test('writeFile - parallel write on same files works and is sequentalized', function (done: () => void) { const id = uuid.generateUuid(); const parentDir = path.join(os.tmpdir(), 'vsctests', id); const newDir = path.join(parentDir, 'pfs', id); const testFile = path.join(newDir, 'writefile.txt'); const onMkdirp = error => { if (error) { return onError(error, done); } assert.ok(fs.existsSync(newDir)); TPromise.join([ pfs.writeFile(testFile, 'Hello World 1', null), pfs.writeFile(testFile, 'Hello World 2', null), TPromise.timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 3', null)), pfs.writeFile(testFile, 'Hello World 4', null), TPromise.timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 5', null)) ]).done(() => { assert.equal(fs.readFileSync(testFile), 'Hello World 5'); extfs.del(parentDir, os.tmpdir(), () => { }, done); }, error => onError(error, done)); }; pfs.mkdirp(newDir, 493).done(() => onMkdirp(null), error => onMkdirp(error)); });
test('writeFile - parallel write on different files works', function () { const id = uuid.generateUuid(); const parentDir = path.join(os.tmpdir(), 'vsctests', id); const newDir = path.join(parentDir, 'pfs', id); const testFile1 = path.join(newDir, 'writefile1.txt'); const testFile2 = path.join(newDir, 'writefile2.txt'); const testFile3 = path.join(newDir, 'writefile3.txt'); const testFile4 = path.join(newDir, 'writefile4.txt'); const testFile5 = path.join(newDir, 'writefile5.txt'); return pfs.mkdirp(newDir, 493).then(() => { assert.ok(fs.existsSync(newDir)); return Promise.all([ pfs.writeFile(testFile1, 'Hello World 1', null), pfs.writeFile(testFile2, 'Hello World 2', null), pfs.writeFile(testFile3, 'Hello World 3', null), pfs.writeFile(testFile4, 'Hello World 4', null), pfs.writeFile(testFile5, 'Hello World 5', null) ]).then(() => { assert.equal(fs.readFileSync(testFile1), 'Hello World 1'); assert.equal(fs.readFileSync(testFile2), 'Hello World 2'); assert.equal(fs.readFileSync(testFile3), 'Hello World 3'); assert.equal(fs.readFileSync(testFile4), 'Hello World 4'); assert.equal(fs.readFileSync(testFile5), 'Hello World 5'); return pfs.del(parentDir, os.tmpdir()); }); }); });
test('default', async function () { await mkdirp(parentDir); fs.writeFileSync(installSource, 'my.install.source'); const props = await resolveWorkbenchCommonProperties(nestStorage2Service, commit, version, 'someMachineId', installSource); assert.ok('commitHash' in props); assert.ok('sessionID' in props); assert.ok('timestamp' in props); assert.ok('common.platform' in props); assert.ok('common.nodePlatform' in props); assert.ok('common.nodeArch' in props); assert.ok('common.timesincesessionstart' in props); assert.ok('common.sequence' in props); // assert.ok('common.version.shell' in first.data); // only when running on electron // assert.ok('common.version.renderer' in first.data); assert.ok('common.platformVersion' in props, 'platformVersion'); assert.ok('version' in props); assert.equal(props['common.source'], 'my.install.source'); assert.ok('common.firstSessionDate' in props, 'firstSessionDate'); assert.ok('common.lastSessionDate' in props, 'lastSessionDate'); // conditional, see below, 'lastSessionDate'ow assert.ok('common.isNewSession' in props, 'isNewSession'); // machine id et al assert.ok('common.instanceId' in props, 'instanceId'); assert.ok('common.machineId' in props, 'machineId'); fs.unlinkSync(installSource); const props_1 = await resolveWorkbenchCommonProperties(nestStorage2Service, commit, version, 'someMachineId', installSource); assert.ok(!('common.source' in props_1)); });
export function save(file: string, content: string): any { mkdirp(dirname(file)).then(() => { return writeFile(file, content, 'ascii'); }, err => { // }); }
test('basics (corrupt DB falls back to empty DB if backup is corrupt)', async () => { const storageDir = uniqueStorageDir(); await mkdirp(storageDir); const storagePath = join(storageDir, 'storage.db'); let storage = new SQLiteStorageImpl({ path: storagePath }); const items = new Map<string, string>(); items.set('foo', 'bar'); items.set('some/foo/path', 'some/bar/path'); items.set(JSON.stringify({ foo: 'bar' }), JSON.stringify({ bar: 'foo' })); await storage.updateItems({ insert: items }); await storage.close(); await writeFile(storagePath, 'This is now a broken DB'); await writeFile(`${storagePath}.backup`, 'This is now also a broken DB'); storage = new SQLiteStorageImpl({ path: storagePath }); const storedItems = await storage.getItems(); equal(storedItems.size, 0); await testDBBasics(storagePath); await del(storageDir, tmpdir()); });
function extractEntry(stream: Readable, fileName: string, mode: number, targetPath: string, options: IOptions, token: CancellationToken): TPromise<void> { const dirName = path.dirname(fileName); const targetDirName = path.join(targetPath, dirName); if (targetDirName.indexOf(targetPath) !== 0) { return TPromise.wrapError(new Error(nls.localize('invalid file', "Error extracting {0}. Invalid file.", fileName))); } const targetFileName = path.join(targetPath, fileName); let istream: WriteStream; once(token.onCancellationRequested)(() => { if (istream) { istream.close(); } }); return mkdirp(targetDirName, void 0, token).then(() => new TPromise((c, e) => { if (token.isCancellationRequested) { return; } istream = createWriteStream(targetFileName, { mode }); istream.once('close', () => c(null)); istream.once('error', e); stream.once('error', e); stream.pipe(istream); })); }
test('basics (corrupt DB restores from previous backup)', async () => { const storageDir = uniqueStorageDir(); await mkdirp(storageDir); const storagePath = join(storageDir, 'storage.db'); let storage = new SQLiteStorageImpl({ path: storagePath }); const items = new Map<string, string>(); items.set('foo', 'bar'); items.set('some/foo/path', 'some/bar/path'); items.set(JSON.stringify({ foo: 'bar' }), JSON.stringify({ bar: 'foo' })); await storage.updateItems({ insert: items }); await storage.close(); await writeFile(storagePath, 'This is now a broken DB'); storage = new SQLiteStorageImpl({ path: storagePath }); const storedItems = await storage.getItems(); equal(storedItems.size, items.size); equal(storedItems.get('foo'), 'bar'); equal(storedItems.get('some/foo/path'), 'some/bar/path'); equal(storedItems.get(JSON.stringify({ foo: 'bar' })), JSON.stringify({ bar: 'foo' })); await storage.close(); await del(storageDir, tmpdir()); });
function extractEntry(stream: Readable, fileName: string, mode: number, targetPath: string, options: IOptions, token: CancellationToken): Promise<void> { const dirName = path.dirname(fileName); const targetDirName = path.join(targetPath, dirName); if (targetDirName.indexOf(targetPath) !== 0) { return Promise.reject(new Error(nls.localize('invalid file', "Error extracting {0}. Invalid file.", fileName))); } const targetFileName = path.join(targetPath, fileName); let istream: WriteStream; Event.once(token.onCancellationRequested)(() => { if (istream) { istream.destroy(); } }); return Promise.resolve(mkdirp(targetDirName, undefined, token)).then(() => new Promise<void>((c, e) => { if (token.isCancellationRequested) { return; } try { istream = createWriteStream(targetFileName, { mode }); istream.once('close', () => c()); istream.once('error', e); stream.once('error', e); stream.pipe(istream); } catch (error) { e(error); } })); }
test('Migrate Data', async () => { class StorageTestEnvironmentService extends EnvironmentService { constructor(private workspaceStorageFolderPath: string, private _extensionsPath) { super(parseArgs(process.argv), process.execPath); } get workspaceStorageHome(): string { return this.workspaceStorageFolderPath; } get extensionsPath(): string { return this._extensionsPath; } } const storageDir = uniqueStorageDir(); await mkdirp(storageDir); const storage = new StorageService(new InMemoryStorageDatabase(), new NullLogService(), new StorageTestEnvironmentService(storageDir, storageDir)); await storage.initialize({ id: String(Date.now()) }); storage.store('bar', 'foo', StorageScope.WORKSPACE); storage.store('barNumber', 55, StorageScope.WORKSPACE); storage.store('barBoolean', true, StorageScope.GLOBAL); await storage.migrate({ id: String(Date.now() + 100) }); equal(storage.get('bar', StorageScope.WORKSPACE), 'foo'); equal(storage.getInteger('barNumber', StorageScope.WORKSPACE), 55); equal(storage.getBoolean('barBoolean', StorageScope.GLOBAL), true); await storage.close(); await del(storageDir, tmpdir()); });