diff --git a/t/01_cmd_test.go b/t/01_cmd_test.go index 80854bb5..c01a6909 100644 --- a/t/01_cmd_test.go +++ b/t/01_cmd_test.go @@ -1,6 +1,7 @@ package main import ( + "os" "testing" "github.com/stretchr/testify/require" @@ -38,4 +39,6 @@ func TestCommandFlags(t *testing.T) { Args: []string{"run", "check_snclient_version"}, Like: []string{`SNClient\+ v`}, }) + + os.Remove("snclient.ini") } diff --git a/t/02_daemon_test.go b/t/02_daemon_test.go new file mode 100644 index 00000000..0ffac690 --- /dev/null +++ b/t/02_daemon_test.go @@ -0,0 +1,91 @@ +package main + +import ( + "fmt" + "os" + "pkg/utils" + "syscall" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ( + localDaemonPort = 40555 + localDaemonPassword = "test" + localDaemonINI = ` +[/modules] +CheckBuiltinPlugins = enabled + +[/settings/default] +password = ` + localDaemonPassword + ` + +[/settings/WEB/server] +use ssl = disabled +port = ` + fmt.Sprintf("%d", localDaemonPort) + ` +` +) + +func TestDaemonRequests(t *testing.T) { + bin := getBinary() + require.FileExistsf(t, bin, "snclient binary must exist") + + writeFile(t, `snclient.ini`, localDaemonINI) + pidFile := "snclient.lock" + pid := 0 + + // start daemon + go func() { + res := runCmd(t, &cmd{ + Cmd: bin, + Args: []string{"-vv", "-logfile", "stdout", "-pidfile", pidFile}, + Like: []string{"starting", "listener on", "got sigterm", "snclient exited"}, + Unlike: []string{"PANIC"}, + }) + t.Logf("daemon finished") + assert.Emptyf(t, res.Stderr, "stderr should be empty") + }() + + startTimeOut := time.Now().Add(10 * time.Second) + for { + if time.Now().After(startTimeOut) { + break + } + pidN, err := utils.ReadPid(pidFile) + if err == nil { + pid = pidN + + break + } + time.Sleep(50 * time.Millisecond) + } + + require.Greaterf(t, pid, 0, "daemon started") + + t.Logf("daemon started with pid: %d", pid) + time.Sleep(500 * time.Millisecond) + + runCmd(t, &cmd{ + Cmd: bin, + Args: []string{"run", "check_nsc_web", "-p", localDaemonPassword, "-u", fmt.Sprintf("http://127.0.0.1:%d", localDaemonPort)}, + Like: []string{`OK: REST API reachable on http:`}, + }) + + runCmd(t, &cmd{ + Cmd: bin, + Args: []string{"run", "check_nsc_web", "-p", localDaemonPassword, "-r", "-u", fmt.Sprintf("http://127.0.0.1:%d/api/v1/inventory", localDaemonPort)}, + Like: []string{`{"inventory":`}, + }) + + t.Logf("test done, shuting down") + process, err := os.FindProcess(pid) + require.NoErrorf(t, err, "find daemon process") + + err = process.Signal(syscall.SIGTERM) + require.NoErrorf(t, err, "killing daemon") + os.Remove(pidFile) + os.Remove("snclient.ini") + time.Sleep(500 * time.Millisecond) +} diff --git a/t/utils.go b/t/utils.go index 3b156487..ef49d42c 100644 --- a/t/utils.go +++ b/t/utils.go @@ -38,6 +38,7 @@ type cmd struct { Like []string // stdout must contain these lines (regexp) ErrLike []string // stderr must contain these lines (regexp), if nil, stderr must be empty Exit int64 // exit code must match this number, set to -1 to accept all exit code (default 0) + Unlike []string // stdout must not contain these lines (regexp) // optional values when running a cmd Timeout time.Duration // maximum run duration (default 30sec) @@ -45,7 +46,7 @@ type cmd struct { } // runCmd runs a test command defined from the Cmd struct -func runCmd(t *testing.T, opt *cmd) { +func runCmd(t *testing.T, opt *cmd) *cmdResult { t.Helper() assert.NotEmptyf(t, opt.Cmd, "command must not be empty") @@ -70,15 +71,16 @@ func runCmd(t *testing.T, opt *cmd) { // extract stdout and stderr res := &cmdResult{ - Stdout: outbuf.String(), - Stderr: errbuf.String(), + ExitCode: -1, + Stdout: outbuf.String(), + Stderr: errbuf.String(), } if err != nil && check.ProcessState == nil { logCmd(t, check, res) require.NoErrorf(t, err, fmt.Sprintf("command wait: %s", opt.Cmd)) - return + return res } state := check.ProcessState @@ -88,7 +90,7 @@ func runCmd(t *testing.T, opt *cmd) { logCmd(t, check, res) assert.Fail(t, fmt.Sprintf("command run into timeout after %s", opt.Timeout.String())) - return + return res } if waitStatus, ok := state.Sys().(syscall.WaitStatus); ok { @@ -103,7 +105,11 @@ func runCmd(t *testing.T, opt *cmd) { } for _, l := range opt.Like { - assert.Regexpf(t, l, res.Stdout, "stdout contains: "+l) + assert.Regexpf(t, l, res.Stdout, "stdout must contain: "+l) + } + + for _, l := range opt.Unlike { + assert.NotRegexpf(t, l, res.Stdout, "stdout must not contain: "+l) } if len(opt.ErrLike) == 0 { @@ -113,6 +119,8 @@ func runCmd(t *testing.T, opt *cmd) { assert.Regexpf(t, l, res.Stderr, "stderr contains: "+l) } } + + return res } func prepareCmd(ctx context.Context, opt *cmd) (check *exec.Cmd, outbuf, errbuf *bytes.Buffer) {