| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- // Copyright 2015 Daniel Theophanes.
- // Use of this source code is governed by a zlib-style
- // license that can be found in the LICENSE file.
- // This needs to be run as root/admin hence the reason there is a build tag
- // +build su
- package service_test
- import (
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "regexp"
- "testing"
- "time"
- "github.com/kardianos/service"
- )
- const runAsServiceArg = "RunThisAsService"
- func TestMain(m *testing.M) {
- if len(os.Args) == 2 {
- os.Exit(m.Run())
- } else if len(os.Args) == 4 && os.Args[2] == runAsServiceArg {
- reportDir := os.Args[3]
- writeReport(reportDir, "call")
- runService()
- writeReport(reportDir, "finished")
- os.Exit(0)
- }
- log.Fatalf("Invalid arguments: %v", os.Args)
- }
- func TestInstallRunRestartStopRemove(t *testing.T) {
- p := &program{}
- reportDir := mustTempDir(t)
- defer os.RemoveAll(reportDir)
- s := mustNewRunAsService(t, p, reportDir)
- _ = s.Uninstall()
- if err := s.Install(); err != nil {
- t.Fatal("Install", err)
- }
- defer s.Uninstall()
- if err := s.Start(); err != nil {
- t.Fatal("Start", err)
- }
- defer s.Stop()
- checkReport(t, reportDir, "Start()", 1, 0)
- if err := s.Restart(); err != nil {
- t.Fatal("restart", err)
- }
- checkReport(t, reportDir, "Restart()", 2, 1)
- p.numStopped = 0
- if err := s.Stop(); err != nil {
- t.Fatal("stop", err)
- }
- checkReport(t, reportDir, "Stop()", 2, 2)
- if err := s.Uninstall(); err != nil {
- t.Fatal("uninstall", err)
- }
- }
- func runService() {
- p := &program{}
- sc := &service.Config{
- Name: "go_service_test",
- }
- s, err := service.New(p, sc)
- if err != nil {
- log.Fatal(err)
- }
- if err = s.Run(); err != nil {
- log.Fatal(err)
- }
- }
- func mustTempDir(t *testing.T) string {
- dir, err := ioutil.TempDir("", "servicetest")
- if err != nil {
- t.Fatal(err)
- }
- return dir
- }
- func writeReport(reportDir string, action string) {
- b := []byte("go_test_service_report")
- timeStamp := time.Now().UnixNano()
- err := ioutil.WriteFile(
- filepath.Join(reportDir, fmt.Sprintf("%d-%s", timeStamp, action)),
- b,
- 0644,
- )
- if err != nil {
- log.Fatal(err)
- }
- }
- var matchActionRegexp = regexp.MustCompile("^(\\d+-)([a-z]*)$")
- func getReport(
- t *testing.T,
- reportDir string,
- ) (numCalls int, numFinished int) {
- numCalls = 0
- numFinished = 0
- files, err := ioutil.ReadDir(reportDir)
- if err != nil {
- t.Fatalf("ReadDir(%s) err: %s", reportDir, err)
- }
- for _, file := range files {
- if matchActionRegexp.MatchString(file.Name()) {
- action := matchActionRegexp.ReplaceAllString(file.Name(), "$2")
- switch action {
- case "call":
- numCalls++
- case "finished":
- numFinished++
- default:
- t.Fatalf("getReport() found report with incorrect action: %s", action)
- }
- }
- }
- return
- }
- func checkReport(
- t *testing.T,
- reportDir string,
- msgPrefix string,
- wantNumCalled int,
- wantNumFinished int,
- ) {
- var numCalled int
- var numFinished int
- for i := 0; i < 25; i++ {
- numCalled, numFinished = getReport(t, reportDir)
- <-time.After(200 * time.Millisecond)
- if numCalled == wantNumCalled && numFinished == wantNumFinished {
- return
- }
- }
- if numCalled != wantNumCalled {
- t.Fatalf("%s - numCalled: %d, want %d",
- msgPrefix, numCalled, wantNumCalled)
- }
- if numFinished != wantNumFinished {
- t.Fatalf("%s - numFinished: %d, want %d",
- msgPrefix, numFinished, wantNumFinished)
- }
- }
- func mustNewRunAsService(
- t *testing.T,
- p *program,
- reportDir string,
- ) service.Service {
- sc := &service.Config{
- Name: "go_service_test",
- Arguments: []string{"-test.v=true", runAsServiceArg, reportDir},
- }
- s, err := service.New(p, sc)
- if err != nil {
- t.Fatal(err)
- }
- return s
- }
|