Skip to content

Commit de3be90

Browse files
committed
feat(metrics,configparse): allow any metric types for tests
1 parent 10d28a3 commit de3be90

7 files changed

Lines changed: 84 additions & 23 deletions

File tree

internal/configparse/parse.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package configparse
22

33
import (
44
"errors"
5+
"fmt"
56
"net/http"
67
"net/url"
78
"os"
89
"path/filepath"
10+
"strconv"
911
"time"
1012

1113
"github.com/benchttp/engine/runner"
@@ -261,12 +263,16 @@ func newParsedConfig(uconf unmarshaledConfig) (parsedConfig, error) { //nolint:g
261263
if tests := uconf.Tests; len(tests) > 0 {
262264
cases := make([]runner.TestCase, len(tests))
263265
for i, t := range tests {
264-
d, _ := parseOptionalDuration(*t.Target)
266+
source := runner.MetricsSource(*t.Source)
267+
target, err := parseMetricValue(source.Type(), *t.Target)
268+
if err != nil {
269+
return parsedConfig{}, err
270+
}
265271
cases[i] = runner.TestCase{
266272
Name: *t.Name,
267273
Source: runner.MetricsSource(*t.Source),
268274
Predicate: runner.TestPredicate(*t.Predicate),
269-
Target: runner.MetricsValue(d),
275+
Target: target,
270276
}
271277
}
272278
cfg.Tests = cases
@@ -309,3 +315,14 @@ func parseOptionalDuration(raw string) (time.Duration, error) {
309315
}
310316
return time.ParseDuration(raw)
311317
}
318+
319+
func parseMetricValue(typ runner.MetricsType, in string) (runner.MetricsValue, error) {
320+
switch typ {
321+
case runner.MetricsTypeInt:
322+
return strconv.Atoi(in)
323+
case runner.MetricsTypeDuration:
324+
return time.ParseDuration(in)
325+
default:
326+
return nil, fmt.Errorf("cannot parse metrics type: %v", typ)
327+
}
328+
}

internal/configparse/parse_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,12 @@ func newExpConfig() runner.Config {
222222
Predicate: "LTE",
223223
Target: 120 * time.Millisecond,
224224
},
225+
{
226+
Name: "100% availability",
227+
Source: "FAILURE_COUNT",
228+
Predicate: "EQ",
229+
Target: 0,
230+
},
225231
},
226232
}
227233
}

internal/configparse/testdata/valid/benchttp.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,21 @@
2828
"tests": [
2929
{
3030
"name": "minimum response time",
31-
"metric": "MIN",
31+
"source": "MIN",
3232
"predicate": "GT",
33-
"value": "80ms"
33+
"target": "80ms"
3434
},
3535
{
3636
"name": "maximum response time",
37-
"metric": "MAX",
37+
"source": "MAX",
3838
"predicate": "LTE",
39-
"value": "120ms"
39+
"target": "120ms"
40+
},
41+
{
42+
"name": "100% availability",
43+
"source": "FAILURE_COUNT",
44+
"predicate": "EQ",
45+
"target": "0"
4046
}
4147
]
4248
}

internal/configparse/testdata/valid/benchttp.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ output:
2626

2727
tests:
2828
- name: minimum response time
29-
metric: MIN
29+
source: MIN
3030
predicate: GT
31-
value: 80ms
31+
target: 80ms
3232
- name: maximum response time
33-
metric: MAX
33+
source: MAX
3434
predicate: LTE
35-
value: 120ms
36-
# - name: 100% availability
37-
# metric: FAILURE_COUNT
38-
# predicate: EQ
39-
# value: 0
35+
target: 120ms
36+
- name: 100% availability
37+
source: FAILURE_COUNT
38+
predicate: EQ
39+
target: 0

internal/configparse/testdata/valid/benchttp.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ output:
2323

2424
tests:
2525
- name: minimum response time
26-
metric: MIN
26+
source: MIN
2727
predicate: GT
28-
value: 80ms
28+
target: 80ms
2929
- name: maximum response time
30-
metric: MAX
30+
source: MAX
3131
predicate: LTE
32-
value: 120ms
33-
# - name: 100% availability
34-
# metric: FAILURE_COUNT
35-
# predicate: EQ
36-
# value: 0
32+
target: 120ms
33+
- name: 100% availability
34+
source: FAILURE_COUNT
35+
predicate: EQ
36+
target: 0

runner/internal/metrics/metrics.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package metrics
22

3+
import "reflect"
4+
35
type Value interface{}
46

57
type Source string
@@ -13,6 +15,23 @@ const (
1315
RequestCount Source = "TOTAL_COUNT"
1416
)
1517

18+
type Type uint8
19+
20+
const (
21+
TypeInt Type = Type(reflect.Int)
22+
TypeDuration Type = 12
23+
)
24+
25+
func (src Source) Type() Type {
26+
switch src {
27+
case ResponseTimeAvg, ResponseTimeMin, ResponseTimeMax:
28+
return TypeDuration
29+
case RequestFailCount, RequestSuccessCount, RequestCount:
30+
return TypeInt
31+
}
32+
panic(badSource(src))
33+
}
34+
1635
func (agg Aggregate) MetricOf(src Source) Metric {
1736
var v interface{}
1837
switch src {
@@ -29,7 +48,7 @@ func (agg Aggregate) MetricOf(src Source) Metric {
2948
case RequestCount:
3049
v = agg.TotalCount
3150
default:
32-
panic("metrics.Aggregate.MetricOf: unknown Source: " + src)
51+
panic(badSource(src))
3352
}
3453
return Metric{Source: src, Value: v}
3554
}
@@ -42,3 +61,11 @@ type Metric struct {
4261
func (m Metric) Compare(to Metric) ComparisonResult {
4362
return compareMetrics(m, to)
4463
}
64+
65+
func ValueOf(src Source, v Value) Value {
66+
return Metric{Source: src, Value: v}
67+
}
68+
69+
func badSource(src Source) string {
70+
return "metrics: unknown Source: " + string(src)
71+
}

runner/runner.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type (
2525

2626
MetricsSource = metrics.Source
2727
MetricsValue = metrics.Value
28+
MetricsType = metrics.Type
2829

2930
TestCase = tests.Case
3031
TestPredicate = tests.Predicate
@@ -55,6 +56,10 @@ var (
5556
ConfigFieldsUsage = config.FieldsUsage
5657
NewRequestBody = config.NewRequestBody
5758
IsConfigField = config.IsField
59+
60+
MetricsValueOf = metrics.ValueOf
61+
MetricsTypeInt = metrics.TypeInt
62+
MetricsTypeDuration = metrics.TypeDuration
5863
)
5964

6065
type Runner struct {

0 commit comments

Comments
 (0)