Просмотр исходного кода

Merge pull request #1641 from avrodrigues5/avr/intersection-btw-cloudcostAggr

Interesection between CloudCost aggregate properties to preserve only the values that are equal
Sean Holcomb 3 лет назад
Родитель
Сommit
5ca8386138
2 измененных файлов с 133 добавлено и 4 удалено
  1. 30 0
      pkg/kubecost/cloudcostaggregate.go
  2. 103 4
      pkg/kubecost/cloudcostaggregate_test.go

+ 30 - 0
pkg/kubecost/cloudcostaggregate.go

@@ -35,6 +35,33 @@ func (ccap CloudCostAggregateProperties) Equal(that CloudCostAggregateProperties
 		ccap.LabelValue == that.LabelValue
 }
 
+// Intersection ensure the values of two CloudCostAggregateProperties are maintain only if they are equal
+func (ccap CloudCostAggregateProperties) Intersection(that CloudCostAggregateProperties) CloudCostAggregateProperties {
+	if ccap.Equal(that) {
+		return ccap
+	}
+	intersectionCCAP := CloudCostAggregateProperties{}
+	if ccap == intersectionCCAP || that == intersectionCCAP {
+		return intersectionCCAP
+	}
+
+	if ccap.Provider == that.Provider {
+		intersectionCCAP.Provider = ccap.Provider
+	}
+	if ccap.WorkGroupID == that.WorkGroupID {
+		intersectionCCAP.WorkGroupID = ccap.WorkGroupID
+	}
+	if ccap.BillingID == that.BillingID {
+		intersectionCCAP.BillingID = ccap.BillingID
+	}
+	if ccap.Service == that.Service {
+		intersectionCCAP.Service = ccap.Service
+	}
+	if ccap.LabelValue == that.LabelValue {
+		intersectionCCAP.LabelValue = ccap.LabelValue
+	}
+	return intersectionCCAP
+}
 func (ccap CloudCostAggregateProperties) Key(props []string) string {
 	if len(props) == 0 {
 		return fmt.Sprintf("%s/%s/%s/%s/%s", ccap.Provider, ccap.BillingID, ccap.WorkGroupID, ccap.Service, ccap.LabelValue)
@@ -145,6 +172,9 @@ func (cca *CloudCostAggregate) add(that *CloudCostAggregate) {
 		return
 	}
 
+	// Preserve string properties of cloud cost aggregates that are matching between the two CloudCostAggregate
+	cca.Properties = cca.Properties.Intersection(that.Properties)
+
 	// Compute KubernetesPercent for sum
 	k8sPct := 0.0
 	sumCost := cca.Cost + that.Cost

+ 103 - 4
pkg/kubecost/cloudcostaggregate_test.go

@@ -1,9 +1,10 @@
 package kubecost
 
 import (
-	"github.com/opencost/opencost/pkg/util/timeutil"
 	"testing"
 	"time"
+
+	"github.com/opencost/opencost/pkg/util/timeutil"
 )
 
 var ccaProperties1 = CloudCostAggregateProperties{
@@ -14,6 +15,104 @@ var ccaProperties1 = CloudCostAggregateProperties{
 	LabelValue:  "labelValue1",
 }
 
+func TestCloudCostAggregatePropertiesIntersection(t *testing.T) {
+	testCases := map[string]struct {
+		baseCCAP     CloudCostAggregateProperties
+		intCCAP      CloudCostAggregateProperties
+		expectedCCAP CloudCostAggregateProperties
+	}{
+		"When properties match between both CloudCostAggregateProperties": {
+			baseCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID1",
+				BillingID:   "BillingID1",
+				Service:     "Service1",
+				LabelValue:  "Label1",
+			},
+			intCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID1",
+				BillingID:   "BillingID1",
+				Service:     "Service1",
+				LabelValue:  "Label1",
+			},
+			expectedCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID1",
+				BillingID:   "BillingID1",
+				Service:     "Service1",
+				LabelValue:  "Label1",
+			},
+		},
+		"When one of the properties differ in the two CloudCostAggregateProperties": {
+			baseCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID1",
+				BillingID:   "BillingID1",
+				Service:     "Service1",
+				LabelValue:  "Label1",
+			},
+			intCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID1",
+				BillingID:   "BillingID1",
+				Service:     "Service2",
+				LabelValue:  "Label1",
+			},
+			expectedCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID1",
+				BillingID:   "BillingID1",
+				Service:     "",
+				LabelValue:  "Label1",
+			},
+		},
+		"When two of the properties differ in the two CloudCostAggregateProperties": {
+			baseCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID1",
+				BillingID:   "BillingID1",
+				Service:     "Service1",
+				LabelValue:  "Label1",
+			},
+			intCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "WorkGroupID2",
+				BillingID:   "BillingID1",
+				Service:     "Service2",
+				LabelValue:  "Label1",
+			},
+			expectedCCAP: CloudCostAggregateProperties{
+				Provider:    "CustomProvider",
+				WorkGroupID: "",
+				BillingID:   "BillingID1",
+				Service:     "",
+				LabelValue:  "Label1",
+			},
+		},
+	}
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			actualCCAP := tc.baseCCAP.Intersection(tc.intCCAP)
+			if actualCCAP.Provider != tc.expectedCCAP.Provider {
+				t.Errorf("Case %s: Provider properties dont match with expected CloudCostAggregateProperties: %v actual %v", name, tc.expectedCCAP, actualCCAP)
+			}
+			if actualCCAP.WorkGroupID != tc.expectedCCAP.WorkGroupID {
+				t.Errorf("Case %s: WorkGroupID properties dont match with expected CloudCostAggregateProperties: %v actual %v", name, tc.expectedCCAP, actualCCAP)
+			}
+			if actualCCAP.BillingID != tc.expectedCCAP.BillingID {
+				t.Errorf("Case %s: BillingID properties dont match with expected CloudCostAggregateProperties: %v actual %v", name, tc.expectedCCAP, actualCCAP)
+			}
+			if actualCCAP.Service != tc.expectedCCAP.Service {
+				t.Errorf("Case %s: Service properties dont match with expected CloudCostAggregateProperties: %v actual %v", name, tc.expectedCCAP, actualCCAP)
+			}
+			if actualCCAP.LabelValue != tc.expectedCCAP.LabelValue {
+				t.Errorf("Case %s: LabelValue properties dont match with expected CloudCostAggregateProperties: %v actual %v", name, tc.expectedCCAP, actualCCAP)
+			}
+		})
+	}
+}
+
 // TestCloudCostAggregate_LoadCloudCostAggregate checks that loaded CloudCostAggregates end up in the correct set in the
 // correct proportions
 func TestCloudCostAggregate_LoadCloudCostAggregate(t *testing.T) {
@@ -240,9 +339,9 @@ func TestCloudCostAggregate_LoadCloudCostAggregate(t *testing.T) {
 					},
 				},
 				{
-					Integration: "integration",
-					LabelName:   "label",
-					Window:      dayWindows[2],
+					Integration:         "integration",
+					LabelName:           "label",
+					Window:              dayWindows[2],
 					CloudCostAggregates: map[string]*CloudCostAggregate{},
 				},
 			},