Przeglądaj źródła

Updated diff type to use generics rather than just Assets

nickcurie 3 lat temu
rodzic
commit
48bea41d46
2 zmienionych plików z 103 dodań i 23 usunięć
  1. 38 10
      pkg/kubecost/asset.go
  2. 65 13
      pkg/kubecost/diff_test.go

+ 38 - 10
pkg/kubecost/asset.go

@@ -2838,31 +2838,59 @@ func (as *AssetSet) accumulate(that *AssetSet) (*AssetSet, error) {
 	return acc, nil
 }
 
-type Diff struct {
-	Asset Asset
-	ChangedType string
+
+type DiffKind string
+
+const (
+    DiffAdded DiffKind = "added"
+    DiffRemoved = "removed"
+)
+
+type Diff[T any] struct {
+	Entity T
+	Kind DiffKind
 }
 
-func DiffAsset(before, after *AssetSet) []Diff{
-	changedAssets := []Diff{}
+func DiffAsset(before, after *AssetSet) []Diff[Asset]{
+	changedItems := []Diff[Asset]{}
 
 	for assetKey1, asset1 := range before.assets {
 		if _, ok := after.assets[assetKey1]; !ok {
-			d := Diff{asset1, "removed"}
-			changedAssets = append(changedAssets, d)
+			d := Diff[Asset]{asset1, DiffRemoved}
+			changedItems = append(changedItems, d)
 		}
 	}
 	
 	for assetKey2, asset2 := range after.assets {
 		if _, ok := before.assets[assetKey2]; !ok {
-			d := Diff{asset2, "added"}
-			changedAssets = append(changedAssets, d)
+			d := Diff[Asset]{asset2, DiffAdded}
+			changedItems = append(changedItems, d)
 		}
 	}
 
-	return changedAssets
+	return changedItems
 }
 
+// func DiffAllocation(before, after *AllocationSet) []Diff[Allocation]{
+// 	changedItems := []Diff[Allocation]{}
+
+// 	for allocationKey1, allocation1 := range before.allocations {
+// 		if _, ok := after.allocations[allocationKey1]; !ok {
+// 			d := Diff[Allocation]{allocation1, removedState}
+// 			changedItems = append(changedItems, d)
+// 		}
+// 	}
+	
+// 	for allocationKey2, allocation2 := range after.allocations {
+// 		if _, ok := before.allocations[allocationKey2]; !ok {
+// 			d := Diff[Allocation]{allocation2, addedState}
+// 			changedItems = append(changedItems, d)
+// 		}
+// 	}
+
+// 	return changedItems
+// }
+
 // AssetSetRange is a thread-safe slice of AssetSets. It is meant to
 // be used such that the AssetSets held are consecutive and coherent with
 // respect to using the same aggregation properties, UTC offset, and

+ 65 - 13
pkg/kubecost/diff_test.go

@@ -1,6 +1,7 @@
 package kubecost
 
 import (
+	"sort"
 	"testing"
 	"time"
 
@@ -23,19 +24,63 @@ func TestDiff(t *testing.T) {
 	cases := map[string]struct {
 		inputAssetsBefore []Asset
 		inputAssetsAfter  []Asset
-		expected          []Diff
+		expected          []Diff[Asset]
 	}{
-		"added node":       {inputAssetsBefore: []Asset{node1, node2}, inputAssetsAfter: []Asset{node1, node2, node3}, expected: []Diff{{node3, "added"}}},
-		"multiple adds":    {inputAssetsBefore: []Asset{node1, node2}, inputAssetsAfter: []Asset{node1, node2, node3, node4}, expected: []Diff{{node3, "added"}, {node4, "added"}}},
-		"removed node":     {inputAssetsBefore: []Asset{node1, node2}, inputAssetsAfter: []Asset{node2}, expected: []Diff{{node1, "removed"}}},
-		"multiple removes": {inputAssetsBefore: []Asset{node1, node2, node3}, inputAssetsAfter: []Asset{node2}, expected: []Diff{{node1, "removed"}, {node3, "removed"}}},
-		"remove all":       {inputAssetsBefore: []Asset{node1, node2}, inputAssetsAfter: []Asset{}, expected: []Diff{{node1, "removed"}, {node2, "removed"}}},
-		"add and remove":   {inputAssetsBefore: []Asset{node1, node2}, inputAssetsAfter: []Asset{node2, node3}, expected: []Diff{{node1, "removed"}, {node3, "added"}}},
-		"no change":        {inputAssetsBefore: []Asset{node1, node2}, inputAssetsAfter: []Asset{node1, node2}, expected: []Diff{}},
-		"order switch":     {inputAssetsBefore: []Asset{node2, node1}, inputAssetsAfter: []Asset{node1, node2}, expected: []Diff{}},
-		"disk add":         {inputAssetsBefore: []Asset{disk1, node1}, inputAssetsAfter: []Asset{disk1, node1, disk2}, expected: []Diff{{disk2, "added"}}},
-		"disk and node add": {inputAssetsBefore: []Asset{disk1, node1}, inputAssetsAfter: []Asset{disk1, node1, disk2, node2}, expected: []Diff{{disk2, "added"}, {node2, "added"}}},
-		"disk and node removed": {inputAssetsBefore: []Asset{disk1, node1, disk2, node2}, inputAssetsAfter: []Asset{disk2, node2}, expected: []Diff{{disk1, "removed"}, {node1, "removed"}}},
+		"added node":            {
+			inputAssetsBefore: []Asset{node1, node2}, 
+			inputAssetsAfter:  []Asset{node1, node2, node3}, 
+			expected:          []Diff[Asset]{{node3, DiffAdded}},
+		},
+		"multiple adds":         {
+			inputAssetsBefore: []Asset{node1, node2}, 
+			inputAssetsAfter:  []Asset{node1, node2, node3, node4}, 
+			expected:          []Diff[Asset]{{node3, DiffAdded}, {node4, DiffAdded}},
+		},
+		"removed node":          {
+			inputAssetsBefore: []Asset{node1, node2}, 
+			inputAssetsAfter:  []Asset{node2}, 
+			expected:          []Diff[Asset]{{node1, DiffRemoved}},
+		},
+		"multiple removes":      {
+			inputAssetsBefore: []Asset{node1, node2, node3}, 
+			inputAssetsAfter:  []Asset{node2}, 
+			expected:          []Diff[Asset]{{node1, DiffRemoved}, {node3, DiffRemoved}},
+		},
+		"remove all":            {
+			inputAssetsBefore: []Asset{node1, node2}, 
+			inputAssetsAfter:  []Asset{}, 
+			expected:          []Diff[Asset]{{node1, DiffRemoved}, {node2, DiffRemoved}},
+		},
+		"add and remove":        {
+			inputAssetsBefore: []Asset{node1, node2}, 
+			inputAssetsAfter:  []Asset{node2, node3}, 
+			expected:          []Diff[Asset]{{node1, DiffRemoved}, {node3, DiffAdded}},
+		},
+		"no change":             {
+			inputAssetsBefore: []Asset{node1, node2}, 
+			inputAssetsAfter:  []Asset{node1, node2}, 
+			expected:          []Diff[Asset]{},
+		},
+		"order switch":          {
+			inputAssetsBefore: []Asset{node2, node1}, 
+			inputAssetsAfter:  []Asset{node1, node2}, 
+			expected:          []Diff[Asset]{},
+		},
+		"disk add":              {
+			inputAssetsBefore: []Asset{disk1, node1}, 
+			inputAssetsAfter:  []Asset{disk1, node1, disk2}, 
+			expected:          []Diff[Asset]{{disk2, DiffAdded}},
+		},
+		"disk and node add":     {
+			inputAssetsBefore: []Asset{disk1, node1}, 
+			inputAssetsAfter:  []Asset{disk1, node1, disk2, node2}, 
+			expected:          []Diff[Asset]{{disk2, DiffAdded}, {node2, DiffAdded}},
+		},
+		"disk and node removed": {
+			inputAssetsBefore: []Asset{disk1, node1, disk2, node2}, 
+			inputAssetsAfter:  []Asset{disk2, node2}, 
+			expected:          []Diff[Asset]{{disk1, DiffRemoved}, {node1, DiffRemoved}},
+		},
 	}
 
 	for name, tc := range cases {
@@ -45,7 +90,14 @@ func TestDiff(t *testing.T) {
 
 			result := DiffAsset(as1.Clone(), as2.Clone())
 
-			diff := cmp.Diff(tc.expected, result) 
+			trans := cmp.Transformer("Sort", func(in []Diff[Asset]) []Diff[Asset] {
+				out := append([]Diff[Asset](nil), in...) // Copy input to avoid mutating it
+				sort.Slice(out, func(i, j int) bool {
+					return out[i].Kind < out[j].Kind
+				})
+				return out
+			})
+			diff := cmp.Diff(tc.expected, result, trans) 
 
 			if diff != "" {
 				t.Fatalf(diff)