Explorar o código

Merge branch 'develop' into alex/opencost-1753-cluster-id

Alex Meijer %!s(int64=3) %!d(string=hai) anos
pai
achega
00bc89381e

+ 5 - 0
pkg/kubecost/allocation.go

@@ -8,6 +8,7 @@ import (
 
 	"github.com/opencost/opencost/pkg/log"
 	"github.com/opencost/opencost/pkg/util"
+	"github.com/opencost/opencost/pkg/util/timeutil"
 )
 
 // TODO Clean-up use of IsEmpty; nil checks should be separated for safety.
@@ -2253,6 +2254,10 @@ func (asr *AllocationSetRange) accumulateByMonth() (*AllocationSetRange, error)
 }
 
 func (asr *AllocationSetRange) accumulateByWeek() (*AllocationSetRange, error) {
+	if len(asr.Allocations) > 0 && asr.Allocations[0].Window.Duration() == timeutil.Week {
+		return asr, nil
+	}
+
 	var toAccumulate *AllocationSetRange
 	result := NewAllocationSetRange()
 	for i, as := range asr.Allocations {

+ 5 - 0
pkg/kubecost/asset.go

@@ -9,6 +9,7 @@ import (
 
 	"github.com/opencost/opencost/pkg/log"
 	"github.com/opencost/opencost/pkg/util/json"
+	"github.com/opencost/opencost/pkg/util/timeutil"
 )
 
 // UndefinedKey is used in composing Asset group keys if the group does not have that property defined.
@@ -3376,6 +3377,10 @@ func (asr *AssetSetRange) accumulateByMonth() (*AssetSetRange, error) {
 }
 
 func (asr *AssetSetRange) accumulateByWeek() (*AssetSetRange, error) {
+	if len(asr.Assets) > 0 && asr.Assets[0].Window.Duration() == timeutil.Week {
+		return asr, nil
+	}
+
 	var toAccumulate *AssetSetRange
 	result := NewAssetSetRange()
 	for i, as := range asr.Assets {

+ 5 - 0
pkg/kubecost/summaryallocation.go

@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/opencost/opencost/pkg/log"
+	"github.com/opencost/opencost/pkg/util/timeutil"
 )
 
 // SummaryAllocation summarizes an Allocation, keeping only fields necessary
@@ -1628,6 +1629,10 @@ func (sasr *SummaryAllocationSetRange) accumulateByMonth() (*SummaryAllocationSe
 }
 
 func (sasr *SummaryAllocationSetRange) accumulateByWeek() (*SummaryAllocationSetRange, error) {
+	if len(sasr.SummaryAllocationSets) > 0 && sasr.SummaryAllocationSets[0].Window.Duration() == timeutil.Week {
+		return sasr, nil
+	}
+
 	var toAccumulate *SummaryAllocationSetRange
 	result := NewSummaryAllocationSetRange()
 	for i, as := range sasr.SummaryAllocationSets {

+ 2 - 7
pkg/kubecost/window.go

@@ -22,8 +22,8 @@ const (
 )
 
 var (
-	durationRegex       = regexp.MustCompile(`^(\d+)(m|h|d)$`)
-	durationOffsetRegex = regexp.MustCompile(`^(\d+)(m|h|d) offset (\d+)(m|h|d)$`)
+	durationRegex       = regexp.MustCompile(`^(\d+)(m|h|d|w)$`)
+	durationOffsetRegex = regexp.MustCompile(`^(\d+)(m|h|d|w) offset (\d+)(m|h|d|w)$`)
 	offesetRegex        = regexp.MustCompile(`^(\+|-)(\d\d):(\d\d)$`)
 	rfc3339             = `\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ`
 	rfcRegex            = regexp.MustCompile(fmt.Sprintf(`(%s),(%s)`, rfc3339, rfc3339))
@@ -46,11 +46,6 @@ func RoundBack(t time.Time, resolution time.Duration) time.Time {
 // in the given time's timezone.
 // e.g. 2020-01-01T12:37:48-0700, 24h = 2020-01-02T00:00:00-0700
 func RoundForward(t time.Time, resolution time.Duration) time.Time {
-	// if the duration is a week - roll forward to the following Sunday
-	if resolution == timeutil.Week {
-		return timeutil.RoundToStartOfFollowingWeek(t)
-	}
-
 	back := RoundBack(t, resolution)
 	if back.Equal(t) {
 		// The given time is exactly a multiple of the given resolution

+ 13 - 0
pkg/kubecost/window_test.go

@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/google/go-cmp/cmp"
+
 	"github.com/opencost/opencost/pkg/util/timeutil"
 
 	"github.com/opencost/opencost/pkg/env"
@@ -177,6 +178,18 @@ func TestRoundForward(t *testing.T) {
 	if !tb.Equal(time.Date(2020, time.January, 5, 0, 0, 0, 0, time.UTC)) {
 		t.Fatalf("RoundForward: expected 2020-01-05T00:00:00Z; actual %s", tb)
 	}
+
+	to = time.Date(2020, time.January, 5, 23, 59, 0, 0, time.UTC)
+	tb = RoundForward(to, timeutil.Week)
+	if !tb.Equal(time.Date(2020, time.January, 12, 0, 0, 0, 0, time.UTC)) {
+		t.Fatalf("RoundForward: expected 2020-01-05T00:00:00Z; actual %s", tb)
+	}
+
+	to = time.Date(2020, time.January, 5, 0, 0, 0, 0, time.UTC)
+	tb = RoundForward(to, timeutil.Week)
+	if !tb.Equal(time.Date(2020, time.January, 5, 0, 0, 0, 0, time.UTC)) {
+		t.Fatalf("RoundForward: expected 2020-01-05T00:00:00Z; actual %s", tb)
+	}
 }
 
 func TestParseWindowUTC(t *testing.T) {

+ 6 - 5
pkg/util/timeutil/timeutil.go

@@ -112,7 +112,8 @@ var unitMap = map[string]int64{
 	"s":  int64(time.Second),
 	"m":  int64(time.Minute),
 	"h":  int64(time.Hour),
-	"d":  int64(time.Hour * 24),
+	"d":  int64(Day),
+	"w":  int64(Week),
 }
 
 // goParseDuration is time.ParseDuration lifted from the go std library and enhanced with the ability to
@@ -264,14 +265,14 @@ func FormatDurationStringDaysToHours(param string) (string, error) {
 	return param, nil
 }
 
-// RoundToStartOfWeek creates a new time.Time for the preceding Monday 00:00 UTC
+// RoundToStartOfWeek creates a new time.Time for the preceding Sunday 00:00 UTC
 func RoundToStartOfWeek(t time.Time) time.Time {
 	date := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC)
-	daysFromMonday := int(date.Weekday())
-	return date.Add(-1 * time.Duration(daysFromMonday) * Day)
+	daysFromSunday := int(date.Weekday())
+	return date.Add(-1 * time.Duration(daysFromSunday) * Day)
 }
 
-// RoundToStartOfFollowingWeek creates a new time.Time for the following Monday 00:00 UTC
+// RoundToStartOfFollowingWeek creates a new time.Time for the following Sunday 00:00 UTC
 func RoundToStartOfFollowingWeek(t time.Time) time.Time {
 	date := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC)
 	daysFromSunday := 7 - int(date.Weekday())

+ 29 - 0
pkg/util/timeutil/timeutil_test.go

@@ -1,6 +1,7 @@
 package timeutil
 
 import (
+	"fmt"
 	"testing"
 	"time"
 )
@@ -388,3 +389,31 @@ func Test_FormatDurationStringDaysToHours(t *testing.T) {
 		})
 	}
 }
+
+func TestRoundToStartOfWeek(t *testing.T) {
+	sunday := time.Date(2023, 03, 26, 12, 12, 12, 12, time.UTC)
+	roundedFromSunday := RoundToStartOfWeek(sunday)
+	if roundedFromSunday.Day() != 26 || roundedFromSunday.Weekday() == time.Sunday {
+		fmt.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromSunday.Day(), roundedFromSunday.Weekday().String())
+	}
+
+	tuesday := time.Date(2023, 03, 28, 12, 12, 12, 12, time.UTC)
+	roundedFromTuesday := RoundToStartOfWeek(tuesday)
+	if roundedFromTuesday.Day() != 26 || roundedFromTuesday.Weekday() == time.Sunday {
+		fmt.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromTuesday.Day(), roundedFromTuesday.Weekday().String())
+	}
+}
+
+func TestRoundToStartOfFollowingWeek(t *testing.T) {
+	sunday := time.Date(2023, 03, 26, 12, 12, 12, 12, time.UTC)
+	roundedFromSunday := RoundToStartOfFollowingWeek(sunday)
+	if roundedFromSunday.Month() != 4 || roundedFromSunday.Day() != 2 || roundedFromSunday.Weekday() == time.Sunday {
+		fmt.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromSunday.Day(), roundedFromSunday.Weekday().String())
+	}
+
+	tuesday := time.Date(2023, 03, 28, 12, 12, 12, 12, time.UTC)
+	roundedFromTuesday := RoundToStartOfFollowingWeek(tuesday)
+	if roundedFromTuesday.Month() != 4 || roundedFromTuesday.Day() != 2 || roundedFromTuesday.Weekday() == time.Sunday {
+		fmt.Errorf("expected date to be rounded to the same sunday, got: %d, %s", roundedFromTuesday.Day(), roundedFromTuesday.Weekday().String())
+	}
+}