snapshot of https://github.com/nats-io/nats-server.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
NATS Server Tests / Lint (push) Failing after 3s
NATS Server Tests / Build (Latest Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2022) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2025) (push) Has been skipped
NATS Server Tests / Test Stores (push) Has been skipped
NATS Server Tests / Test JetStream (push) Has been skipped
NATS Server Tests / Test Raft (push) Has been skipped
NATS Server Tests / Test JetStream Consumers (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 1 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 2 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 3 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 4 (push) Has been skipped
NATS Server Tests / Test JetStream Supercluster (push) Has been skipped
NATS Server Tests / Test No-Race 1 (push) Has been skipped
NATS Server Tests / Test No-Race 2 (push) Has been skipped
NATS Server Tests / Test MQTT (push) Has been skipped
NATS Server Tests / Test Message Tracing (push) Has been skipped
NATS Server Tests / Test JWT (push) Has been skipped
NATS Server Tests / Test Remaining Server Tests (push) Has been skipped
NATS Server Tests / Test Other Packages (push) Has been skipped
Vulnerability Scan / govulncheck (push) Failing after 12m2s
Some checks failed
NATS Server Tests / Lint (push) Failing after 3s
NATS Server Tests / Build (Latest Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2022) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2025) (push) Has been skipped
NATS Server Tests / Test Stores (push) Has been skipped
NATS Server Tests / Test JetStream (push) Has been skipped
NATS Server Tests / Test Raft (push) Has been skipped
NATS Server Tests / Test JetStream Consumers (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 1 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 2 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 3 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 4 (push) Has been skipped
NATS Server Tests / Test JetStream Supercluster (push) Has been skipped
NATS Server Tests / Test No-Race 1 (push) Has been skipped
NATS Server Tests / Test No-Race 2 (push) Has been skipped
NATS Server Tests / Test MQTT (push) Has been skipped
NATS Server Tests / Test Message Tracing (push) Has been skipped
NATS Server Tests / Test JWT (push) Has been skipped
NATS Server Tests / Test Remaining Server Tests (push) Has been skipped
NATS Server Tests / Test Other Packages (push) Has been skipped
Vulnerability Scan / govulncheck (push) Failing after 12m2s
This commit is contained in:
179
server/service_windows_test.go
Normal file
179
server/service_windows_test.go
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright 2012-2026 The NATS Authors
|
||||
// Licensed 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.
|
||||
|
||||
//go:build windows
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
)
|
||||
|
||||
// TestWinServiceWrapper reproduces the tests for service,
|
||||
// with extra complication for windows API
|
||||
func TestWinServiceWrapper(t *testing.T) {
|
||||
/*
|
||||
Since the windows API can't be tested through just the Run func,
|
||||
a basic mock checks the intractions of the server, as happens in svc.Run.
|
||||
This test checks :
|
||||
- that the service fails to start within an unreasonable timeframe (serverC)
|
||||
- that the service signals its state correctly to windows with svc.StartPending (mockC)
|
||||
- that no other signal is sent to the windows service API(mockC)
|
||||
*/
|
||||
var (
|
||||
wsw = &winServiceWrapper{New(DefaultOptions())}
|
||||
args = make([]string, 0)
|
||||
// Size of 1 should be enough but don't want to block if the test fails.
|
||||
serverC = make(chan error, 10)
|
||||
mockC = make(chan error, 10)
|
||||
changes = make(chan svc.ChangeRequest)
|
||||
status = make(chan svc.Status)
|
||||
)
|
||||
t.Setenv("NATS_STARTUP_DELAY", "1ns") // purposely small
|
||||
// prepare mock expectations
|
||||
wsm := &winSvcMock{status: status}
|
||||
wsm.Expect(svc.StartPending)
|
||||
|
||||
go func() {
|
||||
mockC <- wsm.Listen(250 * time.Millisecond)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
_, exitCode := wsw.Execute(args, changes, status)
|
||||
// We expect an error...
|
||||
if exitCode == 0 {
|
||||
err = errors.New("Should have exitCode != 0")
|
||||
}
|
||||
serverC <- err
|
||||
}()
|
||||
|
||||
checkErr := func(c chan error, txt string) {
|
||||
select {
|
||||
case err := <-c:
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", txt, err)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("Test timed out")
|
||||
}
|
||||
}
|
||||
checkErr(mockC, "windows.svc mock")
|
||||
checkErr(serverC, "server behavior")
|
||||
|
||||
wsw.server.Shutdown()
|
||||
}
|
||||
|
||||
func TestWinServiceLDMExit(t *testing.T) {
|
||||
var (
|
||||
wsw = &winServiceWrapper{New(DefaultOptions())}
|
||||
args = make([]string, 0)
|
||||
// Size of 1 should be enough but don't want to block if the test fails.
|
||||
serverC = make(chan error, 10)
|
||||
mockC = make(chan error, 10)
|
||||
changes = make(chan svc.ChangeRequest, 1)
|
||||
status = make(chan svc.Status)
|
||||
)
|
||||
// prepare mock expectations
|
||||
wsm := &winSvcMock{status: status}
|
||||
wsm.Expect(svc.StartPending)
|
||||
// Expect that we will be running
|
||||
wsm.Expect(svc.Running)
|
||||
// Sending the LDM signal
|
||||
changes <- svc.ChangeRequest{Cmd: svc.Cmd(ldmCode)}
|
||||
// Expect to be stopping
|
||||
wsm.Expect(svc.StopPending)
|
||||
|
||||
go func() {
|
||||
// Duration long enough for the test to complete, but not too long
|
||||
// to wait for nothing.
|
||||
mockC <- wsm.Listen(time.Second)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
if _, exitCode := wsw.Execute(args, changes, status); exitCode != 0 {
|
||||
err = fmt.Errorf("exited with %v", exitCode)
|
||||
}
|
||||
serverC <- err
|
||||
}()
|
||||
|
||||
checkErr := func(c chan error, txt string) {
|
||||
select {
|
||||
case err := <-c:
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", txt, err)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("Test timed out")
|
||||
}
|
||||
}
|
||||
checkErr(mockC, "windows.svc mock")
|
||||
checkErr(serverC, "server behavior")
|
||||
|
||||
// At this point, we have proven already that the LDM signal did
|
||||
// end the NATS server's Execute() loop because we received the
|
||||
// svc.StopPending status. Still, we will verify that we get
|
||||
// notified that the server has shutdown.
|
||||
ch := make(chan struct{}, 1)
|
||||
go func() {
|
||||
wsw.server.WaitForShutdown()
|
||||
ch <- struct{}{}
|
||||
}()
|
||||
select {
|
||||
case <-ch:
|
||||
// OK
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("Did not finish shutdown")
|
||||
}
|
||||
}
|
||||
|
||||
// winSvcMock mocks part of the golang.org/x/sys/windows/svc
|
||||
// execution stack, listening to svc.Status on its chan.
|
||||
type winSvcMock struct {
|
||||
status chan svc.Status
|
||||
expectedSt []svc.State
|
||||
}
|
||||
|
||||
// Expect allows to prepare a winSvcMock to receive a specific type of StatusMessage
|
||||
func (w *winSvcMock) Expect(st svc.State) {
|
||||
w.expectedSt = append(w.expectedSt, st)
|
||||
}
|
||||
|
||||
// Listen is the mock's mainloop, expects messages to comply with previous Expect().
|
||||
func (w *winSvcMock) Listen(dur time.Duration) error {
|
||||
timeout := time.NewTimer(dur)
|
||||
defer timeout.Stop()
|
||||
for _, state := range w.expectedSt {
|
||||
select {
|
||||
case status := <-w.status:
|
||||
if status.State != state {
|
||||
return fmt.Errorf("message to winsock: expected %v, got %v", state, status.State)
|
||||
}
|
||||
case <-timeout.C:
|
||||
return errors.New("Mock timed out")
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-timeout.C:
|
||||
return nil
|
||||
case st := <-w.status:
|
||||
return fmt.Errorf("extra message to winsock: got %v", st)
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user