Skip to content

Commit

Permalink
Test adwatchd main package
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielNagy committed May 29, 2024
1 parent 3f82a88 commit 6ab8ec4
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 4 deletions.
13 changes: 9 additions & 4 deletions cmd/adwatchd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ import (
"github.com/ubuntu/go-i18n"
)

func run(a *commands.App) int {
type app interface {
Run() error
UsageError() bool
Quit(syscall.Signal) error
}

func run(a app) int {
i18n.InitI18nDomain(consts.TEXTDOMAIN, po.Files)
defer installSignalHandler(a)()
log.SetFormatter(&log.TextFormatter{
Expand All @@ -38,7 +44,7 @@ func run(a *commands.App) int {
return 0
}

func installSignalHandler(a *commands.App) func() {
func installSignalHandler(a app) func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)

Expand Down Expand Up @@ -70,6 +76,5 @@ func installSignalHandler(a *commands.App) func() {
}

func main() {
app := commands.New()
os.Exit(run(app))
os.Exit(run(commands.New()))
}
114 changes: 114 additions & 0 deletions cmd/adwatchd/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package main

import (
"errors"
"os"
"os/exec"
"syscall"
"testing"
"time"

"github.com/stretchr/testify/require"
)

type myApp struct {
done chan struct{}

runError bool
usageErrorReturn bool
}

func (a *myApp) Run() error {
<-a.done
if a.runError {
return errors.New("Error requested")
}
return nil
}

func (a myApp) UsageError() bool {
return a.usageErrorReturn
}

func (a *myApp) Quit(_ syscall.Signal) error {
close(a.done)
return nil
}

func TestRun(t *testing.T) {
tests := map[string]struct {
runError bool
usageErrorReturn bool
sendSig syscall.Signal

wantReturnCode int
}{
"Run and exit successfully": {},
"Run and return error": {runError: true, wantReturnCode: 1},
"Run and return usage error": {usageErrorReturn: true, runError: true, wantReturnCode: 2},
"Run and usage error only does not fail": {usageErrorReturn: true},

// Signals handling
"Send SIGINT exits": {sendSig: syscall.SIGINT},
"Send SIGTERM exits": {sendSig: syscall.SIGTERM},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
// Signal handler tests cannot run in parallel
//

a := myApp{
done: make(chan struct{}),
runError: tc.runError,
usageErrorReturn: tc.usageErrorReturn,
}

var rc int
wait := make(chan struct{})
go func() {
rc = run(&a)
close(wait)
}()

time.Sleep(100 * time.Millisecond)

var exited bool
switch tc.sendSig {
case syscall.SIGINT:
fallthrough
case syscall.SIGTERM:
err := syscall.Kill(syscall.Getpid(), tc.sendSig)
require.NoError(t, err, "Teardown: kill should return no error")
select {
case <-time.After(50 * time.Millisecond):
exited = false
case <-wait:
exited = true
}
require.Equal(t, true, exited, "Expect to exit on SIGINT and SIGTERM")
}

if !exited {
_ = a.Quit(syscall.SIGINT)
<-wait
}

require.Equal(t, tc.wantReturnCode, rc, "Return expected code")
})
}
}

func TestMainApp(t *testing.T) {
if os.Getenv("ADSYS_CALL_MAIN") != "" {
main()
return
}

// #nosec G204: this is only for tests, under controlled args
cmd := exec.Command(os.Args[0], "version", "-test.run=TestMainApp")
cmd.Env = append(os.Environ(), "ADSYS_CALL_MAIN=1")
out, err := cmd.CombinedOutput()

require.Contains(t, string(out), "adwatchd\tdev", "Main function should print the version")
require.NoError(t, err, "Main should not return an error")
}

0 comments on commit 6ab8ec4

Please sign in to comment.