Skip to content

Commit 08668bf

Browse files
committed
# This is a combination of 15 commits.
# This is the 1st commit message: Copy extension binaries for CI tests # This is the commit message #2: try installing the extension another way # This is the commit message #3: add ability to skip external terminal test on linux/mac VM # This is the commit message #4: Install gdb and search deeper for extensions folder on macOS # This is the commit message #5: find the right extensions folder # This is the commit message #6: additional logging # This is the commit message #7: try to fix the pathing issue # This is the commit message #8: switch to runVSCodeCommand # This is the commit message #9: debug the failing test # This is the commit message #10: try older binary # This is the commit message #11: WIP # This is the commit message #12: force debug logging # This is the commit message #13: add pipeline changes to branch # This is the commit message #14: Remove hard coded logging # This is the commit message #15: Fix a squiggle
1 parent b3110d8 commit 08668bf

10 files changed

Lines changed: 128 additions & 56 deletions

File tree

.github/workflows/ci_mac.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ jobs:
2323
platform: mac
2424
checkout-ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target-ref || github.ref }}
2525
yarn-args: --network-timeout 100000
26+

.github/workflows/job-compile-and-test.yml

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ jobs:
3838
run: yarn install ${{ inputs.yarn-args }}
3939
working-directory: Extension
4040

41+
- name: Install gdb (linux)
42+
if: ${{ inputs.platform == 'linux' }}
43+
run: |
44+
sudo apt-get update
45+
sudo apt-get install -y gdb
46+
4147
- name: Compile Sources
4248
run: yarn run compile
4349
working-directory: Extension
@@ -50,53 +56,46 @@ jobs:
5056
run: yarn test
5157
working-directory: Extension
5258

53-
# These tests don't require the binary.
54-
# On Linux, it is failing (before the tests actually run) with: Test run terminated with signal SIGSEGV.
55-
# But it works on Linux during the E2E test.
56-
- name: Run SingleRootProject tests
57-
if: ${{ inputs.platform != 'linux' }}
58-
run: yarn test --scenario=SingleRootProject --skipCheckBinaries
59+
- name: Acquire Native Binaries
60+
run: yarn install-and-copy-binaries-for-test
5961
working-directory: Extension
6062

61-
# NOTE : We can't run the test that require the native binary files
62-
# yet -- there will be an update soon that allows the tester to
63-
# acquire them on-the-fly
64-
# - name: Run languageServer integration tests
65-
# if: ${{ inputs.platform == 'windows' }}
66-
# run: yarn test --scenario=SingleRootProject
67-
# working-directory: Extension
63+
- name: Run languageServer integration tests (Windows)
64+
if: ${{ inputs.platform == 'windows' }}
65+
run: yarn test --scenario=SingleRootProject
66+
working-directory: Extension
6867

69-
# - name: Run E2E IntelliSense features tests
70-
# if: ${{ inputs.platform == 'windows' }}
71-
# run: yarn test --scenario=MultirootDeadlockTest
72-
# working-directory: Extension
68+
- name: Run E2E IntelliSense features tests (Windows)
69+
if: ${{ inputs.platform == 'windows' }}
70+
run: yarn test --scenario=MultirootDeadlockTest
71+
working-directory: Extension
7372

74-
# - name: Run E2E IntelliSense features tests
75-
# if: ${{ inputs.platform == 'windows' }}
76-
# run: yarn test --scenario=RunWithoutDebugging
77-
# working-directory: Extension
73+
- name: Run RunWithoutDebugging tests (Windows)
74+
if: ${{ inputs.platform == 'windows' }}
75+
run: yarn test --scenario=RunWithoutDebugging
76+
working-directory: Extension
7877

7978
# NOTE: For mac/linux run the tests with xvfb-action for UI support.
8079
# Another way to start xvfb https://github.com/microsoft/vscode-test/blob/master/sample/azure-pipelines.yml
8180

