diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 9daabbca75..b252b61ca9 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -27,7 +27,6 @@ jobs:
matrix:
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
ruby-version: ['3.3', '3.2', '3.1', '3.0', '2.7']
-
name: Ruby ${{ matrix.ruby-version }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
@@ -43,3 +42,23 @@ jobs:
run: bundle install
- name: Run tests
run: bundle exec rake test TESTOPTS="-v --no-show-detail-immediately"
+
+ test-windows-service:
+ runs-on: windows-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby-version: ['3.3', '3.2', '3.1', '3.0', '2.7']
+ name: Windows service (Ruby ${{ matrix.ruby-version }})
+ steps:
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@e34163cd15f4bb403dcd72d98e295997e6a55798 # v1.238.0
+ with:
+ ruby-version: ${{ matrix.ruby-version }}
+ - name: Install dependencies
+ run: |
+ bundle install
+ rake install
+ - name: Run tests
+ run: test\scripts\windows_service_test.ps1
diff --git a/lib/fluent/winsvc.rb b/lib/fluent/winsvc.rb
index 5262fa01c6..2b3cdabeb1 100644
--- a/lib/fluent/winsvc.rb
+++ b/lib/fluent/winsvc.rb
@@ -63,7 +63,7 @@ def service_main
loop do
sleep 5
break unless running?
- raise Errno::ECHILD unless Process.waitpid2(@pid, Process::WNOHANG)
+ raise Errno::ECHILD if Process.waitpid(@pid, Process::WNOHANG)
end
rescue Errno::ECHILD
@pid = 0
diff --git a/test/scripts/windows_service_test.ps1 b/test/scripts/windows_service_test.ps1
new file mode 100644
index 0000000000..06c4e56ab7
--- /dev/null
+++ b/test/scripts/windows_service_test.ps1
@@ -0,0 +1,73 @@
+$ErrorActionPreference = "Stop"
+Set-PSDebug -Trace 1
+
+$default_conf_path = (Resolve-Path fluent.conf).Path
+$current_path = (Get-Location).Path
+$log_path = "$current_path/fluentd.log"
+
+ruby bin/fluentd --reg-winsvc i --reg-winsvc-fluentdopt "-c '$default_conf_path' -o '$log_path'"
+
+# Test: must not start automatically
+if ((Get-Service fluentdwinsvc).Status -ne "Stopped") {
+ Write-Error "The service should not start automatically."
+}
+
+Start-Service fluentdwinsvc
+Start-Sleep 30
+
+# Test: the service should be running after started
+if ((Get-Service fluentdwinsvc).Status -ne "Running") {
+ Write-Error "The service should be running after started."
+}
+
+# Test: no warn/error/fatal logs
+Get-ChildItem "*.log" | %{
+ Get-Content $_
+ if (Select-String -Path $_ -Pattern "[warn]", "[error]", "[fatal]" -SimpleMatch -Quiet) {
+ Select-String -Path $_ -Pattern "[warn]", "[error]", "[fatal]" -SimpleMatch
+ Write-Error "There are abnormal level logs in ${_}:"
+ }
+}
+
+Stop-Service fluentdwinsvc
+Start-Sleep 10 # Somehow it is possible that some processes stay alive for a while. (This could be not good behavior...)
+
+# Test: status after stopped
+if ((Get-Service fluentdwinsvc).Status -ne "Stopped") {
+ Write-Error "The service should be in 'Stopped' status after stopped."
+}
+# Test: all Ruby processes should stop
+$ruby_processes = Get-Process -name ruby -ErrorAction SilentlyContinue
+if ($ruby_processes.Count -ne 0) {
+ Write-Output $ruby_processes
+ Write-Error "All Ruby processes should stop."
+}
+
+# Test: service should stop when the supervisor fails to launch
+# https://github.com/fluent/fluentd/pull/4909
+$test_setting = @'
+
+ @type sample
+ @id DUPLICATED_ID
+ tag test
+
+
+ @type stdout
+ @id DUPLICATED_ID
+
+'@
+Add-Content -Path "duplicated_id.conf" -Encoding UTF8 -Value $test_setting
+ruby bin/fluentd --reg-winsvc-fluentdopt "-c '$current_path/duplicated_id.conf' -o '$log_path'"
+Start-Service fluentdwinsvc
+Start-Sleep 30
+if ((Get-Service fluentdwinsvc).Status -ne "Stopped") {
+ Write-Error "The service should be in 'Stopped' status when the supervisor fails to launch."
+}
+$ruby_processes = Get-Process -name ruby -ErrorAction SilentlyContinue
+if ($ruby_processes.Count -ne 0) {
+ Write-Output $ruby_processes
+ Write-Error "All Ruby processes should stop."
+}
+
+ruby bin/fluentd --reg-winsvc u
+Remove-Item $log_path