From 6bc2e369a0fddc22b3fb5fb49fe8e360e48d694b Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Mon, 4 Nov 2024 13:22:55 -0500 Subject: [PATCH 01/57] Setup Windows GH actions job We cannot use the existing windows job setup because it launches a docker container which we cannot open a VS Code window in to run the tests as no tool like Xvfb exists for Windows Fix up some tests that fail on windows (mostly related to path separator mismatches) --- .github/workflows/pull_request.yml | 27 +++++++++ docker/test-windows.ps1 | 7 +++ .../tasks/SwiftTaskProvider.test.ts | 59 ++++++++++--------- 3 files changed, 64 insertions(+), 29 deletions(-) create mode 100644 docker/test-windows.ps1 diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f9aee2a51..0b3a1e3a3 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -25,6 +25,33 @@ jobs: linux_build_command: ./docker/test.sh enable_windows_checks: false + tests-windows: + name: Windows (${{ matrix.swift_version }}) + runs-on: ${{ contains(matrix.swift_version, 'nightly') && 'windows-2019' || 'windows-2022' }} + strategy: + fail-fast: false + matrix: + swift_version: ['5.9', '5.10', '6.0', 'nightly', 'nightly-6.0'] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Create test script + run: | + mkdir $env:TEMP\test-script + echo 'Set-PSDebug -Trace 1' >> $env:TEMP\test-script\run.ps1 + echo '$ErrorActionPreference = "Stop"' >> $env:TEMP\test-script\run.ps1 + echo 'winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom "--add Microsoft.VisualStudio.Component.Windows11SDK.22000 --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64"' >> $env:TEMP\test-script\run.ps1 + echo 'winget install --id Swift.Toolchain -e' >> $env:TEMP\test-script\run.ps1 + echo 'winget install --id Schniz.fnm -e' >> $env:TEMP\test-script\run.ps1 + echo 'fnm env --use-on-cd | Out-String | Invoke-Expression' >> $env:TEMP\test-script\run.ps1 + echo 'fnm use --install-if-missing 18.19.0' >> $env:TEMP\test-script\run.ps1 + echo 'refreshenv' >> $env:TEMP\test-script\run.ps1 + echo 'swift --version' >> $env:TEMP\test-script\run.ps1 + echo 'node --version' >> $env:TEMP\test-script\run.ps1 + echo 'cd $env:GITHUB_WORKSPACE' >> $env:TEMP\test-script\run.ps1 + echo 'docker\test-windows.ps1' >> $env:TEMP\test-script\run.ps1 + powershell.exe -NoLogo -File $env:TEMP\test-script\run.ps1 + soundness: name: Soundness uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main diff --git a/docker/test-windows.ps1 b/docker/test-windows.ps1 new file mode 100644 index 000000000..ea88e5601 --- /dev/null +++ b/docker/test-windows.ps1 @@ -0,0 +1,7 @@ +$env:CI = "1" +$env:FAST_TEST_RUN = "1" +npm ci -ignore-script node-pty +npm run lint +npm run format +npm run package +npm run integration-test diff --git a/test/integration-tests/tasks/SwiftTaskProvider.test.ts b/test/integration-tests/tasks/SwiftTaskProvider.test.ts index 31531e4bc..01529cca9 100644 --- a/test/integration-tests/tasks/SwiftTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftTaskProvider.test.ts @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import { expect } from "chai"; import * as vscode from "vscode"; import * as assert from "assert"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; @@ -31,7 +32,6 @@ import { Version } from "../../../src/utilities/version"; import { FolderContext } from "../../../src/FolderContext"; import { mockGlobalObject } from "../../MockUtils"; import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities"; -import { expect } from "chai"; suite("SwiftTaskProvider Test Suite", () => { let workspaceContext: WorkspaceContext; @@ -64,10 +64,21 @@ suite("SwiftTaskProvider Test Suite", () => { toolchain ); const { exitCode } = await executeTaskAndWaitForResult(task); - assert.equal(exitCode, 0); - }).timeout(10000); + expect(exitCode).to.equal(0); + }); test("Exit code on failure", async () => { + const task = createSwiftTask( + ["invalid_swift_command"], + "invalid", + { cwd: workspaceFolder.uri, scope: vscode.TaskScope.Workspace }, + toolchain + ); + const { exitCode } = await executeTaskAndWaitForResult(task); + expect(exitCode).to.equal(1); + }); + + test("Exit code on failure to launch", async () => { const task = createSwiftTask( ["--help"], "help", @@ -85,8 +96,8 @@ suite("SwiftTaskProvider Test Suite", () => { ) ); const { exitCode } = await executeTaskAndWaitForResult(task); - assert.equal(exitCode, 1); - }).timeout(10000); + expect(exitCode).to.not.equal(0); + }); }); suite("provideTasks", () => { @@ -99,10 +110,9 @@ suite("SwiftTaskProvider Test Suite", () => { }); test("provided", async () => { - assert.equal( - task?.detail, - "swift build --build-tests -Xswiftc -diagnostic-style=llvm" - ); + expect(task?.detail) + .to.include("swift build --build-tests") + .and.to.include("-Xswiftc -diagnostic-style=llvm"); }); test("executes @slow", async () => { @@ -110,7 +120,7 @@ suite("SwiftTaskProvider Test Suite", () => { const exitPromise = waitForEndTaskProcess(task); await vscode.tasks.executeTask(task); const exitCode = await exitPromise; - assert.equal(exitCode, 0); + expect(exitCode).to.equal(0); }).timeout(180000); // 3 minutes to build }); @@ -123,7 +133,7 @@ suite("SwiftTaskProvider Test Suite", () => { }); test("provided", async () => { - assert.equal(task?.detail, "swift build --show-bin-path"); + expect(task?.detail).to.include("swift build --show-bin-path"); }); test("executes", async () => { @@ -131,17 +141,16 @@ suite("SwiftTaskProvider Test Suite", () => { const exitPromise = waitForEndTaskProcess(task); await vscode.tasks.executeTask(task); const exitCode = await exitPromise; - assert.equal(exitCode, 0); + expect(exitCode).to.equal(0); }); }); test("includes product debug task", async () => { const tasks = await vscode.tasks.fetchTasks({ type: "swift" }); const task = tasks.find(t => t.name === "Build Debug PackageExe (defaultPackage)"); - assert.equal( - task?.detail, - "swift build --product PackageExe -Xswiftc -diagnostic-style=llvm" - ); + expect(task?.detail) + .to.include("swift build --product PackageExe") + .and.to.include("-Xswiftc -diagnostic-style=llvm"); }); test("includes product release task", async () => { @@ -150,30 +159,23 @@ suite("SwiftTaskProvider Test Suite", () => { new vscode.CancellationTokenSource().token ); const task = tasks.find(t => t.name === "Build Release PackageExe (defaultPackage)"); - assert.equal( - task?.detail, - "swift build -c release --product PackageExe -Xswiftc -diagnostic-style=llvm" - ); + expect(task?.detail).to.include("swift build -c release --product PackageExe"); }); test("includes additional folders", async () => { const tasks = await vscode.tasks.fetchTasks({ type: "swift" }); const diagnosticTasks = tasks.filter(t => t.name.endsWith("(diagnostics)")); - assert.equal(diagnosticTasks.length, 3); + expect(diagnosticTasks).to.have.lengthOf(3); }); }); suite("createBuildAllTask", () => { test("should return same task instance", async () => { - assert.strictEqual( - createBuildAllTask(folderContext), - createBuildAllTask(folderContext) - ); + expect(createBuildAllTask(folderContext)).to.equal(createBuildAllTask(folderContext)); }); test("different task returned for release mode", async () => { - assert.notEqual( - createBuildAllTask(folderContext), + expect(createBuildAllTask(folderContext)).to.not.equal( createBuildAllTask(folderContext, true) ); }); @@ -184,8 +186,7 @@ suite("SwiftTaskProvider Test Suite", () => { test("creates build all task when it cannot find one", async () => { tasksMock.fetchTasks.resolves([]); - assert.strictEqual( - await getBuildAllTask(folderContext), + await expect(getBuildAllTask(folderContext)).to.eventually.equal( createBuildAllTask(folderContext) ); }); From c307c6c6048d41080516cec68415e48097b75410 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Mon, 4 Nov 2024 13:34:58 -0500 Subject: [PATCH 02/57] Install winget --- .github/workflows/pull_request.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 0b3a1e3a3..633dcf24e 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -35,6 +35,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Install winget + uses: Cyberboss/install-winget@main - name: Create test script run: | mkdir $env:TEMP\test-script From ea047a215eccf46c174707bbb49d116e467d63d6 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Mon, 4 Nov 2024 15:13:13 -0500 Subject: [PATCH 03/57] Disable WinGet prompts --- .github/workflows/pull_request.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 633dcf24e..0a3a98ca8 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -42,12 +42,12 @@ jobs: mkdir $env:TEMP\test-script echo 'Set-PSDebug -Trace 1' >> $env:TEMP\test-script\run.ps1 echo '$ErrorActionPreference = "Stop"' >> $env:TEMP\test-script\run.ps1 - echo 'winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom "--add Microsoft.VisualStudio.Component.Windows11SDK.22000 --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64"' >> $env:TEMP\test-script\run.ps1 - echo 'winget install --id Swift.Toolchain -e' >> $env:TEMP\test-script\run.ps1 - echo 'winget install --id Schniz.fnm -e' >> $env:TEMP\test-script\run.ps1 + echo 'winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom "--add Microsoft.VisualStudio.Component.Windows11SDK.22000 --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64" --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 + echo 'winget install --id Swift.Toolchain -e --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 + echo 'winget install --id Schniz.fnm -e --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 + echo 'refreshenv' >> $env:TEMP\test-script\run.ps1 echo 'fnm env --use-on-cd | Out-String | Invoke-Expression' >> $env:TEMP\test-script\run.ps1 echo 'fnm use --install-if-missing 18.19.0' >> $env:TEMP\test-script\run.ps1 - echo 'refreshenv' >> $env:TEMP\test-script\run.ps1 echo 'swift --version' >> $env:TEMP\test-script\run.ps1 echo 'node --version' >> $env:TEMP\test-script\run.ps1 echo 'cd $env:GITHUB_WORKSPACE' >> $env:TEMP\test-script\run.ps1 From 1196eafb1125bc6312dce8993cf91d057f762efc Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Mon, 4 Nov 2024 15:22:19 -0500 Subject: [PATCH 04/57] Refresh the env post installs --- .github/workflows/pull_request.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 0a3a98ca8..b7fda2a71 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -45,6 +45,7 @@ jobs: echo 'winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom "--add Microsoft.VisualStudio.Component.Windows11SDK.22000 --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64" --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 echo 'winget install --id Swift.Toolchain -e --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 echo 'winget install --id Schniz.fnm -e --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 + echo 'Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1' >> $env:TEMP\test-script\run.ps1 echo 'refreshenv' >> $env:TEMP\test-script\run.ps1 echo 'fnm env --use-on-cd | Out-String | Invoke-Expression' >> $env:TEMP\test-script\run.ps1 echo 'fnm use --install-if-missing 18.19.0' >> $env:TEMP\test-script\run.ps1 From 6676db6bf3c4b1b3cb4ead364eae1ec20d019bd1 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Tue, 5 Nov 2024 14:59:45 -0500 Subject: [PATCH 05/57] Move installation of deps to powershell scripts Take inspiration from the Swift Dockerfiles --- .github/workflows/pull_request.yml | 32 +++++++++---------- .../scripts/windows/install-nodejs.ps1 | 22 +++++++++++++ .../workflows/scripts/windows/install-vsb.ps1 | 30 +++++++++++++++++ .../windows/swift/install-swift-5.10.ps1 | 25 +++++++++++++++ .../windows/swift/install-swift-6.0.ps1 | 25 +++++++++++++++ docker/test-windows.ps1 | 8 ++++- 6 files changed, 124 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/scripts/windows/install-nodejs.ps1 create mode 100644 .github/workflows/scripts/windows/install-vsb.ps1 create mode 100644 .github/workflows/scripts/windows/swift/install-swift-5.10.ps1 create mode 100644 .github/workflows/scripts/windows/swift/install-swift-6.0.ps1 diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index b7fda2a71..19126442c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -35,25 +35,23 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Install winget - uses: Cyberboss/install-winget@main + - name: Install node.js + if: ${{ !vars.skip_nodejs_install }} + run: powershell.exe -NoLogo -File $env:GITHUB_WORKSPACE\.github\workflows\scripts\windows\install-nodejs.ps1 + - name: Install Visual Studio Build Tools + if: ${{ !vars.skip_vsb_install }} + run: powershell.exe -NoLogo -File $env:GITHUB_WORKSPACE\.github\workflows\scripts\windows\install-vsb.ps1 + - name: Install Swift + if: ${{ !vars.skip_swift_install }} + run: powershell.exe -NoLogo -File $env:GITHUB_WORKSPACE\.github\workflows\scripts\windows\swift\install-swift-${{ matrix.swift_version }}.ps1 + - name: Check dependencies + run: | + swift --version + node --version - name: Create test script run: | - mkdir $env:TEMP\test-script - echo 'Set-PSDebug -Trace 1' >> $env:TEMP\test-script\run.ps1 - echo '$ErrorActionPreference = "Stop"' >> $env:TEMP\test-script\run.ps1 - echo 'winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom "--add Microsoft.VisualStudio.Component.Windows11SDK.22000 --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64" --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 - echo 'winget install --id Swift.Toolchain -e --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 - echo 'winget install --id Schniz.fnm -e --disable-interactivity --accept-source-agreements' >> $env:TEMP\test-script\run.ps1 - echo 'Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1' >> $env:TEMP\test-script\run.ps1 - echo 'refreshenv' >> $env:TEMP\test-script\run.ps1 - echo 'fnm env --use-on-cd | Out-String | Invoke-Expression' >> $env:TEMP\test-script\run.ps1 - echo 'fnm use --install-if-missing 18.19.0' >> $env:TEMP\test-script\run.ps1 - echo 'swift --version' >> $env:TEMP\test-script\run.ps1 - echo 'node --version' >> $env:TEMP\test-script\run.ps1 - echo 'cd $env:GITHUB_WORKSPACE' >> $env:TEMP\test-script\run.ps1 - echo 'docker\test-windows.ps1' >> $env:TEMP\test-script\run.ps1 - powershell.exe -NoLogo -File $env:TEMP\test-script\run.ps1 + cd $env:GITHUB_WORKSPACE + powershell.exe -NoLogo -File docker\test-windows.ps1 soundness: name: Soundness diff --git a/.github/workflows/scripts/windows/install-nodejs.ps1 b/.github/workflows/scripts/windows/install-nodejs.ps1 new file mode 100644 index 000000000..af10b79af --- /dev/null +++ b/.github/workflows/scripts/windows/install-nodejs.ps1 @@ -0,0 +1,22 @@ +$NODEJS='https://nodejs.org/dist/v18.20.4/node-v18.20.4-x64.msi' +$NODEJS_SHA256='c2654d3557abd59de08474c6dd009b1d358f420b8e4010e4debbf130b1dfb90a' +Write-Host -NoNewLine ('Downloading {0} ... ' -f ${NODEJS}) +Invoke-WebRequest -Uri ${NODEJS} -OutFile $env:TEMP\node.msi +Write-Host 'SUCCESS' +Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f ${NODEJS_SHA256}) +$Hash = Get-FileHash $env:TEMP\node.msi -Algorithm sha256 +if ($Hash.Hash -eq ${NODEJS_SHA256}) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Hash.Hash) + exit 1 +} +Write-Host -NoNewLine 'Installing node.js for Windows ... ' +$Process = Start-Process msiexec "/i $env:TEMP\node.msi /norestart /qn" -Wait -PassThru +if ($Process.ExitCode -eq 0) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Process.ExitCode) + exit 1 +} +Remove-Item -Force $env:TEMP\node.msi \ No newline at end of file diff --git a/.github/workflows/scripts/windows/install-vsb.ps1 b/.github/workflows/scripts/windows/install-vsb.ps1 new file mode 100644 index 000000000..35c5f0aac --- /dev/null +++ b/.github/workflows/scripts/windows/install-vsb.ps1 @@ -0,0 +1,30 @@ +$VSB='https://aka.ms/vs/17/release/vs_buildtools.exe' +$VSB_SHA256='99C7677154366062A43082921F40F3CE00EF2614DBF94DB23B244DD13DC9443D' +Write-Host -NoNewLine ('Downloading {0} ... ' -f ${VSB}) +Invoke-WebRequest -Uri $VSB -OutFile $env:TEMP\vs_buildtools.exe +Write-Host 'SUCCESS' +Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f $VSB_SHA256) +$Hash = Get-FileHash $env:TEMP\vs_buildtools.exe -Algorithm sha256 +if ($Hash.Hash -eq $VSB_SHA256) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Hash.Hash) + exit 1 +} +Write-Host -NoNewLine 'Installing Visual Studio Build Tools ... ' +$Process = + Start-Process $env:TEMP\vs_buildtools.exe -Wait -PassThru -NoNewWindow -ArgumentList @( + '--quiet', + '--wait', + '--norestart', + '--nocache', + '--add', 'Microsoft.VisualStudio.Component.Windows11SDK.22000', + '--add', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' + ) +if ($Process.ExitCode -eq 0 -or $Process.ExitCode -eq 3010) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Process.ExitCode) + exit 1 +} +Remove-Item -Force $env:TEMP\vs_buildtools.exe \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 b/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 new file mode 100644 index 000000000..f8329e640 --- /dev/null +++ b/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 @@ -0,0 +1,25 @@ +$SWIFT='https://download.swift.org/swift-5.10.1-release/windows10/swift-5.10.1-RELEASE/swift-5.10.1-RELEASE-windows10.exe' +$SWIFT_SHA256='3027762138ACFA1BBE3050FF6613BBE754332E84C9EFA5C23984646009297286' +Write-Host -NoNewLine ('Downloading {0} ... ' -f ${env:SWIFT}) +Invoke-WebRequest -Uri ${env:SWIFT} -OutFile installer.exe +Write-Host 'SUCCESS' +Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f ${env:SWIFT_SHA256}) +$Hash = Get-FileHash installer.exe -Algorithm sha256 +if ($Hash.Hash -eq ${env:SWIFT_SHA256}) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Hash.Hash) + exit 1 +} +Write-Host -NoNewLine 'Installing Swift ... ' +$Process = Start-Process installer.exe -Wait -PassThru -NoNewWindow -ArgumentList @( + '/quiet', + '/norestart' +) +if ($Process.ExitCode -eq 0) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Process.ExitCode) + exit 1 +} +Remove-Item -Force installer.exe diff --git a/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 b/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 new file mode 100644 index 000000000..7b543126e --- /dev/null +++ b/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 @@ -0,0 +1,25 @@ +$SWIFT='https://download.swift.org/swift-6.0.2-release/windows10/swift-6.0.2-RELEASE/swift-6.0.2-RELEASE-windows10.exe' +$SWIFT_SHA256='516FE8E64713BD92F03C01E5198011B74A27F8C1C88627607A2F421718636126' +Write-Host -NoNewLine ('Downloading {0} ... ' -f $SWIFT) +Invoke-WebRequest -Uri $SWIFT -OutFile installer.exe +Write-Host 'SUCCESS' +Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f $SWIFT_SHA256) +$Hash = Get-FileHash installer.exe -Algorithm sha256 +if ($Hash.Hash -eq $SWIFT_SHA256) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Hash.Hash) + exit 1 +} +Write-Host -NoNewLine 'Installing Swift ... ' +$Process = Start-Process installer.exe -Wait -PassThru -NoNewWindow -ArgumentList @( + '/quiet', + '/norestart' +) +if ($Process.ExitCode -eq 0) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Process.ExitCode) + exit 1 +} +Remove-Item -Force installer.exe diff --git a/docker/test-windows.ps1 b/docker/test-windows.ps1 index ea88e5601..ddee27e8e 100644 --- a/docker/test-windows.ps1 +++ b/docker/test-windows.ps1 @@ -4,4 +4,10 @@ npm ci -ignore-script node-pty npm run lint npm run format npm run package -npm run integration-test +$Process = Start-Process npm "run integration-test" -Wait -PassThru -NoNewWindow +if ($Process.ExitCode -eq 0) { + Write-Host 'SUCCESS' +} else { + Write-Host ('FAILED ({0})' -f $Process.ExitCode) + exit 1 +} From caa9d7edbe33a3ebac70798540840b17bbb67611 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Wed, 6 Nov 2024 08:38:23 -0500 Subject: [PATCH 06/57] Share docker-less setup with swiftlang github-workflows (copied file for now for testing) --- .github/workflows/pull_request.yml | 34 ++-- .../scripts/windows/install-nodejs.ps1 | 2 + .../workflows/scripts/windows/install-vsb.ps1 | 2 + .../windows/swift/install-swift-5.10.ps1 | 27 +-- .../windows/swift/install-swift-5.9.ps1 | 6 + .../windows/swift/install-swift-6.0.ps1 | 27 +-- .../swift/install-swift-nightly-6.0.ps1 | 7 + .../scripts/windows/swift/install-swift.ps1 | 31 ++++ .github/workflows/swift_package_test.yml | 159 ++++++++++++++++++ 9 files changed, 238 insertions(+), 57 deletions(-) create mode 100644 .github/workflows/scripts/windows/swift/install-swift-5.9.ps1 create mode 100644 .github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 create mode 100644 .github/workflows/scripts/windows/swift/install-swift.ps1 create mode 100644 .github/workflows/swift_package_test.yml diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 19126442c..762528caa 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -7,8 +7,9 @@ on: jobs: tests: name: Test - uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main + uses: ./.github/workflows/swift_package_test.yml with: + # Linux linux_exclude_swift_versions: '[{"swift_version": "nightly-main"}]' linux_env_vars: | NODE_VERSION=v18.19.0 @@ -23,9 +24,21 @@ jobs: /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION" echo "$NODE_PATH" >> $GITHUB_PATH linux_build_command: ./docker/test.sh - enable_windows_checks: false + enable_linux_checks: false + # Windows + enable_windows_checks: true + enable_windows_docker: false + windows_exclude_swift_versions: '[{"swift_version": "nightly-main"}]' + windows_env_vars: | + CI=1 + FAST_TEST_RUN=1 + windows_pre_build_command: .github\workflows\scripts\windows\install-nodejs.ps1 + windows_build_command: docker\test-windows.ps1 tests-windows: + defaults: + run: + shell: powershell name: Windows (${{ matrix.swift_version }}) runs-on: ${{ contains(matrix.swift_version, 'nightly') && 'windows-2019' || 'windows-2022' }} strategy: @@ -37,21 +50,19 @@ jobs: uses: actions/checkout@v4 - name: Install node.js if: ${{ !vars.skip_nodejs_install }} - run: powershell.exe -NoLogo -File $env:GITHUB_WORKSPACE\.github\workflows\scripts\windows\install-nodejs.ps1 + run: . .github\workflows\scripts\windows\install-nodejs.ps1 - name: Install Visual Studio Build Tools if: ${{ !vars.skip_vsb_install }} - run: powershell.exe -NoLogo -File $env:GITHUB_WORKSPACE\.github\workflows\scripts\windows\install-vsb.ps1 + run: . .github\workflows\scripts\windows\install-vsb.ps1 - name: Install Swift if: ${{ !vars.skip_swift_install }} - run: powershell.exe -NoLogo -File $env:GITHUB_WORKSPACE\.github\workflows\scripts\windows\swift\install-swift-${{ matrix.swift_version }}.ps1 - - name: Check dependencies - run: | - swift --version - node --version - - name: Create test script + run: . .github\workflows\scripts\windows\swift\install-swift-${{ matrix.swift_version }}.ps1 + - name: Build / Test run: | cd $env:GITHUB_WORKSPACE - powershell.exe -NoLogo -File docker\test-windows.ps1 + Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1 + refreshenv + docker\test-windows.ps1 soundness: name: Soundness @@ -65,3 +76,4 @@ jobs: format_check_enabled: false shell_check_enabled: true unacceptable_language_check_enabled: true + diff --git a/.github/workflows/scripts/windows/install-nodejs.ps1 b/.github/workflows/scripts/windows/install-nodejs.ps1 index af10b79af..2105d63ad 100644 --- a/.github/workflows/scripts/windows/install-nodejs.ps1 +++ b/.github/workflows/scripts/windows/install-nodejs.ps1 @@ -1,5 +1,7 @@ $NODEJS='https://nodejs.org/dist/v18.20.4/node-v18.20.4-x64.msi' $NODEJS_SHA256='c2654d3557abd59de08474c6dd009b1d358f420b8e4010e4debbf130b1dfb90a' +Set-Variable ErrorActionPreference Stop +Set-Variable ProgressPreference SilentlyContinue Write-Host -NoNewLine ('Downloading {0} ... ' -f ${NODEJS}) Invoke-WebRequest -Uri ${NODEJS} -OutFile $env:TEMP\node.msi Write-Host 'SUCCESS' diff --git a/.github/workflows/scripts/windows/install-vsb.ps1 b/.github/workflows/scripts/windows/install-vsb.ps1 index 35c5f0aac..5529a6e4f 100644 --- a/.github/workflows/scripts/windows/install-vsb.ps1 +++ b/.github/workflows/scripts/windows/install-vsb.ps1 @@ -1,5 +1,7 @@ $VSB='https://aka.ms/vs/17/release/vs_buildtools.exe' $VSB_SHA256='99C7677154366062A43082921F40F3CE00EF2614DBF94DB23B244DD13DC9443D' +Set-Variable ErrorActionPreference Stop +Set-Variable ProgressPreference SilentlyContinue Write-Host -NoNewLine ('Downloading {0} ... ' -f ${VSB}) Invoke-WebRequest -Uri $VSB -OutFile $env:TEMP\vs_buildtools.exe Write-Host 'SUCCESS' diff --git a/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 b/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 index f8329e640..85daf4b12 100644 --- a/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 +++ b/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 @@ -1,25 +1,6 @@ +. $PSScriptRoot\install-swift.ps1 + $SWIFT='https://download.swift.org/swift-5.10.1-release/windows10/swift-5.10.1-RELEASE/swift-5.10.1-RELEASE-windows10.exe' $SWIFT_SHA256='3027762138ACFA1BBE3050FF6613BBE754332E84C9EFA5C23984646009297286' -Write-Host -NoNewLine ('Downloading {0} ... ' -f ${env:SWIFT}) -Invoke-WebRequest -Uri ${env:SWIFT} -OutFile installer.exe -Write-Host 'SUCCESS' -Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f ${env:SWIFT_SHA256}) -$Hash = Get-FileHash installer.exe -Algorithm sha256 -if ($Hash.Hash -eq ${env:SWIFT_SHA256}) { - Write-Host 'SUCCESS' -} else { - Write-Host ('FAILED ({0})' -f $Hash.Hash) - exit 1 -} -Write-Host -NoNewLine 'Installing Swift ... ' -$Process = Start-Process installer.exe -Wait -PassThru -NoNewWindow -ArgumentList @( - '/quiet', - '/norestart' -) -if ($Process.ExitCode -eq 0) { - Write-Host 'SUCCESS' -} else { - Write-Host ('FAILED ({0})' -f $Process.ExitCode) - exit 1 -} -Remove-Item -Force installer.exe + +Install-Swift -Url $SWIFT -Sha256 $SWIFT_SHA256 diff --git a/.github/workflows/scripts/windows/swift/install-swift-5.9.ps1 b/.github/workflows/scripts/windows/swift/install-swift-5.9.ps1 new file mode 100644 index 000000000..c34c02a87 --- /dev/null +++ b/.github/workflows/scripts/windows/swift/install-swift-5.9.ps1 @@ -0,0 +1,6 @@ +. $PSScriptRoot\install-swift.ps1 + +$SWIFT='https://download.swift.org/swift-5.9.2-release/windows10/swift-5.9.2-RELEASE/swift-5.9.2-RELEASE-windows10.exe' +$SWIFT_SHA256='D78A717551C78E824C9B74B0CFB1AD86060FC286EA071FDDB26DF18F56DC7212' + +Install-Swift -Url $SWIFT -Sha256 $SWIFT_SHA256 \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 b/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 index 7b543126e..82cbd143d 100644 --- a/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 +++ b/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 @@ -1,25 +1,6 @@ +. $PSScriptRoot\install-swift.ps1 + $SWIFT='https://download.swift.org/swift-6.0.2-release/windows10/swift-6.0.2-RELEASE/swift-6.0.2-RELEASE-windows10.exe' $SWIFT_SHA256='516FE8E64713BD92F03C01E5198011B74A27F8C1C88627607A2F421718636126' -Write-Host -NoNewLine ('Downloading {0} ... ' -f $SWIFT) -Invoke-WebRequest -Uri $SWIFT -OutFile installer.exe -Write-Host 'SUCCESS' -Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f $SWIFT_SHA256) -$Hash = Get-FileHash installer.exe -Algorithm sha256 -if ($Hash.Hash -eq $SWIFT_SHA256) { - Write-Host 'SUCCESS' -} else { - Write-Host ('FAILED ({0})' -f $Hash.Hash) - exit 1 -} -Write-Host -NoNewLine 'Installing Swift ... ' -$Process = Start-Process installer.exe -Wait -PassThru -NoNewWindow -ArgumentList @( - '/quiet', - '/norestart' -) -if ($Process.ExitCode -eq 0) { - Write-Host 'SUCCESS' -} else { - Write-Host ('FAILED ({0})' -f $Process.ExitCode) - exit 1 -} -Remove-Item -Force installer.exe + +Install-Swift -Url $SWIFT -Sha256 $SWIFT_SHA256 \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 b/.github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 new file mode 100644 index 000000000..6641f3805 --- /dev/null +++ b/.github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 @@ -0,0 +1,7 @@ +. $PSScriptRoot\install-swift.ps1 + +$SWIFT_RELEASE_METADATA='http://download.swift.org/swift-6.0-branch/windows10/latest-build.json' +$Release = curl.exe -sL ${SWIFT_RELEASE_METADATA} +$SWIFT_URL = "https://download.swift.org/swift-6.0-branch/windows10/$($($Release | ConvertFrom-JSON).dir)/$($($Release | ConvertFrom-JSON).download)" + +Install-Swift -Url $SWIFT_URL -Sha256 "" \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift.ps1 b/.github/workflows/scripts/windows/swift/install-swift.ps1 new file mode 100644 index 000000000..f81c5d8ff --- /dev/null +++ b/.github/workflows/scripts/windows/swift/install-swift.ps1 @@ -0,0 +1,31 @@ +function Install-Swift { + param ( + [string]$Url, + [string]$Sha256 + ) + Set-Variable ErrorActionPreference Stop + Set-Variable ProgressPreference SilentlyContinue + Write-Host -NoNewLine ('Downloading {0} ... ' -f $url) + Invoke-WebRequest -Uri $url -OutFile installer.exe + Write-Host 'SUCCESS' + Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f $Sha256) + $Hash = Get-FileHash installer.exe -Algorithm sha256 + if ($Hash.Hash -eq $Sha256 -or $Sha256 -eq "") { + Write-Host 'SUCCESS' + } else { + Write-Host ('FAILED ({0})' -f $Hash.Hash) + exit 1 + } + Write-Host -NoNewLine 'Installing Swift ... ' + $Process = Start-Process installer.exe -Wait -PassThru -NoNewWindow -ArgumentList @( + '/quiet', + '/norestart' + ) + if ($Process.ExitCode -eq 0) { + Write-Host 'SUCCESS' + } else { + Write-Host ('FAILED ({0})' -f $Process.ExitCode) + exit 1 + } + Remove-Item -Force installer.exe +} \ No newline at end of file diff --git a/.github/workflows/swift_package_test.yml b/.github/workflows/swift_package_test.yml new file mode 100644 index 000000000..a350c6cb8 --- /dev/null +++ b/.github/workflows/swift_package_test.yml @@ -0,0 +1,159 @@ +name: Swift Linux Matrix + +on: + workflow_call: + inputs: + linux_exclude_swift_versions: + type: string + description: "Exclude Linux Swift version list (JSON)" + default: "[{\"swift_version\": \"\"}]" + linux_os_versions: + type: string + description: "Linux OS version list (JSON)" + default: "[\"jammy\"]" + windows_exclude_swift_versions: + type: string + description: "Exclude Windows Swift version list (JSON)" + default: "[{\"swift_version\": \"\"}]" + swift_flags: + type: string + description: "Swift flags for release version" + default: "" + swift_nightly_flags: + type: string + description: "Swift flags for nightly version" + default: "" + linux_pre_build_command: + type: string + description: "Linux command to execute before building the Swift package" + default: "" + linux_build_command: + type: string + description: "Linux command to build and test the package" + default: "swift test" + windows_pre_build_command: + type: string + description: "Windows Command Prompt command to execute before building the Swift package" + default: "" + windows_build_command: + type: string + description: "Windows Command Prompt command to build and test the package" + default: "swift test" + linux_env_vars: + description: "List of environment variables" + type: string + windows_env_vars: + description: "List of environment variables" + type: string + enable_linux_checks: + type: boolean + description: "Boolean to enable linux testing. Defaults to true" + default: true + enable_windows_checks: + type: boolean + description: "Boolean to enable windows testing. Defaults to true" + default: true + enable_windows_docker: + type: boolean + description: "Boolean to enable running build in windows docker container. Defaults to true" + default: true + +jobs: + linux-build: + name: Linux (${{ matrix.swift_version }} - ${{ matrix.os_version }}) + if: ${{ inputs.enable_linux_checks }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + swift_version: ['5.8', '5.9', '5.10', '6.0', 'nightly-main', 'nightly-6.0'] + os_version: ${{ fromJson(inputs.linux_os_versions) }} + exclude: + - ${{ fromJson(inputs.linux_exclude_swift_versions) }} + container: + image: ${{ (contains(matrix.swift_version, 'nightly') && 'swiftlang/swift') || 'swift' }}:${{ matrix.swift_version }}-${{ matrix.os_version }} + steps: + - name: Swift version + run: swift --version + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set environment variables + if: ${{ inputs.linux_env_vars }} + run: | + for i in "${{ inputs.linux_env_vars }}" + do + printf "%s\n" $i | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + done + - name: Pre-build + run: ${{ inputs.linux_pre_build_command }} + - name: Build / Test + run: ${{ inputs.linux_build_command }} ${{ (contains(matrix.swift_version, 'nightly') && inputs.swift_nightly_flags) || inputs.swift_flags }} + + windows-build: + name: Windows (${{ matrix.swift_version }} - windows-2022) + if: ${{ inputs.enable_windows_checks }} + runs-on: ${{ contains(matrix.swift_version, 'nightly') && 'windows-2019' || 'windows-2022' }} + outputs: + image: ${{ steps.pull_docker_image.outputs.image }} + strategy: + fail-fast: false + matrix: + swift_version: ['5.9', '5.10', '6.0', 'nightly', 'nightly-6.0'] + exclude: + - ${{ fromJson(inputs.windows_exclude_swift_versions) }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set environment variables + if: ${{ inputs.windows_env_vars }} + run: | + $lines = "${{ inputs.windows_env_vars }}" -split "`r`n" + foreach ($line in $lines) { + echo $line | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append + } + - name: Pull Docker image + id: pull_docker_image + if: ${{ inputs.enable_windows_docker }} + run: | + if ("${{ matrix.swift_version }}".Contains("nightly")) { + $Image = "swiftlang/swift:${{ matrix.swift_version }}-windowsservercore-1809" + } else { + $Image = "swift:${{ matrix.swift_version }}-windowsservercore-ltsc2022" + } + docker pull $Image + echo "image='$Image'" >> $env:GITHUB_OUTPUT + cat "$env:GITHUB_OUTPUT" + - name: Install Visual Studio Build Tools + if: ${{ !inputs.enable_windows_docker }} + run: . .github\workflows\scripts\windows\install-vsb.ps1 + - name: Install Swift + if: ${{ !inputs.enable_windows_docker }} + run: . .github\workflows\scripts\windows\swift\install-swift-${{ matrix.swift_version }}.ps1 + - name: Create test script + run: | + mkdir $env:TEMP\test-script + echo 'Set-PSDebug -Trace 1' >> $env:TEMP\test-script\run.ps1 + echo '$ErrorActionPreference = "Stop"' >> $env:TEMP\test-script\run.ps1 + echo 'swift --version' >> $env:TEMP\test-script\run.ps1 + echo 'swift test --version' >> $env:TEMP\test-script\run.ps1 + echo 'cd C:\source\' >> $env:TEMP\test-script\run.ps1 + echo @' + ${{ inputs.windows_pre_build_command }} + '@ >> $env:TEMP\test-script\run.ps1 + echo '${{ inputs.windows_build_command }} ${{ (contains(matrix.swift_version, 'nightly') && inputs.swift_nightly_flags) || inputs.swift_flags }}' >> $env:TEMP\test-script\run.ps1 + # Docker build + - name: Build / Test + timeout-minutes: 60 + if: ${{ !inputs.enable_windows_docker }} + run: | + if ("${{ matrix.swift_version }}".Contains("nightly")) { + $Image = "swiftlang/swift:${{ matrix.swift_version }}-windowsservercore-1809" + } else { + $Image = "swift:${{ matrix.swift_version }}-windowsservercore-ltsc2022" + } + docker run -v ${{ github.workspace }}:C:\source -v $env:TEMP\test-script:C:\test-script "$Image" powershell.exe -NoLogo -File C:\test-script\run.ps1 + # Docker-less build + - name: Build / Test + timeout-minutes: 60 + if: ${{ inputs.enable_windows_docker }} + run: powershell.exe -NoLogo -File $env:TEMP\test-script\run.ps1 \ No newline at end of file From 7578469173c761f264d430d2f6951fe94227b413 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Thu, 7 Nov 2024 10:48:01 -0500 Subject: [PATCH 07/57] Point to branch in forked workflows repo --- .github/workflows/pull_request.yml | 36 +--- .../workflows/scripts/windows/install-vsb.ps1 | 32 ---- .../windows/swift/install-swift-5.10.ps1 | 6 - .../windows/swift/install-swift-5.9.ps1 | 6 - .../windows/swift/install-swift-6.0.ps1 | 6 - .../swift/install-swift-nightly-6.0.ps1 | 7 - .../scripts/windows/swift/install-swift.ps1 | 31 ---- .github/workflows/swift_package_test.yml | 159 ------------------ 8 files changed, 3 insertions(+), 280 deletions(-) delete mode 100644 .github/workflows/scripts/windows/install-vsb.ps1 delete mode 100644 .github/workflows/scripts/windows/swift/install-swift-5.10.ps1 delete mode 100644 .github/workflows/scripts/windows/swift/install-swift-5.9.ps1 delete mode 100644 .github/workflows/scripts/windows/swift/install-swift-6.0.ps1 delete mode 100644 .github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 delete mode 100644 .github/workflows/scripts/windows/swift/install-swift.ps1 delete mode 100644 .github/workflows/swift_package_test.yml diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 762528caa..64d0aab6c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -7,7 +7,7 @@ on: jobs: tests: name: Test - uses: ./.github/workflows/swift_package_test.yml + uses: award999/github-workflows/.github/workflows/swift_package_test.yml@dockerless-windows with: # Linux linux_exclude_swift_versions: '[{"swift_version": "nightly-main"}]' @@ -24,46 +24,17 @@ jobs: /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION" echo "$NODE_PATH" >> $GITHUB_PATH linux_build_command: ./docker/test.sh - enable_linux_checks: false + enable_linux_checks: true # Windows enable_windows_checks: true enable_windows_docker: false - windows_exclude_swift_versions: '[{"swift_version": "nightly-main"}]' + windows_exclude_swift_versions: '[{"swift_version": "nightly"}]' windows_env_vars: | CI=1 FAST_TEST_RUN=1 windows_pre_build_command: .github\workflows\scripts\windows\install-nodejs.ps1 windows_build_command: docker\test-windows.ps1 - tests-windows: - defaults: - run: - shell: powershell - name: Windows (${{ matrix.swift_version }}) - runs-on: ${{ contains(matrix.swift_version, 'nightly') && 'windows-2019' || 'windows-2022' }} - strategy: - fail-fast: false - matrix: - swift_version: ['5.9', '5.10', '6.0', 'nightly', 'nightly-6.0'] - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Install node.js - if: ${{ !vars.skip_nodejs_install }} - run: . .github\workflows\scripts\windows\install-nodejs.ps1 - - name: Install Visual Studio Build Tools - if: ${{ !vars.skip_vsb_install }} - run: . .github\workflows\scripts\windows\install-vsb.ps1 - - name: Install Swift - if: ${{ !vars.skip_swift_install }} - run: . .github\workflows\scripts\windows\swift\install-swift-${{ matrix.swift_version }}.ps1 - - name: Build / Test - run: | - cd $env:GITHUB_WORKSPACE - Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1 - refreshenv - docker\test-windows.ps1 - soundness: name: Soundness uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main @@ -76,4 +47,3 @@ jobs: format_check_enabled: false shell_check_enabled: true unacceptable_language_check_enabled: true - diff --git a/.github/workflows/scripts/windows/install-vsb.ps1 b/.github/workflows/scripts/windows/install-vsb.ps1 deleted file mode 100644 index 5529a6e4f..000000000 --- a/.github/workflows/scripts/windows/install-vsb.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -$VSB='https://aka.ms/vs/17/release/vs_buildtools.exe' -$VSB_SHA256='99C7677154366062A43082921F40F3CE00EF2614DBF94DB23B244DD13DC9443D' -Set-Variable ErrorActionPreference Stop -Set-Variable ProgressPreference SilentlyContinue -Write-Host -NoNewLine ('Downloading {0} ... ' -f ${VSB}) -Invoke-WebRequest -Uri $VSB -OutFile $env:TEMP\vs_buildtools.exe -Write-Host 'SUCCESS' -Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f $VSB_SHA256) -$Hash = Get-FileHash $env:TEMP\vs_buildtools.exe -Algorithm sha256 -if ($Hash.Hash -eq $VSB_SHA256) { - Write-Host 'SUCCESS' -} else { - Write-Host ('FAILED ({0})' -f $Hash.Hash) - exit 1 -} -Write-Host -NoNewLine 'Installing Visual Studio Build Tools ... ' -$Process = - Start-Process $env:TEMP\vs_buildtools.exe -Wait -PassThru -NoNewWindow -ArgumentList @( - '--quiet', - '--wait', - '--norestart', - '--nocache', - '--add', 'Microsoft.VisualStudio.Component.Windows11SDK.22000', - '--add', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' - ) -if ($Process.ExitCode -eq 0 -or $Process.ExitCode -eq 3010) { - Write-Host 'SUCCESS' -} else { - Write-Host ('FAILED ({0})' -f $Process.ExitCode) - exit 1 -} -Remove-Item -Force $env:TEMP\vs_buildtools.exe \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 b/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 deleted file mode 100644 index 85daf4b12..000000000 --- a/.github/workflows/scripts/windows/swift/install-swift-5.10.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -. $PSScriptRoot\install-swift.ps1 - -$SWIFT='https://download.swift.org/swift-5.10.1-release/windows10/swift-5.10.1-RELEASE/swift-5.10.1-RELEASE-windows10.exe' -$SWIFT_SHA256='3027762138ACFA1BBE3050FF6613BBE754332E84C9EFA5C23984646009297286' - -Install-Swift -Url $SWIFT -Sha256 $SWIFT_SHA256 diff --git a/.github/workflows/scripts/windows/swift/install-swift-5.9.ps1 b/.github/workflows/scripts/windows/swift/install-swift-5.9.ps1 deleted file mode 100644 index c34c02a87..000000000 --- a/.github/workflows/scripts/windows/swift/install-swift-5.9.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -. $PSScriptRoot\install-swift.ps1 - -$SWIFT='https://download.swift.org/swift-5.9.2-release/windows10/swift-5.9.2-RELEASE/swift-5.9.2-RELEASE-windows10.exe' -$SWIFT_SHA256='D78A717551C78E824C9B74B0CFB1AD86060FC286EA071FDDB26DF18F56DC7212' - -Install-Swift -Url $SWIFT -Sha256 $SWIFT_SHA256 \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 b/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 deleted file mode 100644 index 82cbd143d..000000000 --- a/.github/workflows/scripts/windows/swift/install-swift-6.0.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -. $PSScriptRoot\install-swift.ps1 - -$SWIFT='https://download.swift.org/swift-6.0.2-release/windows10/swift-6.0.2-RELEASE/swift-6.0.2-RELEASE-windows10.exe' -$SWIFT_SHA256='516FE8E64713BD92F03C01E5198011B74A27F8C1C88627607A2F421718636126' - -Install-Swift -Url $SWIFT -Sha256 $SWIFT_SHA256 \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 b/.github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 deleted file mode 100644 index 6641f3805..000000000 --- a/.github/workflows/scripts/windows/swift/install-swift-nightly-6.0.ps1 +++ /dev/null @@ -1,7 +0,0 @@ -. $PSScriptRoot\install-swift.ps1 - -$SWIFT_RELEASE_METADATA='http://download.swift.org/swift-6.0-branch/windows10/latest-build.json' -$Release = curl.exe -sL ${SWIFT_RELEASE_METADATA} -$SWIFT_URL = "https://download.swift.org/swift-6.0-branch/windows10/$($($Release | ConvertFrom-JSON).dir)/$($($Release | ConvertFrom-JSON).download)" - -Install-Swift -Url $SWIFT_URL -Sha256 "" \ No newline at end of file diff --git a/.github/workflows/scripts/windows/swift/install-swift.ps1 b/.github/workflows/scripts/windows/swift/install-swift.ps1 deleted file mode 100644 index f81c5d8ff..000000000 --- a/.github/workflows/scripts/windows/swift/install-swift.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -function Install-Swift { - param ( - [string]$Url, - [string]$Sha256 - ) - Set-Variable ErrorActionPreference Stop - Set-Variable ProgressPreference SilentlyContinue - Write-Host -NoNewLine ('Downloading {0} ... ' -f $url) - Invoke-WebRequest -Uri $url -OutFile installer.exe - Write-Host 'SUCCESS' - Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f $Sha256) - $Hash = Get-FileHash installer.exe -Algorithm sha256 - if ($Hash.Hash -eq $Sha256 -or $Sha256 -eq "") { - Write-Host 'SUCCESS' - } else { - Write-Host ('FAILED ({0})' -f $Hash.Hash) - exit 1 - } - Write-Host -NoNewLine 'Installing Swift ... ' - $Process = Start-Process installer.exe -Wait -PassThru -NoNewWindow -ArgumentList @( - '/quiet', - '/norestart' - ) - if ($Process.ExitCode -eq 0) { - Write-Host 'SUCCESS' - } else { - Write-Host ('FAILED ({0})' -f $Process.ExitCode) - exit 1 - } - Remove-Item -Force installer.exe -} \ No newline at end of file diff --git a/.github/workflows/swift_package_test.yml b/.github/workflows/swift_package_test.yml deleted file mode 100644 index a350c6cb8..000000000 --- a/.github/workflows/swift_package_test.yml +++ /dev/null @@ -1,159 +0,0 @@ -name: Swift Linux Matrix - -on: - workflow_call: - inputs: - linux_exclude_swift_versions: - type: string - description: "Exclude Linux Swift version list (JSON)" - default: "[{\"swift_version\": \"\"}]" - linux_os_versions: - type: string - description: "Linux OS version list (JSON)" - default: "[\"jammy\"]" - windows_exclude_swift_versions: - type: string - description: "Exclude Windows Swift version list (JSON)" - default: "[{\"swift_version\": \"\"}]" - swift_flags: - type: string - description: "Swift flags for release version" - default: "" - swift_nightly_flags: - type: string - description: "Swift flags for nightly version" - default: "" - linux_pre_build_command: - type: string - description: "Linux command to execute before building the Swift package" - default: "" - linux_build_command: - type: string - description: "Linux command to build and test the package" - default: "swift test" - windows_pre_build_command: - type: string - description: "Windows Command Prompt command to execute before building the Swift package" - default: "" - windows_build_command: - type: string - description: "Windows Command Prompt command to build and test the package" - default: "swift test" - linux_env_vars: - description: "List of environment variables" - type: string - windows_env_vars: - description: "List of environment variables" - type: string - enable_linux_checks: - type: boolean - description: "Boolean to enable linux testing. Defaults to true" - default: true - enable_windows_checks: - type: boolean - description: "Boolean to enable windows testing. Defaults to true" - default: true - enable_windows_docker: - type: boolean - description: "Boolean to enable running build in windows docker container. Defaults to true" - default: true - -jobs: - linux-build: - name: Linux (${{ matrix.swift_version }} - ${{ matrix.os_version }}) - if: ${{ inputs.enable_linux_checks }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - swift_version: ['5.8', '5.9', '5.10', '6.0', 'nightly-main', 'nightly-6.0'] - os_version: ${{ fromJson(inputs.linux_os_versions) }} - exclude: - - ${{ fromJson(inputs.linux_exclude_swift_versions) }} - container: - image: ${{ (contains(matrix.swift_version, 'nightly') && 'swiftlang/swift') || 'swift' }}:${{ matrix.swift_version }}-${{ matrix.os_version }} - steps: - - name: Swift version - run: swift --version - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set environment variables - if: ${{ inputs.linux_env_vars }} - run: | - for i in "${{ inputs.linux_env_vars }}" - do - printf "%s\n" $i | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - done - - name: Pre-build - run: ${{ inputs.linux_pre_build_command }} - - name: Build / Test - run: ${{ inputs.linux_build_command }} ${{ (contains(matrix.swift_version, 'nightly') && inputs.swift_nightly_flags) || inputs.swift_flags }} - - windows-build: - name: Windows (${{ matrix.swift_version }} - windows-2022) - if: ${{ inputs.enable_windows_checks }} - runs-on: ${{ contains(matrix.swift_version, 'nightly') && 'windows-2019' || 'windows-2022' }} - outputs: - image: ${{ steps.pull_docker_image.outputs.image }} - strategy: - fail-fast: false - matrix: - swift_version: ['5.9', '5.10', '6.0', 'nightly', 'nightly-6.0'] - exclude: - - ${{ fromJson(inputs.windows_exclude_swift_versions) }} - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set environment variables - if: ${{ inputs.windows_env_vars }} - run: | - $lines = "${{ inputs.windows_env_vars }}" -split "`r`n" - foreach ($line in $lines) { - echo $line | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - } - - name: Pull Docker image - id: pull_docker_image - if: ${{ inputs.enable_windows_docker }} - run: | - if ("${{ matrix.swift_version }}".Contains("nightly")) { - $Image = "swiftlang/swift:${{ matrix.swift_version }}-windowsservercore-1809" - } else { - $Image = "swift:${{ matrix.swift_version }}-windowsservercore-ltsc2022" - } - docker pull $Image - echo "image='$Image'" >> $env:GITHUB_OUTPUT - cat "$env:GITHUB_OUTPUT" - - name: Install Visual Studio Build Tools - if: ${{ !inputs.enable_windows_docker }} - run: . .github\workflows\scripts\windows\install-vsb.ps1 - - name: Install Swift - if: ${{ !inputs.enable_windows_docker }} - run: . .github\workflows\scripts\windows\swift\install-swift-${{ matrix.swift_version }}.ps1 - - name: Create test script - run: | - mkdir $env:TEMP\test-script - echo 'Set-PSDebug -Trace 1' >> $env:TEMP\test-script\run.ps1 - echo '$ErrorActionPreference = "Stop"' >> $env:TEMP\test-script\run.ps1 - echo 'swift --version' >> $env:TEMP\test-script\run.ps1 - echo 'swift test --version' >> $env:TEMP\test-script\run.ps1 - echo 'cd C:\source\' >> $env:TEMP\test-script\run.ps1 - echo @' - ${{ inputs.windows_pre_build_command }} - '@ >> $env:TEMP\test-script\run.ps1 - echo '${{ inputs.windows_build_command }} ${{ (contains(matrix.swift_version, 'nightly') && inputs.swift_nightly_flags) || inputs.swift_flags }}' >> $env:TEMP\test-script\run.ps1 - # Docker build - - name: Build / Test - timeout-minutes: 60 - if: ${{ !inputs.enable_windows_docker }} - run: | - if ("${{ matrix.swift_version }}".Contains("nightly")) { - $Image = "swiftlang/swift:${{ matrix.swift_version }}-windowsservercore-1809" - } else { - $Image = "swift:${{ matrix.swift_version }}-windowsservercore-ltsc2022" - } - docker run -v ${{ github.workspace }}:C:\source -v $env:TEMP\test-script:C:\test-script "$Image" powershell.exe -NoLogo -File C:\test-script\run.ps1 - # Docker-less build - - name: Build / Test - timeout-minutes: 60 - if: ${{ inputs.enable_windows_docker }} - run: powershell.exe -NoLogo -File $env:TEMP\test-script\run.ps1 \ No newline at end of file From 7a6a8c4148e8cde070861f6a067b88c179d0d842 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Thu, 7 Nov 2024 13:42:48 -0500 Subject: [PATCH 08/57] Fix failing test case --- .github/workflows/pull_request.yml | 4 +--- test/integration-tests/tasks/SwiftTaskProvider.test.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 64d0aab6c..6c5ad856c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -24,16 +24,14 @@ jobs: /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION" echo "$NODE_PATH" >> $GITHUB_PATH linux_build_command: ./docker/test.sh - enable_linux_checks: true # Windows - enable_windows_checks: true - enable_windows_docker: false windows_exclude_swift_versions: '[{"swift_version": "nightly"}]' windows_env_vars: | CI=1 FAST_TEST_RUN=1 windows_pre_build_command: .github\workflows\scripts\windows\install-nodejs.ps1 windows_build_command: docker\test-windows.ps1 + enable_windows_docker: false soundness: name: Soundness diff --git a/test/integration-tests/tasks/SwiftTaskProvider.test.ts b/test/integration-tests/tasks/SwiftTaskProvider.test.ts index 01529cca9..291ebbefe 100644 --- a/test/integration-tests/tasks/SwiftTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftTaskProvider.test.ts @@ -75,7 +75,7 @@ suite("SwiftTaskProvider Test Suite", () => { toolchain ); const { exitCode } = await executeTaskAndWaitForResult(task); - expect(exitCode).to.equal(1); + expect(exitCode).to.not.equal(0); }); test("Exit code on failure to launch", async () => { From 709c1bc19c894bff844f64657727d55b80d8ff55 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Fri, 8 Nov 2024 15:24:44 -0500 Subject: [PATCH 09/57] Fix plugin tasks provider tests --- .../tasks/SwiftPluginTaskProvider.test.ts | 23 ++++++++----------- test/utilities.ts | 13 +++++++++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts index cbb99142e..71897c7a8 100644 --- a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts @@ -14,12 +14,12 @@ import * as vscode from "vscode"; import * as assert from "assert"; +import { expect } from "chai"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; import { SwiftPluginTaskProvider } from "../../../src/tasks/SwiftPluginTaskProvider"; import { FolderContext } from "../../../src/FolderContext"; import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities"; -import { executeTaskAndWaitForResult, mutable, waitForEndTaskProcess } from "../../utilities"; -import { expect } from "chai"; +import { cleanOutput, executeTaskAndWaitForResult, mutable, waitForEndTaskProcess } from "../../utilities"; suite("SwiftPluginTaskProvider Test Suite", () => { let workspaceContext: WorkspaceContext; @@ -29,7 +29,6 @@ suite("SwiftPluginTaskProvider Test Suite", () => { async setup(ctx) { workspaceContext = ctx; folderContext = await folderInRootWorkspace("command-plugin", workspaceContext); - expect(workspaceContext.folders).to.not.have.lengthOf(0); await folderContext.loadSwiftPlugins(); expect(workspaceContext.folders).to.not.have.lengthOf(0); }, @@ -48,12 +47,8 @@ suite("SwiftPluginTaskProvider Test Suite", () => { scope: folderContext.workspaceFolder, }); const { exitCode, output } = await executeTaskAndWaitForResult(task); - assert.equal(exitCode, 0); - assert.equal( - output.trim().endsWith("Hello, World!"), - true, - "Expceted output to end with 'Hello, World!'" - ); + expect(exitCode).to.equal(0); + expect(cleanOutput(output)).to.include("Hello, World!"); }).timeout(10000); test("Exit code on failure", async () => { @@ -70,7 +65,7 @@ suite("SwiftPluginTaskProvider Test Suite", () => { ); mutable(task.execution).command = "/definitely/not/swift"; const { exitCode } = await executeTaskAndWaitForResult(task); - assert.notEqual(exitCode, 0); + expect(exitCode).to.not.equal(0); }).timeout(10000); }); @@ -84,7 +79,7 @@ suite("SwiftPluginTaskProvider Test Suite", () => { }); test("provides", () => { - assert.equal(task?.detail, "swift package command_plugin"); + expect(task?.detail).to.equal("swift package command_plugin"); }); test("executes", async () => { @@ -92,7 +87,7 @@ suite("SwiftPluginTaskProvider Test Suite", () => { const exitPromise = waitForEndTaskProcess(task); await vscode.tasks.executeTask(task); const exitCode = await exitPromise; - assert.equal(exitCode, 0); + expect(exitCode).to.equal(0); }).timeout(30000); // 30 seconds to run }); @@ -105,7 +100,7 @@ suite("SwiftPluginTaskProvider Test Suite", () => { }); test("provides", () => { - assert.equal(task?.detail, "swift package command_plugin --foo"); + expect(task?.detail).to.equal("swift package command_plugin --foo"); }); test("executes", async () => { @@ -113,7 +108,7 @@ suite("SwiftPluginTaskProvider Test Suite", () => { const exitPromise = waitForEndTaskProcess(task); await vscode.tasks.executeTask(task); const exitCode = await exitPromise; - assert.equal(exitCode, 0); + expect(exitCode).to.equal(0); }).timeout(30000); // 30 seconds to run }); }); diff --git a/test/utilities.ts b/test/utilities.ts index e851f5c05..92ade71a4 100644 --- a/test/utilities.ts +++ b/test/utilities.ts @@ -13,6 +13,8 @@ //===----------------------------------------------------------------------===// import * as vscode from "vscode"; +// eslint-disable-next-line @typescript-eslint/no-require-imports +import stripAnsi = require("strip-ansi"); import { SwiftTaskFixture } from "./fixtures"; import { SwiftTask } from "../src/tasks/SwiftTaskProvider"; @@ -141,3 +143,14 @@ export function waitForEndTaskProcess(task: vscode.Task): Promise Date: Fri, 8 Nov 2024 15:53:56 -0500 Subject: [PATCH 10/57] Fix workspace context tests --- .../WorkspaceContext.test.ts | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/test/integration-tests/WorkspaceContext.test.ts b/test/integration-tests/WorkspaceContext.test.ts index ae40aa0fd..43ce49914 100644 --- a/test/integration-tests/WorkspaceContext.test.ts +++ b/test/integration-tests/WorkspaceContext.test.ts @@ -21,6 +21,17 @@ import { Version } from "../../src/utilities/version"; import { SwiftExecution } from "../../src/tasks/SwiftExecution"; import { activateExtensionForSuite } from "./utilities/testutilities"; +function assertContainsArg(execution: SwiftExecution, arg: string) { + assert(execution?.args.find(a => a === arg)); +} + +function assertNotContainsArg(execution: SwiftExecution, arg: string) { + assert.equal( + execution?.args.find(a => a.includes(arg)), + undefined + ); +} + suite("WorkspaceContext Test Suite", () => { let workspaceContext: WorkspaceContext; const packageFolder: vscode.Uri = testAssetUri("defaultPackage"); @@ -75,10 +86,10 @@ suite("WorkspaceContext Test Suite", () => { const execution = buildAllTask.execution; assert.strictEqual(buildAllTask.definition.type, "swift"); assert.strictEqual(buildAllTask.name, "Build All (defaultPackage)"); - assert.strictEqual(execution?.args[0], "build"); - assert.strictEqual(execution?.args[1], "--build-tests"); - assert.strictEqual(execution?.args[2], "-Xswiftc"); - assert.strictEqual(execution?.args[3], "-diagnostic-style=llvm"); + assertContainsArg(execution, "build"); + assertContainsArg(execution, "--build-tests"); + assertContainsArg(execution, "-Xswiftc"); + assertContainsArg(execution, "-diagnostic-style=llvm"); assert.strictEqual(buildAllTask.scope, folder.workspaceFolder); }); @@ -92,8 +103,9 @@ suite("WorkspaceContext Test Suite", () => { const execution = buildAllTask.execution; assert.strictEqual(buildAllTask.definition.type, "swift"); assert.strictEqual(buildAllTask.name, "Build All (defaultPackage)"); - assert.strictEqual(execution?.args[0], "build"); - assert.strictEqual(execution?.args[1], "--build-tests"); + assertContainsArg(execution, "build"); + assertContainsArg(execution, "--build-tests"); + assertNotContainsArg(execution, "-diagnostic-style"); assert.strictEqual(buildAllTask.scope, folder.workspaceFolder); }); @@ -107,10 +119,10 @@ suite("WorkspaceContext Test Suite", () => { const execution = buildAllTask.execution; assert.strictEqual(buildAllTask.definition.type, "swift"); assert.strictEqual(buildAllTask.name, "Build All (defaultPackage)"); - assert.strictEqual(execution?.args[0], "build"); - assert.strictEqual(execution?.args[1], "--build-tests"); - assert.strictEqual(execution?.args[2], "-Xswiftc"); - assert.strictEqual(execution?.args[3], "-diagnostic-style=swift"); + assertContainsArg(execution, "build"); + assertContainsArg(execution, "--build-tests"); + assertContainsArg(execution, "-Xswiftc"); + assertContainsArg(execution, "-diagnostic-style=swift"); assert.strictEqual(buildAllTask.scope, folder.workspaceFolder); }); @@ -123,11 +135,7 @@ suite("WorkspaceContext Test Suite", () => { await swiftConfig.update("buildArguments", ["--sanitize=thread"]); const buildAllTask = createBuildAllTask(folder); const execution = buildAllTask.execution as SwiftExecution; - assert.strictEqual(execution?.args[0], "build"); - assert.strictEqual(execution?.args[1], "--build-tests"); - assert.strictEqual(execution?.args[2], "-Xswiftc"); - assert.strictEqual(execution?.args[3], "-diagnostic-style=llvm"); - assert.strictEqual(execution?.args[4], "--sanitize=thread"); + assertContainsArg(execution, "--sanitize=thread"); await swiftConfig.update("buildArguments", []); }); From bde84a0ca8e68aec0f0c9d1ba17879300ab10905 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Mon, 11 Nov 2024 09:56:59 -0500 Subject: [PATCH 11/57] Some more plugin task test fixes --- .../tasks/SwiftPluginTaskProvider.test.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts index 71897c7a8..e58cdcf82 100644 --- a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts @@ -18,8 +18,16 @@ import { expect } from "chai"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; import { SwiftPluginTaskProvider } from "../../../src/tasks/SwiftPluginTaskProvider"; import { FolderContext } from "../../../src/FolderContext"; -import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities"; -import { cleanOutput, executeTaskAndWaitForResult, mutable, waitForEndTaskProcess } from "../../utilities"; +import { + activateExtensionForSuite, + folderInRootWorkspace, +} from "../utilities/testutilities"; +import { + cleanOutput, + executeTaskAndWaitForResult, + mutable, + waitForEndTaskProcess, +} from "../../utilities"; suite("SwiftPluginTaskProvider Test Suite", () => { let workspaceContext: WorkspaceContext; From cd8b272b1693c79d1b83bbe95980242f9c35a739 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Mon, 11 Nov 2024 09:57:31 -0500 Subject: [PATCH 12/57] Some depedency view test fixes --- .../ui/PackageDependencyProvider.test.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/integration-tests/ui/PackageDependencyProvider.test.ts b/test/integration-tests/ui/PackageDependencyProvider.test.ts index 686eb5614..eec66a763 100644 --- a/test/integration-tests/ui/PackageDependencyProvider.test.ts +++ b/test/integration-tests/ui/PackageDependencyProvider.test.ts @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import { expect } from "chai"; +import * as path from "path"; import { PackageDependenciesProvider, PackageNode, @@ -47,7 +48,7 @@ suite("PackageDependencyProvider Test Suite", function () { expect(dep).to.not.be.undefined; expect(dep?.location).to.equal("https://github.com/swiftlang/swift-markdown.git"); expect(dep?.path).to.equal( - `${testAssetPath("dependencies")}/.build/checkouts/swift-markdown` + path.join(testAssetPath("dependencies"), ".build/checkouts/swift-markdown") ); }); @@ -70,20 +71,22 @@ suite("PackageDependencyProvider Test Suite", function () { const folder = folders.find(n => n.name === "Sources"); expect(folder).to.not.be.undefined; - expect(folder?.path).to.equal(`${testAssetPath("defaultPackage")}/Sources`); + expect(folder?.path).to.equal(path.join(testAssetPath("defaultPackage"), "Sources")); const childFolders = await treeProvider.getChildren(folder); const childFolder = childFolders.find(n => n.name === "PackageExe"); expect(childFolder).to.not.be.undefined; - expect(childFolder?.path).to.equal(`${testAssetPath("defaultPackage")}/Sources/PackageExe`); + expect(childFolder?.path).to.equal( + path.join(testAssetPath("defaultPackage"), "Sources/PackageExe") + ); const files = await treeProvider.getChildren(childFolder); const file = files.find(n => n.name === "main.swift"); expect(file).to.not.be.undefined; expect(file?.path).to.equal( - `${testAssetPath("defaultPackage")}/Sources/PackageExe/main.swift` + path.join(testAssetPath("defaultPackage"), "Sources/PackageExe/main.swift") ); }); @@ -97,19 +100,19 @@ suite("PackageDependencyProvider Test Suite", function () { const folder = folders.find(n => n.name === "Sources"); expect(folder).to.not.be.undefined; - const path = `${testAssetPath("dependencies")}/.build/checkouts/swift-markdown`; - expect(folder?.path).to.equal(`${path}/Sources`); + const depPath = path.join(testAssetPath("dependencies"), ".build/checkouts/swift-markdown"); + expect(folder?.path).to.equal(path.join(depPath, "Sources")); const childFolders = await treeProvider.getChildren(folder); const childFolder = childFolders.find(n => n.name === "CAtomic"); expect(childFolder).to.not.be.undefined; - expect(childFolder?.path).to.equal(`${path}/Sources/CAtomic`); + expect(childFolder?.path).to.equal(path.join(depPath, "Sources/CAtomic")); const files = await treeProvider.getChildren(childFolder); const file = files.find(n => n.name === "CAtomic.c"); expect(file).to.not.be.undefined; - expect(file?.path).to.equal(`${path}/Sources/CAtomic/CAtomic.c`); + expect(file?.path).to.equal(path.join(depPath, "Sources/CAtomic/CAtomic.c")); }); }); From 39a5b92010390d359b743f2409ec3ae45d540649 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 8 Nov 2024 18:53:35 -0500 Subject: [PATCH 13/57] Fix LSPTestDiscovery tests on Windows --- test/integration-tests/testexplorer/LSPTestDiscovery.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts b/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts index 48a60ccc4..7e109d6d9 100644 --- a/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts +++ b/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts @@ -83,7 +83,7 @@ suite("LSPTestDiscovery Suite", () => { let client: TestLanguageClient; let discoverer: LSPTestDiscovery; let pkg: SwiftPackage; - const file = vscode.Uri.file("file:///some/file.swift"); + const file = vscode.Uri.file("/some/file.swift"); beforeEach(async function () { this.timeout(10000000); From b2e64dbccc3689726acc2b55ae3f3c64bc32b432 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 8 Nov 2024 21:45:16 -0500 Subject: [PATCH 14/57] Strip ANSII from captured test output to fix swift-testing integration tests --- src/TestExplorer/TestRunner.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/TestExplorer/TestRunner.ts b/src/TestExplorer/TestRunner.ts index fe736bf8f..bf4cd80a1 100644 --- a/src/TestExplorer/TestRunner.ts +++ b/src/TestExplorer/TestRunner.ts @@ -40,6 +40,8 @@ import { BuildConfigurationFactory, TestingConfigurationFactory } from "../debug import { TestKind, isDebugging, isRelease } from "./TestKind"; import { reduceTestItemChildren } from "./TestUtils"; import { CompositeCancellationToken } from "../utilities/cancellation"; +// eslint-disable-next-line @typescript-eslint/no-require-imports +import stripAnsi = require("strip-ansi"); export enum TestLibrary { xctest = "XCTest", @@ -264,7 +266,7 @@ export class TestRunProxy { test?: vscode.TestItem ) { testRun.appendOutput(output, location, test); - this.runState.output.push(output); + this.runState.output.push(stripAnsi(output)); } private prependIterationToOutput(output: string): string { From 261b25177f71a8eb32488804d6e7cdd711094d8f Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 8 Nov 2024 22:41:35 -0500 Subject: [PATCH 15/57] Add expected issue ansi to test expectation --- .../testexplorer/TestExplorerIntegration.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index 6f3c9be4c..6000a02a4 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -479,6 +479,8 @@ suite("Test Explorer Suite", function () { let xcTestFailureMessage: string; beforeEach(() => { + const suffix = process.platform === "win32" ? "\x1b[0K" : ""; + // From 5.7 to 5.10 running with the --parallel option dumps the test results out // to the console with no newlines, so it isn't possible to distinguish where errors // begin and end. Consequently we can't record them, and so we manually mark them @@ -487,7 +489,7 @@ suite("Test Explorer Suite", function () { runProfile === TestKind.parallel && !workspaceContext.toolchain.hasMultiLineParallelTestOutput ? "failed" - : "failed - oh no"; + : `failed - oh no${suffix}`; }); suite(runProfile, () => { From 9d2aa39736279c3d4b960326cf93e1ee7048773c Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Mon, 11 Nov 2024 11:19:02 -0500 Subject: [PATCH 16/57] Remove test issue failure suffix --- .../testexplorer/TestExplorerIntegration.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index 6000a02a4..007f7f7b4 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -479,8 +479,6 @@ suite("Test Explorer Suite", function () { let xcTestFailureMessage: string; beforeEach(() => { - const suffix = process.platform === "win32" ? "\x1b[0K" : ""; - // From 5.7 to 5.10 running with the --parallel option dumps the test results out // to the console with no newlines, so it isn't possible to distinguish where errors // begin and end. Consequently we can't record them, and so we manually mark them @@ -489,7 +487,7 @@ suite("Test Explorer Suite", function () { runProfile === TestKind.parallel && !workspaceContext.toolchain.hasMultiLineParallelTestOutput ? "failed" - : `failed - oh no${suffix}`; + : `failed - oh no`; }); suite(runProfile, () => { From 2eabab2ff4fd2c77aa63390e30a5f0cd349297dc Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Mon, 11 Nov 2024 16:10:33 -0500 Subject: [PATCH 17/57] Normalize diagnostics paths in tests --- test/integration-tests/DiagnosticsManager.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index 04981f921..13a929261 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -28,9 +28,9 @@ import { activateExtensionForSuite, folderInRootWorkspace } from "./utilities/te const waitForDiagnostics = (uris: vscode.Uri[], allowEmpty: boolean = true) => new Promise(res => vscode.languages.onDidChangeDiagnostics(e => { - const paths = e.uris.map(u => u.path); + const paths = e.uris.map(u => u.fsPath); for (const uri of uris) { - if (!paths.includes(uri.path)) { + if (!paths.includes(uri.fsPath)) { return; } if (!allowEmpty && !vscode.languages.getDiagnostics(uri).length) { From 568c36e4c0e59c0cdff7539dc362a92d4b217ab8 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 12 Nov 2024 16:12:50 -0500 Subject: [PATCH 18/57] Skip Sourcekit-lsp diagnostics test until nightly tests enabled --- test/integration-tests/DiagnosticsManager.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index 13a929261..6b6b12cc5 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -917,7 +917,8 @@ suite("DiagnosticsManager Test Suite", async function () { }); }); - suite("SourceKit-LSP diagnostics", () => { + // Skipped until we enable it in a nightly build + suite("SourceKit-LSP diagnostics @slow", () => { suiteSetup(async function () { if (workspaceContext.swiftVersion.isLessThan(new Version(5, 7, 0))) { this.skip(); From 1988f692d437f3820cc099ec91aebb649fdaee63 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 12 Nov 2024 20:47:22 -0500 Subject: [PATCH 19/57] Fixup diagnostics tests --- .vscode-test.js | 2 +- src/DiagnosticsManager.ts | 6 +- src/tasks/SwiftProcess.ts | 2 +- .../DiagnosticsManager.test.ts | 235 +++++++++++------- 4 files changed, 152 insertions(+), 93 deletions(-) diff --git a/.vscode-test.js b/.vscode-test.js index 43e2dcc09..c62c65bd8 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -15,7 +15,7 @@ const { defineConfig } = require("@vscode/test-cli"); const path = require("path"); -const isCIBuild = process.env["CI"] === "1"; +const isCIBuild = false; // process.env["CI"] === "1"; const isFastTestRun = process.env["FAST_TEST_RUN"] === "1"; // "env" in launch.json doesn't seem to work with vscode-test diff --git a/src/DiagnosticsManager.ts b/src/DiagnosticsManager.ts index 4498ac7b8..924d691e8 100644 --- a/src/DiagnosticsManager.ts +++ b/src/DiagnosticsManager.ts @@ -89,13 +89,13 @@ export class DiagnosticsManager implements vscode.Disposable { .then(map => { // Clean up old "swiftc" diagnostics this.removeSwiftcDiagnostics(); - map.forEach((diagnostics, uri) => + map.forEach((diagnostics, uri) => { this.handleDiagnostics( vscode.Uri.file(uri), DiagnosticsManager.isSwiftc, diagnostics - ) - ); + ); + }); }) .catch(e => context.outputChannel.log(`${e}`, 'Failed to provide "swiftc" diagnostics') diff --git a/src/tasks/SwiftProcess.ts b/src/tasks/SwiftProcess.ts index bbf923aad..1c0ce05e8 100644 --- a/src/tasks/SwiftProcess.ts +++ b/src/tasks/SwiftProcess.ts @@ -104,7 +104,7 @@ export class SwiftPtyProcess implements SwiftProcess { useConpty, // https://github.com/swiftlang/vscode-swift/issues/1074 // Causing weird truncation issues - cols: !isWindows || useConpty ? undefined : 2147483647, // Max int32 + cols: isWindows ? 4096 : undefined, }); this.spawnEmitter.fire(); this.spawnedProcess.onData(data => { diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index 6b6b12cc5..645b77e46 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -25,27 +25,14 @@ import { Version } from "../../src/utilities/version"; import { Workbench } from "../../src/utilities/commands"; import { activateExtensionForSuite, folderInRootWorkspace } from "./utilities/testutilities"; -const waitForDiagnostics = (uris: vscode.Uri[], allowEmpty: boolean = true) => - new Promise(res => - vscode.languages.onDidChangeDiagnostics(e => { - const paths = e.uris.map(u => u.fsPath); - for (const uri of uris) { - if (!paths.includes(uri.fsPath)) { - return; - } - if (!allowEmpty && !vscode.languages.getDiagnostics(uri).length) { - return; - } - } - res(); - }) +const isEqual = (d1: vscode.Diagnostic, d2: vscode.Diagnostic) => { + return ( + d1.severity === d2.severity && + d1.source === d2.source && + d1.message === d2.message && + d1.range.isEqual(d2.range) ); - -const isEqual = (d1: vscode.Diagnostic, d2: vscode.Diagnostic) => - d1.severity === d2.severity && - d1.source === d2.source && - d1.message === d2.message && - d1.range.isEqual(d2.range); +}; const findDiagnostic = (expected: vscode.Diagnostic) => (d: vscode.Diagnostic) => isEqual(d, expected); @@ -56,7 +43,7 @@ function assertHasDiagnostic(uri: vscode.Uri, expected: vscode.Diagnostic): vsco assert.notEqual( diagnostic, undefined, - `Could not find diagnostic matching:\n${JSON.stringify(expected)}\nDiagnostics:\n${JSON.stringify(diagnostics)}` + `Could not find diagnostic matching:\n${JSON.stringify(expected)}\nDiagnostics found:\n${JSON.stringify(diagnostics)}` ); return diagnostic!; } @@ -90,6 +77,50 @@ suite("DiagnosticsManager Test Suite", async function () { let cUri: vscode.Uri; let cppUri: vscode.Uri; let cppHeaderUri: vscode.Uri; + let diagnosticWaiterDisposable: vscode.Disposable | undefined; + let remainingExpectedDiagnostics: + | { + [uri: string]: vscode.Diagnostic[]; + } + | undefined; + + // Wait for all the expected diagnostics to be recieved. This may happen over several `onChangeDiagnostics` events. + const waitForDiagnostics = (expectedDiagnostics: { [uri: string]: vscode.Diagnostic[] }) => { + return new Promise(resolve => { + if (diagnosticWaiterDisposable) { + console.warn( + "Wait for diagnostics was called before the previous wait was resolved. Only one waitForDiagnostics should run per test." + ); + diagnosticWaiterDisposable?.dispose(); + } + // Keep a lookup of diagnostics we haven't encountered yet. When all array values in + // this lookup are empty then we've seen all diagnostics and we can resolve successfully. + const expected = { ...expectedDiagnostics }; + diagnosticWaiterDisposable = vscode.languages.onDidChangeDiagnostics(e => { + const matchingPaths = Object.keys(expectedDiagnostics).filter(uri => + e.uris.some(u => u.fsPath === uri) + ); + for (const uri of matchingPaths) { + const actualDiagnostics = vscode.languages.getDiagnostics(vscode.Uri.file(uri)); + expected[uri] = expected[uri].filter(expectedDiagnostic => { + return !actualDiagnostics.some(actualDiagnostic => + isEqual(actualDiagnostic, expectedDiagnostic) + ); + }); + remainingExpectedDiagnostics = expected; + } + + const allDiagnosticsFulfilled = Object.values(expected).every( + diagnostics => diagnostics.length === 0 + ); + + if (allDiagnosticsFulfilled) { + diagnosticWaiterDisposable?.dispose(); + resolve(); + } + }); + }); + }; activateExtensionForSuite({ async setup(ctx) { @@ -113,6 +144,23 @@ suite("DiagnosticsManager Test Suite", async function () { }, }); + teardown(function () { + diagnosticWaiterDisposable?.dispose(); + const allDiagnosticsFulfilled = Object.values(remainingExpectedDiagnostics ?? {}).every( + diagnostics => diagnostics.length === 0 + ); + if (!allDiagnosticsFulfilled) { + const title = this.currentTest?.fullTitle() ?? ""; + const remainingDiagnostics = Object.entries(remainingExpectedDiagnostics ?? {}).filter( + ([_uri, diagnostics]) => diagnostics.length > 0 + ); + console.error( + `${title} - Not all diagnostics were fulfilled`, + JSON.stringify(remainingDiagnostics, undefined, " ") + ); + } + }); + suite("Parse diagnostics", async () => { suite("Parse from task output", async () => { const expectedWarningDiagnostic = new vscode.Diagnostic( @@ -166,64 +214,76 @@ suite("DiagnosticsManager Test Suite", async function () { await swiftConfig.update("diagnosticsStyle", undefined); }); - test("default diagnosticsStyle", async () => { + test("default diagnosticsStyle", async function () { + // Swift 5.10 and 6.0 on Windows have a bug where the + // diagnostics are not emitted on their own line. + const swiftVersion = workspaceContext.toolchain.swiftVersion; + if ( + process.platform === "win32" && + swiftVersion.isGreaterThanOrEqual(new Version(5, 10, 0)) && + swiftVersion.isLessThanOrEqual(new Version(6, 0, 999)) + ) { + this.skip(); + return; + } await swiftConfig.update("diagnosticsStyle", "default"); - const task = createBuildAllTask(folderContext); - // Run actual task - const promise = waitForDiagnostics([mainUri, funcUri]); - await executeTaskAndWaitForResult(task); - await promise; - await waitForNoRunningTasks(); - // Should have parsed correct severity - assertHasDiagnostic(mainUri, expectedWarningDiagnostic); - assertHasDiagnostic(mainUri, expectedMainErrorDiagnostic); - if (workspaceContext.swiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0))) { - assertHasDiagnostic(mainUri, expectedMacroDiagnostic); - } - // Check parsed for other file - assertHasDiagnostic(funcUri, expectedFuncErrorDiagnostic); - }).timeout(2 * 60 * 1000); // Allow 2 minutes to build + await Promise.all([ + executeTaskAndWaitForResult(createBuildAllTask(folderContext)), + waitForDiagnostics({ + [mainUri.fsPath]: [ + expectedWarningDiagnostic, + expectedMainErrorDiagnostic, + ...(workspaceContext.swiftVersion.isGreaterThanOrEqual( + new Version(6, 0, 0) + ) + ? [expectedMacroDiagnostic] + : []), + ], // Should have parsed correct severity + [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file + }), + ]); + + await waitForNoRunningTasks(); + }); test("swift diagnosticsStyle", async function () { - // This is only supported in swift versions >=5.10.0 + // This is only supported in swift versions >=5.10.0. + // Swift 5.10 and 6.0 on Windows have a bug where the + // diagnostics are not emitted on their own line. const swiftVersion = workspaceContext.toolchain.swiftVersion; - if (swiftVersion.isLessThan(new Version(5, 10, 0))) { + if ( + swiftVersion.isLessThan(new Version(5, 10, 0)) || + (process.platform === "win32" && + swiftVersion.isGreaterThanOrEqual(new Version(5, 10, 0)) && + swiftVersion.isLessThanOrEqual(new Version(6, 0, 0))) + ) { this.skip(); - return; } await swiftConfig.update("diagnosticsStyle", "swift"); - const task = createBuildAllTask(folderContext); - // Run actual task - const promise = waitForDiagnostics([mainUri, funcUri]); - await executeTaskAndWaitForResult(task); - await promise; + await Promise.all([ + executeTaskAndWaitForResult(createBuildAllTask(folderContext)), + waitForDiagnostics({ + [mainUri.fsPath]: [expectedWarningDiagnostic, expectedMainErrorDiagnostic], // Should have parsed correct severity + [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file + }), + ]); await waitForNoRunningTasks(); - - // Should have parsed severity - assertHasDiagnostic(mainUri, expectedWarningDiagnostic); - assertHasDiagnostic(mainUri, expectedMainErrorDiagnostic); - if (workspaceContext.swiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0))) { - assertHasDiagnostic(mainUri, expectedMacroDiagnostic); - } - // Check parsed for other file - assertHasDiagnostic(funcUri, expectedFuncErrorDiagnostic); - }).timeout(2 * 60 * 1000); // Allow 2 minutes to build + }); test("llvm diagnosticsStyle", async () => { await swiftConfig.update("diagnosticsStyle", "llvm"); - const task = createBuildAllTask(folderContext); - // Run actual task - const promise = waitForDiagnostics([mainUri, funcUri]); - await executeTaskAndWaitForResult(task); - await promise; + + await Promise.all([ + executeTaskAndWaitForResult(createBuildAllTask(folderContext)), + waitForDiagnostics({ + [mainUri.fsPath]: [expectedWarningDiagnostic, expectedMainErrorDiagnostic], // Should have parsed correct severity + [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file + }), + ]); await waitForNoRunningTasks(); // Should have parsed severity - assertHasDiagnostic(mainUri, expectedWarningDiagnostic); - - // llvm style doesn't do macro diagnostics - assertWithoutDiagnostic(mainUri, expectedMacroDiagnostic); const diagnostic = assertHasDiagnostic(mainUri, expectedMainErrorDiagnostic); // Should have parsed related note assert.equal(diagnostic.relatedInformation?.length, 1); @@ -238,9 +298,7 @@ suite("DiagnosticsManager Test Suite", async function () { ), true ); - // Check parsed for other file - assertHasDiagnostic(funcUri, expectedFuncErrorDiagnostic); - }).timeout(2 * 60 * 1000); // Allow 2 minutes to build + }); test("Parses C diagnostics", async function () { const swiftVersion = workspaceContext.toolchain.swiftVersion; @@ -251,12 +309,6 @@ suite("DiagnosticsManager Test Suite", async function () { } await swiftConfig.update("diagnosticsStyle", "llvm"); - const task = createBuildAllTask(cFolderContext); - // Run actual task - const promise = waitForDiagnostics([cUri]); - await executeTaskAndWaitForResult(task); - await promise; - await waitForNoRunningTasks(); // Should have parsed severity const expectedDiagnostic1 = new vscode.Diagnostic( @@ -272,8 +324,13 @@ suite("DiagnosticsManager Test Suite", async function () { ); expectedDiagnostic2.source = "swiftc"; - assertHasDiagnostic(cUri, expectedDiagnostic1); - assertHasDiagnostic(cUri, expectedDiagnostic2); + await Promise.all([ + executeTaskAndWaitForResult(createBuildAllTask(cFolderContext)), + waitForDiagnostics({ + [cUri.fsPath]: [expectedDiagnostic1, expectedDiagnostic2], + }), + ]); + await waitForNoRunningTasks(); }); test("Parses C++ diagnostics", async function () { @@ -285,12 +342,6 @@ suite("DiagnosticsManager Test Suite", async function () { } await swiftConfig.update("diagnosticsStyle", "llvm"); - const task = createBuildAllTask(cppFolderContext); - // Run actual task - const promise = waitForDiagnostics([cppUri]); - await executeTaskAndWaitForResult(task); - await promise; - await waitForNoRunningTasks(); // Should have parsed severity const expectedDiagnostic1 = new vscode.Diagnostic( @@ -299,7 +350,6 @@ suite("DiagnosticsManager Test Suite", async function () { vscode.DiagnosticSeverity.Error ); expectedDiagnostic1.source = "swiftc"; - assertHasDiagnostic(cppUri, expectedDiagnostic1); // Should have parsed releated information const expectedDiagnostic2 = new vscode.Diagnostic( @@ -308,6 +358,15 @@ suite("DiagnosticsManager Test Suite", async function () { vscode.DiagnosticSeverity.Error ); expectedDiagnostic2.source = "swiftc"; + + await Promise.all([ + executeTaskAndWaitForResult(createBuildAllTask(cppFolderContext)), + waitForDiagnostics({ + [cppUri.fsPath]: [expectedDiagnostic1, expectedDiagnostic2], + }), + ]); + await waitForNoRunningTasks(); + const diagnostic = assertHasDiagnostic(cppUri, expectedDiagnostic2); assert.equal( diagnostic.relatedInformation![0].location.uri.fsPath, @@ -338,7 +397,7 @@ suite("DiagnosticsManager Test Suite", async function () { test("Parse partial line", async () => { const fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - const diagnosticsPromise = waitForDiagnostics([mainUri]); + const diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); // Wait to spawn before writing fixture.process.write(`${mainUri.fsPath}:13:5: err`, ""); fixture.process.write("or: Cannot find 'fo", ""); @@ -354,7 +413,7 @@ suite("DiagnosticsManager Test Suite", async function () { test("Ignore duplicates", async () => { const fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - const diagnosticsPromise = waitForDiagnostics([mainUri]); + const diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); // Wait to spawn before writing const output = `${mainUri.fsPath}:13:5: error: Cannot find 'foo' in scope`; fixture.process.write(output); @@ -372,7 +431,7 @@ suite("DiagnosticsManager Test Suite", async function () { test("New set of swiftc diagnostics clear old list", async () => { let fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - let diagnosticsPromise = waitForDiagnostics([mainUri]); + let diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); // Wait to spawn before writing fixture.process.write(`${mainUri.fsPath}:13:5: error: Cannot find 'foo' in scope`); fixture.process.close(1); @@ -386,7 +445,7 @@ suite("DiagnosticsManager Test Suite", async function () { // Run again but no diagnostics returned fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - diagnosticsPromise = waitForDiagnostics([mainUri]); + diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); fixture.process.close(0); await waitForNoRunningTasks(); await diagnosticsPromise; @@ -943,7 +1002,7 @@ suite("DiagnosticsManager Test Suite", async function () { await executeTaskAndWaitForResult(task); // Open file - const promise = waitForDiagnostics([mainUri], false); + const promise = Promise.resolve(); // waitForDiagnostics([mainUri], false); const document = await vscode.workspace.openTextDocument(mainUri); await vscode.languages.setTextDocumentLanguage(document, "swift"); await vscode.window.showTextDocument(document); @@ -984,7 +1043,7 @@ suite("DiagnosticsManager Test Suite", async function () { await executeTaskAndWaitForResult(task); // Open file - const promise = waitForDiagnostics([cUri], false); + const promise = Promise.resolve(); // waitForDiagnostics([cUri], false); const document = await vscode.workspace.openTextDocument(cUri); await vscode.languages.setTextDocumentLanguage(document, "c"); await vscode.window.showTextDocument(document); From 0b94c969710685cc4ae4c446830450c1f76979f1 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 13 Nov 2024 15:00:38 -0500 Subject: [PATCH 20/57] Debug build run test --- src/commands/build.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/commands/build.ts b/src/commands/build.ts index afd2bfe67..4d07b2949 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -74,16 +74,26 @@ export async function debugBuildWithOptions( ) { const current = ctx.currentFolder; if (!current) { + console.log(" >>> debugBuildWithOptions: No current folder on WorkspaceContext"); return; } const file = vscode.window.activeTextEditor?.document.fileName; if (!file) { + console.log(" >>> debugBuildWithOptions: No active text editor"); return; } const target = current.swiftPackage.getTarget(file); - if (!target || target.type !== "executable") { + if (!target) { + console.log(" >>> debugBuildWithOptions: No active target"); + return; + } + + if (target.type !== "executable") { + console.log( + ` >>> debugBuildWithOptions: Target is not an executable, instead is ${target.type}` + ); return; } From 2d4259edcb0573dbda2a90236aa9922d842a38c2 Mon Sep 17 00:00:00 2001 From: "Michael (SPG) Weng" Date: Wed, 13 Nov 2024 15:08:37 -0500 Subject: [PATCH 21/57] - Address launch config not being able to be found on windows - Added comments to make the intent more explicit --- src/debugger/launch.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/debugger/launch.ts b/src/debugger/launch.ts index 87bf04edf..549d8d13a 100644 --- a/src/debugger/launch.ts +++ b/src/debugger/launch.ts @@ -113,17 +113,27 @@ export function getLaunchConfiguration( const wsLaunchSection = vscode.workspace.getConfiguration("launch", folderCtx.workspaceFolder); const launchConfigs = wsLaunchSection.get("configurations") || []; const { folder } = getFolderAndNameSuffix(folderCtx); - const buildDirectory = BuildFlags.buildDirectoryFromWorkspacePath(folder, true); + const targetPath = path.join( + BuildFlags.buildDirectoryFromWorkspacePath(folder, true), + "debug", + target + ); + // Users could be on different platforms with different path annotations, + // so normalize before we compare. return launchConfigs.find( - config => config.program === path.join(buildDirectory, "debug", target) + config => path.normalize(config.program) === path.normalize(targetPath) ); } // Return array of DebugConfigurations for executables based on what is in Package.swift function createExecutableConfigurations(ctx: FolderContext): vscode.DebugConfiguration[] { const executableProducts = ctx.swiftPackage.executableProducts; + + // Windows understand the forward slashes, so make the configuration unified as posix path + // to make it easier for users switching between platforms. const { folder, nameSuffix } = getFolderAndNameSuffix(ctx, undefined, "posix"); const buildDirectory = BuildFlags.buildDirectoryFromWorkspacePath(folder, true, "posix"); + return executableProducts.flatMap(product => { const baseConfig = { type: DebugAdapter.getLaunchConfigType(ctx.workspaceContext.swiftVersion), From 771d57dc5f99c6df940bc9517a6e4233540485a1 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 13 Nov 2024 20:23:24 -0500 Subject: [PATCH 22/57] Normalize file paths in PackageDependencyProvider tests --- .vscode-test.js | 2 +- .../ui/PackageDependencyProvider.test.ts | 27 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.vscode-test.js b/.vscode-test.js index c62c65bd8..43e2dcc09 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -15,7 +15,7 @@ const { defineConfig } = require("@vscode/test-cli"); const path = require("path"); -const isCIBuild = false; // process.env["CI"] === "1"; +const isCIBuild = process.env["CI"] === "1"; const isFastTestRun = process.env["FAST_TEST_RUN"] === "1"; // "env" in launch.json doesn't seem to work with vscode-test diff --git a/test/integration-tests/ui/PackageDependencyProvider.test.ts b/test/integration-tests/ui/PackageDependencyProvider.test.ts index eec66a763..69568af27 100644 --- a/test/integration-tests/ui/PackageDependencyProvider.test.ts +++ b/test/integration-tests/ui/PackageDependencyProvider.test.ts @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import { expect } from "chai"; +import * as vscode from "vscode"; import * as path from "path"; import { PackageDependenciesProvider, @@ -47,7 +48,8 @@ suite("PackageDependencyProvider Test Suite", function () { const dep = items.find(n => n.name === "swift-markdown") as PackageNode; expect(dep).to.not.be.undefined; expect(dep?.location).to.equal("https://github.com/swiftlang/swift-markdown.git"); - expect(dep?.path).to.equal( + assertPathsEqual( + dep?.path, path.join(testAssetPath("dependencies"), ".build/checkouts/swift-markdown") ); }); @@ -58,7 +60,7 @@ suite("PackageDependencyProvider Test Suite", function () { const dep = items.find(n => n.name === "defaultpackage") as PackageNode; expect(dep).to.not.be.undefined; expect(dep?.location).to.equal(testAssetPath("defaultPackage")); - expect(dep?.path).to.equal(testAssetPath("defaultPackage")); + assertPathsEqual(dep?.path, testAssetPath("defaultPackage")); }); test("Lists local dependency file structure", async () => { @@ -71,13 +73,14 @@ suite("PackageDependencyProvider Test Suite", function () { const folder = folders.find(n => n.name === "Sources"); expect(folder).to.not.be.undefined; - expect(folder?.path).to.equal(path.join(testAssetPath("defaultPackage"), "Sources")); + assertPathsEqual(folder?.path, path.join(testAssetPath("defaultPackage"), "Sources")); const childFolders = await treeProvider.getChildren(folder); const childFolder = childFolders.find(n => n.name === "PackageExe"); expect(childFolder).to.not.be.undefined; - expect(childFolder?.path).to.equal( + assertPathsEqual( + childFolder?.path, path.join(testAssetPath("defaultPackage"), "Sources/PackageExe") ); @@ -85,7 +88,8 @@ suite("PackageDependencyProvider Test Suite", function () { const file = files.find(n => n.name === "main.swift"); expect(file).to.not.be.undefined; - expect(file?.path).to.equal( + assertPathsEqual( + file?.path, path.join(testAssetPath("defaultPackage"), "Sources/PackageExe/main.swift") ); }); @@ -101,18 +105,25 @@ suite("PackageDependencyProvider Test Suite", function () { expect(folder).to.not.be.undefined; const depPath = path.join(testAssetPath("dependencies"), ".build/checkouts/swift-markdown"); - expect(folder?.path).to.equal(path.join(depPath, "Sources")); + assertPathsEqual(folder?.path, path.join(depPath, "Sources")); const childFolders = await treeProvider.getChildren(folder); const childFolder = childFolders.find(n => n.name === "CAtomic"); expect(childFolder).to.not.be.undefined; - expect(childFolder?.path).to.equal(path.join(depPath, "Sources/CAtomic")); + assertPathsEqual(childFolder?.path, path.join(depPath, "Sources/CAtomic")); const files = await treeProvider.getChildren(childFolder); const file = files.find(n => n.name === "CAtomic.c"); expect(file).to.not.be.undefined; - expect(file?.path).to.equal(path.join(depPath, "Sources/CAtomic/CAtomic.c")); + assertPathsEqual(file?.path, path.join(depPath, "Sources/CAtomic/CAtomic.c")); }); + + function assertPathsEqual(path1: string | undefined, path2: string | undefined) { + expect(path1).to.not.be.undefined; + expect(path2).to.not.be.undefined; + // Convert to vscode.Uri to normalize paths, including drive letter capitalization on Windows. + expect(vscode.Uri.file(path1!).fsPath).to.equal(vscode.Uri.file(path2!).fsPath); + } }); From aa0bb962df8b37234e56a1a07d33e6b1a72d81cf Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 13 Nov 2024 20:45:57 -0500 Subject: [PATCH 23/57] Ensure required codelldb extension is installed for integration tests --- .vscode-test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode-test.js b/.vscode-test.js index 43e2dcc09..5fa7ce6ba 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -53,6 +53,7 @@ module.exports = defineConfig({ }, }, reuseMachineInstall: !isCIBuild, + installExtensions: ["vadimcn.vscode-lldb"], }, { label: "unitTests", From 7c731ae9ad50dcf7827ac5e50a1d67a6fb399890 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 13 Nov 2024 21:18:22 -0500 Subject: [PATCH 24/57] Dependencies test project must be built before test run These tests rely on the workspace-state.json being present in the .build folder, however on fresh checkouts this file has not been created before the tests run. --- assets/test/dependencies/Packages/swift-markdown | 1 + 1 file changed, 1 insertion(+) create mode 120000 assets/test/dependencies/Packages/swift-markdown diff --git a/assets/test/dependencies/Packages/swift-markdown b/assets/test/dependencies/Packages/swift-markdown new file mode 120000 index 000000000..c2cf3786f --- /dev/null +++ b/assets/test/dependencies/Packages/swift-markdown @@ -0,0 +1 @@ +/Users/plemarquand/work/vscode-swift/assets/test/Swift-Markdown \ No newline at end of file From f90b97881f707ea08a6e8cdedc622d1b171a84ca Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 13 Nov 2024 21:35:30 -0500 Subject: [PATCH 25/57] Fix missed assertion in PackageDependencyProvider tests --- test/integration-tests/ui/PackageDependencyProvider.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration-tests/ui/PackageDependencyProvider.test.ts b/test/integration-tests/ui/PackageDependencyProvider.test.ts index 69568af27..b5095b69e 100644 --- a/test/integration-tests/ui/PackageDependencyProvider.test.ts +++ b/test/integration-tests/ui/PackageDependencyProvider.test.ts @@ -59,7 +59,7 @@ suite("PackageDependencyProvider Test Suite", function () { const dep = items.find(n => n.name === "defaultpackage") as PackageNode; expect(dep).to.not.be.undefined; - expect(dep?.location).to.equal(testAssetPath("defaultPackage")); + assertPathsEqual(dep?.location, testAssetPath("defaultPackage")); assertPathsEqual(dep?.path, testAssetPath("defaultPackage")); }); From 31106b355b283fab97c87bce96fd62b6d37bf63e Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 13 Nov 2024 21:36:34 -0500 Subject: [PATCH 26/57] Make dependency test timeout longer because Windows tests are running slower --- test/integration-tests/commands/dependency.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/commands/dependency.test.ts b/test/integration-tests/commands/dependency.test.ts index a0f6592e6..a83beba29 100644 --- a/test/integration-tests/commands/dependency.test.ts +++ b/test/integration-tests/commands/dependency.test.ts @@ -33,8 +33,8 @@ import { suite("Dependency Commmands Test Suite", function () { // full workflow's interaction with spm is longer than the default timeout - // 15 seconds for each test should be more than enough - this.timeout(15 * 1000); + // 60 seconds for each test should be more than enough + this.timeout(60 * 1000); suite("spm Resolve Update Contract Tests", function () { let folderContext: FolderContext; From d51c70946152f52562f840e3f8f8177295b2ad93 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 13 Nov 2024 21:40:01 -0500 Subject: [PATCH 27/57] Remove mistakenly added file --- assets/test/dependencies/Packages/swift-markdown | 1 - 1 file changed, 1 deletion(-) delete mode 120000 assets/test/dependencies/Packages/swift-markdown diff --git a/assets/test/dependencies/Packages/swift-markdown b/assets/test/dependencies/Packages/swift-markdown deleted file mode 120000 index c2cf3786f..000000000 --- a/assets/test/dependencies/Packages/swift-markdown +++ /dev/null @@ -1 +0,0 @@ -/Users/plemarquand/work/vscode-swift/assets/test/Swift-Markdown \ No newline at end of file From dfd5e524459439ba9ad591585a6535b5f8187164 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Thu, 14 Nov 2024 12:08:39 -0500 Subject: [PATCH 28/57] Strip ANSI from messages during test issue output verification --- test/integration-tests/testexplorer/utilities.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/testexplorer/utilities.ts b/test/integration-tests/testexplorer/utilities.ts index 6a86b9a26..c1c0db196 100644 --- a/test/integration-tests/testexplorer/utilities.ts +++ b/test/integration-tests/testexplorer/utilities.ts @@ -26,6 +26,8 @@ import { SettingsMap, updateSettings, } from "../utilities/testutilities"; +// eslint-disable-next-line @typescript-eslint/no-require-imports +import stripAnsi = require("strip-ansi"); /** * Sets up a test that leverages the TestExplorer, returning the TestExplorer, @@ -139,8 +141,8 @@ export function assertTestResults( .map(({ test, message }) => ({ test: test.id, issues: Array.isArray(message) - ? message.map(({ message }) => message) - : [(message as vscode.TestMessage).message], + ? message.map(({ message }) => stripAnsi(message.toString())) + : [stripAnsi((message as vscode.TestMessage).message.toString())], })) .sort(), skipped: testRun.runState.skipped.map(({ id }) => id).sort(), From d4862ae2b05c95763ffb44c0da51222dd5cb1577 Mon Sep 17 00:00:00 2001 From: Michael Weng Date: Thu, 14 Nov 2024 14:58:10 -0500 Subject: [PATCH 29/57] Address spm reset broken on windows after using local dependency --- test/integration-tests/commands/dependency.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/integration-tests/commands/dependency.test.ts b/test/integration-tests/commands/dependency.test.ts index a83beba29..cf9c51209 100644 --- a/test/integration-tests/commands/dependency.test.ts +++ b/test/integration-tests/commands/dependency.test.ts @@ -116,7 +116,11 @@ suite("Dependency Commmands Test Suite", function () { expect(output).to.include("required"); } - test("Use local dependency - Reset", async () => { + test("Use local dependency - Reset", async function () { + // spm reset after using local dependency is broken on windows + if (process.platform === "win32") { + this.skip(); + } await useLocalDependencyTest(); // Contract: spm reset From 50b23ab964678dcb08af32288f18baf8cc43c5a2 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Thu, 14 Nov 2024 15:17:51 -0500 Subject: [PATCH 30/57] Strip ansi from the generated test message --- test/integration-tests/testexplorer/utilities.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/integration-tests/testexplorer/utilities.ts b/test/integration-tests/testexplorer/utilities.ts index c1c0db196..e11fced09 100644 --- a/test/integration-tests/testexplorer/utilities.ts +++ b/test/integration-tests/testexplorer/utilities.ts @@ -151,7 +151,12 @@ export function assertTestResults( }, { passed: (state.passed ?? []).sort(), - failed: (state.failed ?? []).sort(), + failed: (state.failed ?? []) + .map(({ test, issues }) => ({ + test, + issues: issues.map(message => stripAnsi(message)), + })) + .sort(), skipped: (state.skipped ?? []).sort(), errored: (state.errored ?? []).sort(), unknown: 0, From ecc48fb4965d6527f14623f9d02fcc074ce7038b Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Mon, 18 Nov 2024 16:23:20 -0500 Subject: [PATCH 31/57] Strip ANSI from XCTest output when parsing --- src/TestExplorer/TestParsers/XCTestOutputParser.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/TestExplorer/TestParsers/XCTestOutputParser.ts b/src/TestExplorer/TestParsers/XCTestOutputParser.ts index 49b067fdd..e373e8517 100644 --- a/src/TestExplorer/TestParsers/XCTestOutputParser.ts +++ b/src/TestExplorer/TestParsers/XCTestOutputParser.ts @@ -15,6 +15,8 @@ import { ITestRunState, TestIssueDiff } from "./TestRunState"; import { sourceLocationToVSCodeLocation } from "../../utilities/utilities"; import { MarkdownString, Location } from "vscode"; +// eslint-disable-next-line @typescript-eslint/no-require-imports +import stripAnsi = require("strip-ansi"); /** Regex for parsing XCTest output */ interface TestRegex { @@ -148,7 +150,10 @@ export class XCTestOutputParser implements IXCTestOutputParser { * Parse results from `swift test` and update tests accordingly * @param output Output from `swift test` */ - public parseResult(output: string, runState: ITestRunState) { + public parseResult(rawOutput: string, runState: ITestRunState) { + // Windows is inserting ANSI codes into the output to do things like clear the cursor, + // which we don't care about. + const output = process.platform === "win32" ? stripAnsi(rawOutput) : rawOutput; const output2 = output.replace(/\r\n/g, "\n"); const lines = output2.split("\n"); if (runState.excess) { From 32bc17dbb29e613c15011245326a36be9da307ea Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 19 Nov 2024 10:36:22 -0500 Subject: [PATCH 32/57] Fixup test naming --- test/integration-tests/testexplorer/utilities.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/testexplorer/utilities.ts b/test/integration-tests/testexplorer/utilities.ts index e11fced09..cfc69b6f0 100644 --- a/test/integration-tests/testexplorer/utilities.ts +++ b/test/integration-tests/testexplorer/utilities.ts @@ -36,12 +36,12 @@ import stripAnsi = require("strip-ansi"); * @returns Object containing the TestExplorer, WorkspaceContext and a callback to revert * the settings back to their original values. */ -export async function setupTestExplorerTest(settings: SettingsMap = {}) { +export async function setupTestExplorerTest(currentTest?: Mocha.Test, settings: SettingsMap = {}) { const settingsTeardown = await updateSettings(settings); const testProject = testAssetUri("defaultPackage"); - const workspaceContext = await activateExtension(); + const workspaceContext = await activateExtension(currentTest); const testExplorer = testExplorerFor(workspaceContext, testProject); // Set up the listener before bringing the text explorer in to focus, From 01f4eecaa9150de6234aabc0f7d991798551eaaf Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 19 Nov 2024 10:54:20 -0500 Subject: [PATCH 33/57] Set env var for tests in a cross platform way --- .vscode-test.js | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.vscode-test.js b/.vscode-test.js index 5fa7ce6ba..ccf529de9 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -15,6 +15,10 @@ const { defineConfig } = require("@vscode/test-cli"); const path = require("path"); +// Set the environment variable here instead of in the package.json since this +// lets us set it cross platform. +process.env.VSCODE_TEST = "1"; + const isCIBuild = process.env["CI"] === "1"; const isFastTestRun = process.env["FAST_TEST_RUN"] === "1"; diff --git a/package.json b/package.json index 42540fa80..830713b71 100644 --- a/package.json +++ b/package.json @@ -1280,7 +1280,7 @@ "pretest": "npm run compile-tests", "soundness": "docker compose -f docker/docker-compose.yaml -p swift-vscode-soundness-prb run --rm soundness", "test-soundness": "scripts/soundness.sh", - "test": "VSCODE_TEST=1 vscode-test", + "test": "vscode-test", "test-ci": "docker/test-ci.sh ci", "test-nightly": "docker/test-ci.sh nightly", "integration-test": "npm test -- --label integrationTests", From 4032b10546c9404442fc7a12e41ab04c3833bee6 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 19 Nov 2024 11:10:26 -0500 Subject: [PATCH 34/57] Extension teardown in TestExplorerintegrationTest --- .../testexplorer/TestExplorerIntegration.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index 007f7f7b4..03824a383 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -76,6 +76,17 @@ suite("Test Explorer Suite", function () { }); } + beforeEach(() => { + settingsTeardown = undefined; + }); + + afterEach(async () => { + // If a test was skipped there may be nothing to teardown. + if (settingsTeardown) { + await settingsTeardown(); + } + }); + suite("lldb-dap", () => { activateExtensionForTest({ async setup(ctx) { From 994a377a9e063c378517d785c133d6869156fad1 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 19 Nov 2024 15:09:43 -0500 Subject: [PATCH 35/57] Skip broken test on windows 5.9 --- test/integration-tests/DiagnosticsManager.test.ts | 2 ++ test/integration-tests/commands/build.test.ts | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index 645b77e46..5658e824f 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -116,6 +116,7 @@ suite("DiagnosticsManager Test Suite", async function () { if (allDiagnosticsFulfilled) { diagnosticWaiterDisposable?.dispose(); + diagnosticWaiterDisposable = undefined; resolve(); } }); @@ -146,6 +147,7 @@ suite("DiagnosticsManager Test Suite", async function () { teardown(function () { diagnosticWaiterDisposable?.dispose(); + diagnosticWaiterDisposable = undefined; const allDiagnosticsFulfilled = Object.values(remainingExpectedDiagnostics ?? {}).every( diagnostics => diagnostics.length === 0 ); diff --git a/test/integration-tests/commands/build.test.ts b/test/integration-tests/commands/build.test.ts index 2fc2e178d..df7af0ca1 100644 --- a/test/integration-tests/commands/build.test.ts +++ b/test/integration-tests/commands/build.test.ts @@ -30,6 +30,7 @@ import { updateSettings, } from "../utilities/testutilities"; import { pathExists } from "../../../src/utilities/filesystem"; +import { Version } from "../../../src/utilities/version"; suite("Build Commands", function () { let folderContext: FolderContext; @@ -42,6 +43,15 @@ suite("Build Commands", function () { activateExtensionForSuite({ async setup(ctx) { + // The description of this package is crashing on Windows with Swift 5.9.x and below, + // preventing it from being built. + if ( + process.platform === "win32" && + ctx.swiftVersion.isLessThan(new Version(5, 10, 0)) + ) { + this.skip(); + } + workspaceContext = ctx; await waitForNoRunningTasks(); folderContext = await folderInRootWorkspace("defaultPackage", workspaceContext); From 79dab5514f81040af117167d2758423fd55c6d2c Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 20 Nov 2024 11:57:25 -0500 Subject: [PATCH 36/57] Fixup rebase issues --- .../tasks/SwiftPluginTaskProvider.test.ts | 5 +---- .../testexplorer/TestExplorerIntegration.test.ts | 11 ----------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts index e58cdcf82..aa1a186f6 100644 --- a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts @@ -18,10 +18,7 @@ import { expect } from "chai"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; import { SwiftPluginTaskProvider } from "../../../src/tasks/SwiftPluginTaskProvider"; import { FolderContext } from "../../../src/FolderContext"; -import { - activateExtensionForSuite, - folderInRootWorkspace, -} from "../utilities/testutilities"; +import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities"; import { cleanOutput, executeTaskAndWaitForResult, diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index 03824a383..007f7f7b4 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -76,17 +76,6 @@ suite("Test Explorer Suite", function () { }); } - beforeEach(() => { - settingsTeardown = undefined; - }); - - afterEach(async () => { - // If a test was skipped there may be nothing to teardown. - if (settingsTeardown) { - await settingsTeardown(); - } - }); - suite("lldb-dap", () => { activateExtensionForTest({ async setup(ctx) { From dae0440741e8965db63e1da998e21ed58085693e Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 20 Nov 2024 12:11:13 -0500 Subject: [PATCH 37/57] Skip build tests on Windows --- .github/workflows/pull_request.yml | 1 + .vscode-test.js | 4 ---- test/integration-tests/commands/build.test.ts | 9 +++------ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 6c5ad856c..d7a9ed7ed 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -28,6 +28,7 @@ jobs: windows_exclude_swift_versions: '[{"swift_version": "nightly"}]' windows_env_vars: | CI=1 + VSCODE_TEST=1 FAST_TEST_RUN=1 windows_pre_build_command: .github\workflows\scripts\windows\install-nodejs.ps1 windows_build_command: docker\test-windows.ps1 diff --git a/.vscode-test.js b/.vscode-test.js index ccf529de9..5fa7ce6ba 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -15,10 +15,6 @@ const { defineConfig } = require("@vscode/test-cli"); const path = require("path"); -// Set the environment variable here instead of in the package.json since this -// lets us set it cross platform. -process.env.VSCODE_TEST = "1"; - const isCIBuild = process.env["CI"] === "1"; const isFastTestRun = process.env["FAST_TEST_RUN"] === "1"; diff --git a/test/integration-tests/commands/build.test.ts b/test/integration-tests/commands/build.test.ts index df7af0ca1..3cae81a9a 100644 --- a/test/integration-tests/commands/build.test.ts +++ b/test/integration-tests/commands/build.test.ts @@ -30,7 +30,6 @@ import { updateSettings, } from "../utilities/testutilities"; import { pathExists } from "../../../src/utilities/filesystem"; -import { Version } from "../../../src/utilities/version"; suite("Build Commands", function () { let folderContext: FolderContext; @@ -44,11 +43,9 @@ suite("Build Commands", function () { activateExtensionForSuite({ async setup(ctx) { // The description of this package is crashing on Windows with Swift 5.9.x and below, - // preventing it from being built. - if ( - process.platform === "win32" && - ctx.swiftVersion.isLessThan(new Version(5, 10, 0)) - ) { + // preventing it from being built. The cleanup in the teardown is failng as well with + // an EBUSY error. Skip this test on Windows until the issue is resolved. + if (process.platform === "win32") { this.skip(); } From b308a8a878ca805d3ded45f33eb9108afa2766ef Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 20 Nov 2024 12:33:04 -0500 Subject: [PATCH 38/57] Return test explorer directly --- src/FolderContext.ts | 5 ++++- .../testexplorer/TestExplorerIntegration.test.ts | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/FolderContext.ts b/src/FolderContext.ts index 387daea06..f95fd8a66 100644 --- a/src/FolderContext.ts +++ b/src/FolderContext.ts @@ -152,7 +152,10 @@ export class FolderContext implements vscode.Disposable { /** Create Test explorer for this folder */ addTestExplorer() { - this.testExplorer = new TestExplorer(this); + if (this.testExplorer === undefined) { + this.testExplorer = new TestExplorer(this); + } + return this.testExplorer; } /** Create Test explorer for this folder */ diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index 007f7f7b4..daceb0b42 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -175,10 +175,12 @@ suite("Test Explorer Suite", function () { const targetFolder = workspaceContext.folders.find( folder => folder.folder.path === packageFolder.path ); - if (!targetFolder || !targetFolder.testExplorer) { + + if (!targetFolder) { throw new Error("Unable to find test explorer"); } - testExplorer = targetFolder.testExplorer; + + testExplorer = targetFolder.addTestExplorer(); // Set up the listener before bringing the text explorer in to focus, // which starts searching the workspace for tests. From 511d0d3c608543f3f6eb83a61d05c9fc8b7c7e07 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Wed, 20 Nov 2024 14:42:06 -0500 Subject: [PATCH 39/57] Properly dispose of test explorer on folder context --- .vscode-test.js | 2 +- .../TestExplorerIntegration.test.ts | 35 ++++++++----------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.vscode-test.js b/.vscode-test.js index 5fa7ce6ba..b15850560 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -15,7 +15,7 @@ const { defineConfig } = require("@vscode/test-cli"); const path = require("path"); -const isCIBuild = process.env["CI"] === "1"; +const isCIBuild = false; // process.env["CI"] === "1"; const isFastTestRun = process.env["FAST_TEST_RUN"] === "1"; // "env" in launch.json doesn't seem to work with vscode-test diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index daceb0b42..6f35499e7 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -40,11 +40,7 @@ import { reduceTestItemChildren, } from "../../../src/TestExplorer/TestUtils"; import { runnableTag } from "../../../src/TestExplorer/TestDiscovery"; -import { - activateExtensionForSuite, - activateExtensionForTest, - updateSettings, -} from "../utilities/testutilities"; +import { activateExtensionForTest, updateSettings } from "../utilities/testutilities"; import { Commands } from "../../../src/commands"; import { SwiftToolchain } from "../../../src/toolchain/toolchain"; @@ -164,27 +160,24 @@ suite("Test Explorer Suite", function () { }); suite("Standard", () => { - activateExtensionForSuite({ + activateExtensionForTest({ async setup(ctx) { workspaceContext = ctx; - }, - }); - - beforeEach(async () => { - const packageFolder = testAssetUri("defaultPackage"); - const targetFolder = workspaceContext.folders.find( - folder => folder.folder.path === packageFolder.path - ); + const packageFolder = testAssetUri("defaultPackage"); + const targetFolder = workspaceContext.folders.find( + folder => folder.folder.path === packageFolder.path + ); - if (!targetFolder) { - throw new Error("Unable to find test explorer"); - } + if (!targetFolder) { + throw new Error("Unable to find test explorer"); + } - testExplorer = targetFolder.addTestExplorer(); + testExplorer = targetFolder.addTestExplorer(); - // Set up the listener before bringing the text explorer in to focus, - // which starts searching the workspace for tests. - await waitForTestExplorerReady(testExplorer); + // Set up the listener before bringing the text explorer in to focus, + // which starts searching the workspace for tests. + await waitForTestExplorerReady(testExplorer); + }, }); test("Finds Tests", async function () { From e7c72122db8a0f20d7545559cb0974a8ec3ef4db Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Thu, 21 Nov 2024 15:24:21 -0500 Subject: [PATCH 40/57] Disable swift-testing tests on 6.0 since it cannot produce JSON events --- .../TestExplorerIntegration.test.ts | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index 6f35499e7..65c100213 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -63,7 +63,15 @@ suite("Test Explorer Suite", function () { }); } - async function runSwiftTesting() { + async function runSwiftTesting(this: Mocha.Context) { + if ( + // swift-testing was not able to produce JSON events until 6.0.2 on Windows. + process.platform === "win32" && + workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 2)) + ) { + this.skip(); + } + const testId = "PackageTests.topLevelTestPassing()"; const testRun = await runTest(testExplorer, TestKind.debug, testId); @@ -97,7 +105,9 @@ suite("Test Explorer Suite", function () { }); test("Debugs specified XCTest test", runXCTest); - test("Debugs specified swift-testing test", runSwiftTesting); + test("Debugs specified swift-testing test", async function () { + await runSwiftTesting.call(this); + }); }); suite("CodeLLDB", () => { @@ -154,7 +164,7 @@ suite("Test Explorer Suite", function () { if (workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 0))) { this.skip(); } - await runSwiftTesting(); + await runSwiftTesting.call(this); }); }); }); @@ -235,7 +245,12 @@ suite("Test Explorer Suite", function () { suite("swift-testing", () => { suiteSetup(function () { - if (workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 0))) { + if ( + workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 0)) || + // swift-testing was not able to produce JSON events until 6.0.2 on Windows. + (process.platform === "win32" && + workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 2))) + ) { this.skip(); } }); @@ -488,7 +503,11 @@ suite("Test Explorer Suite", function () { suite(runProfile, () => { suite(`swift-testing (${runProfile})`, function () { suiteSetup(function () { - if (workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 0))) { + if ( + workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 0)) || + (process.platform === "win32" && + workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 2))) + ) { this.skip(); } }); From 3f4ac2a47da27ddaf184803d3f3f23ac7702f3b0 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Thu, 21 Nov 2024 15:24:47 -0500 Subject: [PATCH 41/57] Improve error message when an error is thrown in before/beforeEach --- test/integration-tests/utilities/testutilities.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/integration-tests/utilities/testutilities.ts b/test/integration-tests/utilities/testutilities.ts index a5f6b101b..57b720701 100644 --- a/test/integration-tests/utilities/testutilities.ts +++ b/test/integration-tests/utilities/testutilities.ts @@ -82,9 +82,14 @@ const extensionBootstrapper = (() => { // Typically this is the promise returned from `updateSettings`, which will // undo any settings changed during setup. autoTeardown = await setup.call(this, workspaceContext); - } catch (error) { - console.error(`Error during test/suite setup, captured logs are:`); - workspaceContext.outputChannel.logs.map(log => console.log(log)); + } catch (error: any) { + // Mocha will throw an error to break out of a test if `.skip` is used. + if (error.message?.indexOf("sync skip;") === -1) { + console.error(`Error during test/suite setup: ${JSON.stringify(error)}`); + console.error("Captured logs are:"); + workspaceContext.outputChannel.logs.map(log => console.error(log)); + console.error("================ end test logs ================"); + } throw error; } }); From f4bc6ce56134f331b95563b4493b85cad5b7eb28 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Thu, 21 Nov 2024 15:38:04 -0500 Subject: [PATCH 42/57] Add more logging on startup --- src/debugger/lldb.ts | 4 +++- src/extension.ts | 8 ++++++++ test/unit-tests/debugger/lldb.test.ts | 6 ++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/debugger/lldb.ts b/src/debugger/lldb.ts index ff4eccbe1..dc1877d64 100644 --- a/src/debugger/lldb.ts +++ b/src/debugger/lldb.ts @@ -151,6 +151,8 @@ export async function getLldbProcess( } }); } catch (error) { - vscode.window.showErrorMessage(`Failed to run LLDB: ${getErrorDescription(error)}`); + const errorMessage = `Failed to run LLDB: ${getErrorDescription(error)}`; + ctx.outputChannel.log(errorMessage); + vscode.window.showErrorMessage(errorMessage); } } diff --git a/src/extension.ts b/src/extension.ts index f2dc998c2..bc53d1ac7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -122,6 +122,14 @@ export async function activate(context: vscode.ExtensionContext): Promise { } const workspaceContext = await WorkspaceContext.create(outputChannel, toolchain); + + workspaceContext.outputChannel.log("Platform:", process.platform); + workspaceContext.outputChannel.log( + "Swift Version:", + workspaceContext.swiftVersion.toString() + ); + workspaceContext.outputChannel.log("Swift toolchain found at:", toolchain.swiftFolderPath); + context.subscriptions.push(...commands.register(workspaceContext)); context.subscriptions.push(workspaceContext); context.subscriptions.push(registerDebugger(workspaceContext)); diff --git a/test/unit-tests/debugger/lldb.test.ts b/test/unit-tests/debugger/lldb.test.ts index e2f59aadc..0bc5c1d6d 100644 --- a/test/unit-tests/debugger/lldb.test.ts +++ b/test/unit-tests/debugger/lldb.test.ts @@ -30,6 +30,7 @@ import { } from "../../MockUtils"; import { SwiftToolchain } from "../../../src/toolchain/toolchain"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; +import { SwiftOutputChannel } from "../../../src/ui/SwiftOutputChannel"; suite("debugger.lldb Tests", () => { suite("getLLDBLibPath Tests", () => { @@ -144,11 +145,16 @@ suite("debugger.lldb Tests", () => { let mockToolchain: MockedObject; setup(() => { + windowMock.createOutputChannel.returns({ + appendLine() {}, + } as unknown as vscode.LogOutputChannel); + mockToolchain = mockObject({ getLLDB: mockFn(s => s.resolves("/path/to/lldb")), }); mockContext = mockObject({ toolchain: instance(mockToolchain), + outputChannel: new SwiftOutputChannel("mockChannel", false), }); }); From 64eb87910b2f2fb34f481758b720f0503735aa03 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 09:35:00 -0500 Subject: [PATCH 43/57] Disable LLDB tests on 6.0; lldb.exe wont launch in docker --- src/debugger/lldb.ts | 3 ++- src/extension.ts | 9 +++++---- src/ui/SwiftOutputChannel.ts | 9 ++------- test/integration-tests/debugger/lldb.test.ts | 14 ++++++++++++-- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/debugger/lldb.ts b/src/debugger/lldb.ts index dc1877d64..803913c27 100644 --- a/src/debugger/lldb.ts +++ b/src/debugger/lldb.ts @@ -142,7 +142,7 @@ export async function getLldbProcess( "platform process list --show-args --all-users", ]); const entries = stdout.split("\n"); - return entries.flatMap(line => { + const processes = entries.flatMap(line => { const match = /^(\d+)\s+\d+\s+\S+\s+\S+\s+(.+)$/.exec(line); if (match) { return [{ pid: parseInt(match[1]), label: `${match[1]}: ${match[2]}` }]; @@ -150,6 +150,7 @@ export async function getLldbProcess( return []; } }); + return processes; } catch (error) { const errorMessage = `Failed to run LLDB: ${getErrorDescription(error)}`; ctx.outputChannel.log(errorMessage); diff --git a/src/extension.ts b/src/extension.ts index bc53d1ac7..5ae7a7828 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -123,12 +123,13 @@ export async function activate(context: vscode.ExtensionContext): Promise { const workspaceContext = await WorkspaceContext.create(outputChannel, toolchain); - workspaceContext.outputChannel.log("Platform:", process.platform); + workspaceContext.outputChannel.log(`Platform: ${process.platform}`); workspaceContext.outputChannel.log( - "Swift Version:", - workspaceContext.swiftVersion.toString() + `Swift Version: ${workspaceContext.swiftVersion.toString()}` + ); + workspaceContext.outputChannel.log( + `Swift toolchain found at: ${toolchain.swiftFolderPath}` ); - workspaceContext.outputChannel.log("Swift toolchain found at:", toolchain.swiftFolderPath); context.subscriptions.push(...commands.register(workspaceContext)); context.subscriptions.push(workspaceContext); diff --git a/src/ui/SwiftOutputChannel.ts b/src/ui/SwiftOutputChannel.ts index 17446aac2..04291b0ba 100644 --- a/src/ui/SwiftOutputChannel.ts +++ b/src/ui/SwiftOutputChannel.ts @@ -86,15 +86,10 @@ export class SwiftOutputChannel implements vscode.OutputChannel { } logDiagnostic(message: string, label?: string) { - if (!configuration.diagnostics) { + if (!configuration.diagnostics && process.env["CI"] !== "1") { return; } - let fullMessage: string; - if (label !== undefined) { - fullMessage = `${label}: ${message}`; - } else { - fullMessage = message; - } + const fullMessage = label !== undefined ? `${label}: ${message}` : message; this.appendLine(`${this.nowFormatted}: ${fullMessage}`); } diff --git a/test/integration-tests/debugger/lldb.test.ts b/test/integration-tests/debugger/lldb.test.ts index 6731e67a5..aa070721c 100644 --- a/test/integration-tests/debugger/lldb.test.ts +++ b/test/integration-tests/debugger/lldb.test.ts @@ -15,13 +15,23 @@ import { expect } from "chai"; import { getLLDBLibPath, getLldbProcess } from "../../../src/debugger/lldb"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; -import { activateExtensionForSuite } from "../utilities/testutilities"; +import { activateExtensionForTest } from "../utilities/testutilities"; +import { Version } from "../../../src/utilities/version"; suite("lldb contract test suite", () => { let workspaceContext: WorkspaceContext; - activateExtensionForSuite({ + activateExtensionForTest({ async setup(ctx) { + // lldb.exe on Windows is not launching correctly, but only in Docker. + if ( + process.env["CI"] && + process.platform === "win32" && + ctx.swiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0)) && + ctx.swiftVersion.isLessThan(new Version(6, 0, 2)) + ) { + this.skip(); + } workspaceContext = ctx; }, }); From 9e6c62846947f808a7c5e689d9d7475181fbcea0 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 11:54:27 -0500 Subject: [PATCH 44/57] Move extra logging to diagnostics getter --- src/extension.ts | 9 --------- src/toolchain/toolchain.ts | 2 ++ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 5ae7a7828..f2dc998c2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -122,15 +122,6 @@ export async function activate(context: vscode.ExtensionContext): Promise { } const workspaceContext = await WorkspaceContext.create(outputChannel, toolchain); - - workspaceContext.outputChannel.log(`Platform: ${process.platform}`); - workspaceContext.outputChannel.log( - `Swift Version: ${workspaceContext.swiftVersion.toString()}` - ); - workspaceContext.outputChannel.log( - `Swift toolchain found at: ${toolchain.swiftFolderPath}` - ); - context.subscriptions.push(...commands.register(workspaceContext)); context.subscriptions.push(workspaceContext); context.subscriptions.push(registerDebugger(workspaceContext)); diff --git a/src/toolchain/toolchain.ts b/src/toolchain/toolchain.ts index 7f78f6ff1..89d0bc1bd 100644 --- a/src/toolchain/toolchain.ts +++ b/src/toolchain/toolchain.ts @@ -468,6 +468,8 @@ export class SwiftToolchain { get diagnostics(): string { let str = ""; str += this.swiftVersionString; + str += `\nPlatform: ${process.platform}`; + str += `\nSwift Version: ${this.swiftVersion.toString()}`; str += `\nSwift Path: ${this.swiftFolderPath}`; str += `\nToolchain Path: ${this.toolchainPath}`; if (this.runtimePath) { From f5f336093e6d4b3c2820b958b25827bf20885cbc Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 11:54:44 -0500 Subject: [PATCH 45/57] Always clean up observe folders disposable --- .../WorkspaceContext.test.ts | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/test/integration-tests/WorkspaceContext.test.ts b/test/integration-tests/WorkspaceContext.test.ts index 43ce49914..3c0bf5ecb 100644 --- a/test/integration-tests/WorkspaceContext.test.ts +++ b/test/integration-tests/WorkspaceContext.test.ts @@ -45,22 +45,26 @@ suite("WorkspaceContext Test Suite", () => { suite("Folder Events", () => { test("Add", async () => { let count = 0; - const observer = workspaceContext?.onDidChangeFolders(({ folder, operation }) => { - assert(folder !== null); - assert.strictEqual(folder!.swiftPackage.name, "package2"); - switch (operation) { - case FolderOperation.add: - count++; - break; + let observer: vscode.Disposable | undefined; + try { + observer = workspaceContext?.onDidChangeFolders(({ folder, operation }) => { + assert(folder !== null); + assert.strictEqual(folder!.swiftPackage.name, "package2"); + switch (operation) { + case FolderOperation.add: + count++; + break; + } + }); + const workspaceFolder = vscode.workspace.workspaceFolders?.values().next().value; + if (!workspaceFolder) { + throw new Error("No workspace folders found in workspace"); } - }); - const workspaceFolder = vscode.workspace.workspaceFolders?.values().next().value; - if (!workspaceFolder) { - throw new Error("No workspace folders found in workspace"); + await workspaceContext?.addPackageFolder(testAssetUri("package2"), workspaceFolder); + assert.strictEqual(count, 1); + } finally { + observer?.dispose(); } - await workspaceContext?.addPackageFolder(testAssetUri("package2"), workspaceFolder); - assert.strictEqual(count, 1); - observer?.dispose(); }).timeout(15000); }); From bc91435cc72edae0dedda340a69b0a5f79858a71 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 12:06:58 -0500 Subject: [PATCH 46/57] More robust activation tests --- test/integration-tests/ExtensionActivation.test.ts | 10 +++++----- test/integration-tests/utilities/testutilities.ts | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/integration-tests/ExtensionActivation.test.ts b/test/integration-tests/ExtensionActivation.test.ts index a06daab7b..52913d17a 100644 --- a/test/integration-tests/ExtensionActivation.test.ts +++ b/test/integration-tests/ExtensionActivation.test.ts @@ -37,23 +37,23 @@ suite("Extension Activation/Deactivation Tests", () => { } test("Activation", async function () { - await activate(this.currentTest); + await activate(this.test as Mocha.Test); }); test("Duplicate Activation", async function () { - await activate(this.currentTest); - assert.rejects(activateExtension(this.currentTest), err => { + await activate(this.test as Mocha.Test); + assert.rejects(activateExtension(this.test as Mocha.Test), err => { const msg = (err as unknown as any).message; return ( msg.includes("Extension is already activated") && - msg.includes(this.currentTest?.fullTitle()) + msg.includes((this.test as Mocha.Test)?.titlePath().join(" → ")) ); }); }); }); test("Deactivation", async function () { - const workspaceContext = await activateExtension(this.currentTest); + const workspaceContext = await activateExtension(this.test as Mocha.Test); await deactivateExtension(); const ext = vscode.extensions.getExtension("sswg.swift-lang"); assert(ext); diff --git a/test/integration-tests/utilities/testutilities.ts b/test/integration-tests/utilities/testutilities.ts index 57b720701..7dbd044f1 100644 --- a/test/integration-tests/utilities/testutilities.ts +++ b/test/integration-tests/utilities/testutilities.ts @@ -140,10 +140,14 @@ const extensionBootstrapper = (() => { // Subsequent activations must be done through the returned API object. if (!activator) { activatedAPI = await ext.activate(); + // Save the test name so if the test doesn't clean up by deactivating properly the next + // test that tries to activate can throw an error with the name of the test that needs to clean up. + lastTestName = currentTest?.titlePath().join(" → "); activator = activatedAPI.activate; workspaceContext = activatedAPI.workspaceContext; } else { activatedAPI = await activator(); + lastTestName = currentTest?.titlePath().join(" → "); workspaceContext = activatedAPI.workspaceContext; } @@ -158,10 +162,6 @@ const extensionBootstrapper = (() => { await workspaceContext.addPackageFolder(packageFolder, workspaceFolder); } - // Save the test name so if the test doesn't clean up by deactivating properly the next - // test that tries to activate can throw an error with the name of the test that needs to clean up. - lastTestName = currentTest?.fullTitle(); - return workspaceContext; }, deactivateExtension: async () => { From cd1adf53d4112aa2018fb0c536a2754d99ed5433 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 12:50:36 -0500 Subject: [PATCH 47/57] Disable lldb-dap tests on <6.0.2 --- src/toolchain/toolchain.ts | 1 - .../testexplorer/TestExplorerIntegration.test.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/toolchain/toolchain.ts b/src/toolchain/toolchain.ts index 89d0bc1bd..9ee7b3938 100644 --- a/src/toolchain/toolchain.ts +++ b/src/toolchain/toolchain.ts @@ -469,7 +469,6 @@ export class SwiftToolchain { let str = ""; str += this.swiftVersionString; str += `\nPlatform: ${process.platform}`; - str += `\nSwift Version: ${this.swiftVersion.toString()}`; str += `\nSwift Path: ${this.swiftFolderPath}`; str += `\nToolchain Path: ${this.toolchainPath}`; if (this.runtimePath) { diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index 65c100213..b058a29fe 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -83,8 +83,8 @@ suite("Test Explorer Suite", function () { suite("lldb-dap", () => { activateExtensionForTest({ async setup(ctx) { - // lldb-dap is only present in the toolchain in 6.0 and up. - if (ctx.swiftVersion.isLessThan(new Version(6, 0, 0))) { + // lldb-dap is only present/functional in the toolchain in 6.0.2 and up. + if (ctx.swiftVersion.isLessThan(new Version(6, 0, 2))) { this.skip(); } From 2e7fb7d91b2f8d422438cf2456c984037dd9fd74 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 13:30:03 -0500 Subject: [PATCH 48/57] Avoid folder events test improperly recording the defaultPackage addition in extension setup --- .../WorkspaceContext.test.ts | 63 ++++++++++++------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/test/integration-tests/WorkspaceContext.test.ts b/test/integration-tests/WorkspaceContext.test.ts index 3c0bf5ecb..bf651ad93 100644 --- a/test/integration-tests/WorkspaceContext.test.ts +++ b/test/integration-tests/WorkspaceContext.test.ts @@ -20,6 +20,7 @@ import { createBuildAllTask } from "../../src/tasks/SwiftTaskProvider"; import { Version } from "../../src/utilities/version"; import { SwiftExecution } from "../../src/tasks/SwiftExecution"; import { activateExtensionForSuite } from "./utilities/testutilities"; +import { FolderContext } from "../../src/FolderContext"; function assertContainsArg(execution: SwiftExecution, arg: string) { assert(execution?.args.find(a => a === arg)); @@ -36,39 +37,53 @@ suite("WorkspaceContext Test Suite", () => { let workspaceContext: WorkspaceContext; const packageFolder: vscode.Uri = testAssetUri("defaultPackage"); - activateExtensionForSuite({ - async setup(ctx) { - workspaceContext = ctx; - }, - }); - suite("Folder Events", () => { + activateExtensionForSuite({ + async setup(ctx) { + workspaceContext = ctx; + }, + // No default assets as we want to verify against a clean workspace. + testAssets: [], + }); + test("Add", async () => { - let count = 0; let observer: vscode.Disposable | undefined; + const recordedFolders: { + folder: FolderContext | null; + operation: FolderOperation; + }[] = []; + try { - observer = workspaceContext?.onDidChangeFolders(({ folder, operation }) => { - assert(folder !== null); - assert.strictEqual(folder!.swiftPackage.name, "package2"); - switch (operation) { - case FolderOperation.add: - count++; - break; - } + observer = workspaceContext.onDidChangeFolders(changedFolderRecord => { + recordedFolders.push(changedFolderRecord); }); + const workspaceFolder = vscode.workspace.workspaceFolders?.values().next().value; - if (!workspaceFolder) { - throw new Error("No workspace folders found in workspace"); - } - await workspaceContext?.addPackageFolder(testAssetUri("package2"), workspaceFolder); - assert.strictEqual(count, 1); + + assert.ok(workspaceFolder, "No workspace folders found in workspace"); + + await workspaceContext.addPackageFolder(testAssetUri("package2"), workspaceFolder); + + const foldersNames = recordedFolders.map(({ folder }) => folder?.swiftPackage.name); + assert.deepStrictEqual(foldersNames, ["package2"]); + + const addedCount = recordedFolders.filter( + ({ operation }) => operation === FolderOperation.add + ).length; + assert.strictEqual(addedCount, 1, "Expected only one add folder operation"); } finally { observer?.dispose(); } - }).timeout(15000); + }).timeout(60000); }); suite("Tasks", async function () { + activateExtensionForSuite({ + async setup(ctx) { + workspaceContext = ctx; + }, + }); + // Was hitting a timeout in suiteSetup during CI build once in a while this.timeout(5000); @@ -158,6 +173,12 @@ suite("WorkspaceContext Test Suite", () => { }); suite("Toolchain", () => { + activateExtensionForSuite({ + async setup(ctx) { + workspaceContext = ctx; + }, + }); + test("get project templates", async () => { // This is only supported in swift versions >=5.8.0 const swiftVersion = workspaceContext.toolchain.swiftVersion; From 469777eb73f872fc20540fbb2960f42d3e25e887 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 14:02:40 -0500 Subject: [PATCH 49/57] Increase some timeouts --- test/integration-tests/WorkspaceContext.test.ts | 2 +- test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/WorkspaceContext.test.ts b/test/integration-tests/WorkspaceContext.test.ts index bf651ad93..3d2836407 100644 --- a/test/integration-tests/WorkspaceContext.test.ts +++ b/test/integration-tests/WorkspaceContext.test.ts @@ -74,7 +74,7 @@ suite("WorkspaceContext Test Suite", () => { } finally { observer?.dispose(); } - }).timeout(60000); + }).timeout(60000 * 2); }); suite("Tasks", async function () { diff --git a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts index aa1a186f6..9f91ab740 100644 --- a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts @@ -54,7 +54,7 @@ suite("SwiftPluginTaskProvider Test Suite", () => { const { exitCode, output } = await executeTaskAndWaitForResult(task); expect(exitCode).to.equal(0); expect(cleanOutput(output)).to.include("Hello, World!"); - }).timeout(10000); + }).timeout(60000); test("Exit code on failure", async () => { const task = taskProvider.createSwiftPluginTask( From fc54deae0cb9f7a6d9d7bf03f9f7baae62b4ab77 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 14:18:18 -0500 Subject: [PATCH 50/57] Better package dep provider assertions --- .../ui/PackageDependencyProvider.test.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/ui/PackageDependencyProvider.test.ts b/test/integration-tests/ui/PackageDependencyProvider.test.ts index b5095b69e..85d62556b 100644 --- a/test/integration-tests/ui/PackageDependencyProvider.test.ts +++ b/test/integration-tests/ui/PackageDependencyProvider.test.ts @@ -40,6 +40,7 @@ suite("PackageDependencyProvider Test Suite", function () { async teardown() { treeProvider.dispose(); }, + testAssets: ["dependencies"], }); test("Includes remote dependency", async () => { @@ -58,7 +59,10 @@ suite("PackageDependencyProvider Test Suite", function () { const items = await treeProvider.getChildren(); const dep = items.find(n => n.name === "defaultpackage") as PackageNode; - expect(dep).to.not.be.undefined; + expect( + dep, + `Expected to find defaultPackage, but instead items were ${items.map(n => n.name)}` + ).to.not.be.undefined; assertPathsEqual(dep?.location, testAssetPath("defaultPackage")); assertPathsEqual(dep?.path, testAssetPath("defaultPackage")); }); @@ -67,7 +71,10 @@ suite("PackageDependencyProvider Test Suite", function () { const items = await treeProvider.getChildren(); const dep = items.find(n => n.name === "defaultpackage") as PackageNode; - expect(dep).to.not.be.undefined; + expect( + dep, + `Expected to find defaultPackage, but instead items were ${items.map(n => n.name)}` + ).to.not.be.undefined; const folders = await treeProvider.getChildren(dep); const folder = folders.find(n => n.name === "Sources"); From f738646d1dd62e34f455596a6b8899ba678edf5e Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 16:10:07 -0500 Subject: [PATCH 51/57] Only configure test explorer once in tests --- .../TestExplorerIntegration.test.ts | 122 ++++++++---------- .../testexplorer/utilities.ts | 16 ++- 2 files changed, 65 insertions(+), 73 deletions(-) diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index b058a29fe..a646c1c64 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -14,7 +14,7 @@ import * as assert from "assert"; import * as vscode from "vscode"; -import { beforeEach } from "mocha"; +import { beforeEach, afterEach } from "mocha"; import { testAssetUri } from "../../fixtures"; import { TestExplorer } from "../../../src/TestExplorer/TestExplorer"; import { @@ -24,7 +24,6 @@ import { eventPromise, gatherTests, runTest, - testExplorerFor, waitForTestExplorerReady, } from "./utilities"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; @@ -40,7 +39,7 @@ import { reduceTestItemChildren, } from "../../../src/TestExplorer/TestUtils"; import { runnableTag } from "../../../src/TestExplorer/TestDiscovery"; -import { activateExtensionForTest, updateSettings } from "../utilities/testutilities"; +import { activateExtensionForSuite, updateSettings } from "../utilities/testutilities"; import { Commands } from "../../../src/commands"; import { SwiftToolchain } from "../../../src/toolchain/toolchain"; @@ -52,6 +51,26 @@ suite("Test Explorer Suite", function () { let workspaceContext: WorkspaceContext; let testExplorer: TestExplorer; + activateExtensionForSuite({ + async setup(ctx) { + workspaceContext = ctx; + const packageFolder = testAssetUri("defaultPackage"); + const targetFolder = workspaceContext.folders.find( + folder => folder.folder.path === packageFolder.path + ); + + if (!targetFolder) { + throw new Error("Unable to find test explorer"); + } + + testExplorer = targetFolder.addTestExplorer(); + + // Set up the listener before bringing the text explorer in to focus, + // which starts searching the workspace for tests. + await waitForTestExplorerReady(testExplorer); + }, + }); + suite("Debugging", function () { async function runXCTest() { const suiteId = "PackageTests.PassingXCTestSuite"; @@ -81,27 +100,22 @@ suite("Test Explorer Suite", function () { } suite("lldb-dap", () => { - activateExtensionForTest({ - async setup(ctx) { - // lldb-dap is only present/functional in the toolchain in 6.0.2 and up. - if (ctx.swiftVersion.isLessThan(new Version(6, 0, 2))) { - this.skip(); - } - - workspaceContext = ctx; - testExplorer = testExplorerFor( - workspaceContext, - testAssetUri("defaultPackage") - ); + let resetSettings: (() => Promise) | undefined; + beforeEach(async function () { + // lldb-dap is only present/functional in the toolchain in 6.0.2 and up. + if (workspaceContext.swiftVersion.isLessThan(new Version(6, 0, 2))) { + this.skip(); + } - // Set up the listener before bringing the text explorer in to focus, - // which starts searching the workspace for tests. - await waitForTestExplorerReady(testExplorer); + resetSettings = await updateSettings({ + "swift.debugger.useDebugAdapterFromToolchain": true, + }); + }); - return await updateSettings({ - "swift.debugger.useDebugAdapterFromToolchain": true, - }); - }, + afterEach(async () => { + if (resetSettings) { + await resetSettings(); + } }); test("Debugs specified XCTest test", runXCTest); @@ -122,34 +136,28 @@ suite("Test Explorer Suite", function () { } } - activateExtensionForTest({ - async setup(ctx) { - // CodeLLDB on windows doesn't print output and so cannot be parsed - if (process.platform === "win32") { - this.skip(); - return; - } - - workspaceContext = ctx; - testExplorer = testExplorerFor( - workspaceContext, - testAssetUri("defaultPackage") - ); + let resetSettings: (() => Promise) | undefined; + beforeEach(async function () { + // CodeLLDB on windows doesn't print output and so cannot be parsed + if (process.platform === "win32") { + this.skip(); + } - // Set up the listener before bringing the text explorer in to focus, - // which starts searching the workspace for tests. - await waitForTestExplorerReady(testExplorer); + const lldbPath = + process.env["CI"] === "1" + ? { "lldb.library": await getLLDBDebugAdapterPath() } + : {}; - const lldbPath = - process.env["CI"] === "1" - ? { "lldb.library": await getLLDBDebugAdapterPath() } - : {}; + resetSettings = await updateSettings({ + "swift.debugger.useDebugAdapterFromToolchain": false, + ...lldbPath, + }); + }); - return await updateSettings({ - "swift.debugger.useDebugAdapterFromToolchain": false, - ...lldbPath, - }); - }, + afterEach(async () => { + if (resetSettings) { + await resetSettings(); + } }); test("Debugs specified XCTest test", async function () { @@ -170,26 +178,6 @@ suite("Test Explorer Suite", function () { }); suite("Standard", () => { - activateExtensionForTest({ - async setup(ctx) { - workspaceContext = ctx; - const packageFolder = testAssetUri("defaultPackage"); - const targetFolder = workspaceContext.folders.find( - folder => folder.folder.path === packageFolder.path - ); - - if (!targetFolder) { - throw new Error("Unable to find test explorer"); - } - - testExplorer = targetFolder.addTestExplorer(); - - // Set up the listener before bringing the text explorer in to focus, - // which starts searching the workspace for tests. - await waitForTestExplorerReady(testExplorer); - }, - }); - test("Finds Tests", async function () { if (workspaceContext.swiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0))) { // 6.0 uses the LSP which returns tests in the order they're declared. diff --git a/test/integration-tests/testexplorer/utilities.ts b/test/integration-tests/testexplorer/utilities.ts index cfc69b6f0..af64c6731 100644 --- a/test/integration-tests/testexplorer/utilities.ts +++ b/test/integration-tests/testexplorer/utilities.ts @@ -239,12 +239,16 @@ export async function gatherTests( const testItems = tests.map(test => { const testItem = getTestItem(controller, test); if (!testItem) { - const testsInController: string[] = []; - controller.items.forEach(item => { - testsInController.push( - `${item.id}: ${item.label} ${item.error ? `(error: ${item.error})` : ""}` - ); - }); + const testsInController = reduceTestItemChildren( + controller.items, + (acc, item) => { + acc.push( + `${item.id}: ${item.label} ${item.error ? `(error: ${item.error})` : ""}` + ); + return acc; + }, + [] as string[] + ); assert.fail( `Unable to find ${test} in Test Controller. Items in test controller are: ${testsInController.join(", ")}` From 164907d5ffdec5219d0d351300e1363e97ef23d2 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 16:17:46 -0500 Subject: [PATCH 52/57] Improve folder add test again --- test/integration-tests/DiagnosticsManager.test.ts | 2 +- test/integration-tests/WorkspaceContext.test.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index 5658e824f..afb11bb85 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -125,7 +125,7 @@ suite("DiagnosticsManager Test Suite", async function () { activateExtensionForSuite({ async setup(ctx) { - this.timeout(60000); + this.timeout(60000 * 2); workspaceContext = ctx; toolchain = workspaceContext.toolchain; diff --git a/test/integration-tests/WorkspaceContext.test.ts b/test/integration-tests/WorkspaceContext.test.ts index 3d2836407..e12583216 100644 --- a/test/integration-tests/WorkspaceContext.test.ts +++ b/test/integration-tests/WorkspaceContext.test.ts @@ -21,6 +21,7 @@ import { Version } from "../../src/utilities/version"; import { SwiftExecution } from "../../src/tasks/SwiftExecution"; import { activateExtensionForSuite } from "./utilities/testutilities"; import { FolderContext } from "../../src/FolderContext"; +import { assertContains } from "./testexplorer/utilities"; function assertContainsArg(execution: SwiftExecution, arg: string) { assert(execution?.args.find(a => a === arg)); @@ -65,12 +66,16 @@ suite("WorkspaceContext Test Suite", () => { await workspaceContext.addPackageFolder(testAssetUri("package2"), workspaceFolder); const foldersNames = recordedFolders.map(({ folder }) => folder?.swiftPackage.name); - assert.deepStrictEqual(foldersNames, ["package2"]); + assertContains(foldersNames, "package2"); const addedCount = recordedFolders.filter( ({ operation }) => operation === FolderOperation.add ).length; - assert.strictEqual(addedCount, 1, "Expected only one add folder operation"); + assert.strictEqual( + addedCount, + 1, + `Expected only one add folder operation, instead got folders: ${recordedFolders}` + ); } finally { observer?.dispose(); } From 09c94d3e32f79d19ef9ef50b9a5c8c7fc8deb075 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 16:47:19 -0500 Subject: [PATCH 53/57] Increate diagnostics test timeouts --- test/integration-tests/DiagnosticsManager.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index afb11bb85..01600b53b 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -163,7 +163,9 @@ suite("DiagnosticsManager Test Suite", async function () { } }); - suite("Parse diagnostics", async () => { + suite("Parse diagnostics", async function () { + this.timeout(60000); + suite("Parse from task output", async () => { const expectedWarningDiagnostic = new vscode.Diagnostic( new vscode.Range(new vscode.Position(1, 8), new vscode.Position(1, 8)), @@ -226,7 +228,6 @@ suite("DiagnosticsManager Test Suite", async function () { swiftVersion.isLessThanOrEqual(new Version(6, 0, 999)) ) { this.skip(); - return; } await swiftConfig.update("diagnosticsStyle", "default"); From a90cc0e6a361fcc5c5305102e56e22cfedc6d9eb Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 22 Nov 2024 19:50:49 -0500 Subject: [PATCH 54/57] Wait for diagnostics before building --- test/integration-tests/DiagnosticsManager.test.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index 01600b53b..48db101a9 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -164,7 +164,7 @@ suite("DiagnosticsManager Test Suite", async function () { }); suite("Parse diagnostics", async function () { - this.timeout(60000); + this.timeout(60000 * 2); suite("Parse from task output", async () => { const expectedWarningDiagnostic = new vscode.Diagnostic( @@ -232,7 +232,6 @@ suite("DiagnosticsManager Test Suite", async function () { await swiftConfig.update("diagnosticsStyle", "default"); await Promise.all([ - executeTaskAndWaitForResult(createBuildAllTask(folderContext)), waitForDiagnostics({ [mainUri.fsPath]: [ expectedWarningDiagnostic, @@ -245,6 +244,7 @@ suite("DiagnosticsManager Test Suite", async function () { ], // Should have parsed correct severity [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file }), + executeTaskAndWaitForResult(createBuildAllTask(folderContext)), ]); await waitForNoRunningTasks(); @@ -264,12 +264,13 @@ suite("DiagnosticsManager Test Suite", async function () { this.skip(); } await swiftConfig.update("diagnosticsStyle", "swift"); + await Promise.all([ - executeTaskAndWaitForResult(createBuildAllTask(folderContext)), waitForDiagnostics({ [mainUri.fsPath]: [expectedWarningDiagnostic, expectedMainErrorDiagnostic], // Should have parsed correct severity [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file }), + executeTaskAndWaitForResult(createBuildAllTask(folderContext)), ]); await waitForNoRunningTasks(); }); @@ -278,11 +279,11 @@ suite("DiagnosticsManager Test Suite", async function () { await swiftConfig.update("diagnosticsStyle", "llvm"); await Promise.all([ - executeTaskAndWaitForResult(createBuildAllTask(folderContext)), waitForDiagnostics({ [mainUri.fsPath]: [expectedWarningDiagnostic, expectedMainErrorDiagnostic], // Should have parsed correct severity [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file }), + executeTaskAndWaitForResult(createBuildAllTask(folderContext)), ]); await waitForNoRunningTasks(); @@ -328,10 +329,10 @@ suite("DiagnosticsManager Test Suite", async function () { expectedDiagnostic2.source = "swiftc"; await Promise.all([ - executeTaskAndWaitForResult(createBuildAllTask(cFolderContext)), waitForDiagnostics({ [cUri.fsPath]: [expectedDiagnostic1, expectedDiagnostic2], }), + executeTaskAndWaitForResult(createBuildAllTask(cFolderContext)), ]); await waitForNoRunningTasks(); }); @@ -363,10 +364,10 @@ suite("DiagnosticsManager Test Suite", async function () { expectedDiagnostic2.source = "swiftc"; await Promise.all([ - executeTaskAndWaitForResult(createBuildAllTask(cppFolderContext)), waitForDiagnostics({ [cppUri.fsPath]: [expectedDiagnostic1, expectedDiagnostic2], }), + executeTaskAndWaitForResult(createBuildAllTask(cppFolderContext)), ]); await waitForNoRunningTasks(); From 72fd9cb13a6dab1cb9dbf0daa56823e993bdc44d Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 3 Dec 2024 10:37:52 -0500 Subject: [PATCH 55/57] Final cleanup --- .vscode-test.js | 2 +- src/commands/build.ts | 8 ++++---- test/integration-tests/DiagnosticsManager.test.ts | 8 -------- test/integration-tests/WorkspaceContext.test.ts | 2 +- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/.vscode-test.js b/.vscode-test.js index b15850560..5fa7ce6ba 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -15,7 +15,7 @@ const { defineConfig } = require("@vscode/test-cli"); const path = require("path"); -const isCIBuild = false; // process.env["CI"] === "1"; +const isCIBuild = process.env["CI"] === "1"; const isFastTestRun = process.env["FAST_TEST_RUN"] === "1"; // "env" in launch.json doesn't seem to work with vscode-test diff --git a/src/commands/build.ts b/src/commands/build.ts index 4d07b2949..9c48c2a8b 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -74,25 +74,25 @@ export async function debugBuildWithOptions( ) { const current = ctx.currentFolder; if (!current) { - console.log(" >>> debugBuildWithOptions: No current folder on WorkspaceContext"); + console.log("debugBuildWithOptions: No current folder on WorkspaceContext"); return; } const file = vscode.window.activeTextEditor?.document.fileName; if (!file) { - console.log(" >>> debugBuildWithOptions: No active text editor"); + console.log("debugBuildWithOptions: No active text editor"); return; } const target = current.swiftPackage.getTarget(file); if (!target) { - console.log(" >>> debugBuildWithOptions: No active target"); + console.log("debugBuildWithOptions: No active target"); return; } if (target.type !== "executable") { console.log( - ` >>> debugBuildWithOptions: Target is not an executable, instead is ${target.type}` + `debugBuildWithOptions: Target is not an executable, instead is ${target.type}` ); return; } diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index 48db101a9..a55691cea 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -401,14 +401,12 @@ suite("DiagnosticsManager Test Suite", async function () { test("Parse partial line", async () => { const fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - const diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); // Wait to spawn before writing fixture.process.write(`${mainUri.fsPath}:13:5: err`, ""); fixture.process.write("or: Cannot find 'fo", ""); fixture.process.write("o' in scope"); fixture.process.close(1); await waitForNoRunningTasks(); - await diagnosticsPromise; // Should have parsed assertHasDiagnostic(mainUri, outputDiagnostic); }); @@ -417,7 +415,6 @@ suite("DiagnosticsManager Test Suite", async function () { test("Ignore duplicates", async () => { const fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - const diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); // Wait to spawn before writing const output = `${mainUri.fsPath}:13:5: error: Cannot find 'foo' in scope`; fixture.process.write(output); @@ -425,7 +422,6 @@ suite("DiagnosticsManager Test Suite", async function () { fixture.process.write(output); fixture.process.close(1); await waitForNoRunningTasks(); - await diagnosticsPromise; const diagnostics = vscode.languages.getDiagnostics(mainUri); // Should only include one assert.equal(diagnostics.length, 1); @@ -435,12 +431,10 @@ suite("DiagnosticsManager Test Suite", async function () { test("New set of swiftc diagnostics clear old list", async () => { let fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - let diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); // Wait to spawn before writing fixture.process.write(`${mainUri.fsPath}:13:5: error: Cannot find 'foo' in scope`); fixture.process.close(1); await waitForNoRunningTasks(); - await diagnosticsPromise; let diagnostics = vscode.languages.getDiagnostics(mainUri); // Should only include one assert.equal(diagnostics.length, 1); @@ -449,10 +443,8 @@ suite("DiagnosticsManager Test Suite", async function () { // Run again but no diagnostics returned fixture = testSwiftTask("swift", ["build"], workspaceFolder, toolchain); await vscode.tasks.executeTask(fixture.task); - diagnosticsPromise = Promise.resolve(); // waitForDiagnostics([mainUri]); fixture.process.close(0); await waitForNoRunningTasks(); - await diagnosticsPromise; diagnostics = vscode.languages.getDiagnostics(mainUri); // Should have cleaned up assert.equal(diagnostics.length, 0); diff --git a/test/integration-tests/WorkspaceContext.test.ts b/test/integration-tests/WorkspaceContext.test.ts index e12583216..d7f2030aa 100644 --- a/test/integration-tests/WorkspaceContext.test.ts +++ b/test/integration-tests/WorkspaceContext.test.ts @@ -74,7 +74,7 @@ suite("WorkspaceContext Test Suite", () => { assert.strictEqual( addedCount, 1, - `Expected only one add folder operation, instead got folders: ${recordedFolders}` + `Expected only one add folder operation, instead got folders: ${recordedFolders.map(folder => folder.folder?.name)}` ); } finally { observer?.dispose(); From ef8544d45d3ba9a9a08db8eaf169d0c24fd326e7 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 3 Dec 2024 13:23:48 -0500 Subject: [PATCH 56/57] Switch back to swiftlang/github-workflows --- .github/workflows/pull_request.yml | 2 +- test/integration-tests/DiagnosticsManager.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d7a9ed7ed..796ab2521 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -7,7 +7,7 @@ on: jobs: tests: name: Test - uses: award999/github-workflows/.github/workflows/swift_package_test.yml@dockerless-windows + uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main with: # Linux linux_exclude_swift_versions: '[{"swift_version": "nightly-main"}]' diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index a55691cea..8e0938e9c 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -259,7 +259,7 @@ suite("DiagnosticsManager Test Suite", async function () { swiftVersion.isLessThan(new Version(5, 10, 0)) || (process.platform === "win32" && swiftVersion.isGreaterThanOrEqual(new Version(5, 10, 0)) && - swiftVersion.isLessThanOrEqual(new Version(6, 0, 0))) + swiftVersion.isLessThanOrEqual(new Version(6, 0, 999))) ) { this.skip(); } From 1b98a555dc9115c9a7b38027b5c5ad37b6339466 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 3 Dec 2024 14:27:57 -0500 Subject: [PATCH 57/57] Log in OutputChannel not console.log --- src/commands/build.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/commands/build.ts b/src/commands/build.ts index 9c48c2a8b..03e66489a 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -74,24 +74,26 @@ export async function debugBuildWithOptions( ) { const current = ctx.currentFolder; if (!current) { - console.log("debugBuildWithOptions: No current folder on WorkspaceContext"); + ctx.outputChannel.appendLine( + "debugBuildWithOptions: No current folder on WorkspaceContext" + ); return; } const file = vscode.window.activeTextEditor?.document.fileName; if (!file) { - console.log("debugBuildWithOptions: No active text editor"); + ctx.outputChannel.appendLine("debugBuildWithOptions: No active text editor"); return; } const target = current.swiftPackage.getTarget(file); if (!target) { - console.log("debugBuildWithOptions: No active target"); + ctx.outputChannel.appendLine("debugBuildWithOptions: No active target"); return; } if (target.type !== "executable") { - console.log( + ctx.outputChannel.appendLine( `debugBuildWithOptions: Target is not an executable, instead is ${target.type}` ); return;