Skip to content

Commit

Permalink
testing: add TestRecordContractSetAndChurnMetric
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisSchinnerl committed Oct 17, 2023
1 parent a6d303e commit 272e48d
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 7 deletions.
1 change: 1 addition & 0 deletions api/bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ const (
ChurnDirAdded = "added"
ChurnDirRemoved = "removed"

MetricContractSet = "contractset"
MetricContractSetChurn = "churn"
)

Expand Down
19 changes: 19 additions & 0 deletions bus/bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ type (
}

MetricsStore interface {
ContractSetMetrics(ctx context.Context, opts api.ContractSetMetricsQueryOpts) ([]api.ContractSetMetric, error)
ContractSetChurnMetrics(ctx context.Context, opts api.ContractSetChurnMetricsQueryOpts) ([]api.ContractSetChurnMetric, error)
RecordContractSetChurnMetric(ctx context.Context, metrics ...api.ContractSetChurnMetric) error
}
Expand Down Expand Up @@ -1807,6 +1808,24 @@ func (b *bus) metricsHandlerGET(jc jape.Context) {
key := jc.PathParam("key")
var err error
switch key {
case api.MetricContractSet:
var metrics []api.ContractSetMetric
var opts api.ContractSetMetricsQueryOpts
if jc.DecodeForm("after", (*api.TimeRFC3339)(&opts.After)) != nil {
return
} else if jc.DecodeForm("before", (*api.TimeRFC3339)(&opts.Before)) != nil {
return
} else if jc.DecodeForm("name", &opts.Name) != nil {
return
} else if jc.DecodeForm("offset", &opts.Offset) != nil {
return
} else if jc.DecodeForm("limit", &opts.Limit) != nil {
return
} else if metrics, err = b.mtrcs.ContractSetMetrics(jc.Request.Context(), opts); jc.Check("failed to get contract churn metrics", err) != nil {
return
}
jc.Encode(metrics)
return
case api.MetricContractSetChurn:
var metrics []api.ContractSetChurnMetric
var opts api.ContractSetChurnMetricsQueryOpts
Expand Down
25 changes: 25 additions & 0 deletions bus/client/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,31 @@ import (
"go.sia.tech/renterd/api"
)

func (c *Client) ContractSetMetrics(ctx context.Context, opts api.ContractSetMetricsQueryOpts) ([]api.ContractSetMetric, error) {
values := url.Values{}
if opts.After != (time.Time{}) {
values.Set("after", api.TimeRFC3339(opts.After).String())
}
if opts.Before != (time.Time{}) {
values.Set("before", api.TimeRFC3339(opts.Before).String())
}
if opts.Name != "" {
values.Set("name", opts.Name)
}
if opts.Offset != 0 {
values.Set("offset", fmt.Sprint(opts.Offset))
}
if opts.Limit != 0 {
values.Set("limit", fmt.Sprint(opts.Limit))
}
var resp []api.ContractSetMetric
err := c.c.WithContext(ctx).GET(fmt.Sprintf("/metrics/%s?"+values.Encode(), api.MetricContractSet), &resp)
if err != nil {
return nil, err
}
return resp, nil
}

func (c *Client) ContractSetChurnMetrics(ctx context.Context, opts api.ContractSetChurnMetricsQueryOpts) ([]api.ContractSetChurnMetric, error) {
values := url.Values{}
if opts.After != (time.Time{}) {
Expand Down
40 changes: 33 additions & 7 deletions internal/testing/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1944,26 +1944,52 @@ func TestMultipartUploads(t *testing.T) {
}
}

func TestRecordContractSetChurnMetric(t *testing.T) {
func TestRecordContractSetAndChurnMetric(t *testing.T) {
startTime := time.Now()

cluster := newTestCluster(t, clusterOptsDefault)
defer cluster.Shutdown()

// Add 1 host.
cluster.AddHostsBlocking(1)

// Get contract set metrics.
csMetrics, err := cluster.Bus.ContractSetMetrics(context.Background(), api.ContractSetMetricsQueryOpts{})
cluster.tt.OK(err)

Check failure on line 1958 in internal/testing/cluster_test.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 1.20)

Test go.sia.tech/renterd/internal/testing/TestRecordContractSetAndChurnMetric failed in 6.09s

cluster_test.go:1958: failed to get contract churn metrics: failed to fetch contract set metrics: sql: Scan error on column index 2, name "time": failed to unmarshal unixTimeMS value: [49 54 57 55 53 52 54 49 50 52 55 57 54] []uint8; sql: Scan error on column index 2, name "time": failed to unmarshal unixTimeMS value: [49 54 57 55 53 52 54 49 50 53 56 53 57] []uint8; sql: Scan error on column index 2, name "time": failed to unmarshal unixTimeMS value: [49 54 57 55 53 52 54 49 50 54 56 50 53] []uint8; sql: Scan error on column index 2, name "time": failed to unmarshal unixTimeMS value: [49 54 57 55 53 52 54 49 50 55 56 51 57] []uint8; sql: Scan error on column index 2, name "time": failed to unmarshal unixTimeMS value: [49 54 57 55 53 52 54 49 50 56 56 49 55] []uint8; sql: Scan error on column index 2, name "time": failed to unmarshal unixTimeMS value: [49 54 57 55 53 52 54 49 50 57 56 55 54] []uint8

for i := 0; i < len(csMetrics); i++ {
// Remove metrics from before contract was formed.
if csMetrics[i].Contracts > 0 {
csMetrics = csMetrics[i:]
break
}
}
if len(csMetrics) == 0 {
t.Fatal("expected at least 1 metric with contracts")
}
for _, m := range csMetrics {
if m.Contracts != 1 {
t.Fatalf("expected 1 contract, got %v", m.Contracts)
} else if m.Name != testContractSet {
t.Fatalf("expected contract set %v, got %v", testContractSet, m.Name)
} else if !m.Time.After(startTime) {
t.Fatal("expected time to be after start time")
}
}

// Get churn metrics. Should have 1 for the new contract.
metrics, err := cluster.Bus.ContractSetChurnMetrics(context.Background(), api.ContractSetChurnMetricsQueryOpts{})
cscMetrics, err := cluster.Bus.ContractSetChurnMetrics(context.Background(), api.ContractSetChurnMetricsQueryOpts{})
cluster.tt.OK(err)

if len(metrics) != 1 {
t.Fatalf("expected 1 metric, got %v", len(metrics))
} else if m := metrics[0]; m.Direction != api.ChurnDirAdded {
if len(cscMetrics) != 1 {
t.Fatalf("expected 1 metric, got %v", len(cscMetrics))
} else if m := cscMetrics[0]; m.Direction != api.ChurnDirAdded {
t.Fatalf("expected added churn, got %v", m.Direction)
} else if m.FCID == (types.FileContractID{}) {
t.Fatal("expected non-zero FCID")
} else if m.Name != testContractSet {
t.Fatalf("expected contract set %v, got %v", testContractSet, m.Name)
} else if m.Time == (time.Time{}) {
t.Fatal("expected non-zero time")
} else if !m.Time.After(startTime) {
t.Fatal("expected time to be after start time")
}
}

0 comments on commit 272e48d

Please sign in to comment.