Files
coder/scaletest/dashboard/run_test.go
Kyle Carberry 22e781eced chore: add /v2 to import module path (#9072)
* chore: add /v2 to import module path

go mod requires semantic versioning with versions greater than 1.x

This was a mechanical update by running:
```
go install github.com/marwan-at-work/mod/cmd/mod@latest
mod upgrade
```

Migrate generated files to import /v2

* Fix gen
2023-08-18 18:55:43 +00:00

126 lines
3.0 KiB
Go

package dashboard_test
import (
"context"
"runtime"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/scaletest/dashboard"
"github.com/coder/coder/v2/testutil"
)
func Test_Run(t *testing.T) {
t.Parallel()
if testutil.RaceEnabled() {
t.Skip("skipping timing-sensitive test because of race detector")
}
if runtime.GOOS == "windows" {
t.Skip("skipping test on Windows")
}
client := coderdtest.New(t, nil)
_ = coderdtest.CreateFirstUser(t, client)
successfulAction := func(context.Context, *dashboard.Params) error {
return nil
}
failingAction := func(context.Context, *dashboard.Params) error {
return xerrors.Errorf("failed")
}
hangingAction := func(ctx context.Context, _ *dashboard.Params) error {
<-ctx.Done()
return ctx.Err()
}
testActions := []dashboard.RollTableEntry{
{0, successfulAction, "succeeds"},
{1, failingAction, "fails"},
{2, hangingAction, "hangs"},
}
log := slogtest.Make(t, &slogtest.Options{
IgnoreErrors: true,
})
m := &testMetrics{}
cfg := dashboard.Config{
MinWait: time.Millisecond,
MaxWait: 10 * time.Millisecond,
Logger: log,
RollTable: testActions,
}
r := dashboard.NewRunner(client, m, cfg)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
t.Cleanup(cancel)
done := make(chan error)
go func() {
defer close(done)
done <- r.Run(ctx, "", nil)
}()
err, ok := <-done
assert.True(t, ok)
require.NoError(t, err)
if assert.NotEmpty(t, m.ObservedDurations["succeeds"]) {
assert.NotZero(t, m.ObservedDurations["succeeds"][0])
}
if assert.NotEmpty(t, m.ObservedDurations["fails"]) {
assert.NotZero(t, m.ObservedDurations["fails"][0])
}
if assert.NotEmpty(t, m.ObservedDurations["hangs"]) {
assert.GreaterOrEqual(t, m.ObservedDurations["hangs"][0], cfg.MaxWait.Seconds())
}
assert.Zero(t, m.Errors["succeeds"])
assert.NotZero(t, m.Errors["fails"])
assert.NotZero(t, m.Errors["hangs"])
assert.NotEmpty(t, m.Statuses["succeeds"])
assert.NotEmpty(t, m.Statuses["fails"])
assert.NotEmpty(t, m.Statuses["hangs"])
}
type testMetrics struct {
sync.RWMutex
ObservedDurations map[string][]float64
Errors map[string]int
Statuses map[string]map[string]int
}
func (m *testMetrics) ObserveDuration(action string, d time.Duration) {
m.Lock()
defer m.Unlock()
if m.ObservedDurations == nil {
m.ObservedDurations = make(map[string][]float64)
}
m.ObservedDurations[action] = append(m.ObservedDurations[action], d.Seconds())
}
func (m *testMetrics) IncErrors(action string) {
m.Lock()
defer m.Unlock()
if m.Errors == nil {
m.Errors = make(map[string]int)
}
m.Errors[action]++
}
func (m *testMetrics) IncStatuses(action string, code string) {
m.Lock()
defer m.Unlock()
if m.Statuses == nil {
m.Statuses = make(map[string]map[string]int)
}
if m.Statuses[action] == nil {
m.Statuses[action] = make(map[string]int)
}
m.Statuses[action][code]++
}