From 81d1c00369e21cad7b860feea7475109e044dc52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 25 Oct 2025 02:14:05 +0200 Subject: [PATCH 01/20] First attempt at a Pester test for Windows --- .github/workflows/pester-tests.yml | 44 ++++++++++++++ solr/packaging/build.gradle | 59 +++++++++++++++++++ .../powershell-tests/Test-Version.ps1 | 54 +++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 .github/workflows/pester-tests.yml create mode 100644 solr/packaging/powershell-tests/Test-Version.ps1 diff --git a/.github/workflows/pester-tests.yml b/.github/workflows/pester-tests.yml new file mode 100644 index 00000000000..475e191b353 --- /dev/null +++ b/.github/workflows/pester-tests.yml @@ -0,0 +1,44 @@ +name: Powershell Pester Tests + +on: + push: + branches: [ main, SOLR-17508-* ] + paths: + - 'solr/packaging/powershell-tests/**' + - 'solr/packaging/build.gradle' + - 'solr/bin/solr.cmd' + - 'solr/bin/solr.in.cmd' + pull_request: + branches: [ main ] + +jobs: + pester-tests: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'temurin' + + - name: Build Solr distribution + run: | + cd solr/packaging + gradle installFullDist + shell: powershell + + - name: Run Pester tests + run: | + cd solr/packaging + gradle pesterTests + shell: powershell + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v3 + with: + name: pester-test-results + path: solr/packaging/build/test-output/ diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle index 8d0e8723b61..e79a1fc3e7d 100644 --- a/solr/packaging/build.gradle +++ b/solr/packaging/build.gradle @@ -273,6 +273,65 @@ task integrationTests(type: BatsTask) { environment BATS_LIB_PREFIX: "$nodeProjectDir/node_modules" } +task pesterTests { + dependsOn installFullDist + onlyIf { Os.isFamily(Os.FAMILY_WINDOWS) } + + def integrationTestOutput = "$buildDir/test-output" + def solrHome = "$integrationTestOutput/solr-home" + def solrTestFailuresDir = "$integrationTestOutput/failure-snapshots" + var solrPort = Integer.parseInt((String) project.findProperty('pester.port') ?: System.getProperty("pester.port", "-1")) + while (solrPort > 64000 || solrPort < 0) { // We need room for +1000 for ZK + try (ServerSocket s = new ServerSocket(0)) { + solrPort = s.getLocalPort() + } catch (Exception e) { + println("WARN: Could not assign random port for Pester tests. Using default port 8983.") + solrPort = 8983 + } + } + + inputs.dir(distDir) + outputs.dir(integrationTestOutput) + + doFirst { + delete integrationTestOutput + mkdir integrationTestOutput + mkdir solrHome + mkdir solrTestFailuresDir + + println("Running Pester tests with Solr base port ${solrPort}") + } + + doLast { + exec { + executable "powershell" + args = [ + "-Command", + "& { " + + "Import-Module Pester -MinimumVersion 5.0; " + + "\$config = New-PesterConfiguration; " + + "\$config.Run.Path = 'powershell-tests'; " + + "\$config.Run.Exit = \$true; " + + "\$config.TestResult.OutputPath = '${integrationTestOutput}/test-results.xml'; " + + "\$env:SOLR_TIP = '${distDir}'; " + + "\$env:SOLR_HOME = '${solrHome}'; " + + "\$env:SOLR_PID_DIR = '${solrHome}'; " + + "\$env:SOLR_PORT = ${solrPort}; " + + "\$env:SOLR2_PORT = ${solrPort + 1}; " + + "\$env:SOLR3_PORT = ${solrPort + 2}; " + + "\$env:ZK_PORT = ${solrPort + 1000}; " + + "\$env:SOLR_LOGS_DIR = '${solrHome}/logs'; " + + "\$env:TEST_OUTPUT_DIR = '${integrationTestOutput}'; " + + "\$env:TEST_FAILURE_DIR = '${solrTestFailuresDir}'; " + + "Invoke-Pester -Configuration \$config; " + + "}" + ] + + workingDir projectDir.toString() + } + } +} + class BatsTask extends Exec { @InputDirectory String testDir = 'test' diff --git a/solr/packaging/powershell-tests/Test-Version.ps1 b/solr/packaging/powershell-tests/Test-Version.ps1 new file mode 100644 index 00000000000..59bf8740b48 --- /dev/null +++ b/solr/packaging/powershell-tests/Test-Version.ps1 @@ -0,0 +1,54 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +<# + Pester tests for Solr version command + Ported from test/test_version.bats +#> + +BeforeAll { + # Get the Solr installation directory from environment variable + $script:SolrTip = $env:SOLR_TIP + if (-not $SolrTip) { + throw "SOLR_TIP environment variable is not set" + } + + # Determine the Solr executable based on OS + $script:SolrCmd = Join-Path $SolrTip "bin\solr.cmd" + + if (-not (Test-Path $SolrCmd)) { + throw "Solr executable not found at: $SolrCmd" + } + + Write-Host "Using Solr installation at: $SolrTip" + Write-Host "Using Solr command: $SolrCmd" +} + +Describe "Solr Version Command" { + Context "When using --version flag" { + It "--version returns Solr version" { + $output = & $SolrCmd --version 2>&1 + $output | Should -Contain "Solr version is:" + } + } + + Context "When using version as direct command" { + It "version as direct tool call still runs" { + $output = & $SolrCmd version 2>&1 + $output | Should -Contain "Solr version is:" + } + } +} From 4a25bdfff8f120df5e6ea2dcd2b7ca5a91ceb3c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 25 Oct 2025 02:24:07 +0200 Subject: [PATCH 02/20] Fix action --- .github/workflows/pester-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pester-tests.yml b/.github/workflows/pester-tests.yml index 475e191b353..851a84f48c7 100644 --- a/.github/workflows/pester-tests.yml +++ b/.github/workflows/pester-tests.yml @@ -38,7 +38,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: pester-test-results path: solr/packaging/build/test-output/ From 1960625b8eac7560beb1065a9135db8cc50ec81e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 25 Oct 2025 02:27:33 +0200 Subject: [PATCH 03/20] No gradle daemon --- .github/workflows/pester-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pester-tests.yml b/.github/workflows/pester-tests.yml index 851a84f48c7..d8f96167523 100644 --- a/.github/workflows/pester-tests.yml +++ b/.github/workflows/pester-tests.yml @@ -33,7 +33,7 @@ jobs: - name: Run Pester tests run: | cd solr/packaging - gradle pesterTests + gradle --no-daemon pesterTests shell: powershell - name: Upload test results From b6998f8b33fa6df169a9c1e93c14f0a4c1a4b203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 25 Oct 2025 02:30:04 +0200 Subject: [PATCH 04/20] Use gradlew --- .github/workflows/pester-tests.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pester-tests.yml b/.github/workflows/pester-tests.yml index d8f96167523..9e3e336b1ca 100644 --- a/.github/workflows/pester-tests.yml +++ b/.github/workflows/pester-tests.yml @@ -26,14 +26,12 @@ jobs: - name: Build Solr distribution run: | - cd solr/packaging - gradle installFullDist + .\gradlew.bat -p solr/packaging installFullDist shell: powershell - name: Run Pester tests run: | - cd solr/packaging - gradle --no-daemon pesterTests + .\gradlew.bat -p solr/packaging --no-daemon pesterTests shell: powershell - name: Upload test results From 2ece5e66e84acd8623c8e5084df4400dcf4a6683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 25 Oct 2025 02:33:23 +0200 Subject: [PATCH 05/20] Use a distinct integrationTestOutput folder for pester --- solr/packaging/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle index e79a1fc3e7d..303d09afd8c 100644 --- a/solr/packaging/build.gradle +++ b/solr/packaging/build.gradle @@ -277,7 +277,7 @@ task pesterTests { dependsOn installFullDist onlyIf { Os.isFamily(Os.FAMILY_WINDOWS) } - def integrationTestOutput = "$buildDir/test-output" + def integrationTestOutput = "$buildDir/powershell-test-output" def solrHome = "$integrationTestOutput/solr-home" def solrTestFailuresDir = "$integrationTestOutput/failure-snapshots" var solrPort = Integer.parseInt((String) project.findProperty('pester.port') ?: System.getProperty("pester.port", "-1")) From d8953996437d10bb7a11555b91146f81399feaf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 25 Oct 2025 23:53:23 +0200 Subject: [PATCH 06/20] Fix OS detection bug --- solr/packaging/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle index 303d09afd8c..3550297c4f8 100644 --- a/solr/packaging/build.gradle +++ b/solr/packaging/build.gradle @@ -16,6 +16,7 @@ */ import org.apache.tools.ant.util.TeeOutputStream +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform // This project puts together a "distribution", assembling dependencies from // various other projects. @@ -275,7 +276,7 @@ task integrationTests(type: BatsTask) { task pesterTests { dependsOn installFullDist - onlyIf { Os.isFamily(Os.FAMILY_WINDOWS) } + onlyIf { DefaultNativePlatform.getCurrentOperatingSystem().isWindows() } def integrationTestOutput = "$buildDir/powershell-test-output" def solrHome = "$integrationTestOutput/solr-home" From 5daa0db0a224bdb5fabee4ae0d5a0e41acdc2254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sat, 25 Oct 2025 23:56:43 +0200 Subject: [PATCH 07/20] Collapse two gradle steps into one, don't use daemon --- .github/workflows/pester-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pester-tests.yml b/.github/workflows/pester-tests.yml index 9e3e336b1ca..57fbe83d692 100644 --- a/.github/workflows/pester-tests.yml +++ b/.github/workflows/pester-tests.yml @@ -26,12 +26,12 @@ jobs: - name: Build Solr distribution run: | - .\gradlew.bat -p solr/packaging installFullDist + .\gradlew.bat --no-daemon -p solr/packaging installFullDist shell: powershell - name: Run Pester tests run: | - .\gradlew.bat -p solr/packaging --no-daemon pesterTests + .\gradlew.bat --no-daemon -p solr/packaging pesterTests shell: powershell - name: Upload test results From ffcc870c9771e92b7975b3370ab58ff6309eb1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 26 Oct 2025 00:07:18 +0200 Subject: [PATCH 08/20] Rename a test file --- .../powershell-tests/{Test-Version.ps1 => Version.Tests.ps1} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename solr/packaging/powershell-tests/{Test-Version.ps1 => Version.Tests.ps1} (100%) diff --git a/solr/packaging/powershell-tests/Test-Version.ps1 b/solr/packaging/powershell-tests/Version.Tests.ps1 similarity index 100% rename from solr/packaging/powershell-tests/Test-Version.ps1 rename to solr/packaging/powershell-tests/Version.Tests.ps1 From 30adf7e68a10b663834a515505416df1ec428a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 26 Oct 2025 00:30:00 +0200 Subject: [PATCH 09/20] Adjust test --- solr/packaging/powershell-tests/Version.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/packaging/powershell-tests/Version.Tests.ps1 b/solr/packaging/powershell-tests/Version.Tests.ps1 index 59bf8740b48..6c14dc2c8c4 100644 --- a/solr/packaging/powershell-tests/Version.Tests.ps1 +++ b/solr/packaging/powershell-tests/Version.Tests.ps1 @@ -41,14 +41,14 @@ Describe "Solr Version Command" { Context "When using --version flag" { It "--version returns Solr version" { $output = & $SolrCmd --version 2>&1 - $output | Should -Contain "Solr version is:" + $output | Out-String | Should -Match "Solr version is:" } } Context "When using version as direct command" { It "version as direct tool call still runs" { $output = & $SolrCmd version 2>&1 - $output | Should -Contain "Solr version is:" + $output | Out-String | Should -Match "Solr version is:" } } } From 768c7f6f7177cb77cbe785c4279fb8a1020f4658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 26 Oct 2025 00:32:08 +0200 Subject: [PATCH 10/20] Port the assert test --- .../powershell-tests/Assert.Tests.ps1 | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 solr/packaging/powershell-tests/Assert.Tests.ps1 diff --git a/solr/packaging/powershell-tests/Assert.Tests.ps1 b/solr/packaging/powershell-tests/Assert.Tests.ps1 new file mode 100644 index 00000000000..61cc4185542 --- /dev/null +++ b/solr/packaging/powershell-tests/Assert.Tests.ps1 @@ -0,0 +1,116 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +<# + Pester tests for Solr assert command + Ported from test/test_assert.bats +#> + +BeforeAll { + # Get the Solr installation directory from environment variable + $script:SolrTip = $env:SOLR_TIP + $script:SolrPort = $env:SOLR_PORT + $script:SolrHome = $env:SOLR_HOME + $script:TestFailureDir = $env:TEST_FAILURE_DIR + + if (-not $SolrTip) { + throw "SOLR_TIP environment variable is not set" + } + + if (-not $SolrPort) { + throw "SOLR_PORT environment variable is not set" + } + + # Determine the Solr executable based on OS + $script:SolrCmd = Join-Path $SolrTip "bin\solr.cmd" + + if (-not (Test-Path $SolrCmd)) { + throw "Solr executable not found at: $SolrCmd" + } + + Write-Host "Using Solr installation at: $SolrTip" + Write-Host "Using Solr port: $SolrPort" + Write-Host "Using Solr home: $SolrHome" +} + +AfterEach { + # Stop all Solr instances after each test + & $SolrCmd stop --all 2>&1 | Out-Null + Start-Sleep -Seconds 2 +} + +Describe "Solr Assert Command" { + Context "Assert for non-cloud mode" { + It "assert --not-started before starting Solr" { + $output = & $SolrCmd assert --not-started "http://localhost:$SolrPort" --timeout 5000 2>&1 + $output | Out-String | Should -Match "Solr is not running" + } + + It "assert --started after starting Solr" { + # Start Solr in user-managed mode (non-cloud) + & $SolrCmd start --user-managed 2>&1 | Out-Null + Start-Sleep -Seconds 5 + + $output = & $SolrCmd assert --started "http://localhost:$SolrPort" --timeout 5000 2>&1 + $output | Out-String | Should -Match "Solr is running" + } + + It "assert --not-cloud on standalone Solr instance" { + # Start Solr in user-managed mode (non-cloud) + & $SolrCmd start --user-managed 2>&1 | Out-Null + Start-Sleep -Seconds 5 + + $output = & $SolrCmd assert --not-cloud "http://localhost:$SolrPort/solr" 2>&1 + $output | Out-String | Should -Match "needn't include Solr's context-root" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "assert --cloud fails on standalone Solr instance" { + # Start Solr in user-managed mode (non-cloud) + & $SolrCmd start --user-managed 2>&1 | Out-Null + Start-Sleep -Seconds 5 + + $output = & $SolrCmd assert --cloud "http://localhost:$SolrPort" 2>&1 + $LASTEXITCODE | Should -Not -Be 0 + $output | Out-String | Should -Match "ERROR: Solr is not running in cloud mode" + } + } + + Context "Assert for cloud mode" { + It "assert --cloud on cloud Solr instance" { + # Start Solr in cloud mode (default) + & $SolrCmd start 2>&1 | Out-Null + Start-Sleep -Seconds 5 + + $output = & $SolrCmd assert --started "http://localhost:$SolrPort" --timeout 5000 2>&1 + $output | Out-String | Should -Match "Solr is running" + + $output = & $SolrCmd assert --cloud "http://localhost:$SolrPort" 2>&1 + $output | Out-String | Should -Not -Match "ERROR" + } + + It "assert --not-cloud fails on cloud Solr instance" { + # Start Solr in cloud mode (default) + & $SolrCmd start 2>&1 | Out-Null + Start-Sleep -Seconds 5 + + $output = & $SolrCmd assert --not-cloud "http://localhost:$SolrPort/solr" 2>&1 + $LASTEXITCODE | Should -Not -Be 0 + $output | Out-String | Should -Match "needn't include Solr's context-root" + $output | Out-String | Should -Match "ERROR: Solr is not running in standalone mode" + } + } +} From b7bacb00899c5e53dbd23519ebdfb69f85032c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 26 Oct 2025 01:22:12 +0200 Subject: [PATCH 11/20] Use the Help test --- .../powershell-tests/Assert.Tests.ps1 | 116 ---------------- .../packaging/powershell-tests/Help.Tests.ps1 | 130 ++++++++++++++++++ 2 files changed, 130 insertions(+), 116 deletions(-) delete mode 100644 solr/packaging/powershell-tests/Assert.Tests.ps1 create mode 100644 solr/packaging/powershell-tests/Help.Tests.ps1 diff --git a/solr/packaging/powershell-tests/Assert.Tests.ps1 b/solr/packaging/powershell-tests/Assert.Tests.ps1 deleted file mode 100644 index 61cc4185542..00000000000 --- a/solr/packaging/powershell-tests/Assert.Tests.ps1 +++ /dev/null @@ -1,116 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -<# - Pester tests for Solr assert command - Ported from test/test_assert.bats -#> - -BeforeAll { - # Get the Solr installation directory from environment variable - $script:SolrTip = $env:SOLR_TIP - $script:SolrPort = $env:SOLR_PORT - $script:SolrHome = $env:SOLR_HOME - $script:TestFailureDir = $env:TEST_FAILURE_DIR - - if (-not $SolrTip) { - throw "SOLR_TIP environment variable is not set" - } - - if (-not $SolrPort) { - throw "SOLR_PORT environment variable is not set" - } - - # Determine the Solr executable based on OS - $script:SolrCmd = Join-Path $SolrTip "bin\solr.cmd" - - if (-not (Test-Path $SolrCmd)) { - throw "Solr executable not found at: $SolrCmd" - } - - Write-Host "Using Solr installation at: $SolrTip" - Write-Host "Using Solr port: $SolrPort" - Write-Host "Using Solr home: $SolrHome" -} - -AfterEach { - # Stop all Solr instances after each test - & $SolrCmd stop --all 2>&1 | Out-Null - Start-Sleep -Seconds 2 -} - -Describe "Solr Assert Command" { - Context "Assert for non-cloud mode" { - It "assert --not-started before starting Solr" { - $output = & $SolrCmd assert --not-started "http://localhost:$SolrPort" --timeout 5000 2>&1 - $output | Out-String | Should -Match "Solr is not running" - } - - It "assert --started after starting Solr" { - # Start Solr in user-managed mode (non-cloud) - & $SolrCmd start --user-managed 2>&1 | Out-Null - Start-Sleep -Seconds 5 - - $output = & $SolrCmd assert --started "http://localhost:$SolrPort" --timeout 5000 2>&1 - $output | Out-String | Should -Match "Solr is running" - } - - It "assert --not-cloud on standalone Solr instance" { - # Start Solr in user-managed mode (non-cloud) - & $SolrCmd start --user-managed 2>&1 | Out-Null - Start-Sleep -Seconds 5 - - $output = & $SolrCmd assert --not-cloud "http://localhost:$SolrPort/solr" 2>&1 - $output | Out-String | Should -Match "needn't include Solr's context-root" - $output | Out-String | Should -Not -Match "ERROR" - } - - It "assert --cloud fails on standalone Solr instance" { - # Start Solr in user-managed mode (non-cloud) - & $SolrCmd start --user-managed 2>&1 | Out-Null - Start-Sleep -Seconds 5 - - $output = & $SolrCmd assert --cloud "http://localhost:$SolrPort" 2>&1 - $LASTEXITCODE | Should -Not -Be 0 - $output | Out-String | Should -Match "ERROR: Solr is not running in cloud mode" - } - } - - Context "Assert for cloud mode" { - It "assert --cloud on cloud Solr instance" { - # Start Solr in cloud mode (default) - & $SolrCmd start 2>&1 | Out-Null - Start-Sleep -Seconds 5 - - $output = & $SolrCmd assert --started "http://localhost:$SolrPort" --timeout 5000 2>&1 - $output | Out-String | Should -Match "Solr is running" - - $output = & $SolrCmd assert --cloud "http://localhost:$SolrPort" 2>&1 - $output | Out-String | Should -Not -Match "ERROR" - } - - It "assert --not-cloud fails on cloud Solr instance" { - # Start Solr in cloud mode (default) - & $SolrCmd start 2>&1 | Out-Null - Start-Sleep -Seconds 5 - - $output = & $SolrCmd assert --not-cloud "http://localhost:$SolrPort/solr" 2>&1 - $LASTEXITCODE | Should -Not -Be 0 - $output | Out-String | Should -Match "needn't include Solr's context-root" - $output | Out-String | Should -Match "ERROR: Solr is not running in standalone mode" - } - } -} diff --git a/solr/packaging/powershell-tests/Help.Tests.ps1 b/solr/packaging/powershell-tests/Help.Tests.ps1 new file mode 100644 index 00000000000..4a889619aff --- /dev/null +++ b/solr/packaging/powershell-tests/Help.Tests.ps1 @@ -0,0 +1,130 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +<# + Pester tests for Solr help command + Ported from test/test_help.bats +#> + +BeforeAll { + # Get the Solr installation directory from environment variable + $script:SolrTip = $env:SOLR_TIP + + if (-not $SolrTip) { + throw "SOLR_TIP environment variable is not set" + } + + # Determine the Solr executable based on OS + $script:SolrCmd = Join-Path $SolrTip "bin\solr.cmd" + + if (-not (Test-Path $SolrCmd)) { + throw "Solr executable not found at: $SolrCmd" + } + + Write-Host "Using Solr installation at: $SolrTip" + Write-Host "Using Solr command: $SolrCmd" +} + +Describe "Solr Help Command" { + Context "Main help commands" { + It "solr --help flag prints help" { + $output = & $SolrCmd --help 2>&1 + $output | Out-String | Should -Match "Usage: solr COMMAND OPTIONS" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "solr with no flags prints help" { + $output = & $SolrCmd 2>&1 + $output | Out-String | Should -Match "Usage: solr COMMAND OPTIONS" + $output | Out-String | Should -Not -Match "ERROR" + } + } + + Context "Command-specific help" { + It "start --help flag prints help" { + $output = & $SolrCmd start --help 2>&1 + $output | Out-String | Should -Match "Usage: solr start" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "start -h flag prints help" { + $output = & $SolrCmd start -h 2>&1 + $output | Out-String | Should -Match "Usage: solr start" + $output | Out-String | Should -Not -Match "ERROR: Hostname is required when using the -h option!" + } + + It "stop --help flag prints help" { + $output = & $SolrCmd stop --help 2>&1 + $output | Out-String | Should -Match "Usage: solr stop" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "restart --help flag prints help" { + $output = & $SolrCmd restart --help 2>&1 + $output | Out-String | Should -Match "Usage: solr restart" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "status --help flag prints help" { + $output = & $SolrCmd status --help 2>&1 + $output | Out-String | Should -Match "usage: bin/solr status" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "healthcheck --help flag prints help" { + $output = & $SolrCmd healthcheck --help 2>&1 + $output | Out-String | Should -Match "usage: bin/solr healthcheck" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "create --help flag prints help" { + $output = & $SolrCmd create --help 2>&1 + $output | Out-String | Should -Match "usage: bin/solr create" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "delete -h flag prints help" { + $output = & $SolrCmd delete -h 2>&1 + $output | Out-String | Should -Match "usage: bin/solr delete" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "zk --help flag prints help" { + $output = & $SolrCmd zk --help 2>&1 + $output | Out-String | Should -Match "usage:" + $output | Out-String | Should -Match "bin/solr zk ls" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "auth --help flag prints help" { + $output = & $SolrCmd auth --help 2>&1 + $output | Out-String | Should -Match "bin/solr auth enable" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "assert --help flag prints help" { + $output = & $SolrCmd assert --help 2>&1 + $output | Out-String | Should -Match "usage: bin/solr assert" + $output | Out-String | Should -Not -Match "ERROR" + } + + It "post --help flag prints help" { + $output = & $SolrCmd post --help 2>&1 + $output | Out-String | Should -Match "usage: bin/solr post" + $output | Out-String | Should -Not -Match "ERROR" + } + } +} From 6645e1a2cc3e7bea38a73a42e7f7a1b3a476c98a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Sun, 26 Oct 2025 14:42:12 +0100 Subject: [PATCH 12/20] More verbose logging --- solr/packaging/build.gradle | 2 + .../packaging/powershell-tests/Help.Tests.ps1 | 109 +++++++++++------- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle index 3550297c4f8..d6468c1e39b 100644 --- a/solr/packaging/build.gradle +++ b/solr/packaging/build.gradle @@ -313,6 +313,8 @@ task pesterTests { "\$config = New-PesterConfiguration; " + "\$config.Run.Path = 'powershell-tests'; " + "\$config.Run.Exit = \$true; " + + "\$config.Output.Verbosity = 'Diagnostic'; " + + "\$config.TestResult.OutputFormat = 'NUnitXml'; " + "\$config.TestResult.OutputPath = '${integrationTestOutput}/test-results.xml'; " + "\$env:SOLR_TIP = '${distDir}'; " + "\$env:SOLR_HOME = '${solrHome}'; " + diff --git a/solr/packaging/powershell-tests/Help.Tests.ps1 b/solr/packaging/powershell-tests/Help.Tests.ps1 index 4a889619aff..3e700892016 100644 --- a/solr/packaging/powershell-tests/Help.Tests.ps1 +++ b/solr/packaging/powershell-tests/Help.Tests.ps1 @@ -38,93 +38,116 @@ BeforeAll { Write-Host "Using Solr command: $SolrCmd" } +function Test-HelpOutput { + param( + [string[]]$Arguments, + [string]$ExpectedPattern, + [string]$TestName + ) + + Write-Host "Testing help: $TestName" + Write-Host "Running: $SolrCmd $($Arguments -join ' ')" + + $output = & $SolrCmd @Arguments 2>&1 + $outputStr = $output | Out-String + + Write-Host "Exit Code: $LASTEXITCODE" + if ($outputStr.Length -gt 0) { + Write-Host "Output (first 500 chars): $($outputStr.Substring(0, [Math]::Min(500, $outputStr.Length)))" + } else { + Write-Host "WARNING: Output is empty!" + } + + return $outputStr +} + Describe "Solr Help Command" { Context "Main help commands" { It "solr --help flag prints help" { - $output = & $SolrCmd --help 2>&1 - $output | Out-String | Should -Match "Usage: solr COMMAND OPTIONS" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("--help") "Usage: solr COMMAND OPTIONS" "solr --help" + $output | Should -Match "Usage: solr COMMAND OPTIONS" + $output | Should -Not -Match "ERROR" } It "solr with no flags prints help" { - $output = & $SolrCmd 2>&1 - $output | Out-String | Should -Match "Usage: solr COMMAND OPTIONS" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @() "Usage: solr COMMAND OPTIONS" "solr (no flags)" + $output | Should -Match "Usage: solr COMMAND OPTIONS" + $output | Should -Not -Match "ERROR" } } Context "Command-specific help" { It "start --help flag prints help" { - $output = & $SolrCmd start --help 2>&1 - $output | Out-String | Should -Match "Usage: solr start" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("start", "--help") "Usage: solr start" "start --help" + $output | Should -Match "Usage: solr start" + $output | Should -Not -Match "ERROR" } It "start -h flag prints help" { - $output = & $SolrCmd start -h 2>&1 - $output | Out-String | Should -Match "Usage: solr start" - $output | Out-String | Should -Not -Match "ERROR: Hostname is required when using the -h option!" + $output = Test-HelpOutput @("start", "-h") "Usage: solr start" "start -h" + $output | Should -Match "Usage: solr start" + $output | Should -Not -Match "ERROR: Hostname is required when using the -h option!" } It "stop --help flag prints help" { - $output = & $SolrCmd stop --help 2>&1 - $output | Out-String | Should -Match "Usage: solr stop" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("stop", "--help") "Usage: solr stop" "stop --help" + $output | Should -Match "Usage: solr stop" + $output | Should -Not -Match "ERROR" } It "restart --help flag prints help" { - $output = & $SolrCmd restart --help 2>&1 - $output | Out-String | Should -Match "Usage: solr restart" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("restart", "--help") "Usage: solr restart" "restart --help" + $output | Should -Match "Usage: solr restart" + $output | Should -Not -Match "ERROR" } It "status --help flag prints help" { - $output = & $SolrCmd status --help 2>&1 - $output | Out-String | Should -Match "usage: bin/solr status" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("status", "--help") "usage: bin/solr status" "status --help" + $output | Should -Match "usage: bin/solr status" + $output | Should -Not -Match "ERROR" } It "healthcheck --help flag prints help" { - $output = & $SolrCmd healthcheck --help 2>&1 - $output | Out-String | Should -Match "usage: bin/solr healthcheck" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("healthcheck", "--help") "usage: bin/solr healthcheck" "healthcheck --help" + $output | Should -Match "usage: bin/solr healthcheck" + $output | Should -Not -Match "ERROR" } It "create --help flag prints help" { - $output = & $SolrCmd create --help 2>&1 - $output | Out-String | Should -Match "usage: bin/solr create" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("create", "--help") "usage: bin/solr create" "create --help" + $output | Should -Match "usage: bin/solr create" + $output | Should -Not -Match "ERROR" } It "delete -h flag prints help" { - $output = & $SolrCmd delete -h 2>&1 - $output | Out-String | Should -Match "usage: bin/solr delete" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("delete", "-h") "usage: bin/solr delete" "delete -h" + $output | Should -Match "usage: bin/solr delete" + $output | Should -Not -Match "ERROR" } It "zk --help flag prints help" { - $output = & $SolrCmd zk --help 2>&1 - $output | Out-String | Should -Match "usage:" - $output | Out-String | Should -Match "bin/solr zk ls" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("zk", "--help") "usage:" "zk --help" + $output | Should -Match "usage:" + $output | Should -Match "bin/solr zk ls" + $output | Should -Not -Match "ERROR" } It "auth --help flag prints help" { - $output = & $SolrCmd auth --help 2>&1 - $output | Out-String | Should -Match "bin/solr auth enable" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("auth", "--help") "bin/solr auth enable" "auth --help" + $output | Should -Match "bin/solr auth enable" + $output | Should -Not -Match "ERROR" } It "assert --help flag prints help" { - $output = & $SolrCmd assert --help 2>&1 - $output | Out-String | Should -Match "usage: bin/solr assert" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("assert", "--help") "usage: bin/solr assert" "assert --help" + $output | Should -Match "usage: bin/solr assert" + $output | Should -Not -Match "ERROR" } It "post --help flag prints help" { - $output = & $SolrCmd post --help 2>&1 - $output | Out-String | Should -Match "usage: bin/solr post" - $output | Out-String | Should -Not -Match "ERROR" + $output = Test-HelpOutput @("post", "--help") "usage: bin/solr post" "post --help" + $output | Should -Match "usage: bin/solr post" + $output | Should -Not -Match "ERROR" } } } From cac5d787b552b84f57e2a665bcd22191d0266230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Oct 2025 09:15:13 +0100 Subject: [PATCH 13/20] Fix Help test --- .../packaging/powershell-tests/Help.Tests.ps1 | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/solr/packaging/powershell-tests/Help.Tests.ps1 b/solr/packaging/powershell-tests/Help.Tests.ps1 index 3e700892016..99e48438ca1 100644 --- a/solr/packaging/powershell-tests/Help.Tests.ps1 +++ b/solr/packaging/powershell-tests/Help.Tests.ps1 @@ -36,29 +36,29 @@ BeforeAll { Write-Host "Using Solr installation at: $SolrTip" Write-Host "Using Solr command: $SolrCmd" -} -function Test-HelpOutput { - param( - [string[]]$Arguments, - [string]$ExpectedPattern, - [string]$TestName - ) + function Test-HelpOutput { + param( + [string[]]$Arguments, + [string]$ExpectedPattern, + [string]$TestName + ) - Write-Host "Testing help: $TestName" - Write-Host "Running: $SolrCmd $($Arguments -join ' ')" + Write-Host "Testing help: $TestName" + Write-Host "Running: $SolrCmd $($Arguments -join ' ')" - $output = & $SolrCmd @Arguments 2>&1 - $outputStr = $output | Out-String + $output = & $SolrCmd @Arguments 2>&1 + $outputStr = $output | Out-String - Write-Host "Exit Code: $LASTEXITCODE" - if ($outputStr.Length -gt 0) { - Write-Host "Output (first 500 chars): $($outputStr.Substring(0, [Math]::Min(500, $outputStr.Length)))" - } else { - Write-Host "WARNING: Output is empty!" - } + Write-Host "Exit Code: $LASTEXITCODE" + if ($outputStr.Length -gt 0) { + Write-Host "Output (first 500 chars): $($outputStr.Substring(0, [Math]::Min(500, $outputStr.Length)))" + } else { + Write-Host "WARNING: Output is empty!" + } - return $outputStr + return $outputStr + } } Describe "Solr Help Command" { From c9a18db3054adc33a83bf2177f954edcb3729785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Oct 2025 09:18:04 +0100 Subject: [PATCH 14/20] Port he ZK tests --- solr/packaging/powershell-tests/Zk.Tests.ps1 | 198 +++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 solr/packaging/powershell-tests/Zk.Tests.ps1 diff --git a/solr/packaging/powershell-tests/Zk.Tests.ps1 b/solr/packaging/powershell-tests/Zk.Tests.ps1 new file mode 100644 index 00000000000..0ad114c5bf9 --- /dev/null +++ b/solr/packaging/powershell-tests/Zk.Tests.ps1 @@ -0,0 +1,198 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +<# + Pester tests for Solr zk command + Ported from test/test_zk.bats +#> + +BeforeAll { + # Get the Solr installation directory from environment variable + $script:SolrTip = $env:SOLR_TIP + + if (-not $SolrTip) { + throw "SOLR_TIP environment variable is not set" + } + + # Determine the Solr executable based on OS + $script:SolrCmd = Join-Path $SolrTip "bin\solr.cmd" + + if (-not (Test-Path $SolrCmd)) { + throw "Solr executable not found at: $SolrCmd" + } + + Write-Host "Using Solr installation at: $SolrTip" + Write-Host "Using Solr command: $SolrCmd" + + # Get ZooKeeper port from environment or default + $script:ZK_PORT = if ($env:ZK_PORT) { $env:ZK_PORT } else { "9983" } + $script:SOLR_PORT = if ($env:SOLR_PORT) { $env:SOLR_PORT } else { "8983" } + + function Test-CommandOutput { + param( + [string[]]$Arguments, + [string]$TestName + ) + + Write-Host "Testing: $TestName" + Write-Host "Running: $SolrCmd $($Arguments -join ' ')" + + $output = & $SolrCmd @Arguments 2>&1 + $outputStr = $output | Out-String + + Write-Host "Exit Code: $LASTEXITCODE" + if ($outputStr.Length -gt 0) { + Write-Host "Output (first 500 chars): $($outputStr.Substring(0, [Math]::Min(500, $outputStr.Length)))" + } else { + Write-Host "WARNING: Output is empty!" + } + + return $outputStr + } +} + +Describe "Solr Zk Command" { + Context "Help commands" { + It "short help" { + $output = Test-CommandOutput @("zk", "ls", "-h") "zk ls -h" + $output | Should -Match "usage: bin/solr zk" + } + + It "short help is inferred" { + $output = Test-CommandOutput @("zk", "ls") "zk ls" + $output | Should -Match "usage: bin/solr zk" + } + + It "long help" { + $output = Test-CommandOutput @("zk", "-h") "zk -h" + $output | Should -Match "bin/solr zk ls" + $output | Should -Match "bin/solr zk updateacls" + $output | Should -Match "Pass --help or -h after any COMMAND" + } + + It "running subcommands with zk is prevented" { + $output = Test-CommandOutput @("ls", "/", "-z", "localhost:$ZK_PORT") "ls / -z localhost:$ZK_PORT" + $output | Should -Match "You must invoke this subcommand using the zk command" + } + } + + Context "Zk operations (requires running Solr with ZooKeeper)" -Skip:(-not (Test-Path (Join-Path $SolrTip "server\solr"))) { + BeforeAll { + # Check if Solr is running by trying to connect to the port + $solrRunning = $false + try { + $response = Invoke-WebRequest -Uri "http://localhost:$SOLR_PORT/solr/" -UseBasicParsing -ErrorAction SilentlyContinue + if ($response.StatusCode -eq 200) { + $solrRunning = $true + } + } catch { + $solrRunning = $false + } + + $script:SolrRunning = $solrRunning + if (-not $solrRunning) { + Write-Host "WARNING: Solr does not appear to be running on port $SOLR_PORT" + } + } + + It "listing out files" -Skip:(-not $SolrRunning) { + Start-Sleep -Seconds 1 + $output = Test-CommandOutput @("zk", "ls", "/", "-z", "localhost:$ZK_PORT", "--recursive") "zk ls / -z localhost:$ZK_PORT --recursive" + $output | Should -Match "aliases\.json" + } + + It "connecting via solr-url" -Skip:(-not $SolrRunning) { + Start-Sleep -Seconds 1 + $output = Test-CommandOutput @("zk", "ls", "/", "--solr-url", "http://localhost:$SOLR_PORT") "zk ls / --solr-url http://localhost:$SOLR_PORT" + $output | Should -Match "aliases\.json" + } + + It "connecting via -s flag" -Skip:(-not $SolrRunning) { + Start-Sleep -Seconds 1 + $output = Test-CommandOutput @("zk", "ls", "/", "-s", "http://localhost:$SOLR_PORT") "zk ls / -s http://localhost:$SOLR_PORT" + $output | Should -Match "aliases\.json" + } + + It "connecting via default (localhost)" -Skip:(-not $SolrRunning) { + Start-Sleep -Seconds 1 + $output = Test-CommandOutput @("zk", "ls", "/") "zk ls /" + $output | Should -Match "aliases\.json" + } + + It "connecting via -z flag" -Skip:(-not $SolrRunning) { + Start-Sleep -Seconds 1 + $output = Test-CommandOutput @("zk", "ls", "/", "-z", "localhost:$ZK_PORT") "zk ls / -z localhost:$ZK_PORT" + $output | Should -Match "aliases\.json" + } + + It "connecting via --zk-host flag" -Skip:(-not $SolrRunning) { + Start-Sleep -Seconds 1 + $output = Test-CommandOutput @("zk", "ls", "/", "--zk-host", "localhost:$ZK_PORT") "zk ls / --zk-host localhost:$ZK_PORT" + $output | Should -Match "aliases\.json" + } + + It "copying files around" -Skip:(-not $SolrRunning) { + $testFile = "testfile_$([System.IO.Path]::GetRandomFileName()).txt" + try { + # Create test file + "test content" | Out-File -FilePath $testFile -Encoding UTF8 + + # Copy to ZK + $output = Test-CommandOutput @("zk", "cp", $testFile, "zk:/$testFile", "-z", "localhost:$ZK_PORT") "zk cp $testFile to ZK" + $output | Should -Match "Copying from" + + Start-Sleep -Seconds 1 + + # Verify file is in ZK + $listOutput = Test-CommandOutput @("zk", "ls", "/", "-z", "localhost:$ZK_PORT") "zk ls / to verify copy" + $listOutput | Should -Match $testFile + } finally { + # Cleanup + if (Test-Path $testFile) { + Remove-Item $testFile -Force + } + } + } + + It "upconfig" -Skip:(-not $SolrRunning) { + $sourceConfigsetDir = Join-Path $SolrTip "server\solr\configsets\sample_techproducts_configs" + if (Test-Path $sourceConfigsetDir) { + $output = Test-CommandOutput @("zk", "upconfig", "-d", $sourceConfigsetDir, "-n", "techproducts_ps_test", "-z", "localhost:$ZK_PORT") "zk upconfig" + $output | Should -Match "Uploading" + $output | Should -Not -Match "ERROR" + } else { + Set-ItResult -Skipped -Because "sample_techproducts_configs not found" + } + } + + It "downconfig" -Skip:(-not $SolrRunning) { + $tempDir = [System.IO.Path]::GetTempPath() + $downloadDir = Join-Path $tempDir "downconfig_$([System.IO.Path]::GetRandomFileName())" + New-Item -ItemType Directory -Path $downloadDir -Force | Out-Null + + try { + $output = Test-CommandOutput @("zk", "downconfig", "-z", "localhost:$ZK_PORT", "-n", "_default", "-d", $downloadDir) "zk downconfig" + $output | Should -Match "Downloading" + $output | Should -Not -Match "ERROR" + } finally { + # Cleanup + if (Test-Path $downloadDir) { + Remove-Item $downloadDir -Recurse -Force + } + } + } + } +} \ No newline at end of file From 1dc7cd813a569ac4d37ab1555da8bf1483df8ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Oct 2025 09:47:57 +0100 Subject: [PATCH 15/20] Fix a zk test --- solr/packaging/powershell-tests/Zk.Tests.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solr/packaging/powershell-tests/Zk.Tests.ps1 b/solr/packaging/powershell-tests/Zk.Tests.ps1 index 0ad114c5bf9..1b82c3a41fa 100644 --- a/solr/packaging/powershell-tests/Zk.Tests.ps1 +++ b/solr/packaging/powershell-tests/Zk.Tests.ps1 @@ -23,6 +23,7 @@ BeforeAll { # Get the Solr installation directory from environment variable $script:SolrTip = $env:SOLR_TIP + # Note: $SolrTip cannot be used directly in -Skip statements in tests, use $env:SOLR_TIP instead if (-not $SolrTip) { throw "SOLR_TIP environment variable is not set" } @@ -89,7 +90,7 @@ Describe "Solr Zk Command" { } } - Context "Zk operations (requires running Solr with ZooKeeper)" -Skip:(-not (Test-Path (Join-Path $SolrTip "server\solr"))) { + Context "Zk operations (requires running Solr with ZooKeeper)" -Skip:(-not (Test-Path (Join-Path $env:SOLR_TIP "server\solr"))) { BeforeAll { # Check if Solr is running by trying to connect to the port $solrRunning = $false @@ -195,4 +196,4 @@ Describe "Solr Zk Command" { } } } -} \ No newline at end of file +} From 49ffa3c7cbaeb34b324e09e0b3de45a82cb61272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Oct 2025 09:59:19 +0100 Subject: [PATCH 16/20] Try to fix the help test, with case sensitive "refute" matching --- .../packaging/powershell-tests/Help.Tests.ps1 | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/solr/packaging/powershell-tests/Help.Tests.ps1 b/solr/packaging/powershell-tests/Help.Tests.ps1 index 99e48438ca1..e71d9c59ce0 100644 --- a/solr/packaging/powershell-tests/Help.Tests.ps1 +++ b/solr/packaging/powershell-tests/Help.Tests.ps1 @@ -66,13 +66,13 @@ Describe "Solr Help Command" { It "solr --help flag prints help" { $output = Test-HelpOutput @("--help") "Usage: solr COMMAND OPTIONS" "solr --help" $output | Should -Match "Usage: solr COMMAND OPTIONS" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "solr with no flags prints help" { $output = Test-HelpOutput @() "Usage: solr COMMAND OPTIONS" "solr (no flags)" $output | Should -Match "Usage: solr COMMAND OPTIONS" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } } @@ -80,7 +80,7 @@ Describe "Solr Help Command" { It "start --help flag prints help" { $output = Test-HelpOutput @("start", "--help") "Usage: solr start" "start --help" $output | Should -Match "Usage: solr start" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "start -h flag prints help" { @@ -92,62 +92,62 @@ Describe "Solr Help Command" { It "stop --help flag prints help" { $output = Test-HelpOutput @("stop", "--help") "Usage: solr stop" "stop --help" $output | Should -Match "Usage: solr stop" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "restart --help flag prints help" { $output = Test-HelpOutput @("restart", "--help") "Usage: solr restart" "restart --help" $output | Should -Match "Usage: solr restart" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "status --help flag prints help" { $output = Test-HelpOutput @("status", "--help") "usage: bin/solr status" "status --help" $output | Should -Match "usage: bin/solr status" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "healthcheck --help flag prints help" { $output = Test-HelpOutput @("healthcheck", "--help") "usage: bin/solr healthcheck" "healthcheck --help" $output | Should -Match "usage: bin/solr healthcheck" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "create --help flag prints help" { $output = Test-HelpOutput @("create", "--help") "usage: bin/solr create" "create --help" $output | Should -Match "usage: bin/solr create" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "delete -h flag prints help" { $output = Test-HelpOutput @("delete", "-h") "usage: bin/solr delete" "delete -h" $output | Should -Match "usage: bin/solr delete" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "zk --help flag prints help" { $output = Test-HelpOutput @("zk", "--help") "usage:" "zk --help" $output | Should -Match "usage:" $output | Should -Match "bin/solr zk ls" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "auth --help flag prints help" { $output = Test-HelpOutput @("auth", "--help") "bin/solr auth enable" "auth --help" $output | Should -Match "bin/solr auth enable" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "assert --help flag prints help" { $output = Test-HelpOutput @("assert", "--help") "usage: bin/solr assert" "assert --help" $output | Should -Match "usage: bin/solr assert" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } It "post --help flag prints help" { $output = Test-HelpOutput @("post", "--help") "usage: bin/solr post" "post --help" $output | Should -Match "usage: bin/solr post" - $output | Should -Not -Match "ERROR" + $output | Should -Not -cmatch "ERROR" } } } From 64f3449a8d64358f33abdc4ccc023957bdca4c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Oct 2025 10:19:08 +0100 Subject: [PATCH 17/20] Use another way to test if solr is running --- solr/packaging/powershell-tests/Zk.Tests.ps1 | 27 +++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/solr/packaging/powershell-tests/Zk.Tests.ps1 b/solr/packaging/powershell-tests/Zk.Tests.ps1 index 1b82c3a41fa..818079c85bf 100644 --- a/solr/packaging/powershell-tests/Zk.Tests.ps1 +++ b/solr/packaging/powershell-tests/Zk.Tests.ps1 @@ -109,43 +109,50 @@ Describe "Solr Zk Command" { } } - It "listing out files" -Skip:(-not $SolrRunning) { + It "listing out files" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } Start-Sleep -Seconds 1 $output = Test-CommandOutput @("zk", "ls", "/", "-z", "localhost:$ZK_PORT", "--recursive") "zk ls / -z localhost:$ZK_PORT --recursive" $output | Should -Match "aliases\.json" } - It "connecting via solr-url" -Skip:(-not $SolrRunning) { + It "connecting via solr-url" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } Start-Sleep -Seconds 1 $output = Test-CommandOutput @("zk", "ls", "/", "--solr-url", "http://localhost:$SOLR_PORT") "zk ls / --solr-url http://localhost:$SOLR_PORT" $output | Should -Match "aliases\.json" } - It "connecting via -s flag" -Skip:(-not $SolrRunning) { + It "connecting via -s flag" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } Start-Sleep -Seconds 1 $output = Test-CommandOutput @("zk", "ls", "/", "-s", "http://localhost:$SOLR_PORT") "zk ls / -s http://localhost:$SOLR_PORT" $output | Should -Match "aliases\.json" } - It "connecting via default (localhost)" -Skip:(-not $SolrRunning) { + It "connecting via default (localhost)" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } Start-Sleep -Seconds 1 $output = Test-CommandOutput @("zk", "ls", "/") "zk ls /" $output | Should -Match "aliases\.json" } - It "connecting via -z flag" -Skip:(-not $SolrRunning) { + It "connecting via -z flag" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } Start-Sleep -Seconds 1 $output = Test-CommandOutput @("zk", "ls", "/", "-z", "localhost:$ZK_PORT") "zk ls / -z localhost:$ZK_PORT" $output | Should -Match "aliases\.json" } - It "connecting via --zk-host flag" -Skip:(-not $SolrRunning) { + It "connecting via --zk-host flag" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } Start-Sleep -Seconds 1 $output = Test-CommandOutput @("zk", "ls", "/", "--zk-host", "localhost:$ZK_PORT") "zk ls / --zk-host localhost:$ZK_PORT" $output | Should -Match "aliases\.json" } - It "copying files around" -Skip:(-not $SolrRunning) { + It "copying files around" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } $testFile = "testfile_$([System.IO.Path]::GetRandomFileName()).txt" try { # Create test file @@ -168,7 +175,8 @@ Describe "Solr Zk Command" { } } - It "upconfig" -Skip:(-not $SolrRunning) { + It "upconfig" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } $sourceConfigsetDir = Join-Path $SolrTip "server\solr\configsets\sample_techproducts_configs" if (Test-Path $sourceConfigsetDir) { $output = Test-CommandOutput @("zk", "upconfig", "-d", $sourceConfigsetDir, "-n", "techproducts_ps_test", "-z", "localhost:$ZK_PORT") "zk upconfig" @@ -179,7 +187,8 @@ Describe "Solr Zk Command" { } } - It "downconfig" -Skip:(-not $SolrRunning) { + It "downconfig" { + if (-not $script:SolrRunning) { Set-ItResult -Skipped -Because "Solr is not running"; return } $tempDir = [System.IO.Path]::GetTempPath() $downloadDir = Join-Path $tempDir "downconfig_$([System.IO.Path]::GetRandomFileName())" New-Item -ItemType Directory -Path $downloadDir -Force | Out-Null From a6e4338189f43fac9d2688bb9443e7b11b6f241b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Tue, 28 Oct 2025 10:21:00 +0100 Subject: [PATCH 18/20] Reduce logging to "Normal" --- solr/packaging/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle index d6468c1e39b..66296326e15 100644 --- a/solr/packaging/build.gradle +++ b/solr/packaging/build.gradle @@ -313,7 +313,7 @@ task pesterTests { "\$config = New-PesterConfiguration; " + "\$config.Run.Path = 'powershell-tests'; " + "\$config.Run.Exit = \$true; " + - "\$config.Output.Verbosity = 'Diagnostic'; " + + "\$config.Output.Verbosity = 'Normal'; " + "\$config.TestResult.OutputFormat = 'NUnitXml'; " + "\$config.TestResult.OutputPath = '${integrationTestOutput}/test-results.xml'; " + "\$env:SOLR_TIP = '${distDir}'; " + From 00b1b69ccab4da570e4c7d61e8476aacbec40210 Mon Sep 17 00:00:00 2001 From: Christos Malliaridis Date: Thu, 30 Oct 2025 18:55:15 +0200 Subject: [PATCH 19/20] Add solr startup for tests that require a solr instance --- solr/packaging/powershell-tests/Zk.Tests.ps1 | 94 ++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/solr/packaging/powershell-tests/Zk.Tests.ps1 b/solr/packaging/powershell-tests/Zk.Tests.ps1 index 818079c85bf..e012ee2721f 100644 --- a/solr/packaging/powershell-tests/Zk.Tests.ps1 +++ b/solr/packaging/powershell-tests/Zk.Tests.ps1 @@ -42,6 +42,81 @@ BeforeAll { $script:ZK_PORT = if ($env:ZK_PORT) { $env:ZK_PORT } else { "9983" } $script:SOLR_PORT = if ($env:SOLR_PORT) { $env:SOLR_PORT } else { "8983" } + # Check if Solr is already running + $solrAlreadyRunning = $false + try { + $response = Invoke-WebRequest -Uri "http://localhost:$SOLR_PORT/solr/" -UseBasicParsing -TimeoutSec 2 -ErrorAction SilentlyContinue + if ($response.StatusCode -eq 200) { + $solrAlreadyRunning = $true + Write-Host "Solr is already running on port $SOLR_PORT" + } + } catch { + $solrAlreadyRunning = $false + } + + $script:SolrStartedByTests = $false + + # Start Solr if it's not already running + if (-not $solrAlreadyRunning) { + Write-Host "Starting Solr in cloud mode..." + + # Start Solr with embedded ZooKeeper using Start-Process to run asynchronously + $startArgs = @("start", "-p", "$SOLR_PORT") + Write-Host "Running: $SolrCmd $($startArgs -join ' ')" + + # Use Start-Job with cmd.exe to properly parse arguments and maintain process hierarchy + $solrJob = Start-Job -ScriptBlock { + param($cmd, $argString) + cmd /c "`"$cmd`" $argString" 2>&1 + } -ArgumentList $SolrCmd, $startArgs + + # Wait a bit for Solr to start + Start-Sleep -Seconds 5 + + Write-Host "Solr starting on port $SOLR_PORT (Job ID: $($solrJob.Id))" + + # Check if there were any immediate errors + $jobOutput = Receive-Job -Job $solrJob -Keep + if ($jobOutput) { + Write-Host "Solr output: $jobOutput" + } + + $script:SolrStartedByTests = $true + + # Wait for Solr to be ready (max 60 seconds) + Write-Host "Waiting for Solr to be ready..." + $maxWaitTime = 60 + $waitInterval = 2 + $elapsed = 0 + $solrReady = $false + + while ($elapsed -lt $maxWaitTime) { + Start-Sleep -Seconds $waitInterval + $elapsed += $waitInterval + + try { + $response = Invoke-WebRequest -Uri "http://localhost:$SOLR_PORT/solr/" -UseBasicParsing -TimeoutSec 5 -ErrorAction Stop + + if ($response.StatusCode -eq 200) { + $solrReady = $true + Write-Host "Solr is ready! (took $elapsed seconds)" + break + } + } catch { + Write-Host "Still waiting... ($elapsed seconds elapsed) - Error: $($_.Exception.Message)" + } + } + + if (-not $solrReady) { + throw "Solr did not become ready within $maxWaitTime seconds" + } + + # Give it a bit more time to fully initialize ZooKeeper + Start-Sleep -Seconds 3 + } + + $script:SolrRunning = $true + function Test-CommandOutput { param( [string[]]$Arguments, @@ -65,6 +140,25 @@ BeforeAll { } } +AfterAll { + # Stop Solr only if we started it + if ($script:SolrStartedByTests) { + Write-Host "Stopping Solr..." + $stopArgs = @("stop", "-p", $script:SOLR_PORT) + Write-Host "Running: $script:SolrCmd $($stopArgs -join ' ')" + + $stopOutput = & $script:SolrCmd @stopArgs 2>&1 + $stopOutputStr = $stopOutput | Out-String + Write-Host $stopOutputStr + + if ($LASTEXITCODE -ne 0) { + Write-Warning "Failed to stop Solr cleanly. Exit code: $LASTEXITCODE" + } else { + Write-Host "Solr stopped successfully" + } + } +} + Describe "Solr Zk Command" { Context "Help commands" { It "short help" { From 78d9f17391a4c6bff6974d288d626984d2f93fd2 Mon Sep 17 00:00:00 2001 From: Christos Malliaridis Date: Thu, 30 Oct 2025 18:56:46 +0200 Subject: [PATCH 20/20] Fix failing test due to false positive --- solr/packaging/powershell-tests/Zk.Tests.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/solr/packaging/powershell-tests/Zk.Tests.ps1 b/solr/packaging/powershell-tests/Zk.Tests.ps1 index e012ee2721f..877fa51791a 100644 --- a/solr/packaging/powershell-tests/Zk.Tests.ps1 +++ b/solr/packaging/powershell-tests/Zk.Tests.ps1 @@ -126,6 +126,8 @@ BeforeAll { Write-Host "Testing: $TestName" Write-Host "Running: $SolrCmd $($Arguments -join ' ')" + # Note that CLI warnings are interpreted as NativeCommandError, since logged to std.err, and therefore may match + # strings like "Error" $output = & $SolrCmd @Arguments 2>&1 $outputStr = $output | Out-String @@ -275,7 +277,7 @@ Describe "Solr Zk Command" { if (Test-Path $sourceConfigsetDir) { $output = Test-CommandOutput @("zk", "upconfig", "-d", $sourceConfigsetDir, "-n", "techproducts_ps_test", "-z", "localhost:$ZK_PORT") "zk upconfig" $output | Should -Match "Uploading" - $output | Should -Not -Match "ERROR" + $LASTEXITCODE | Should -Match 0 } else { Set-ItResult -Skipped -Because "sample_techproducts_configs not found" } @@ -290,7 +292,7 @@ Describe "Solr Zk Command" { try { $output = Test-CommandOutput @("zk", "downconfig", "-z", "localhost:$ZK_PORT", "-n", "_default", "-d", $downloadDir) "zk downconfig" $output | Should -Match "Downloading" - $output | Should -Not -Match "ERROR" + $LASTEXITCODE | Should -Match 0 } finally { # Cleanup if (Test-Path $downloadDir) {