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

added cost change ratio

Signed-off-by: nickcurie <ncurie@kubecost.com>
nickcurie 3 лет назад
Родитель
Сommit
46d0d04325
2 измененных файлов с 26 добавлено и 6 удалено
  1. 9 4
      pkg/kubecost/asset.go
  2. 17 2
      pkg/kubecost/diff_test.go

+ 9 - 4
pkg/kubecost/asset.go

@@ -3,6 +3,7 @@ package kubecost
 import (
 	"encoding"
 	"fmt"
+	"math"
 	"strings"
 	"sync"
 	"time"
@@ -856,8 +857,8 @@ type ClusterManagement struct {
 	labels     AssetLabels
 	properties *AssetProperties
 	window     Window
-	adjustment float64
 	Cost       float64
+	adjustment float64 // @bingen:field[version=16]
 }
 
 // NewClusterManagement creates and returns a new ClusterManagement instance
@@ -2906,14 +2907,18 @@ type Diff[T any] struct {
 // DiffAsset takes two AssetSets and returns a map of keys to Diffs by checking
 // the keys of each AssetSet. If a key is not found or is found with a different total cost,
 // a Diff is generated and added to the map.
-func DiffAsset(before, after *AssetSet) map[string]Diff[Asset] {
+func DiffAsset(before, after *AssetSet, ratioCostChange float64) (map[string]Diff[Asset], error) {
+	if ratioCostChange < 0.0 {
+		return nil, fmt.Errorf("Percent cost change cannot be less than 0")
+	}
+
 	changedItems := map[string]Diff[Asset]{}
 
 	for assetKey1, asset1 := range before.assets {
 		if asset2, ok := after.assets[assetKey1]; !ok {
 			d := Diff[Asset]{asset1, DiffRemoved}
 			changedItems[assetKey1] = d
-		} else if asset1.TotalCost() != asset2.TotalCost() {
+		} else if math.Abs(asset1.TotalCost()-asset2.TotalCost()) > ratioCostChange*asset1.TotalCost() { //check if either value exceeds the other by more than pctCostChange
 			d := Diff[Asset]{asset1, DiffChanged}
 			changedItems[assetKey1] = d
 		}
@@ -2926,7 +2931,7 @@ func DiffAsset(before, after *AssetSet) map[string]Diff[Asset] {
 		}
 	}
 
-	return changedItems
+	return changedItems, nil
 }
 
 // AssetSetRange is a thread-safe slice of AssetSets. It is meant to

+ 17 - 2
pkg/kubecost/diff_test.go

@@ -18,6 +18,9 @@ func TestDiff(t *testing.T) {
 	node1b.CPUCost = 20
 	node1Key, _ := key(node1, nil)
 	node2 := NewNode("node2", "cluster1", "123abc", start, end, window1)
+	node2.CPUCost = 100
+	node2b := node2.Clone().(*Node)
+	node2b.CPUCost = 105
 	node2Key, _ := key(node2, nil)
 	node3 := NewNode("node3", "cluster1", "123abc", start, end, window1)
 	node3Key, _ := key(node3, nil)
@@ -31,6 +34,7 @@ func TestDiff(t *testing.T) {
 	cases := map[string]struct {
 		inputAssetsBefore []Asset
 		inputAssetsAfter  []Asset
+		costChangeRatio   float64
 		expected          map[string]Diff[Asset]
 	}{
 		"added node": {
@@ -88,11 +92,18 @@ func TestDiff(t *testing.T) {
 			inputAssetsAfter:  []Asset{disk2, node2},
 			expected:          map[string]Diff[Asset]{disk1Key: {disk1, DiffRemoved}, node1Key: {node1, DiffRemoved}},
 		},
-		"cost change": {
+		"cost change more than 10%": {
 			inputAssetsBefore: []Asset{node1},
 			inputAssetsAfter:  []Asset{node1b},
+			costChangeRatio:   0.1,
 			expected:          map[string]Diff[Asset]{node1Key: {node1, DiffChanged}},
 		},
+		"cost change less than 10%": {
+			inputAssetsBefore: []Asset{node2},
+			inputAssetsAfter:  []Asset{node2b},
+			costChangeRatio:   0.1,
+			expected:          map[string]Diff[Asset]{},
+		},
 	}
 
 	for name, tc := range cases {
@@ -101,7 +112,11 @@ func TestDiff(t *testing.T) {
 
 			as2 := NewAssetSet(start, end, tc.inputAssetsAfter...)
 
-			result := DiffAsset(as1.Clone(), as2.Clone())
+			result, err := DiffAsset(as1.Clone(), as2.Clone(), tc.costChangeRatio)
+
+			if err != nil {
+				t.Fatalf("error; got %s", err)
+			}
 
 			if !reflect.DeepEqual(result, tc.expected) {
 				t.Fatalf("expected %+v; got %+v", tc.expected, result)