From 68b3eeeaab46798f952dc7277c33d2b2bbae792b Mon Sep 17 00:00:00 2001 From: jjzeng-seattle <56568376+jjzeng-seattle@users.noreply.github.com> Date: Wed, 29 Jul 2020 03:08:59 -0700 Subject: [PATCH] Add helper functions for metric tests in serving (#1564) * Add helper functions for metric tests in seving * typo * Add WithResource to simply the code --- metrics/metricstest/resource_metrics.go | 52 ++++++++----- metrics/metricstest/resource_metrics_test.go | 77 +++++++++++++++++++- metrics/workqueue_test.go | 6 +- 3 files changed, 112 insertions(+), 23 deletions(-) diff --git a/metrics/metricstest/resource_metrics.go b/metrics/metricstest/resource_metrics.go index f9cd6139f..bbe622706 100644 --- a/metrics/metricstest/resource_metrics.go +++ b/metrics/metricstest/resource_metrics.go @@ -41,6 +41,10 @@ type Value struct { Int64 *int64 Float64 *float64 Distribution *metricdata.Distribution + // VerifyDistributionCountOnly makes Equal compare the Distribution with the + // field Count only, and ingore all other fields of Distribution. + // This is ingored when the value is not a Distribution. + VerifyDistributionCountOnly bool } // Metric provides a simplified (for testing) implementation of a metric report @@ -93,7 +97,9 @@ func NewMetric(metric *metricdata.Metric) Metric { for _, ts := range metric.TimeSeries { tags := make(map[string]string, len(metric.Descriptor.LabelKeys)) for i, k := range metric.Descriptor.LabelKeys { - tags[k.Key] = ts.LabelValues[i].Value + if ts.LabelValues[i].Present { + tags[k.Key] = ts.LabelValues[i].Value + } } v := Value{Tags: tags} ts.Points[0].ReadValue(&v) @@ -139,30 +145,37 @@ func GetOneMetric(name string) Metric { return m[0] } -func genericMetricFactory(name string, v Value, keyvalues ...string) Metric { - if len(keyvalues)%2 != 0 { - panic("Odd number of arguments to CountMetric") - } - if v.Tags == nil { - v.Tags = make(map[string]string, len(keyvalues)/2) - } - for i := 0; i < len(keyvalues); i += 2 { - v.Tags[keyvalues[i]] = keyvalues[i+1] - } +// IntMetric creates an Int64 metric. +func IntMetric(name string, value int64, tags map[string]string) Metric { return Metric{ Name: name, - Values: []Value{v}, + Values: []Value{{Int64: &value, Tags: tags}}, } } -// IntMetric is a shortcut factory for creating an Int64 metric. -func IntMetric(name string, value int64, keyvalues ...string) Metric { - return genericMetricFactory(name, Value{Int64: &value}, keyvalues...) +// FloatMetric creates a Float64 metric +func FloatMetric(name string, value float64, tags map[string]string) Metric { + return Metric{ + Name: name, + Values: []Value{{Float64: &value, Tags: tags}}, + } } -// FloatMetric is a shortcut factor for creating a Float64 metric -func FloatMetric(name string, value float64, keyvalues ...string) Metric { - return genericMetricFactory(name, Value{Float64: &value}, keyvalues...) +// DistributionCountOnlyMetric creates a distrubtion metric for test, and verifying only the count. +func DistributionCountOnlyMetric(name string, count int64, tags map[string]string) Metric { + return Metric{ + Name: name, + Values: []Value{{ + Distribution: &metricdata.Distribution{Count: count}, + Tags: tags, + VerifyDistributionCountOnly: true}}, + } +} + +// WithResource sets the resource of the metric. +func (m Metric) WithResource(r *resource.Resource) Metric { + m.Resource = r + return m } // AssertMetric verifies that the metrics have the specified values. Note that @@ -298,6 +311,9 @@ func (v Value) Equal(other Value) bool { if v.Distribution.Count != other.Distribution.Count { return false } + if v.VerifyDistributionCountOnly || other.VerifyDistributionCountOnly { + return true + } if v.Distribution.Sum != other.Distribution.Sum { return false } diff --git a/metrics/metricstest/resource_metrics_test.go b/metrics/metricstest/resource_metrics_test.go index 475a51ddb..6b186f8a4 100644 --- a/metrics/metricstest/resource_metrics_test.go +++ b/metrics/metricstest/resource_metrics_test.go @@ -222,6 +222,24 @@ func TestDistributionEqual(t *testing.T) { Buckets: buckets(1, 0, 3, 1), }, }, + }, { + name: "Equal when count only is set", + want: Value{ + Tags: map[string]string{"key1": "val1"}, + Distribution: &metricdata.Distribution{ + Count: 5, + }, + VerifyDistributionCountOnly: true, + }, + }, { + name: "Not equal when count only is not set", + want: Value{ + Tags: map[string]string{"key1": "val1"}, + Distribution: &metricdata.Distribution{ + Count: 5, + }, + }, + notEqual: true, }, { name: "Missing summary", want: Value{ @@ -281,13 +299,20 @@ func TestDistributionEqual(t *testing.T) { } func TestMetricShortcuts(t *testing.T) { + tags := map[string]string{ + "foo": "bar", + } + r := &resource.Resource{ + Type: "test-resource", + Labels: map[string]string{"foo1": "bar1"}, + } tests := []struct { name string want Metric got metricdata.Metric }{{ name: "IntMetric", - want: IntMetric("test/int", 17, "key1", "val1", "key2", "val2"), + want: IntMetric("test/int", 17, map[string]string{"key1": "val1", "key2": "val2"}), got: metricdata.Metric{ Descriptor: metricdata.Descriptor{ Name: "test/int", @@ -300,7 +325,7 @@ func TestMetricShortcuts(t *testing.T) { }, }, { name: "FloatMetric", - want: FloatMetric("test/float", 0.17, "key1", "val1", "key2", "val2"), + want: FloatMetric("test/float", 0.17, map[string]string{"key1": "val1", "key2": "val2"}), got: metricdata.Metric{ Descriptor: metricdata.Descriptor{ Name: "test/float", @@ -311,6 +336,54 @@ func TestMetricShortcuts(t *testing.T) { Points: []metricdata.Point{metricdata.NewFloat64Point(time.Now(), 0.17)}, }}, }, + }, { + name: "IntMetricWithResource", + want: IntMetric("test/int", 18, tags).WithResource(r), + got: metricdata.Metric{ + Descriptor: metricdata.Descriptor{ + Name: "test/int", + LabelKeys: []metricdata.LabelKey{{"foo", ""}}, + }, + Resource: r, + TimeSeries: []*metricdata.TimeSeries{{ + LabelValues: []metricdata.LabelValue{{"bar", true}}, + Points: []metricdata.Point{metricdata.NewInt64Point(time.Now(), 18)}, + }}, + }, + }, { + name: "FloatMetricWithResource", + want: FloatMetric("test/float", 0.18, tags).WithResource(r), + got: metricdata.Metric{ + Descriptor: metricdata.Descriptor{ + Name: "test/float", + LabelKeys: []metricdata.LabelKey{{"foo", ""}}, + }, + Resource: r, + TimeSeries: []*metricdata.TimeSeries{{ + LabelValues: []metricdata.LabelValue{{"bar", true}}, + Points: []metricdata.Point{metricdata.NewFloat64Point(time.Now(), 0.18)}, + }}, + }, + }, { + name: "DistributionCountOnlyMetricWithResource", + want: DistributionCountOnlyMetric("test/distribution", 19, tags).WithResource(r), + got: metricdata.Metric{ + Descriptor: metricdata.Descriptor{ + Name: "test/distribution", + LabelKeys: []metricdata.LabelKey{{"foo", ""}}, + }, + Resource: r, + TimeSeries: []*metricdata.TimeSeries{{ + LabelValues: []metricdata.LabelValue{{"bar", true}}, + Points: []metricdata.Point{metricdata.NewDistributionPoint(time.Now(), &metricdata.Distribution{ + Count: 19, + Sum: 25.5, + SumOfSquaredDeviation: 45.2, + BucketOptions: bucketOpts(2, 4, 8), + Buckets: buckets(1, 3, 1, 0), + })}, + }}, + }, }} for _, tc := range tests { diff --git a/metrics/workqueue_test.go b/metrics/workqueue_test.go index 4bca14f3e..8d60a8b0d 100644 --- a/metrics/workqueue_test.go +++ b/metrics/workqueue_test.go @@ -85,8 +85,8 @@ func TestWorkqueueMetrics(t *testing.T) { metricstest.AssertMetricExists(t, "adds", "depth") metricstest.AssertNoMetric(t, "latency", "retries", "work_duration", "unfinished_work_seconds", "longest_running_processor_seconds") - wantAdd := metricstest.IntMetric("adds", 1, "name", queueName) - wantDepth := metricstest.IntMetric("depth", 1, "name", queueName) + wantAdd := metricstest.IntMetric("adds", 1, map[string]string{"name": queueName}) + wantDepth := metricstest.IntMetric("depth", 1, map[string]string{"name": queueName}) metricstest.AssertMetric(t, wantAdd, wantDepth) wq.Add("bar") @@ -123,7 +123,7 @@ func TestWorkqueueMetrics(t *testing.T) { // It should show up as a retry now. metricstest.AssertMetricExists(t, "retries") metricstest.AssertNoMetric(t, "unfinished_work_seconds", "longest_running_processor_seconds") - wantRetries := metricstest.IntMetric("retries", 1, "name", queueName) + wantRetries := metricstest.IntMetric("retries", 1, map[string]string{"name": queueName}) metricstest.AssertMetric(t, wantRetries, wantAdd) // It is not added right away. // It doesn't show up as an "add" until the rate limit has elapsed.