Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: packages structure #72

Draft
wants to merge 8 commits into
base: chore/relocate-cli-code
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,24 @@ package metrics
import (
"time"

"github.com/benchttp/engine/benchttp/internal/metrics/timestats"
"github.com/benchttp/engine/benchttp/internal/recorder"
"github.com/benchttp/engine/benchttp/recorder"
)

type TimeStats = timestats.TimeStats

// Aggregate is an aggregate of metrics computed from
// a slice of recorder.Record.
type Aggregate struct {
// ResponseTimes is the common statistics computed from a
// slice recorder.Record. It offers statistics about the
// recorder.Record.Time of the records.
ResponseTimes timestats.TimeStats
ResponseTimes TimeStats
// StatusCodesDistribution maps each status code received to
// its number of occurrence.
StatusCodesDistribution map[int]int
// RequestEventTimes is the common statistics computed from
// the combination of all recorder.Record.Events of a slice
// of recorder.Record. It offers statistics about the
// recorder.Events.Time of the records.
RequestEventTimes map[string]timestats.TimeStats
RequestEventTimes map[string]TimeStats
// Records lists each response time received during the run.
// It offers raw informarion.
Records []struct {
Expand Down Expand Up @@ -51,7 +48,7 @@ func NewAggregate(records []recorder.Record) (agg Aggregate) {
}
}

agg.ResponseTimes = timestats.New(times)
agg.ResponseTimes = NewTimeStats(times)

agg.StatusCodesDistribution = computeStatusCodesDistribution(records)

Expand All @@ -77,7 +74,7 @@ func (agg Aggregate) RequestSuccessCount() int {

// Special compute helpers.

func computeRequestEventTimes(records []recorder.Record) map[string]timestats.TimeStats {
func computeRequestEventTimes(records []recorder.Record) map[string]TimeStats {
events := flattenRelativeTimeEvents(records)

timesByEvent := map[string][]time.Duration{}
Expand All @@ -86,10 +83,10 @@ func computeRequestEventTimes(records []recorder.Record) map[string]timestats.Ti
timesByEvent[e.Name] = append(timesByEvent[e.Name], e.Time)
}

statsByEvent := map[string]timestats.TimeStats{}
statsByEvent := map[string]TimeStats{}

for e, times := range timesByEvent {
statsByEvent[e] = timestats.New(times)
statsByEvent[e] = NewTimeStats(times)
}

return statsByEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import (
"testing"
"time"

"github.com/benchttp/engine/benchttp/internal/metrics"
"github.com/benchttp/engine/benchttp/internal/metrics/timestats"
"github.com/benchttp/engine/benchttp/internal/recorder"
"github.com/benchttp/engine/benchttp/metrics"
"github.com/benchttp/engine/benchttp/recorder"
)

func TestNewAggregate(t *testing.T) {
// Test for "response times stats" is delegated to timestats.New because
// metrics.NewAggregate does not have any specific behavior aound it.
// Test for "response times stats" is delegated to metrics.NewTimeStats
// because metrics.NewAggregate does not have any specific behavior aound it.

t.Run("events times stats", func(t *testing.T) {
eventsStub := func(t1, t2 time.Duration) []recorder.Event {
Expand All @@ -26,7 +25,7 @@ func TestNewAggregate(t *testing.T) {
{Events: eventsStub(400, 500)},
}

want := map[string]timestats.TimeStats{
want := map[string]metrics.TimeStats{
"1": {Min: 100, Max: 400, Mean: 250, Median: 250},
"2": {Min: 200, Max: 500, Mean: 325, Median: 300},
}
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package metrics_test
import (
"testing"

"github.com/benchttp/engine/benchttp/internal/metrics"
"github.com/benchttp/engine/benchttp/metrics"
)

func TestField_Type(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package metrics
import (
"strings"

"github.com/benchttp/engine/benchttp/internal/reflectpath"
"github.com/benchttp/engine/internal/reflectpath"
)

// Value is a concrete metric value, e.g. 120 or 3 * time.Second.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import (
"testing"
"time"

"github.com/benchttp/engine/benchttp/internal/metrics"
"github.com/benchttp/engine/benchttp/internal/metrics/timestats"
"github.com/benchttp/engine/benchttp/metrics"
)

func TestMetric_Compare(t *testing.T) {
Expand Down Expand Up @@ -87,7 +86,7 @@ func TestAggregate_MetricOf(t *testing.T) {
name: "get metrics from nested struct",
fieldID: "ResponseTimes.Mean",
agg: metrics.Aggregate{
ResponseTimes: timestats.TimeStats{
ResponseTimes: metrics.TimeStats{
Mean: 100 * time.Millisecond,
},
},
Expand All @@ -114,7 +113,7 @@ func TestAggregate_MetricOf(t *testing.T) {
name: "get metrics from string map",
fieldID: "RequestEventTimes.FirstResponseByte.Mean",
agg: metrics.Aggregate{
RequestEventTimes: map[string]timestats.TimeStats{
RequestEventTimes: map[string]metrics.TimeStats{
"FirstResponseByte": {Mean: 100 * time.Millisecond},
},
},
Expand All @@ -132,7 +131,7 @@ func TestAggregate_MetricOf(t *testing.T) {
name: "case insensitive",
fieldID: "responsetimes.MEAN",
agg: metrics.Aggregate{
ResponseTimes: timestats.TimeStats{
ResponseTimes: metrics.TimeStats{
Mean: 100 * time.Millisecond,
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package timestats
package metrics

import (
"math"
Expand All @@ -17,7 +17,7 @@ type TimeStats struct {
Deciles []time.Duration
}

func New(times []time.Duration) TimeStats {
func NewTimeStats(times []time.Duration) TimeStats {
n := len(times)
if n == 0 {
return TimeStats{}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package timestats
package metrics

import (
"time"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package timestats_test
package metrics_test

import (
"testing"
"time"

"github.com/benchttp/engine/benchttp/internal/metrics/timestats"
"github.com/benchttp/engine/benchttp/metrics"
)

func TestCompute(t *testing.T) {
t.Run("happy path", func(t *testing.T) {
want := timestats.TimeStats{
want := metrics.TimeStats{
Min: 100,
Max: 400,
Mean: 230,
Expand All @@ -21,7 +21,7 @@ func TestCompute(t *testing.T) {

data := []time.Duration{100, 100, 200, 300, 400, 200, 100, 200, 300, 400, 100, 100, 200, 300, 400, 200, 100, 200, 300, 400}

got := timestats.New(data)
got := metrics.NewTimeStats(data)

for _, stat := range []struct {
name string
Expand Down Expand Up @@ -62,7 +62,7 @@ func TestCompute(t *testing.T) {

t.Run("few values", func(t *testing.T) {
data := []time.Duration{100, 300}
got := timestats.New(data)
got := metrics.NewTimeStats(data)

if got.Deciles != nil {
t.Errorf("deciles: want nil, got %v", got.Deciles)
Expand All @@ -77,8 +77,3 @@ func TestCompute(t *testing.T) {
}
})
}

// approxEqual returns true if val is equal to target with a margin of error.
func approxEqualTime(val, target, margin time.Duration) bool {
return val >= target-margin && val <= target+margin
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"sync"
"time"

"github.com/benchttp/engine/internal/dispatcher"
"github.com/benchttp/engine/internal/workerpool"
)

const (
Expand Down Expand Up @@ -91,7 +91,7 @@ func (r *Recorder) Record(ctx context.Context, req *http.Request) ([]Record, err
r.start = time.Now()
go r.tickProgress()

err := dispatcher.
err := workerpool.
New(numWorker).
Do(ctx, maxIter, r.recordSingle(req, interval))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"testing"
"time"

"github.com/benchttp/engine/internal/dispatcher"
"github.com/benchttp/engine/internal/workerpool"
)

var errTest = errors.New("test-generated error")
Expand All @@ -32,15 +32,15 @@ func TestRecorder_Run(t *testing.T) {
exp: ErrConnection,
},
{
label: "return dispatcher.ErrInvalidValue early on bad dispatcher value",
label: "return workerpool.ErrInvalidValue early on bad workerpool value",
req: withNoopTransport(New(Config{
Requests: 1,
Concurrency: 2, // bad: Concurrency > Requests
RequestTimeout: 1 * time.Second,
GlobalTimeout: 3 * time.Second,
},
)),
exp: dispatcher.ErrInvalidValue,
exp: workerpool.ErrInvalidValue,
},
}

Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions benchttp/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ package benchttp
import (
"time"

"github.com/benchttp/engine/benchttp/internal/metrics"
"github.com/benchttp/engine/benchttp/internal/tests"
"github.com/benchttp/engine/benchttp/metrics"
"github.com/benchttp/engine/benchttp/testsuite"
)

// Report represents a run result as exported by the runner.
type Report struct {
Metadata Metadata
Metrics metrics.Aggregate
Tests tests.SuiteResult
Tests testsuite.Result
}

// Metadata contains contextual information about a run.
Expand All @@ -26,7 +26,7 @@ func newReport(
r Runner,
d time.Duration,
m metrics.Aggregate,
t tests.SuiteResult,
t testsuite.Result,
) *Report {
return &Report{
Metrics: m,
Expand Down
36 changes: 6 additions & 30 deletions benchttp/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,11 @@ import (
"net/http"
"time"

"github.com/benchttp/engine/benchttp/internal/metrics"
"github.com/benchttp/engine/benchttp/internal/recorder"
"github.com/benchttp/engine/benchttp/internal/tests"
"github.com/benchttp/engine/benchttp/metrics"
"github.com/benchttp/engine/benchttp/recorder"
"github.com/benchttp/engine/benchttp/testsuite"
)

type (
RecordingProgress = recorder.Progress
RecordingStatus = recorder.Status

MetricsAggregate = metrics.Aggregate
MetricsField = metrics.Field
MetricsValue = metrics.Value
MetricsTimeStats = metrics.TimeStats

TestCase = tests.Case
TestPredicate = tests.Predicate
TestSuiteResults = tests.SuiteResult
TestCaseResult = tests.CaseResult
)

const (
StatusRunning = recorder.StatusRunning
StatusCanceled = recorder.StatusCanceled
StatusTimeout = recorder.StatusTimeout
StatusDone = recorder.StatusDone
)

var ErrCanceled = recorder.ErrCanceled

type Runner struct {
Request *http.Request

Expand All @@ -46,9 +22,9 @@ type Runner struct {
RequestTimeout time.Duration
GlobalTimeout time.Duration

Tests []tests.Case
Tests []testsuite.Case

OnProgress func(RecordingProgress)
OnProgress func(recorder.Progress)

recorder *recorder.Recorder
}
Expand Down Expand Up @@ -103,7 +79,7 @@ func (r Runner) Run(ctx context.Context) (*Report, error) {

agg := metrics.NewAggregate(records)

testResults := tests.Run(agg, r.Tests)
testResults := testsuite.Run(agg, r.Tests)

return newReport(r, duration, agg, testResults), nil
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package tests
package testsuite

import (
"errors"

"github.com/benchttp/engine/benchttp/internal/metrics"
"github.com/benchttp/engine/benchttp/metrics"
"github.com/benchttp/engine/internal/errorutil"
)

Expand Down
Loading