Browse Source

Merge pull request #2225 from nik-kc/nik/window_rounding

Update ParseWindow Functionality for "7d", "1w", etc.
Cliff Colvin 2 years ago
parent
commit
d19f33c104
2 changed files with 24 additions and 7 deletions
  1. 9 0
      pkg/kubecost/window.go
  2. 15 7
      pkg/kubecost/window_test.go

+ 9 - 0
pkg/kubecost/window.go

@@ -246,6 +246,15 @@ func parseWindow(window string, now time.Time) (Window, error) {
 		end := now
 		start := end.Add(-time.Duration(num) * dur)
 
+		// when using windows such as "7d" and "1w", we have to have a definition for what "the past X days" means.
+		// let "the past X days" be defined as the entirety of today plus the entirety of the past X-1 days, where
+		// "entirety" is defined as midnight to midnight, UTC. given this definition, we round forward the calculated
+		// start and end times to the nearest day to align with midnight boundaries
+		if match[2] == "d" || match[2] == "w" {
+			end = end.Truncate(timeutil.Day).Add(timeutil.Day)
+			start = start.Truncate(timeutil.Day).Add(timeutil.Day)
+		}
+
 		return NewWindow(&start, &end), nil
 	}
 

+ 15 - 7
pkg/kubecost/window_test.go

@@ -265,6 +265,7 @@ func TestParseWindowUTC(t *testing.T) {
 	}
 
 	ago12h := time.Now().UTC().Add(-12 * time.Hour)
+	ago24h := time.Now().UTC().Add(-24 * time.Hour)
 	ago36h := time.Now().UTC().Add(-36 * time.Hour)
 	ago60h := time.Now().UTC().Add(-60 * time.Hour)
 
@@ -291,8 +292,8 @@ func TestParseWindowUTC(t *testing.T) {
 	if dur2d.Duration().Hours() != 48 {
 		t.Fatalf(`expect: window "2d" to have duration 48 hour; actual: %f hours`, dur2d.Duration().Hours())
 	}
-	if !dur2d.Contains(ago36h) {
-		t.Fatalf(`expect: window "2d" to contain 36 hours ago; actual: %s doesn't contain %s`, dur2d, ago36h)
+	if !dur2d.Contains(ago24h) {
+		t.Fatalf(`expect: window "2d" to contain 24 hours ago; actual: %s doesn't contain %s`, dur2d, ago24h)
 	}
 	if dur2d.Contains(ago60h) {
 		t.Fatalf(`expect: window "2d" to not contain 60 hours ago; actual: %s contains %s`, dur2d, ago60h)
@@ -658,16 +659,21 @@ func TestWindow_DurationOffsetForPrometheus(t *testing.T) {
 		t.Fatalf("expected env.IsThanosEnabled() == false")
 	}
 
-	w, err := ParseWindowUTC("1d")
+	now := time.Now().UTC()
+	startOfToday := now.Truncate(timeutil.Day)
+	w, err := parseWindow("1d", now)
 	if err != nil {
 		t.Fatalf(`unexpected error parsing "1d": %s`, err)
 	}
+
 	dur, off, err := w.DurationOffsetForPrometheus()
+	expDur := int(now.Sub(startOfToday).Seconds())
+	expDurStr := fmt.Sprintf("%ds", expDur)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	if dur != "1d" {
-		t.Fatalf(`expect: window to be "1d"; actual: "%s"`, dur)
+	if dur != expDurStr {
+		t.Fatalf(`expect: window to be "%s"; actual: "%s"`, expDurStr, dur)
 	}
 	if off != "" {
 		t.Fatalf(`expect: offset to be ""; actual: "%s"`, off)
@@ -739,9 +745,11 @@ func TestWindow_DurationOffsetForPrometheus(t *testing.T) {
 		t.Fatalf("expected env.IsThanosEnabled() == true")
 	}
 
-	w, err = ParseWindowUTC("1d")
+	// Note - with the updated logic of 1d, 1w, etc. rounding the start and end times forward to the nearest midnight,
+	// DurationOffsetForPrometheus may fail if not using a window using "Xh" as the string to parse
+	w, err = ParseWindowUTC("24h")
 	if err != nil {
-		t.Fatalf(`unexpected error parsing "1d": %s`, err)
+		t.Fatalf(`unexpected error parsing "24h": %s`, err)
 	}
 	dur, off, err = w.DurationOffsetForPrometheus()
 	if err != nil {