Skip to content

Commit 2c12337

Browse files
authored
Allow disabling SwiftPM sandboxing (#1386)
* Allow disabling SwiftPM sandboxing To get our tests to run in a sandbox, we need to disable sandboxing because you cannot create a new sandbox when you're already running under a sandbox - Add new `swift.disableSandbox` setting - Disable sandboxing for tasks and commands run by the extension - Disable hardware acceleration since ci.swift.org will run on x64 - Fix failing xcode watcher unit test - Increase some timeouts as build times seem slower on these nodes - Skip any LSP dependent tests for 6.0 or earlier. The LSP will only allow disabling sandboxing in 6.1+ - Disable debugging tests since need shareport permission * Fix review comment * Disable test for Windows
1 parent 2c43d6f commit 2c12337

32 files changed

+312
-98
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ default.profraw
1212
assets/documentation-webview
1313
assets/test/**/Package.resolved
1414
assets/swift-docc-render
15+
ud

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ node_modules/
1818
/coverage/
1919
/dist/
2020
/snippets/
21+
22+
# macOS CI
23+
/ud/

.vscode-test.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,36 @@ const path = require("path");
1818
const isCIBuild = process.env["CI"] === "1";
1919
const isFastTestRun = process.env["FAST_TEST_RUN"] === "1";
2020

21+
const dataDir = process.env["VSCODE_DATA_DIR"];
22+
2123
// "env" in launch.json doesn't seem to work with vscode-test
2224
const isDebugRun = !(process.env["_"] ?? "").endsWith("node_modules/.bin/vscode-test");
2325

2426
// so tests don't timeout when a breakpoint is hit
2527
const timeout = isDebugRun ? Number.MAX_SAFE_INTEGER : 3000;
2628

29+
const launchArgs = [
30+
"--disable-updates",
31+
"--disable-crash-reporter",
32+
"--disable-workspace-trust",
33+
"--disable-telemetry",
34+
];
35+
if (dataDir) {
36+
launchArgs.push("--user-data-dir", dataDir);
37+
}
38+
// GPU hardware acceleration not working on Darwin for intel
39+
if (process.platform === "darwin" && process.arch === "x64") {
40+
launchArgs.push("--disable-gpu");
41+
}
42+
2743
module.exports = defineConfig({
2844
tests: [
2945
{
3046
label: "integrationTests",
3147
files: ["dist/test/common.js", "dist/test/integration-tests/**/*.test.js"],
3248
version: process.env["VSCODE_VERSION"] ?? "stable",
3349
workspaceFolder: "./assets/test",
34-
launchArgs: [
35-
"--disable-updates",
36-
"--disable-crash-reporter",
37-
"--disable-workspace-trust",
38-
"--disable-telemetry",
39-
],
50+
launchArgs,
4051
mocha: {
4152
ui: "tdd",
4253
color: true,
@@ -59,13 +70,7 @@ module.exports = defineConfig({
5970
label: "unitTests",
6071
files: ["dist/test/common.js", "dist/test/unit-tests/**/*.test.js"],
6172
version: process.env["VSCODE_VERSION"] ?? "stable",
62-
launchArgs: [
63-
"--disable-extensions",
64-
"--disable-updates",
65-
"--disable-crash-reporter",
66-
"--disable-workspace-trust",
67-
"--disable-telemetry",
68-
],
73+
launchArgs: launchArgs.concat("--disable-extensions"),
6974
mocha: {
7075
ui: "tdd",
7176
color: true,

assets/test/.vscode/tasks.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"command": "command_plugin",
3636
"args": ["--foo"],
3737
"cwd": "command-plugin",
38+
"disableSandbox": true,
3839
"problemMatcher": [
3940
"$swiftc"
4041
],

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,12 @@
719719
"swift.swiftSDK": {
720720
"type": "string",
721721
"default": "",
722-
"markdownDescription": "The [Swift SDK](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md) to compile against (`--swift-sdk` parameter).",
722+
"markdownDescription": "The [Swift SDK](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md) to compile against (`--swift-sdk` parameter)."
723+
},
724+
"swift.disableSandox": {
725+
"type": "boolean",
726+
"default": false,
727+
"markdownDescription": "Disable sandboxing when running SwiftPM commands. In most cases you should keep the sandbox enabled and leave this setting set to `false`",
723728
"order": 4
724729
},
725730
"swift.diagnostics": {

src/commands/dependencies/unedit.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ async function uneditFolderDependency(
4444
) {
4545
try {
4646
const uneditOperation = new SwiftExecOperation(
47-
["package", "unedit", ...args, identifier],
47+
ctx.toolchain.buildFlags.withAdditionalFlags([
48+
"package",
49+
"unedit",
50+
...args,
51+
identifier,
52+
]),
4853
folder,
4954
`Finish editing ${identifier}`,
5055
{ showStatusItem: true, checkAlreadyRunning: false, log: "Unedit" },

src/commands/dependencies/useLocal.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ export async function useLocalDependency(
5050
folder = folders[0];
5151
}
5252
const task = createSwiftTask(
53-
["package", "edit", "--path", folder.fsPath, identifier],
53+
ctx.toolchain.buildFlags.withAdditionalFlags([
54+
"package",
55+
"edit",
56+
"--path",
57+
folder.fsPath,
58+
identifier,
59+
]),
5460
"Edit Package Dependency",
5561
{
5662
scope: currentFolder.workspaceFolder,

src/commands/resetPackage.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ export async function resetPackage(ctx: WorkspaceContext) {
3535
*/
3636
export async function folderResetPackage(folderContext: FolderContext) {
3737
const task = createSwiftTask(
38-
["package", "reset"],
38+
folderContext.workspaceContext.toolchain.buildFlags.withAdditionalFlags([
39+
"package",
40+
"reset",
41+
]),
3942
"Reset Package Dependencies",
4043
{
4144
cwd: folderContext.folder,

src/configuration.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ export interface DebuggerConfiguration {
5252
readonly debugAdapter: DebugAdapters;
5353
/** Return path to debug adapter */
5454
readonly customDebugAdapterPath: string;
55+
/** Whether or not to disable setting up the debugger */
56+
readonly disable: boolean;
5557
}
5658

5759
/** workspace folder configuration */
@@ -212,6 +214,11 @@ const configuration = {
212214
get customDebugAdapterPath(): string {
213215
return vscode.workspace.getConfiguration("swift.debugger").get<string>("path", "");
214216
},
217+
get disable(): boolean {
218+
return vscode.workspace
219+
.getConfiguration("swift.debugger")
220+
.get<boolean>("disable", false);
221+
},
215222
};
216223
},
217224
/** Files and directories to exclude from the code coverage. */
@@ -375,6 +382,10 @@ const configuration = {
375382
.getConfiguration("swift")
376383
.get<boolean>("enableTerminalEnvironment", true);
377384
},
385+
/** Whether or not to disable SwiftPM sandboxing */
386+
get disableSandbox(): boolean {
387+
return vscode.workspace.getConfiguration("swift").get<boolean>("disableSandbox", false);
388+
},
378389
};
379390

380391
export default configuration;

src/debugger/buildConfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ export class TestingConfigurationFactory {
535535
}
536536

537537
const swiftTestingArgs = [
538-
...args,
538+
...this.ctx.workspaceContext.toolchain.buildFlags.withAdditionalFlags(args),
539539
"--enable-swift-testing",
540540
"--event-stream-version",
541541
"0",

src/extension.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<Api> {
128128
const workspaceContext = await WorkspaceContext.create(context, outputChannel, toolchain);
129129
context.subscriptions.push(...commands.register(workspaceContext));
130130
context.subscriptions.push(workspaceContext);
131-
context.subscriptions.push(registerDebugger(workspaceContext));
131+
if (!configuration.debugger.disable) {
132+
context.subscriptions.push(registerDebugger(workspaceContext));
133+
}
132134
context.subscriptions.push(new SelectedXcodeWatcher(outputChannel));
133135

134136
// listen for workspace folder changes and active text editor changes

src/tasks/SwiftPluginTaskProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export class SwiftPluginTaskProvider implements vscode.TaskProvider {
8282
task.definition.command,
8383
...task.definition.args,
8484
];
85-
swiftArgs = this.workspaceContext.toolchain.buildFlags.withSwiftSDKFlags(swiftArgs);
85+
swiftArgs = this.workspaceContext.toolchain.buildFlags.withAdditionalFlags(swiftArgs);
8686

8787
const cwd = resolveTaskCwd(task, task.definition.cwd);
8888
const newTask = new vscode.Task(
@@ -122,7 +122,7 @@ export class SwiftPluginTaskProvider implements vscode.TaskProvider {
122122
plugin.command,
123123
...definition.args,
124124
];
125-
swiftArgs = this.workspaceContext.toolchain.buildFlags.withSwiftSDKFlags(swiftArgs);
125+
swiftArgs = this.workspaceContext.toolchain.buildFlags.withAdditionalFlags(swiftArgs);
126126

127127
const presentation = config?.presentationOptions ?? {};
128128
const task = new vscode.Task(

src/tasks/SwiftTaskProvider.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ export function createSwiftTask(
271271
cmdEnv: { [key: string]: string } = {}
272272
): SwiftTask {
273273
const swift = toolchain.getToolchainExecutable("swift");
274-
args = toolchain.buildFlags.withSwiftPackageFlags(toolchain.buildFlags.withSwiftSDKFlags(args));
274+
args = toolchain.buildFlags.withAdditionalFlags(args);
275275

276276
// Add relative path current working directory
277277
const cwd = config.cwd.fsPath;
@@ -422,7 +422,8 @@ export class SwiftTaskProvider implements vscode.TaskProvider {
422422
resolveTask(task: vscode.Task, token: vscode.CancellationToken): vscode.Task {
423423
// We need to create a new Task object here.
424424
// Reusing the task parameter doesn't seem to work.
425-
const swift = this.workspaceContext.toolchain.getToolchainExecutable("swift");
425+
const toolchain = this.workspaceContext.toolchain;
426+
const swift = toolchain.getToolchainExecutable("swift");
426427
// platform specific
427428
let platform: TaskPlatformSpecificConfig | undefined;
428429
if (process.platform === "win32") {

src/toolchain/BuildFlags.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class BuildFlags {
3737
*
3838
* @param args original commandline arguments
3939
*/
40-
withSwiftSDKFlags(args: string[]): string[] {
40+
private withSwiftSDKFlags(args: string[]): string[] {
4141
switch (args[0]) {
4242
case "package": {
4343
const subcommand = args.splice(0, 2).concat(this.buildPathFlags());
@@ -192,6 +192,38 @@ export class BuildFlags {
192192
return indirect ? args.flatMap(arg => ["-Xswiftc", arg]) : args;
193193
}
194194

195+
/**
196+
* Get modified swift arguments with new arguments for disabling
197+
* sandboxing if the `swift.disableSandbox` setting is enabled.
198+
*
199+
* @param args original commandline arguments
200+
*/
201+
private withDisableSandboxFlags(args: string[]): string[] {
202+
if (!configuration.disableSandbox) {
203+
return args;
204+
}
205+
const disableSandboxFlags = ["--disable-sandbox", "-Xswiftc", "-disable-sandbox"];
206+
switch (args[0]) {
207+
case "package": {
208+
return [args[0], ...disableSandboxFlags, ...args.slice(1)];
209+
}
210+
case "build":
211+
case "run":
212+
case "test": {
213+
return [...args, ...disableSandboxFlags];
214+
}
215+
default:
216+
// Do nothing for other commands
217+
return args;
218+
}
219+
}
220+
221+
withAdditionalFlags(args: string[]): string[] {
222+
return this.withSwiftPackageFlags(
223+
this.withDisableSandboxFlags(this.withSwiftSDKFlags(args))
224+
);
225+
}
226+
195227
/**
196228
* Filter argument list
197229
* @param args argument list

src/utilities/utilities.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,14 @@ export async function execFile(
109109
options.env = { ...(options.env ?? process.env), ...runtimeEnv };
110110
}
111111
}
112-
return new Promise<{ stdout: string; stderr: string }>((resolve, reject) =>
112+
return new Promise<{ stdout: string; stderr: string }>((resolve, reject) => {
113113
cp.execFile(executable, args, options, (error, stdout, stderr) => {
114114
if (error) {
115115
reject(new ExecFileError(error, stdout, stderr));
116116
}
117117
resolve({ stdout, stderr });
118-
})
119-
);
118+
});
119+
});
120120
}
121121

122122
export async function execFileStreamOutput(
@@ -187,7 +187,7 @@ export async function execSwift(
187187
swift = toolchain.getToolchainExecutable("swift");
188188
}
189189
if (toolchain !== "default") {
190-
args = toolchain.buildFlags.withSwiftSDKFlags(args);
190+
args = toolchain.buildFlags.withAdditionalFlags(args);
191191
}
192192
if (Object.keys(configuration.swiftEnvironmentVariables).length > 0) {
193193
// when adding environment vars we either combine with vars passed

test/integration-tests/BackgroundCompilation.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,5 @@ suite("BackgroundCompilation Test Suite", () => {
5858
await vscode.workspace.save(uri);
5959

6060
await taskPromise;
61-
}).timeout(120000);
61+
}).timeout(180000);
6262
});

test/integration-tests/DiagnosticsManager.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ suite("DiagnosticsManager Test Suite", async function () {
216216
// after first build and can cause intermittent
217217
// failure if `swiftc` diagnostic is fixed
218218
suiteSetup(async function () {
219-
this.timeout(2 * 60 * 1000); // Allow 2 minutes to build
219+
this.timeout(3 * 60 * 1000); // Allow 3 minutes to build
220220
const task = createBuildAllTask(folderContext);
221221
// This return exit code and output for the task but we will omit it here
222222
// because the failures are expected and we just want the task to build
@@ -1062,7 +1062,7 @@ suite("DiagnosticsManager Test Suite", async function () {
10621062

10631063
assertHasDiagnostic(mainUri, expectedDiagnostic1);
10641064
assertHasDiagnostic(mainUri, expectedDiagnostic2);
1065-
}).timeout(2 * 60 * 1000); // Allow 2 minutes to build
1065+
}).timeout(3 * 60 * 1000); // Allow 3 minutes to build
10661066

10671067
test("Provides clang diagnostics", async () => {
10681068
// Build for indexing
@@ -1099,6 +1099,6 @@ suite("DiagnosticsManager Test Suite", async function () {
10991099

11001100
assertHasDiagnostic(cUri, expectedDiagnostic1);
11011101
assertHasDiagnostic(cUri, expectedDiagnostic2);
1102-
}).timeout(2 * 60 * 1000); // Allow 2 minutes to build
1102+
}).timeout(3 * 60 * 1000); // Allow 3 minutes to build
11031103
});
11041104
});

test/integration-tests/SwiftPackage.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,17 @@ suite("SwiftPackage Test Suite", () => {
4545
assert.strictEqual(spmPackage.targets.length, 2);
4646
}).timeout(10000);
4747

48-
test("Package resolve v2", async () => {
49-
if (toolchain && toolchain.swiftVersion.isLessThan(new Version(5, 6, 0))) {
48+
test("Package resolve v2", async function () {
49+
if (!toolchain) {
5050
return;
5151
}
52+
if (
53+
(process.platform === "win32" &&
54+
toolchain.swiftVersion.isLessThan(new Version(6, 0, 0))) ||
55+
toolchain.swiftVersion.isLessThan(new Version(5, 6, 0))
56+
) {
57+
this.skip();
58+
}
5259
const spmPackage = await SwiftPackage.create(testAssetUri("package5.6"), toolchain);
5360
assert.strictEqual(spmPackage.isValid, true);
5461
assert(spmPackage.resolved !== undefined);

test/integration-tests/SwiftSnippet.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function normalizePath(...segments: string[]): string {
3737
}
3838

3939
suite("SwiftSnippet Test Suite @slow", function () {
40-
this.timeout(120000);
40+
this.timeout(180000);
4141

4242
const uri = testAssetUri("defaultPackage/Snippets/hello.swift");
4343
const breakpoints = [
@@ -62,6 +62,7 @@ suite("SwiftSnippet Test Suite @slow", function () {
6262
// Set a breakpoint
6363
vscode.debug.addBreakpoints(breakpoints);
6464
},
65+
requiresDebugger: true,
6566
});
6667

6768
suiteTeardown(async () => {

test/integration-tests/commands/build.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { Version } from "../../../src/utilities/version";
2828

2929
suite("Build Commands @slow", function () {
3030
// Default timeout is a bit too short, give it a little bit more time
31-
this.timeout(2 * 60 * 1000);
31+
this.timeout(3 * 60 * 1000);
3232

3333
let folderContext: FolderContext;
3434
let workspaceContext: WorkspaceContext;
@@ -56,6 +56,7 @@ suite("Build Commands @slow", function () {
5656
async teardown() {
5757
await vscode.commands.executeCommand(Workbench.ACTION_CLOSEALLEDITORS);
5858
},
59+
requiresDebugger: true,
5960
});
6061

6162
test("Swift: Run Build", async () => {

test/integration-tests/debugger/lldb.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ suite("lldb contract test suite", () => {
3434
}
3535
workspaceContext = ctx;
3636
},
37+
requiresDebugger: true,
3738
});
3839

3940
test("getLldbProcess Contract Test, make sure the command returns", async () => {

0 commit comments

Comments
 (0)