Merge pull request #66 from LawrenceWoodman/improvetest
Improve the TestInstallRunRestartStopRemove test
This commit is contained in:
+130
-20
@@ -8,61 +8,171 @@
|
|||||||
package service_test
|
package service_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/kardianos/service"
|
"github.com/kardianos/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const runAsServiceArg = "RunThisAsService"
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
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()
|
runService()
|
||||||
return
|
writeReport(reportDir, "finished")
|
||||||
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
os.Exit(m.Run())
|
|
||||||
|
log.Fatalf("Invalid arguments: %v", os.Args)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInstallRunRestartStopRemove(t *testing.T) {
|
func TestInstallRunRestartStopRemove(t *testing.T) {
|
||||||
p := &program{}
|
p := &program{}
|
||||||
s, err := service.New(p, sc)
|
reportDir := mustTempDir(t)
|
||||||
if err != nil {
|
defer os.RemoveAll(reportDir)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
s := mustNewRunAsService(t, p, reportDir)
|
||||||
_ = s.Uninstall()
|
_ = s.Uninstall()
|
||||||
|
|
||||||
err = s.Install()
|
if err := s.Install(); err != nil {
|
||||||
if err != nil {
|
t.Fatal("Install", err)
|
||||||
t.Fatal("install", err)
|
|
||||||
}
|
}
|
||||||
defer s.Uninstall()
|
defer s.Uninstall()
|
||||||
|
|
||||||
err = s.Start()
|
if err := s.Start(); err != nil {
|
||||||
if err != nil {
|
t.Fatal("Start", err)
|
||||||
t.Fatal("start", err)
|
|
||||||
}
|
}
|
||||||
err = s.Restart()
|
defer s.Stop()
|
||||||
if err != nil {
|
checkReport(t, reportDir, "Start()", 1, 0)
|
||||||
|
|
||||||
|
if err := s.Restart(); err != nil {
|
||||||
t.Fatal("restart", err)
|
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)
|
t.Fatal("stop", err)
|
||||||
}
|
}
|
||||||
err = s.Uninstall()
|
checkReport(t, reportDir, "Stop()", 2, 2)
|
||||||
if err != nil {
|
|
||||||
|
if err := s.Uninstall(); err != nil {
|
||||||
t.Fatal("uninstall", err)
|
t.Fatal("uninstall", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runService() {
|
func runService() {
|
||||||
p := &program{}
|
p := &program{}
|
||||||
|
sc := &service.Config{
|
||||||
|
Name: "go_service_test",
|
||||||
|
}
|
||||||
s, err := service.New(p, sc)
|
s, err := service.New(p, sc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -79,9 +79,9 @@ func (s *systemd) Install() error {
|
|||||||
|
|
||||||
var to = &struct {
|
var to = &struct {
|
||||||
*Config
|
*Config
|
||||||
Path string
|
Path string
|
||||||
ReloadSignal string
|
ReloadSignal string
|
||||||
PIDFile string
|
PIDFile string
|
||||||
}{
|
}{
|
||||||
s.Config,
|
s.Config,
|
||||||
path,
|
path,
|
||||||
|
|||||||
+13
-19
@@ -5,25 +5,20 @@
|
|||||||
package service_test
|
package service_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kardianos/service"
|
"github.com/kardianos/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
const runAsServiceArg = "RunThisAsService"
|
|
||||||
|
|
||||||
var sc = &service.Config{
|
|
||||||
Name: "go_service_test",
|
|
||||||
Arguments: []string{runAsServiceArg},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRunInterrupt(t *testing.T) {
|
func TestRunInterrupt(t *testing.T) {
|
||||||
p := &program{}
|
p := &program{}
|
||||||
|
sc := &service.Config{
|
||||||
|
Name: "go_service_test",
|
||||||
|
}
|
||||||
s, err := service.New(p, sc)
|
s, err := service.New(p, sc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
t.Fatalf("New err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -32,21 +27,21 @@ func TestRunInterrupt(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-time.After(3 * time.Second)
|
for i := 0; i < 25 && p.numStopped == 0; i++ {
|
||||||
if !p.hasStopped {
|
<-time.After(200 * time.Millisecond)
|
||||||
panic("Run() hasn't been stopped")
|
}
|
||||||
|
if p.numStopped == 0 {
|
||||||
|
t.Fatal("Run() hasn't been stopped")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = s.Run()
|
if err = s.Run(); err != nil {
|
||||||
if err != nil {
|
t.Fatalf("Run() err: %s", err)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type program struct {
|
type program struct {
|
||||||
hasRun bool
|
numStopped int
|
||||||
hasStopped bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *program) Start(s service.Service) error {
|
func (p *program) Start(s service.Service) error {
|
||||||
@@ -54,10 +49,9 @@ func (p *program) Start(s service.Service) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (p *program) run() {
|
func (p *program) run() {
|
||||||
p.hasRun = true
|
|
||||||
// Do work here
|
// Do work here
|
||||||
}
|
}
|
||||||
func (p *program) Stop(s service.Service) error {
|
func (p *program) Stop(s service.Service) error {
|
||||||
p.hasStopped = true
|
p.numStopped++
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user