82-
# - name: Run languageServer integration tests (xvfb)
83-
# if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }}
84-
# uses: coactions/setup-xvfb@v1
85-
# with:
86-
# run: yarn test --scenario=SingleRootProject
87-
# working-directory: Extension
88-
89-
# - name: Run E2E IntelliSense features tests (xvfb)
90-
# if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }}
91-
# uses: coactions/setup-xvfb@v1
92-
# with:
93-
# run: yarn test --scenario=MultirootDeadlockTest
94-
# working-directory: Extension
95-
96-
# - name: Run E2E IntelliSense features tests (xvfb)
97-
# if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }}
98-
# uses: coactions/setup-xvfb@v1
99-
# with:
100-
# run: yarn test --scenario=RunWithoutDebugging
101-
# working-directory: Extension
81+
- name: Run languageServer integration tests (linux/macOS)
82+
if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }}
83+
uses: coactions/setup-xvfb@v1
84+
with:
85+
run: yarn test --scenario=SingleRootProject
86+
working-directory: Extension
87+
88+
- name: Run E2E IntelliSense features tests (linux/macOS)
89+
if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }}
90+
uses: coactions/setup-xvfb@v1
91+
with:
92+
run: yarn test --scenario=MultirootDeadlockTest
93+
working-directory: Extension
94+
95+
- name: Run RunWithoutDebugging tests (linux/macOS)
96+
if: ${{ inputs.platform == 'mac' || inputs.platform == 'linux' }}
97+
uses: coactions/setup-xvfb@v1
98+
with:
99+
run: yarn test --scenario=RunWithoutDebugging --scenario-arg=skipExternalConsole
100+
working-directory: Extension
102101

Extension/.scripts/common.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,18 @@ import { verbose } from '../src/Utility/Text/streams';
2020
export const $root = resolve(`${__dirname}/..`);
2121
export let $cmd = 'main';
2222
export let $scenario = '';
23+
export const $scenarioArgs: string[] = [];
2324

2425
// loop through the args and pick out --scenario=... and remove it from the $args and set $scenario
2526
process.argv.slice(2).filter(each => !(each.startsWith('--scenario=') && ($scenario = each.substring('--scenario='.length))));
27+
// parse out the scenario arguments.
28+
process.argv.slice(2).reduce<string[]>((acc, arg) => {
29+
if (arg.startsWith('--scenario-arg=')) {
30+
acc.push(arg.substring('--scenario-arg='.length));
31+
}
32+
return acc;
33+
}, $scenarioArgs);
34+
2635
export const $args = process.argv.slice(2).filter(each => !each.startsWith('--'));
2736
export const $switches = process.argv.slice(2).filter(each => each.startsWith('--'));
2837

Extension/.scripts/copyExtensionBinaries.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { cp, readdir, rm, stat } from 'node:fs/promises';
77
import { homedir } from 'node:os';
88
import { join } from 'node:path';
9+
import { verbose } from '../src/Utility/Text/streams';
910
import { $args, $root, green, heading, note } from './common';
1011

1112
const extensionPrefix = 'ms-vscode.cpptools-';
@@ -73,17 +74,47 @@ async function getInstalledExtensions(root: string): Promise<InstalledExtension[
7374
}
7475
}
7576

