diff options
author | Valery Piashchynski <[email protected]> | 2022-01-15 12:08:20 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2022-01-15 12:08:20 +0300 |
commit | 5254c8eb27311e2a8a53a4c90c3829cf1238c563 (patch) | |
tree | b51c9a4c1dd4c25adc511498ce0380a7078c5572 /internal/debug | |
parent | 13609dd03dd0d2fa85b9fb850be787bf4e2ea67f (diff) |
Repository content update
Signed-off-by: Valery Piashchynski <[email protected]>
Diffstat (limited to 'internal/debug')
-rw-r--r-- | internal/debug/server.go | 37 | ||||
-rw-r--r-- | internal/debug/server_test.go | 57 |
2 files changed, 94 insertions, 0 deletions
diff --git a/internal/debug/server.go b/internal/debug/server.go new file mode 100644 index 00000000..c07a4549 --- /dev/null +++ b/internal/debug/server.go @@ -0,0 +1,37 @@ +package debug + +import ( + "context" + "net/http" + "net/http/pprof" +) + +// Server is a HTTP server for debugging. +type Server struct { + srv *http.Server +} + +// NewServer creates new HTTP server for debugging. +func NewServer() Server { + mux := http.NewServeMux() + + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + + return Server{srv: &http.Server{Handler: mux}} +} + +// Start debug server. +func (s *Server) Start(addr string) error { + s.srv.Addr = addr + + return s.srv.ListenAndServe() +} + +// Stop debug server. +func (s *Server) Stop(ctx context.Context) error { + return s.srv.Shutdown(ctx) +} diff --git a/internal/debug/server_test.go b/internal/debug/server_test.go new file mode 100644 index 00000000..d2e1f9f0 --- /dev/null +++ b/internal/debug/server_test.go @@ -0,0 +1,57 @@ +package debug_test + +import ( + "context" + "math/rand" + "net" + "net/http" + "strconv" + "testing" + "time" + + "github.com/spiral/roadrunner-binary/v2/internal/debug" + + "github.com/stretchr/testify/assert" +) + +func TestServer_StartingAndStopping(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + + var ( + s = debug.NewServer() + port = strconv.Itoa(rand.Intn(10000) + 10000) //nolint:gosec + ) + + go func() { assert.ErrorIs(t, s.Start(":"+port), http.ErrServerClosed) }() + + defer func() { assert.NoError(t, s.Stop(context.Background())) }() + + for i := 0; i < 100; i++ { // wait for server started state + if l, err := net.Dial("tcp", ":"+port); err != nil { + <-time.After(time.Millisecond) + } else { + _ = l.Close() + + break + } + } + + for _, uri := range []string{ // assert that pprof handlers exists + "http://127.0.0.1:" + port + "/debug/pprof/", + "http://127.0.0.1:" + port + "/debug/pprof/cmdline", + // "http://127.0.0.1:" + port + "/debug/pprof/profile", + "http://127.0.0.1:" + port + "/debug/pprof/symbol", + // "http://127.0.0.1:" + port + "/debug/pprof/trace", + } { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + + req, _ := http.NewRequestWithContext(ctx, http.MethodHead, uri, http.NoBody) + resp, err := http.DefaultClient.Do(req) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + + _ = resp.Body.Close() + + cancel() + } +} |