coder/scaletest/placebo/run.go

67 lines
1.5 KiB
Go

package placebo
import (
"context"
"fmt"
"io"
"math/rand"
"time"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/scaletest/harness"
)
type Runner struct {
cfg Config
}
var _ harness.Runnable = &Runner{}
// NewRunner creates a new placebo loadtest Runner. The test will sleep for the
// specified duration if set, and will add a random amount of jitter between 0
// and the specified jitter value if set.
func NewRunner(cfg Config) *Runner {
return &Runner{
cfg: cfg,
}
}
// Run implements Runnable.
func (r *Runner) Run(ctx context.Context, _ string, logs io.Writer) error {
sleepDur := time.Duration(r.cfg.Sleep)
if r.cfg.Jitter > 0 {
//nolint:gosec // not used for crypto
sleepDur += time.Duration(rand.Int63n(int64(r.cfg.Jitter)))
// This makes it easier to tell if jitter was applied in tests.
sleepDur += time.Millisecond
}
if sleepDur > 0 {
_, _ = fmt.Fprintf(logs, "sleeping for %s\n", sleepDur)
t := time.NewTimer(sleepDur)
defer t.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-t.C:
}
}
if r.cfg.FailureChance > 0 {
_, _ = fmt.Fprintf(logs, "failure chance is %f\n", r.cfg.FailureChance)
_, _ = fmt.Fprintln(logs, "rolling the dice of fate...")
//nolint:gosec // not used for crypto
roll := rand.Float64()
_, _ = fmt.Fprintf(logs, "rolled: %f\n", roll)
if roll < r.cfg.FailureChance {
_, _ = fmt.Fprintln(logs, ":(")
return xerrors.New("test failed due to configured failure chance")
}
}
return nil
}