Skip to content

Commit

Permalink
gtime: Move grafana/grafana intervalv2 functions in plugin-sdk-go (#886)
Browse files Browse the repository at this point in the history
* Move GetIntervalFrom, ParseIntervalStringToTimeDuration and roundInterval

* Remove roundInterval

* fix

* fix 2

* fix 3
  • Loading branch information
itsmylife authored Feb 6, 2024
1 parent b3749a7 commit 5577d46
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
49 changes: 49 additions & 0 deletions backend/gtime/gtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -117,3 +118,51 @@ func FormatInterval(inter time.Duration) string {

return "1ms"
}

// GetIntervalFrom returns the minimum interval.
// dsInterval is the string representation of data source min interval, if configured.
// queryInterval is the string representation of query interval (min interval), e.g. "10ms" or "10s".
// queryIntervalMS is a pre-calculated numeric representation of the query interval in milliseconds.
func GetIntervalFrom(dsInterval, queryInterval string, queryIntervalMS int64, defaultInterval time.Duration) (time.Duration, error) {
// Apparently we are setting default value of queryInterval to 0s now
interval := queryInterval
if interval == "0s" {
interval = ""
}
if interval == "" {
if queryIntervalMS != 0 {
return time.Duration(queryIntervalMS) * time.Millisecond, nil
}
}
if interval == "" && dsInterval != "" {
interval = dsInterval
}
if interval == "" {
return defaultInterval, nil
}

parsedInterval, err := ParseIntervalStringToTimeDuration(interval)
if err != nil {
return time.Duration(0), err
}

return parsedInterval, nil
}

// ParseIntervalStringToTimeDuration converts a string representation of a expected (i.e. 1m30s) to time.Duration
// this method copied from grafana/grafana/pkg/tsdb/intervalv2.go
func ParseIntervalStringToTimeDuration(interval string) (time.Duration, error) {
formattedInterval := strings.Replace(strings.Replace(interval, "<", "", 1), ">", "", 1)
isPureNum, err := regexp.MatchString(`^\d+$`, formattedInterval)
if err != nil {
return time.Duration(0), err
}
if isPureNum {
formattedInterval += "s"
}
parsedInterval, err := ParseDuration(formattedInterval)
if err != nil {
return time.Duration(0), err
}
return parsedInterval, nil
}
63 changes: 63 additions & 0 deletions backend/gtime/gtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,66 @@ func TestFormatInterval(t *testing.T) {
})
}
}

func TestGetIntervalFrom(t *testing.T) {
testCases := []struct {
name string
queryInterval string
queryIntervalMs int64
defaultInterval time.Duration
expected time.Duration
}{
{"45s", "45s", 0, time.Second * 15, time.Second * 45},
{"45", "45", 0, time.Second * 15, time.Second * 45},
{"2m", "2m", 0, time.Second * 15, time.Minute * 2},
{"1d", "1d", 0, time.Second * 15, time.Hour * 24},
{"intervalMs", "", 45000, time.Second * 15, time.Second * 45},
{"intervalMs sub-seconds", "", 45200, time.Second * 15, time.Millisecond * 45200},
{"defaultInterval when interval empty", "", 0, time.Second * 15, time.Second * 15},
{"defaultInterval when intervalMs 0", "", 0, time.Second * 15, time.Second * 15},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actual, err := GetIntervalFrom(tc.queryInterval, "", tc.queryIntervalMs, tc.defaultInterval)
require.Nil(t, err)
require.Equal(t, tc.expected, actual)
})
}
}

func TestParseIntervalStringToTimeDuration(t *testing.T) {
tcs := []struct {
inp string
duration time.Duration
err *regexp.Regexp
}{
{inp: "1s", duration: time.Second},
{inp: "1m", duration: time.Minute},
{inp: "1h", duration: time.Hour},
{inp: "1d", duration: 24 * time.Hour},
{inp: "1w", duration: 7 * 24 * time.Hour},
{inp: "2w", duration: 2 * 7 * 24 * time.Hour},
{inp: "1M", duration: time.Duration(730.5 * float64(time.Hour))},
{inp: "1y", duration: 365.25 * 24 * time.Hour},
{inp: "5y", duration: 5 * 365.25 * 24 * time.Hour},
{inp: "invalid-duration", err: regexp.MustCompile(`^time: invalid duration "?invalid-duration"?$`)},
// ParseIntervalStringToTimeDuration specific conditions
{inp: "10", duration: 10 * time.Second},
{inp: "<10s>", duration: 10 * time.Second},
{inp: "10s>", duration: 10 * time.Second},
{inp: "<10s", duration: 10 * time.Second},
}
for i, tc := range tcs {
t.Run(fmt.Sprintf("testcase %d", i), func(t *testing.T) {
res, err := ParseIntervalStringToTimeDuration(tc.inp)
if tc.err == nil {
require.NoError(t, err, "input %q", tc.inp)
require.Equal(t, tc.duration, res, "input %q", tc.inp)
} else {
require.Error(t, err, "input %q", tc.inp)
require.Regexp(t, tc.err, err.Error())
}
})
}
}

0 comments on commit 5577d46

Please sign in to comment.