github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/server/render_test.go (about)

     1  package server
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"net/url"
     9  
    10  	"github.com/golang/protobuf/proto"
    11  	. "github.com/onsi/ginkgo/v2"
    12  	. "github.com/onsi/gomega"
    13  	"github.com/prometheus/client_golang/prometheus"
    14  	"github.com/sirupsen/logrus"
    15  
    16  	"github.com/pyroscope-io/pyroscope/pkg/config"
    17  	"github.com/pyroscope-io/pyroscope/pkg/exporter"
    18  	"github.com/pyroscope-io/pyroscope/pkg/health"
    19  	"github.com/pyroscope-io/pyroscope/pkg/parser"
    20  	"github.com/pyroscope-io/pyroscope/pkg/storage"
    21  	"github.com/pyroscope-io/pyroscope/pkg/storage/tree"
    22  	"github.com/pyroscope-io/pyroscope/pkg/testing"
    23  )
    24  
    25  var _ = Describe("server", func() {
    26  	var httpServer *httptest.Server
    27  	var s *storage.Storage
    28  
    29  	testing.WithConfig(func(cfg **config.Config) {
    30  		BeforeEach(func() {
    31  			(*cfg).Server.APIBindAddr = ":10044"
    32  			var err error
    33  			s, err = storage.New(
    34  				storage.NewConfig(&(*cfg).Server),
    35  				logrus.StandardLogger(),
    36  				prometheus.NewRegistry(),
    37  				new(health.Controller),
    38  				storage.NoopApplicationMetadataService{},
    39  			)
    40  			Expect(err).ToNot(HaveOccurred())
    41  			e, _ := exporter.NewExporter(nil, nil)
    42  			c, _ := New(Config{
    43  				Configuration:           &(*cfg).Server,
    44  				Storage:                 s,
    45  				Ingester:                parser.New(logrus.StandardLogger(), s, e),
    46  				Logger:                  logrus.New(),
    47  				MetricsRegisterer:       prometheus.NewRegistry(),
    48  				ExportedMetricsRegistry: prometheus.NewRegistry(),
    49  				Notifier:                mockNotifier{},
    50  			})
    51  			h, _ := c.serverMux()
    52  			httpServer = httptest.NewServer(h)
    53  		})
    54  		JustAfterEach(func() {
    55  			s.Close()
    56  			httpServer.Close()
    57  		})
    58  		Context("/render", func() {
    59  			It("supports name and query parameters", func() {
    60  				defer httpServer.Close()
    61  
    62  				resp, err := http.Get(fmt.Sprintf("%s/render?name=%s", httpServer.URL, url.QueryEscape(`app`)))
    63  				Expect(err).ToNot(HaveOccurred())
    64  				Expect(resp.StatusCode).To(Equal(http.StatusOK))
    65  
    66  				resp, err = http.Get(fmt.Sprintf("%s/render?query=%s", httpServer.URL, url.QueryEscape(`app{foo="bar"}`)))
    67  				Expect(err).ToNot(HaveOccurred())
    68  				Expect(resp.StatusCode).To(Equal(http.StatusOK))
    69  
    70  				resp, err = http.Get(fmt.Sprintf("%s/render?query=%s", httpServer.URL, url.QueryEscape(`app{foo"bar"}`)))
    71  				Expect(err).ToNot(HaveOccurred())
    72  				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))
    73  
    74  				resp, err = http.Get(fmt.Sprintf("%s/render", httpServer.URL))
    75  				Expect(err).ToNot(HaveOccurred())
    76  				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))
    77  			})
    78  			It("supports pprof", func() {
    79  				defer httpServer.Close()
    80  
    81  				resp, err := http.Get(fmt.Sprintf("%s/render?query=%s&format=%s", httpServer.URL, url.QueryEscape(`app{foo="bar"}`), "pprof"))
    82  				Expect(err).ToNot(HaveOccurred())
    83  				Expect(resp.StatusCode).To(Equal(http.StatusOK))
    84  				Expect(resp.Header.Get("Content-Disposition")).To(MatchRegexp(
    85  					"^attachment; filename=.+\\.pprof$",
    86  				))
    87  				body, _ := io.ReadAll(resp.Body)
    88  				profile := &tree.Profile{}
    89  				err = proto.Unmarshal(body, profile)
    90  				Expect(err).ToNot(HaveOccurred())
    91  			})
    92  			It("supports collapsed format", func() {
    93  				defer httpServer.Close()
    94  
    95  				resp, err := http.Get(fmt.Sprintf("%s/render?query=%s&format=%s", httpServer.URL, url.QueryEscape(`app{foo="bar"}`), "collapsed"))
    96  				Expect(err).ToNot(HaveOccurred())
    97  				Expect(resp.StatusCode).To(Equal(http.StatusOK))
    98  				Expect(resp.Header.Get("Content-Disposition")).To(MatchRegexp(
    99  					"^attachment; filename.+\\.collapsed.txt$",
   100  				))
   101  			})
   102  		})
   103  	})
   104  })