package testkit import ( "encoding/json" "fmt" "math/rand" "time" "github.com/testground/sdk-go/ptypes" ) // DurationRange is a Testground parameter type that represents a duration // range, suitable use in randomized tests. This type is encoded as a JSON array // of length 2 of element type ptypes.Duration, e.g. ["10s", "10m"]. type DurationRange struct { Min time.Duration Max time.Duration } func (r *DurationRange) ChooseRandom() time.Duration { i := int64(r.Min) + rand.Int63n(int64(r.Max)-int64(r.Min)) return time.Duration(i) } func (r *DurationRange) UnmarshalJSON(b []byte) error { var s []ptypes.Duration if err := json.Unmarshal(b, &s); err != nil { return err } if len(s) != 2 { return fmt.Errorf("expected two-element array of duration strings, got array of length %d", len(s)) } if s[0].Duration > s[1].Duration { return fmt.Errorf("expected first element to be <= second element") } r.Min = s[0].Duration r.Max = s[1].Duration return nil } func (r *DurationRange) MarshalJSON() ([]byte, error) { s := []ptypes.Duration{{r.Min}, {r.Max}} return json.Marshal(s) } // FloatRange is a Testground parameter type that represents a float // range, suitable use in randomized tests. This type is encoded as a JSON array // of length 2 of element type float32, e.g. [1.45, 10.675]. type FloatRange struct { Min float32 Max float32 } func (r *FloatRange) ChooseRandom() float32 { return r.Min + rand.Float32()*(r.Max-r.Min) } func (r *FloatRange) UnmarshalJSON(b []byte) error { var s []float32 if err := json.Unmarshal(b, &s); err != nil { return err } if len(s) != 2 { return fmt.Errorf("expected two-element array of floats, got array of length %d", len(s)) } if s[0] > s[1] { return fmt.Errorf("expected first element to be <= second element") } r.Min = s[0] r.Max = s[1] return nil } func (r *FloatRange) MarshalJSON() ([]byte, error) { s := []float32{r.Min, r.Max} return json.Marshal(s) }