.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / sys@v0.0.0-20210124154548-22da62e12c0c / windows / svc / mgr / mgr_test.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // +build windows
6
7 package mgr_test
8
9 import (
10         "fmt"
11         "os"
12         "path/filepath"
13         "sort"
14         "strings"
15         "syscall"
16         "testing"
17         "time"
18
19         "golang.org/x/sys/windows/svc/mgr"
20 )
21
22 func TestOpenLanManServer(t *testing.T) {
23         m, err := mgr.Connect()
24         if err != nil {
25                 if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
26                         t.Skip("Skipping test: we don't have rights to manage services.")
27                 }
28                 t.Fatalf("SCM connection failed: %s", err)
29         }
30         defer m.Disconnect()
31
32         s, err := m.OpenService("LanmanServer")
33         if err != nil {
34                 t.Fatalf("OpenService(lanmanserver) failed: %s", err)
35         }
36         defer s.Close()
37
38         _, err = s.Config()
39         if err != nil {
40                 t.Fatalf("Config failed: %s", err)
41         }
42 }
43
44 func install(t *testing.T, m *mgr.Mgr, name, exepath string, c mgr.Config) {
45         // Sometimes it takes a while for the service to get
46         // removed after previous test run.
47         for i := 0; ; i++ {
48                 s, err := m.OpenService(name)
49                 if err != nil {
50                         break
51                 }
52                 s.Close()
53
54                 if i > 10 {
55                         t.Fatalf("service %s already exists", name)
56                 }
57                 time.Sleep(300 * time.Millisecond)
58         }
59
60         s, err := m.CreateService(name, exepath, c)
61         if err != nil {
62                 t.Fatalf("CreateService(%s) failed: %v", name, err)
63         }
64         defer s.Close()
65 }
66
67 func depString(d []string) string {
68         if len(d) == 0 {
69                 return ""
70         }
71         for i := range d {
72                 d[i] = strings.ToLower(d[i])
73         }
74         ss := sort.StringSlice(d)
75         ss.Sort()
76         return strings.Join([]string(ss), " ")
77 }
78
79 func testConfig(t *testing.T, s *mgr.Service, should mgr.Config) mgr.Config {
80         is, err := s.Config()
81         if err != nil {
82                 t.Fatalf("Config failed: %s", err)
83         }
84         if should.DelayedAutoStart != is.DelayedAutoStart {
85                 t.Fatalf("config mismatch: DelayedAutoStart is %v, but should have %v", is.DelayedAutoStart, should.DelayedAutoStart)
86         }
87         if should.DisplayName != is.DisplayName {
88                 t.Fatalf("config mismatch: DisplayName is %q, but should have %q", is.DisplayName, should.DisplayName)
89         }
90         if should.StartType != is.StartType {
91                 t.Fatalf("config mismatch: StartType is %v, but should have %v", is.StartType, should.StartType)
92         }
93         if should.Description != is.Description {
94                 t.Fatalf("config mismatch: Description is %q, but should have %q", is.Description, should.Description)
95         }
96         if depString(should.Dependencies) != depString(is.Dependencies) {
97                 t.Fatalf("config mismatch: Dependencies is %v, but should have %v", is.Dependencies, should.Dependencies)
98         }
99         return is
100 }
101
102 func testRecoveryActions(t *testing.T, s *mgr.Service, should []mgr.RecoveryAction) {
103         is, err := s.RecoveryActions()
104         if err != nil {
105                 t.Fatalf("RecoveryActions failed: %s", err)
106         }
107         if len(should) != len(is) {
108                 t.Errorf("recovery action mismatch: contains %v actions, but should have %v", len(is), len(should))
109         }
110         for i, _ := range is {
111                 if should[i].Type != is[i].Type {
112                         t.Errorf("recovery action mismatch: Type is %v, but should have %v", is[i].Type, should[i].Type)
113                 }
114                 if should[i].Delay != is[i].Delay {
115                         t.Errorf("recovery action mismatch: Delay is %v, but should have %v", is[i].Delay, should[i].Delay)
116                 }
117         }
118 }
119
120 func testResetPeriod(t *testing.T, s *mgr.Service, should uint32) {
121         is, err := s.ResetPeriod()
122         if err != nil {
123                 t.Fatalf("ResetPeriod failed: %s", err)
124         }
125         if should != is {
126                 t.Errorf("reset period mismatch: reset period is %v, but should have %v", is, should)
127         }
128 }
129
130 func testSetRecoveryActions(t *testing.T, s *mgr.Service) {
131         r := []mgr.RecoveryAction{
132                 mgr.RecoveryAction{
133                         Type:  mgr.NoAction,
134                         Delay: 60000 * time.Millisecond,
135                 },
136                 mgr.RecoveryAction{
137                         Type:  mgr.ServiceRestart,
138                         Delay: 4 * time.Minute,
139                 },
140                 mgr.RecoveryAction{
141                         Type:  mgr.ServiceRestart,
142                         Delay: time.Minute,
143                 },
144                 mgr.RecoveryAction{
145                         Type:  mgr.RunCommand,
146                         Delay: 4000 * time.Millisecond,
147                 },
148         }
149
150         // 4 recovery actions with reset period
151         err := s.SetRecoveryActions(r, uint32(10000))
152         if err != nil {
153                 t.Fatalf("SetRecoveryActions failed: %v", err)
154         }
155         testRecoveryActions(t, s, r)
156         testResetPeriod(t, s, uint32(10000))
157
158         // Infinite reset period
159         err = s.SetRecoveryActions(r, syscall.INFINITE)
160         if err != nil {
161                 t.Fatalf("SetRecoveryActions failed: %v", err)
162         }
163         testRecoveryActions(t, s, r)
164         testResetPeriod(t, s, syscall.INFINITE)
165
166         // nil recovery actions
167         err = s.SetRecoveryActions(nil, 0)
168         if err.Error() != "recoveryActions cannot be nil" {
169                 t.Fatalf("SetRecoveryActions failed with unexpected error message of %q", err)
170         }
171
172         // Delete all recovery actions and reset period
173         err = s.ResetRecoveryActions()
174         if err != nil {
175                 t.Fatalf("ResetRecoveryActions failed: %v", err)
176         }
177         testRecoveryActions(t, s, nil)
178         testResetPeriod(t, s, 0)
179 }
180
181 func testRebootMessage(t *testing.T, s *mgr.Service, should string) {
182         err := s.SetRebootMessage(should)
183         if err != nil {
184                 t.Fatalf("SetRebootMessage failed: %v", err)
185         }
186         is, err := s.RebootMessage()
187         if err != nil {
188                 t.Fatalf("RebootMessage failed: %v", err)
189         }
190         if should != is {
191                 t.Errorf("reboot message mismatch: message is %q, but should have %q", is, should)
192         }
193 }
194
195 func testRecoveryCommand(t *testing.T, s *mgr.Service, should string) {
196         err := s.SetRecoveryCommand(should)
197         if err != nil {
198                 t.Fatalf("SetRecoveryCommand failed: %v", err)
199         }
200         is, err := s.RecoveryCommand()
201         if err != nil {
202                 t.Fatalf("RecoveryCommand failed: %v", err)
203         }
204         if should != is {
205                 t.Errorf("recovery command mismatch: command is %q, but should have %q", is, should)
206         }
207 }
208
209 func remove(t *testing.T, s *mgr.Service) {
210         err := s.Delete()
211         if err != nil {
212                 t.Fatalf("Delete failed: %s", err)
213         }
214 }
215
216 func TestMyService(t *testing.T) {
217         if testing.Short() {
218                 t.Skip("skipping test in short mode - it modifies system services")
219         }
220
221         const name = "mymgrservice"
222
223         m, err := mgr.Connect()
224         if err != nil {
225                 if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
226                         t.Skip("Skipping test: we don't have rights to manage services.")
227                 }
228                 t.Fatalf("SCM connection failed: %s", err)
229         }
230         defer m.Disconnect()
231
232         c := mgr.Config{
233                 StartType:    mgr.StartDisabled,
234                 DisplayName:  "my service",
235                 Description:  "my service is just a test",
236                 Dependencies: []string{"LanmanServer", "W32Time"},
237         }
238
239         exename := os.Args[0]
240         exepath, err := filepath.Abs(exename)
241         if err != nil {
242                 t.Fatalf("filepath.Abs(%s) failed: %s", exename, err)
243         }
244
245         install(t, m, name, exepath, c)
246
247         s, err := m.OpenService(name)
248         if err != nil {
249                 t.Fatalf("service %s is not installed", name)
250         }
251         defer s.Close()
252
253         c.BinaryPathName = exepath
254         c = testConfig(t, s, c)
255
256         c.StartType = mgr.StartManual
257         err = s.UpdateConfig(c)
258         if err != nil {
259                 t.Fatalf("UpdateConfig failed: %v", err)
260         }
261
262         testConfig(t, s, c)
263
264         c.StartType = mgr.StartAutomatic
265         c.DelayedAutoStart = true
266         err = s.UpdateConfig(c)
267         if err != nil {
268                 t.Fatalf("UpdateConfig failed: %v", err)
269         }
270
271         testConfig(t, s, c)
272
273         svcnames, err := m.ListServices()
274         if err != nil {
275                 t.Fatalf("ListServices failed: %v", err)
276         }
277         var myserviceIsInstalled bool
278         for _, sn := range svcnames {
279                 if sn == name {
280                         myserviceIsInstalled = true
281                         break
282                 }
283         }
284         if !myserviceIsInstalled {
285                 t.Errorf("ListServices failed to find %q service", name)
286         }
287
288         testSetRecoveryActions(t, s)
289         testRebootMessage(t, s, fmt.Sprintf("%s failed", name))
290         testRebootMessage(t, s, "") // delete reboot message
291         testRecoveryCommand(t, s, fmt.Sprintf("sc query %s", name))
292         testRecoveryCommand(t, s, "") // delete recovery command
293
294         remove(t, s)
295 }