Skip to content

Commit

Permalink
http: add tests for AgentMetricsStream
Browse files Browse the repository at this point in the history
  • Loading branch information
dnephin committed Jul 26, 2021
1 parent beea1c2 commit e58a074
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
6 changes: 3 additions & 3 deletions agent/agent_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ func (s *HTTPHandlers) AgentMetricsStream(resp http.ResponseWriter, req *http.Re
var token string
s.parseToken(req, &token)
rule, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, nil, nil)
if err != nil {
switch {
case err != nil:
return nil, err
}
if rule != nil && rule.AgentRead(s.agent.config.NodeName, nil) != acl.Allow {
case rule != nil && rule.AgentRead(s.agent.config.NodeName, nil) != acl.Allow:
return nil, acl.ErrPermissionDenied
}

Expand Down
87 changes: 87 additions & 0 deletions agent/agent_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"testing"
"time"

"github.com/armon/go-metrics"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/serf/serf"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -1406,6 +1408,91 @@ func TestAgent_Metrics_ACLDeny(t *testing.T) {
})
}

func TestHTTPHandlers_AgentMetricsStream_ACLDeny(t *testing.T) {
bd := BaseDeps{}
bd.Tokens = new(tokenStore.Store)
sink := metrics.NewInmemSink(30*time.Millisecond, time.Second)
bd.MetricsHandler = sink
d := fakeResolveTokenDelegate{authorizer: acl.DenyAll()}
agent := &Agent{
baseDeps: bd,
delegate: d,
tokens: bd.Tokens,
config: &config.RuntimeConfig{NodeName: "the-node"},
logger: hclog.NewInterceptLogger(nil),
}
h := HTTPHandlers{agent: agent, denylist: NewDenylist(nil)}

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

resp := httptest.NewRecorder()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/v1/agent/metrics/stream", nil)
require.NoError(t, err)
handle := h.handler(false)
handle.ServeHTTP(resp, req)
require.Equal(t, http.StatusForbidden, resp.Code)
require.Contains(t, resp.Body.String(), "Permission denied")
}

func TestHTTPHandlers_AgentMetricsStream(t *testing.T) {
bd := BaseDeps{}
bd.Tokens = new(tokenStore.Store)
sink := metrics.NewInmemSink(20*time.Millisecond, time.Second)
bd.MetricsHandler = sink
d := fakeResolveTokenDelegate{}
agent := &Agent{
baseDeps: bd,
delegate: d,
tokens: bd.Tokens,
config: &config.RuntimeConfig{NodeName: "the-node"},
logger: hclog.NewInterceptLogger(nil),
}
h := HTTPHandlers{agent: agent, denylist: NewDenylist(nil)}

ctx, cancel := context.WithTimeout(context.Background(), 60*time.Millisecond)
defer cancel()

// produce some metrics
go func() {
for ctx.Err() == nil {
sink.SetGauge([]string{"the-key"}, 12)
time.Sleep(5 * time.Millisecond)
}
}()

resp := httptest.NewRecorder()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/v1/agent/metrics/stream", nil)
require.NoError(t, err)
handle := h.handler(false)
handle.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)

decoder := json.NewDecoder(resp.Body)
var summary metrics.MetricsSummary
err = decoder.Decode(&summary)
require.NoError(t, err)

expected := []metrics.GaugeValue{
{Name: "the-key", Value: 12, DisplayLabels: map[string]string{}},
}
require.Equal(t, expected, summary.Gauges)

// There should be at least two intervals worth of metrics
err = decoder.Decode(&summary)
require.NoError(t, err)
require.Equal(t, expected, summary.Gauges)
}

type fakeResolveTokenDelegate struct {
delegate
authorizer acl.Authorizer
}

func (f fakeResolveTokenDelegate) ResolveTokenAndDefaultMeta(_ string, _ *structs.EnterpriseMeta, _ *acl.AuthorizerContext) (acl.Authorizer, error) {
return f.authorizer, nil
}

func TestAgent_Reload(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
Expand Down

0 comments on commit e58a074

Please sign in to comment.