blob: 843077f3cab94650c19f1e79f171d4b2f66d8f92 [file] [log] [blame]
package gcloud_metrics
import (
"context"
"testing"
"time"
"github.com/googleapis/gax-go/v2"
"github.com/stretchr/testify/require"
"go.skia.org/infra/go/metrics2"
"go.skia.org/infra/go/testutils/unittest"
"google.golang.org/api/iterator"
"google.golang.org/genproto/googleapis/api/monitoredres"
monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
"google.golang.org/protobuf/types/known/timestamppb"
)
// testMetricClient implements MetricClient for testing.
type testMetricClient struct {
mockedTimeSeries []*monitoringpb.TimeSeries
}
func (c *testMetricClient) ListTimeSeries(context.Context, *monitoringpb.ListTimeSeriesRequest, ...gax.CallOption) TimeSeriesIterator {
return &testTimeSeriesIterator{
timeSeries: c.mockedTimeSeries,
idx: 0,
}
}
type testTimeSeriesIterator struct {
timeSeries []*monitoringpb.TimeSeries
idx int
}
func (i *testTimeSeriesIterator) Next() (*monitoringpb.TimeSeries, error) {
if i.idx >= len(i.timeSeries) {
return nil, iterator.Done
}
rv := i.timeSeries[i.idx]
i.idx++
return rv, nil
}
func makeTimeSeries(labels map[string]string, points []int64) *monitoringpb.TimeSeries {
pointsPb := make([]*monitoringpb.Point, 0, len(points))
for _, point := range points {
pointsPb = append(pointsPb, &monitoringpb.Point{
Value: &monitoringpb.TypedValue{
Value: &monitoringpb.TypedValue_Int64Value{
Int64Value: point,
},
},
})
}
return &monitoringpb.TimeSeries{
Points: pointsPb,
Resource: &monitoredres.MonitoredResource{
Labels: labels,
},
}
}
func TestIngestTimeSeries(t *testing.T) {
unittest.SmallTest(t)
// Set up mocks.
ctx := context.Background()
metricsClient := &testMetricClient{
// We use two time series with different values and slightly different
// label sets to verify that ingestTimeSeries finds the correct metrics.
mockedTimeSeries: []*monitoringpb.TimeSeries{
makeTimeSeries(map[string]string{
"key1": "value1a",
"key2": "value2a",
"key3": "value3a",
}, []int64{9, 10, 11}),
makeTimeSeries(map[string]string{
"key2": "value2b",
"key3": "value3b",
"key4": "value4b",
}, []int64{3, 22, 21}),
},
}
// Timestamps are ignored by the mock client.
startTime := timestamppb.New(time.Time{})
endTime := timestamppb.New(time.Time{})
measurement := "fake_measurement"
project := "fake-project"
metrics, err := ingestTimeSeries(ctx, metricsClient, project, "fake-metric-type", measurement, []string{"key1", "key2"}, startTime, endTime)
require.NoError(t, err)
require.Len(t, metrics, 2)
// Ensure that we registered the metrics as expected.
m0 := metrics2.GetInt64Metric(measurement, map[string]string{
"key1": "value1a",
"key2": "value2a",
"project": project, // Added automatically by ingestTimeSeries.
})
require.Equal(t, m0, metrics[0])
require.Equal(t, int64(11), m0.Get()) // We only use the last data point.
m1 := metrics2.GetInt64Metric(measurement, map[string]string{
"key1": "", // Not present in the original time series.
"key2": "value2b",
"project": project, // Added automatically by ingestTimeSeries.
})
require.Equal(t, m1, metrics[1])
require.Equal(t, int64(21), m1.Get()) // We only use the last data point.
}
var _ MetricClient = &testMetricClient{}