76-
async function findLatestInstalledExtension(providedPath?: string): Promise<string> {
77-
if (providedPath) {
78-
return providedPath;
77+
async function findExtensionsFolder(root: string): Promise<string | undefined> {
78+
try {
79+
const entries = await readdir(root, { withFileTypes: true });
80+
for (const entry of entries) {
81+
if (entry.isDirectory()) {
82+
if (entry.name === 'extensions') {
83+
const extensionEntries = await readdir(join(root, entry.name), { withFileTypes: true });
84+
for (const extensionEntry of extensionEntries) {
85+
if (extensionEntry.isDirectory() && extensionEntry.name.startsWith(extensionPrefix)) {
86+
return join(root, entry.name);
87+
}
88+
}
89+
} else {
90+
const result = await findExtensionsFolder(join(root, entry.name));
91+
if (result) {
92+
return result;
93+
}
94+
}
95+
}
96+
}
97+
} catch {
98+
// Ignore errors (permission denied, etc.)
7999
}
100+
return undefined;
101+
}
80102

103+
async function findLatestInstalledExtension(providedPath?: string): Promise<string> {
81104
const searchRoots: string[] = [
82105
join(homedir(), '.vscode', 'extensions'),
83106
join(homedir(), '.vscode-insiders', 'extensions'),
84107
join(homedir(), '.vscode-server', 'extensions'),
85108
join(homedir(), '.vscode-server-insiders', 'extensions')
86109
];
110+
if (providedPath) {
111+
// find a folder called 'extensions' recursively under the provided path and add it to the front of the search roots
112+
const extensionsFolderPath = await findExtensionsFolder(providedPath);
113+
if (extensionsFolderPath) {
114+
verbose(`Found extensions folder under provided path: ${extensionsFolderPath}`);
115+
searchRoots.unshift(extensionsFolderPath);
116+
}
117+
}
87118

88119
const installed: InstalledExtension[] = (await Promise.all(searchRoots.map(each => getInstalledExtensions(each)))).flat();
89120
if (!installed.length) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* --------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All Rights Reserved.
3+
* See 'LICENSE' in the project root for license information.
4+
* ------------------------------------------------------------------------------------------ */
5+
6+
import { runVSCodeCommand } from '@vscode/test-electron';
7+
import { error, heading } from './common';
8+
import * as copy from './copyExtensionBinaries';
9+
import { install, isolated, options } from "./vscode";
10+
11+
export async function main() {
12+
console.log(heading(`Install VS Code`));
13+
const vscode = await install();
14+
15+
console.log(heading('Install latest C/C++ Extension'));
16+
const result = await runVSCodeCommand([...vscode?.args ?? [], '--install-extension', 'ms-vscode.cpptools@1.31.4', '--pre-release'], options);
17+
if (result.stdout) {
18+
console.log(result.stdout.toString());
19+
}
20+
if (result.stderr) {
21+
error(result.stderr.toString());
22+
}
23+
24+
await copy.main(isolated);
25+
}

Extension/.scripts/test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { filepath } from '../src/Utility/Filesystem/filepath';
1414
import { is } from '../src/Utility/System/guards';
1515
import { verbose } from '../src/Utility/Text/streams';
1616
import { getTestInfo } from '../test/common/selectTests';
17-
import { $args, $root, $scenario, assertAnyFile, assertAnyFolder, brightGreen, checkBinaries, cmdSwitch, cyan, error, gray, green, readJson, red, writeJson } from './common';
17+
import { $args, $root, $scenario, $scenarioArgs, assertAnyFile, assertAnyFolder, brightGreen, checkBinaries, cmdSwitch, cyan, error, gray, green, readJson, red, writeJson } from './common';
1818
import { install, isolated, options } from './vscode';
1919

2020
export { install, reset } from './vscode';
@@ -90,7 +90,8 @@ async function scenarioTests(assets: string, name: string, workspace: string) {
9090
extensionTestsPath: resolve($root, 'dist/test/common/selectTests'),
9191
launchArgs: workspace ? [...options.launchArgs, workspace] : options.launchArgs,
9292
extensionTestsEnv: {
93-
SCENARIO: assets
93+
SCENARIO: assets,
94+
SCENARIO_ARGS: $scenarioArgs.join(',')
9495
}
9596
});
9697
}

Extension/.scripts/vscode.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const settings = resolve(userDir, "User", 'settings.json');
1717

1818
export const options = {
1919
cachePath: `${isolated}/cache`,
20-
launchArgs: ['--no-sandbox', '--disable-updates', '--skip-welcome', '--skip-release-notes', `--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`, '--disable-workspace-trust']
20+
launchArgs: ['--no-sandbox', '--disable-updates', '--skip-welcome', '--skip-release-notes', '--disable-extensions', `--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`, '--disable-workspace-trust']
2121
};
2222

2323
export async function install() {
@@ -34,9 +34,9 @@ export async function install() {
3434
args.push(`--extensions-dir=${extensionsDir}`, `--user-data-dir=${userDir}`);
3535

3636
// install the appropriate extensions
37-
// spawnSync(cli, [...args, '--install-extension', 'ms-vscode.cpptools'], { encoding: 'utf-8', stdio: 'ignore' });
38-
// spawnSync(cli, [...args, '--install-extension', 'twxs.cmake'], { encoding: 'utf-8', stdio: 'ignore' });
39-
// spawnSync(cli, [...args, '--install-extension', 'ms-vscode.cmake-tools'], { encoding: 'utf-8', stdio: 'ignore' });
37+
// runVSCodeCommand([...args, '--install-extension', 'ms-vscode.cpptools'], options);
38+
// runVSCodeCommand([...args, '--install-extension', 'twxs.cmake'], options);
39+
// runVSCodeCommand([...args, '--install-extension', 'ms-vscode.cmake-tools'], options);
4040
const settingsJson = await readJson(settings, {});
4141
if (!settingsJson["workbench.colorTheme"]) {
4242
settingsJson["workbench.colorTheme"] = "Tomorrow Night Blue";

Extension/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6806,6 +6806,7 @@
68066806
"generate-options-schema": "ts-node -T ./.scripts/generateOptionsSchema.ts",
68076807
"copy-walkthrough-media": "ts-node -T ./.scripts/copyWalkthruMedia.ts",
68086808
"copy-extension-binaries": "ts-node -T ./.scripts/copyExtensionBinaries.ts",
6809+
"install-and-copy-binaries-for-test": "ts-node -T ./.scripts/installAndCopyBinaries.ts",
68096810
"translations-export": "yarn install && yarn prep && yarn generate-native-strings && gulp translations-export",
68106811
"translations-generate": "gulp translations-generate",
68116812
"translations-import": "gulp translations-import",

Extension/test/common/selectTests.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { readdir } from 'fs/promises';
77
import { IOptions, glob as globSync } from 'glob';
8-
import * as Mocha from 'mocha';
8+
import Mocha from 'mocha';
99
import { basename, dirname, resolve } from 'path';
1010
import { env } from 'process';
1111
import { promisify } from 'util';
@@ -73,10 +73,10 @@ export async function getTestInfo(...scenarioOptions: (string | undefined)[]) {
7373
return undefined;
7474
}
7575

76-
export function run (testsRoot: string, cb: (error: any, failures?: number) => void): void {
77-
/**
78-
* This code runs in the extension host process, and not in the launch (main.ts) process.
79-
*/
76+
export function run(testsRoot: string, cb: (error: any, failures?: number) => void): void {
77+
/**
78+
* This code runs in the extension host process, and not in the launch (main.ts) process.
79+
*/
8080
let location = '';
8181

8282
// scan through the $args to find the --scenario=...
@@ -87,7 +87,7 @@ export function run (testsRoot: string, cb: (error: any, failures?: number) => v
8787
console.error(`The Scenario folder must be specified either by '--scenario=...' or an environment variable 'SCENARIO=...'`);
8888
process.exit(1);
8989
}
90-
const { name} = testInfo;
90+
const { name } = testInfo;
9191

9292
void glob(`${$root}/dist/test/scenarios/${name}/tests/**/**.test.js`).then((files) => {
9393

Extension/test/scenarios/RunWithoutDebugging/tests/runWithoutDebugging.terminals.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ suite('Run Without Debugging Terminal and Arguments Test', function (this: Mocha
108108
'two words',
109109
path.join(workspacePath, 'input folder', 'three words.txt')
110110
];
111+
const skipExternalConsole = process.env.SCENARIO_ARGS?.includes('skipExternalConsole');
111112

112113
suiteSetup(async function (): Promise<void> {
113114
const extension: vscode.Extension<any> = vscode.extensions.getExtension('ms-vscode.cpptools') || assert.fail('Extension not found');
@@ -170,6 +171,10 @@ suite('Run Without Debugging Terminal and Arguments Test', function (this: Mocha
170171
for (const profile of profiles) {
171172
const profileSuffix = profile ? ` with ${profile} as the default terminal` : consoleCase.consoleMode === 'integratedTerminal' ? ' with default terminal' : '';
172173
test(`No-debug launch via ${consoleCase.label} handles ${programCase.label}${profileSuffix}`, async () => {
174+
if (skipExternalConsole && consoleCase.consoleMode === 'externalTerminal') {
175+
console.log(`\tSkipping external terminal test for ${programCase.label}`);
176+
return;
177+
}
173178
await setWindowsDefaultTerminalProfile(profile);
174179

175180
disposeTerminals(executablePaths);

0 commit comments

Comments
 (0)