From 975c70494941f4501c75d7357cba96470b66b439 Mon Sep 17 00:00:00 2001 From: Romain Beuque Date: Sat, 12 May 2018 13:12:53 +0200 Subject: [PATCH] tests: using net/http/httptest instead of real server + cleaning teardown function --- plugins/http/http.go | 9 ++- plugins/http/http_test.go | 89 +++++++++++++++------------ plugins/http/http_utils_test.go | 16 ++--- plugins/processes/processes_test.go | 29 +++++---- plugins/supervisor/supervisor_test.go | 51 +++++++-------- 5 files changed, 101 insertions(+), 93 deletions(-) diff --git a/plugins/http/http.go b/plugins/http/http.go index 9cbb6d8..1ccb729 100644 --- a/plugins/http/http.go +++ b/plugins/http/http.go @@ -21,7 +21,8 @@ func init() { // HTTPChecker is a plugin to check HTTP service type HTTPChecker struct { - cfg httpConfig + cfg httpConfig + client *http.Client } // Name returns the name of the checker @@ -71,7 +72,11 @@ func (c *HTTPChecker) Run(ctx context.Context) plugins.Result { model.Request = *req duration := time.Now() - resp, err := http.DefaultClient.Do(req) + client := http.DefaultClient + if c.client != nil { + client = c.client + } + resp, err := client.Do(req) if err != nil { model.Err = err err = fmt.Errorf(plugins.RenderError(c.cfg.templates.ErrRequest, model)) diff --git a/plugins/http/http_test.go b/plugins/http/http_test.go index 4e71176..0cd8440 100644 --- a/plugins/http/http_test.go +++ b/plugins/http/http_test.go @@ -14,28 +14,27 @@ func TestHTTPServer(t *testing.T) { srvcfg := FakeTestHTTPServer{ StatusCode: 200, } - shutdown := NewHTTPServer(t, srvcfg) - defer func() { - ctx, cancelFunc := context.WithTimeout(context.Background(), 200*time.Millisecond) - defer cancelFunc() - shutdown(ctx) - }() + url, httpclient, shutdown := NewHTTPServer(t, srvcfg) + defer shutdown() time.Sleep(20 * time.Millisecond) // creating HTTP checker cfg := map[string]interface{}{ "type": "request", - "url": "http://localhost:8080", + "url": url, "method": "GET", "warn": 200, "crit": 400, "timeout": 450, "name": "test-1", } - checker, err := NewHTTPChecker(cfg, nil) + genChecker, err := NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker := genChecker.(*HTTPChecker) + checker.client = &httpclient + assert.Equal(t, "HTTP", checker.Name()) assert.Equal(t, "test-1", checker.ServiceName()) @@ -53,28 +52,27 @@ func TestHTTPServerFails(t *testing.T) { StatusCode: 200, Sleep: time.Millisecond * 80, } - shutdown := NewHTTPServer(t, srvcfg) - defer func() { - ctx, cancelFunc := context.WithTimeout(context.Background(), 200*time.Millisecond) - defer cancelFunc() - shutdown(ctx) - }() + url, httpclient, shutdown := NewHTTPServer(t, srvcfg) + defer shutdown() time.Sleep(20 * time.Millisecond) // creating HTTP checker cfg := map[string]interface{}{ "type": "request", - "url": "http://localhost:8080", + "url": url, "method": "GET", "warn": 40, "crit": 200, "timeout": 1000, "name": "test-1", } - checker, err := NewHTTPChecker(cfg, nil) + genChecker, err := NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker := genChecker.(*HTTPChecker) + checker.client = &httpclient + ctxRun, cancelFunc1 := context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() result := checker.Run(ctxRun) @@ -85,9 +83,12 @@ func TestHTTPServerFails(t *testing.T) { // critical cfg["warn"] = 10 cfg["crit"] = 50 - checker, err = NewHTTPChecker(cfg, nil) + genChecker, err = NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker = genChecker.(*HTTPChecker) + checker.client = &httpclient + ctxRun, cancelFunc1 = context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() @@ -98,9 +99,12 @@ func TestHTTPServerFails(t *testing.T) { // bad status code cfg["code"] = 400 - checker, err = NewHTTPChecker(cfg, nil) + genChecker, err = NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker = genChecker.(*HTTPChecker) + checker.client = &httpclient + ctxRun, cancelFunc1 = context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() result = checker.Run(ctxRun) @@ -109,23 +113,27 @@ func TestHTTPServerFails(t *testing.T) { // bad method cfg["code"] = 200 - checker, err = NewHTTPChecker(cfg, nil) + genChecker, err = NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) - httpChecker := checker.(*HTTPChecker) - httpChecker.cfg.Method = "http not valid method" + checker = genChecker.(*HTTPChecker) + checker.client = &httpclient + checker.cfg.Method = "http not valid method" ctxRun, cancelFunc1 = context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() - result = httpChecker.Run(ctxRun) + result = checker.Run(ctxRun) assert.Equal(t, plugins.STATE_CRITICAL, result.Status) assert.Equal(t, `net/http: invalid method "http not valid method"`, result.Message) // conn refused cfg["url"] = "http://localhost:8081" - checker, err = NewHTTPChecker(cfg, nil) + genChecker, err = NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker = genChecker.(*HTTPChecker) + checker.client = &httpclient + ctxRun, cancelFunc1 = context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() @@ -140,12 +148,8 @@ func TestHTTPServerFailsTemplating(t *testing.T) { StatusCode: 200, Sleep: time.Millisecond * 80, } - shutdown := NewHTTPServer(t, srvcfg) - defer func() { - ctx, cancelFunc := context.WithTimeout(context.Background(), 200*time.Millisecond) - defer cancelFunc() - shutdown(ctx) - }() + url, httpclient, shutdown := NewHTTPServer(t, srvcfg) + defer shutdown() time.Sleep(20 * time.Millisecond) @@ -156,7 +160,7 @@ func TestHTTPServerFailsTemplating(t *testing.T) { } cfg := map[string]interface{}{ "type": "request", - "url": "http://localhost:8080", + "url": url, "method": "GET", "warn": 10, "crit": 50, @@ -164,9 +168,12 @@ func TestHTTPServerFailsTemplating(t *testing.T) { "name": "test-1", "templates": templatesCfg, } - checker, err := NewHTTPChecker(cfg, nil) + genChecker, err := NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker := genChecker.(*HTTPChecker) + checker.client = &httpclient + ctxRun, cancelFunc1 := context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() @@ -177,9 +184,12 @@ func TestHTTPServerFailsTemplating(t *testing.T) { // bad status code cfg["code"] = 400 - checker, err = NewHTTPChecker(cfg, nil) + genChecker, err = NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker = genChecker.(*HTTPChecker) + checker.client = &httpclient + ctxRun, cancelFunc1 = context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() result = checker.Run(ctxRun) @@ -193,12 +203,8 @@ func TestHTTPServerFailsTemplatingJSON(t *testing.T) { StatusCode: 400, JSONBody: true, } - shutdown := NewHTTPServer(t, srvcfg) - defer func() { - ctx, cancelFunc := context.WithTimeout(context.Background(), 200*time.Millisecond) - defer cancelFunc() - shutdown(ctx) - }() + url, httpclient, shutdown := NewHTTPServer(t, srvcfg) + defer shutdown() time.Sleep(20 * time.Millisecond) @@ -208,7 +214,7 @@ func TestHTTPServerFailsTemplatingJSON(t *testing.T) { } cfg := map[string]interface{}{ "type": "request", - "url": "http://localhost:8080", + "url": url, "method": "GET", "warn": 200, "crit": 200, @@ -216,9 +222,12 @@ func TestHTTPServerFailsTemplatingJSON(t *testing.T) { "name": "test-1", "templates": templatesCfg, } - checker, err := NewHTTPChecker(cfg, nil) + genChecker, err := NewHTTPChecker(cfg, nil) assert.Nilf(t, err, "http checker instantiation failed: %q", err) + checker := genChecker.(*HTTPChecker) + checker.client = &httpclient + ctxRun, cancelFunc1 := context.WithTimeout(context.Background(), time.Second) defer cancelFunc1() diff --git a/plugins/http/http_utils_test.go b/plugins/http/http_utils_test.go index 8faf42c..92a1f2a 100644 --- a/plugins/http/http_utils_test.go +++ b/plugins/http/http_utils_test.go @@ -1,9 +1,9 @@ package http import ( - "context" "io" "net/http" + "net/http/httptest" "testing" "time" ) @@ -30,15 +30,9 @@ func (s FakeTestHTTPServer) ServeHTTP(respW http.ResponseWriter, req *http.Reque } } -func NewHTTPServer(t *testing.T, cfg FakeTestHTTPServer) func(context.Context) error { - srv := http.Server{ - Addr: ":8080", - Handler: cfg, +func NewHTTPServer(t *testing.T, serverHandler FakeTestHTTPServer) (string, http.Client, func()) { + ts := httptest.NewServer(serverHandler) + return ts.URL, *ts.Client(), func() { + ts.Close() } - go func() { - if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - t.Fatal(err) - } - }() - return srv.Shutdown } diff --git a/plugins/processes/processes_test.go b/plugins/processes/processes_test.go index 8e39470..784e4f4 100644 --- a/plugins/processes/processes_test.go +++ b/plugins/processes/processes_test.go @@ -11,9 +11,8 @@ import ( "github.com/stretchr/testify/assert" ) -var pids []*os.Process - -func startProcesses(t *testing.T) { +func startProcesses(t *testing.T) func() { + var pids []*os.Process cmd := exec.Command("/bin/sleep", "5", "2", "1") if err := cmd.Start(); err != nil { @@ -49,24 +48,24 @@ func startProcesses(t *testing.T) { } pids = append(pids, cmd.Process) -} -func stopProcesses(t *testing.T) { - for _, process := range pids { - if process == nil { - t.Error("process pid is nil") - t.FailNow() - } - if err := process.Kill(); err != nil { - t.Error(err) - t.FailNow() + return func() { + for _, process := range pids { + if process == nil { + t.Error("process pid is nil") + t.FailNow() + } + if err := process.Kill(); err != nil { + t.Error(err) + t.FailNow() + } } } } func TestProcesses(t *testing.T) { - startProcesses(t) - defer stopProcesses(t) + teardown := startProcesses(t) + defer teardown() // creating processes checker cfg := map[string]interface{}{ diff --git a/plugins/supervisor/supervisor_test.go b/plugins/supervisor/supervisor_test.go index 59889e3..b4a15a9 100644 --- a/plugins/supervisor/supervisor_test.go +++ b/plugins/supervisor/supervisor_test.go @@ -63,11 +63,12 @@ directory=/tmp ` ) -var pids []*os.Process -var tmpfile *os.File var mutex sync.Once -func start(t *testing.T, faulty bool) { +func start(t *testing.T, faulty bool) func() { + var pids []*os.Process + var tmpfile *os.File + var err error mutex.Do(func() { cmd := exec.Command("go", "get", "-v", "github.com/ochinchina/supervisord") @@ -105,35 +106,35 @@ func start(t *testing.T, faulty bool) { } pids = append(pids, cmd.Process) -} -func stop(t *testing.T) { - for _, process := range pids { - if process == nil { - t.Error("process pid is nil") - t.FailNow() + return func() { + for _, process := range pids { + if process == nil { + t.Error("process pid is nil") + t.FailNow() + } + if err := process.Kill(); err != nil { + t.Error(err) + t.FailNow() + } } - if err := process.Kill(); err != nil { - t.Error(err) - t.FailNow() + + if tmpfile == nil { + return } - } - if tmpfile == nil { - return + os.Remove(tmpfile.Name()) + os.Remove("/tmp/supervisord.sock") + os.Remove("/tmp/supervisord.log") + os.Remove("/tmp/supervisord.log.0") + os.Remove("/tmp/supervisord.pid") } - - os.Remove(tmpfile.Name()) - os.Remove("/tmp/supervisord.sock") - os.Remove("/tmp/supervisord.log") - os.Remove("/tmp/supervisord.log.0") - os.Remove("/tmp/supervisord.pid") } func TestSupervisor(t *testing.T) { // creating supervisor server - start(t, false) - defer stop(t) + teardown := start(t, false) + defer teardown() time.Sleep(200 * time.Millisecond) @@ -187,8 +188,8 @@ func TestSupervisor(t *testing.T) { func TestSupervisorFaulty(t *testing.T) { // creating supervisor server - start(t, true) - defer stop(t) + teardown := start(t, true) + defer teardown() // sleeping 2 second to let our supervisor process failing time.Sleep(2 * time.Second)