download.test.mjs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { spawnSync } from 'child_process';
  6. import { existsSync, promises as fs } from 'fs';
  7. import { tmpdir } from 'os';
  8. import { dirname, join } from 'path';
  9. import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest';
  10. import { downloadAndUnzipVSCode, fetchInsiderVersions, fetchStableVersions, fetchTargetInferredVersion, } from './download.js';
  11. import { SilentReporter } from './progress.js';
  12. import { isPlatformDarwin, isPlatformLinux, isPlatformWindows, resolveCliPathFromVSCodeExecutablePath } from './util.js';
  13. const platforms = [
  14. 'darwin',
  15. 'darwin-arm64',
  16. 'win32-x64-archive',
  17. 'win32-arm64-archive',
  18. 'linux-x64',
  19. 'linux-arm64',
  20. 'linux-armhf',
  21. 'cli-linux-x64',
  22. 'cli-win32-x64',
  23. 'cli-darwin-x64',
  24. 'server-win32-x64',
  25. 'server-darwin',
  26. 'server-linux-x64',
  27. ];
  28. describe('sane downloads', () => {
  29. const testTempDir = join(tmpdir(), 'vscode-test-download');
  30. beforeAll(async () => {
  31. await fs.mkdir(testTempDir, { recursive: true });
  32. });
  33. const isRunnableOnThisPlatform = process.platform === 'win32'
  34. ? isPlatformWindows
  35. : process.platform === 'darwin'
  36. ? isPlatformDarwin
  37. : isPlatformLinux;
  38. for (const quality of ['insiders', 'stable']) {
  39. for (const platform of platforms) {
  40. test.concurrent(`${quality}/${platform}`, async () => {
  41. const location = await downloadAndUnzipVSCode({
  42. platform,
  43. version: quality,
  44. cachePath: testTempDir,
  45. reporter: new SilentReporter(),
  46. });
  47. if (!existsSync(location)) {
  48. throw new Error(`expected ${location} to exist for ${platform}`);
  49. }
  50. const exePath = resolveCliPathFromVSCodeExecutablePath(location, platform);
  51. if (!existsSync(exePath)) {
  52. throw new Error(`expected ${exePath} to from ${location}`);
  53. }
  54. if (platform.includes(process.arch) && isRunnableOnThisPlatform(platform)) {
  55. const shell = process.platform === 'win32';
  56. const version = spawnSync(shell ? `"${exePath}"` : exePath, ['--version'], { shell });
  57. expect(version.status).to.equal(0);
  58. expect(version.stdout.toString().trim()).to.not.be.empty;
  59. }
  60. });
  61. }
  62. }
  63. afterAll(async () => {
  64. try {
  65. await fs.rmdir(testTempDir, { recursive: true });
  66. }
  67. catch {
  68. // ignored
  69. }
  70. });
  71. });
  72. describe('fetchTargetInferredVersion', () => {
  73. let stable;
  74. let insiders;
  75. const extensionsDevelopmentPath = join(tmpdir(), 'vscode-test-tmp-workspace');
  76. beforeAll(async () => {
  77. [stable, insiders] = await Promise.all([fetchStableVersions(true, 5000), fetchInsiderVersions(true, 5000)]);
  78. });
  79. afterEach(async () => {
  80. await fs.rm(extensionsDevelopmentPath, { recursive: true, force: true });
  81. });
  82. const writeJSON = async (path, contents) => {
  83. const target = join(extensionsDevelopmentPath, path);
  84. await fs.mkdir(dirname(target), { recursive: true });
  85. await fs.writeFile(target, JSON.stringify(contents));
  86. };
  87. const doFetch = (paths = ['./']) => fetchTargetInferredVersion({
  88. cachePath: join(extensionsDevelopmentPath, '.cache'),
  89. platform: 'win32-x64-archive',
  90. timeout: 5000,
  91. extensionsDevelopmentPath: paths.map((p) => join(extensionsDevelopmentPath, p)),
  92. });
  93. test('matches stable if no workspace', async () => {
  94. const version = await doFetch();
  95. expect(version.id).to.equal(stable[0]);
  96. });
  97. test('matches stable by default', async () => {
  98. await writeJSON('package.json', {});
  99. const version = await doFetch();
  100. expect(version.id).to.equal(stable[0]);
  101. });
  102. test('matches if stable is defined', async () => {
  103. await writeJSON('package.json', { engines: { vscode: '^1.50.0' } });
  104. const version = await doFetch();
  105. expect(version.id).to.equal(stable[0]);
  106. });
  107. test('matches best', async () => {
  108. await writeJSON('package.json', { engines: { vscode: '<=1.60.5' } });
  109. const version = await doFetch();
  110. expect(version.id).to.equal('1.60.2');
  111. });
  112. test('matches multiple workspaces', async () => {
  113. await writeJSON('a/package.json', { engines: { vscode: '<=1.60.5' } });
  114. await writeJSON('b/package.json', { engines: { vscode: '<=1.55.5' } });
  115. const version = await doFetch(['a', 'b']);
  116. expect(version.id).to.equal('1.55.2');
  117. });
  118. test('matches insiders to better stable if there is one', async () => {
  119. await writeJSON('package.json', { engines: { vscode: '^1.60.0-insider' } });
  120. const version = await doFetch();
  121. expect(version.id).to.equal(stable[0]);
  122. });
  123. test('matches current insiders', async () => {
  124. await writeJSON('package.json', { engines: { vscode: `^${insiders[0]}` } });
  125. const version = await doFetch();
  126. expect(version.id).to.equal(insiders[0]);
  127. });
  128. test('matches insiders to exact', async () => {
  129. await writeJSON('package.json', { engines: { vscode: '1.60.0-insider' } });
  130. const version = await doFetch();
  131. expect(version.id).to.equal('1.60.0-insider');
  132. });
  133. });