Merge pull request #66 from LawrenceWoodman/improvetest

Improve the TestInstallRunRestartStopRemove test
This commit is contained in:
Daniel Theophanes
2016-07-13 06:32:37 -07:00
committed by GitHub
3 changed files with 145 additions and 41 deletions
+130 -20
View File
@@ -8,61 +8,171 @@
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) > 1 && os.Args[1] == runAsServiceArg {
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()
return
writeReport(reportDir, "finished")
os.Exit(0)
}
os.Exit(m.Run())
log.Fatalf("Invalid arguments: %v", os.Args)
}
func TestInstallRunRestartStopRemove(t *testing.T) {
p := &program{}
s, err := service.New(p, sc)
if err != nil {
t.Fatal(err)
}
reportDir := mustTempDir(t)
defer os.RemoveAll(reportDir)
s := mustNewRunAsService(t, p, reportDir)
_ = s.Uninstall()
err = s.Install()
if err != nil {
t.Fatal("install", err)
if err := s.Install(); err != nil {
t.Fatal("Install", err)
}
defer s.Uninstall()
err = s.Start()
if err != nil {
t.Fatal("start", err)
if err := s.Start(); err != nil {
t.Fatal("Start", err)
}
err = s.Restart()
if err != nil {
defer s.Stop()
checkReport(t, reportDir, "Start()", 1, 0)
if err := s.Restart(); err != nil {
t.Fatal("restart", err)
}
err = s.Stop()
if err != nil {
checkReport(t, reportDir, "Restart()", 2, 1)
p.numStopped = 0
if err := s.Stop(); err != nil {
t.Fatal("stop", err)
}
err = s.Uninstall()
if err != nil {
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)
}
err = s.Run()
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
}
+2 -2
View File
@@ -79,9 +79,9 @@ func (s *systemd) Install() error {
var to = &struct {
*Config
Path string
Path string
ReloadSignal string
PIDFile string
PIDFile string
}{
s.Config,
path,
+13 -19
View File
@@ -5,25 +5,20 @@
package service_test
import (
"log"
"testing"
"time"
"github.com/kardianos/service"
)
const runAsServiceArg = "RunThisAsService"
var sc = &service.Config{
Name: "go_service_test",
Arguments: []string{runAsServiceArg},
}
func TestRunInterrupt(t *testing.T) {
p := &program{}
sc := &service.Config{
Name: "go_service_test",
}
s, err := service.New(p, sc)
if err != nil {
log.Fatal(err)
t.Fatalf("New err: %s", err)
}
go func() {
@@ -32,21 +27,21 @@ func TestRunInterrupt(t *testing.T) {
}()
go func() {
<-time.After(3 * time.Second)
if !p.hasStopped {
panic("Run() hasn't been stopped")
for i := 0; i < 25 && p.numStopped == 0; i++ {
<-time.After(200 * time.Millisecond)
}
if p.numStopped == 0 {
t.Fatal("Run() hasn't been stopped")
}
}()
err = s.Run()
if err != nil {
log.Fatal(err)
if err = s.Run(); err != nil {
t.Fatalf("Run() err: %s", err)
}
}
type program struct {
hasRun bool
hasStopped bool
numStopped int
}
func (p *program) Start(s service.Service) error {
@@ -54,10 +49,9 @@ func (p *program) Start(s service.Service) error {
return nil
}
func (p *program) run() {
p.hasRun = true
// Do work here
}
func (p *program) Stop(s service.Service) error {
p.hasStopped = true
p.numStopped++
return nil
}