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.
20 "golang.org/x/sys/windows/svc"
21 "golang.org/x/sys/windows/svc/mgr"
24 func getState(t *testing.T, s *mgr.Service) svc.State {
25 status, err := s.Query()
27 t.Fatalf("Query(%s) failed: %s", s.Name, err)
32 func testState(t *testing.T, s *mgr.Service, want svc.State) {
33 have := getState(t, s)
35 t.Fatalf("%s state is=%d want=%d", s.Name, have, want)
39 func waitState(t *testing.T, s *mgr.Service, want svc.State) {
41 have := getState(t, s)
46 t.Fatalf("%s state is=%d, waiting timeout", s.Name, have)
48 time.Sleep(300 * time.Millisecond)
52 // stopAndDeleteIfInstalled stops and deletes service name,
53 // if the service is running and / or installed.
54 func stopAndDeleteIfInstalled(t *testing.T, m *mgr.Mgr, name string) {
55 s, err := m.OpenService(name)
57 // Service is not installed.
63 // Make sure the service is not running, otherwise we won't be able to delete it.
64 if getState(t, s) == svc.Running {
65 _, err = s.Control(svc.Stop)
67 t.Fatalf("Control(%s) failed: %s", s.Name, err)
69 waitState(t, s, svc.Stopped)
74 t.Fatalf("Delete failed: %s", err)
78 func TestExample(t *testing.T) {
80 t.Skip("skipping test in short mode - it modifies system services")
83 const name = "myservice"
85 m, err := mgr.Connect()
87 t.Fatalf("SCM connection failed: %s", err)
91 dir, err := ioutil.TempDir("", "svc")
93 t.Fatalf("failed to create temp directory: %v", err)
95 defer os.RemoveAll(dir)
97 exepath := filepath.Join(dir, "a.exe")
98 o, err := exec.Command("go", "build", "-o", exepath, "golang.org/x/sys/windows/svc/example").CombinedOutput()
100 t.Fatalf("failed to build service program: %v\n%v", err, string(o))
103 stopAndDeleteIfInstalled(t, m, name)
105 s, err := m.CreateService(name, exepath, mgr.Config{DisplayName: "my service"}, "is", "auto-started")
107 t.Fatalf("CreateService(%s) failed: %v", name, err)
111 args := []string{"is", "manual-started", fmt.Sprintf("%d", rand.Int())}
113 testState(t, s, svc.Stopped)
114 err = s.Start(args...)
116 t.Fatalf("Start(%s) failed: %s", s.Name, err)
118 waitState(t, s, svc.Running)
119 time.Sleep(1 * time.Second)
121 // testing deadlock from issues 4.
122 _, err = s.Control(svc.Interrogate)
124 t.Fatalf("Control(%s) failed: %s", s.Name, err)
126 _, err = s.Control(svc.Interrogate)
128 t.Fatalf("Control(%s) failed: %s", s.Name, err)
130 time.Sleep(1 * time.Second)
132 _, err = s.Control(svc.Stop)
134 t.Fatalf("Control(%s) failed: %s", s.Name, err)
136 waitState(t, s, svc.Stopped)
140 t.Fatalf("Delete failed: %s", err)
143 out, err := exec.Command("wevtutil.exe", "qe", "Application", "/q:*[System[Provider[@Name='myservice']]]", "/rd:true", "/c:10").CombinedOutput()
145 t.Fatalf("wevtutil failed: %v\n%v", err, string(out))
147 want := strings.Join(append([]string{name}, args...), "-")
148 // Test context passing (see servicemain in sys_386.s and sys_amd64.s).
150 if !strings.Contains(string(out), want) {
151 t.Errorf("%q string does not contain %q", string(out), want)
155 func TestIsAnInteractiveSession(t *testing.T) {
156 isInteractive, err := svc.IsAnInteractiveSession()
161 t.Error("IsAnInteractiveSession retuns false when running interactively.")
165 func TestIsWindowsService(t *testing.T) {
166 isSvc, err := svc.IsWindowsService()
171 t.Error("IsWindowsService retuns true when not running in a service.")