Skip to content

ci: add Windows service start/stop test to CI workflow#606

Open
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-30845478-106611094-d429e1a9-dbd5-4b36-b891-14c7551bd9c5
Open

ci: add Windows service start/stop test to CI workflow#606
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-30845478-106611094-d429e1a9-dbd5-4b36-b891-14c7551bd9c5

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 31, 2026

  • Fix net start/stop OpenDJnet start/stop "OpenDJ Server" (correct service name from pom.xml <name>OpenDJ Server</name>)
  • Fix PowerShell wait loop: remove powershell -Command "..." wrapper since shell is already pwsh (prevents $i/$c being expanded to empty by the outer shell)
Original prompt

In the file .github/workflows/build.yml, the "Test on Windows" step currently tests OpenDJ as a regular process (using start-ds.bat/stop-ds.bat), but does not test the Windows service functionality.

Task: Add a Windows service registration, start, and stop test to the "Test on Windows" step.

After the existing Windows tests (after the final opendj-server-legacy\target\package\opendj\bat\stop-ds.bat), add the following test steps:

  1. Enable OpenDJ as a Windows service using:

    opendj-server-legacy\target\package\opendj\bat\windows-service.bat --enableService
    
  2. Start the service using:

    net start OpenDJ
    
  3. Wait for the service to be ready — add a short delay/polling loop to wait for the LDAPS port to become available. For example using PowerShell:

    powershell -Command "Start-Sleep -Seconds 30"
    
  4. Verify the service is running by performing an LDAP search:

    opendj-server-legacy\target\package\opendj\bat\status.bat --bindDN "cn=Directory Manager" --bindPassword password
    
  5. Stop the service using:

    net stop OpenDJ
    
  6. Disable the Windows service using:

    opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
    

Important notes:

  • The windows-service.bat utility is located at opendj-server-legacy/resource/bin/windows-service.bat and invokes org.opends.server.tools.ConfigureWindowsService class.
  • The service name used by OpenDJ is typically OpenDJ (the ConfigureWindowsService class determines the service name).
  • The new service test block should be placed right before the existing "Upload artifacts" step, after the last stop-ds.bat command in the "Test on Windows" step.
  • This should be a continuation of the existing "Test on Windows" step (same run: block), not a separate step.
  • Keep the existing tests intact — do not modify or remove any existing commands.

Here is the current end of the "Test on Windows" step for reference:

    - name: Test on Windows
      if: runner.os == 'Windows'
      run:   |
        set OPENDJ_JAVA_ARGS="-server -Xmx512m"
        opendj-server-legacy\target\package\opendj\setup.bat -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --sampleData 5000 --cli --acceptLicense --no-prompt
        ... (existing test commands) ...
        opendj-server-legacy\target\package\opendj\bat\stop-ds.bat

After the last stop-ds.bat, append the Windows service test commands.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: для Test on Windows добавь тест запуска и остановки как сервиса

Assistant:

I'll look at the current Windows test section and the Unix test patterns to understand what's needed, then create a PR to add Windows service start/stop testing.

Let me first check if there are any existing Windows service-related scripts or documentation in the repository.

Assistant: Теперь я вижу, что OpenDJ предоставляет утилиту windows-service.bat для регистрации/отмены как Windows-сервиса, а также команды net start/net stop для управления сервисом. Давайте создадим PR с добавлением теста запуска/остановки как Windows-сервиса.

Assistant: I've submitted a request to the Copilot coding agent to create a pull request in OpenIdentityPlatform/OpenDJ that adds Windows service start/stop testing to the "Test on Windows" step in the CI workflow.

The PR will add the following commands at the end of the existing "Test on Windows" step (after the final stop-ds.bat):

  1. windows-service.bat --enableService — register OpenDJ as a Windows service
  2. net start OpenDJ — start the service
  3. Start-Sleep -Seconds 30 — wait for the service to be ready
  4. status.bat — verify the server is running via the service
  5. net stop OpenDJ — stop the service
  6. windows-service.bat --disableService — unregister the service

The Copilot coding agent is working on this now. You'll receive a notification when the pull request is ready for review. You can track progress in the repository's Pull Requests tab.

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Add Windows service start/stop test to CI build workflow ci: add Windows service start/stop test to CI workflow Mar 31, 2026
Copilot AI requested a review from vharseko March 31, 2026 14:36
@vharseko vharseko requested a review from Copilot March 31, 2026 16:23
@vharseko vharseko marked this pull request as ready for review March 31, 2026 16:24
@vharseko vharseko requested a review from maximthomas March 31, 2026 16:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds coverage in the Windows CI job to validate OpenDJ can be registered, started, and stopped as a Windows Service (not just run as a foreground process).

Changes:

  • Register OpenDJ as a Windows service at the end of the existing Windows test run.
  • Start the service, wait for LDAPS port readiness, and re-run an LDAP query for verification.
  • Stop and unregister the service after validation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +237 to +242
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --enableService
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
net stop "OpenDJ Server"
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The added readiness loop on line 239 is PowerShell syntax, but this run: block also contains cmd-style constructs (e.g., set ... earlier in the step, plus find/findstr pipelines). If the step is executed with shell: cmd (or its shell changes), line 239 will fail immediately. Make the shell for this step explicit and consistent (e.g., shell: pwsh with corresponding updates), or explicitly invoke the readiness loop via pwsh -Command ... so it runs reliably regardless of the step shell.

Copilot uses AI. Check for mistakes.
opendj-server-legacy\target\package\opendj\bat\stop-ds.bat
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --enableService
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop can complete without confirming success (e.g., after 12 retries it exits silently), which makes failures harder to diagnose. After the loop, add an explicit failure condition when the port never becomes reachable (e.g., track success in a flag and exit with a clear error message if the port is still closed).

Suggested change
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
$servicePortOpen = $false
for ($i=0; $i -lt 12; $i++) {
try {
$c = New-Object System.Net.Sockets.TcpClient('localhost', 1636)
$c.Close()
$servicePortOpen = $true
break
}
catch {
Start-Sleep -Seconds 5
}
}
if (-not $servicePortOpen) {
Write-Error "OpenDJ Server did not start listening on port 1636 after 12 attempts (60 seconds). Failing the build."
exit 1
}

Copilot uses AI. Check for mistakes.
Comment on lines +238 to +242
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
net stop "OpenDJ Server"
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any command between --enableService and --disableService fails, the step will stop and the disable/cleanup won’t run. Even on ephemeral runners, leaving the service registered can complicate subsequent troubleshooting within the same job log and can produce misleading follow-on failures if more commands are added later. Consider structuring the service block so cleanup runs in a finally/guaranteed cleanup section (or move cleanup into a separate step with if: always() if project constraints allow).

Suggested change
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
net stop "OpenDJ Server"
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
try {
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
net stop "OpenDJ Server"
}
finally {
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
}

Copilot uses AI. Check for mistakes.
Comment on lines +238 to +242
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
net stop "OpenDJ Server"
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any command between --enableService and --disableService fails, the step will stop and the disable/cleanup won’t run. Even on ephemeral runners, leaving the service registered can complicate subsequent troubleshooting within the same job log and can produce misleading follow-on failures if more commands are added later. Consider structuring the service block so cleanup runs in a finally/guaranteed cleanup section (or move cleanup into a separate step with if: always() if project constraints allow).

Suggested change
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
net stop "OpenDJ Server"
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
try {
net start "OpenDJ Server"
for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } }
opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000"
} finally {
net stop "OpenDJ Server" -ErrorAction SilentlyContinue
opendj-server-legacy\target\package\opendj\bat\windows-service.bat --disableService
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants