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

Merge pull request #1361 from opencost/sean/pv-alloc-recon-fix

Fix PV alloc recon, alloc PV marshalling
Sean Holcomb 3 лет назад
Родитель
Сommit
37ef5198bc

+ 2 - 1
pkg/costmodel/allocation.go

@@ -689,7 +689,7 @@ func (cm *CostModel) computeAllocation(start, end time.Time, resolution time.Dur
 						alloc.PVs = kubecost.PVAllocations{}
 					}
 					pvKey := kubecost.PVKey{
-						Cluster: pvc.Cluster,
+						Cluster: pvc.Volume.Cluster,
 						Name:    pvc.Volume.Name,
 					}
 					alloc.PVs[pvKey] = &kubecost.PVAllocation{
@@ -2282,6 +2282,7 @@ func buildPVCMap(window kubecost.Window, pvcMap map[pvcKey]*PVC, pvMap map[pvKey
 
 		pvcMap[pvcKey].Name = name
 		pvcMap[pvcKey].Namespace = namespace
+		pvcMap[pvcKey].Cluster = cluster
 		pvcMap[pvcKey].Volume = pvMap[pvKey]
 		pvcMap[pvcKey].Start = pvcStart
 		pvcMap[pvcKey].End = pvcEnd

+ 21 - 77
pkg/kubecost/allocation.go

@@ -1,7 +1,6 @@
 package kubecost
 
 import (
-	"bytes"
 	"fmt"
 	"sort"
 	"strings"
@@ -10,7 +9,6 @@ import (
 
 	"github.com/opencost/opencost/pkg/log"
 	"github.com/opencost/opencost/pkg/util"
-	"github.com/opencost/opencost/pkg/util/json"
 )
 
 // TODO Clean-up use of IsEmpty; nil checks should be separated for safety.
@@ -69,7 +67,7 @@ type Allocation struct {
 	NetworkCostAdjustment      float64               `json:"networkCostAdjustment"`
 	LoadBalancerCost           float64               `json:"loadBalancerCost"`
 	LoadBalancerCostAdjustment float64               `json:"loadBalancerCostAdjustment"`
-	PVs                        PVAllocations         `json:"-"`
+	PVs                        PVAllocations         `json:"pvs"`
 	PVCostAdjustment           float64               `json:"pvCostAdjustment"`
 	RAMByteHours               float64               `json:"ramByteHours"`
 	RAMBytesRequestAverage     float64               `json:"ramByteRequestAverage"`
@@ -116,13 +114,12 @@ type RawAllocationOnlyData struct {
 type PVAllocations map[PVKey]*PVAllocation
 
 // Clone creates a deep copy of a PVAllocations
-func (pv *PVAllocations) Clone() PVAllocations {
-	if pv == nil || *pv == nil {
+func (pv PVAllocations) Clone() PVAllocations {
+	if pv == nil {
 		return nil
 	}
-	apv := *pv
-	clonePV := make(map[PVKey]*PVAllocation, len(apv))
-	for k, v := range apv {
+	clonePV := make(map[PVKey]*PVAllocation, len(pv))
+	for k, v := range pv {
 		clonePV[k] = &PVAllocation{
 			ByteHours: v.ByteHours,
 			Cost:      v.Cost,
@@ -132,7 +129,7 @@ func (pv *PVAllocations) Clone() PVAllocations {
 }
 
 // Add adds contents of that to the calling PVAllocations
-func (pv *PVAllocations) Add(that PVAllocations) PVAllocations {
+func (pv PVAllocations) Add(that PVAllocations) PVAllocations {
 	apv := pv.Clone()
 	if that != nil {
 		if apv == nil {
@@ -157,6 +154,21 @@ type PVKey struct {
 	Name    string `json:"name"`
 }
 
+func (pvk *PVKey) String() string {
+	return fmt.Sprintf("cluster=%s:name=%s", pvk.Cluster, pvk.Name)
+}
+
+// FromString populates PVKey fields from string
+func (pvk *PVKey) FromString(key string) error {
+	splitKey := strings.Split(key, ":")
+	if len(splitKey) != 2 {
+		return fmt.Errorf("PVKey string '%s' has the incorrect format", key)
+	}
+	pvk.Cluster = strings.TrimPrefix(splitKey[0], "cluster=")
+	pvk.Name = strings.TrimPrefix(splitKey[1], "name=")
+	return nil
+}
+
 // PVAllocation contains the byte hour usage
 // and cost of an Allocation for a single PV
 type PVAllocation struct {
@@ -552,53 +564,6 @@ func (a *Allocation) ResetAdjustments() {
 	a.LoadBalancerCostAdjustment = 0.0
 }
 
-// MarshalJSON implements json.Marshaler interface
-func (a *Allocation) MarshalJSON() ([]byte, error) {
-	buffer := bytes.NewBufferString("{")
-	jsonEncodeString(buffer, "name", a.Name, ",")
-	jsonEncode(buffer, "properties", a.Properties, ",")
-	jsonEncode(buffer, "window", a.Window, ",")
-	jsonEncodeString(buffer, "start", a.Start.Format(time.RFC3339), ",")
-	jsonEncodeString(buffer, "end", a.End.Format(time.RFC3339), ",")
-	jsonEncodeFloat64(buffer, "minutes", a.Minutes(), ",")
-	jsonEncodeFloat64(buffer, "cpuCores", a.CPUCores(), ",")
-	jsonEncodeFloat64(buffer, "cpuCoreRequestAverage", a.CPUCoreRequestAverage, ",")
-	jsonEncodeFloat64(buffer, "cpuCoreUsageAverage", a.CPUCoreUsageAverage, ",")
-	jsonEncodeFloat64(buffer, "cpuCoreHours", a.CPUCoreHours, ",")
-	jsonEncodeFloat64(buffer, "cpuCost", a.CPUCost, ",")
-	jsonEncodeFloat64(buffer, "cpuCostAdjustment", a.CPUCostAdjustment, ",")
-	jsonEncodeFloat64(buffer, "cpuEfficiency", a.CPUEfficiency(), ",")
-	jsonEncodeFloat64(buffer, "gpuCount", a.GPUs(), ",")
-	jsonEncodeFloat64(buffer, "gpuHours", a.GPUHours, ",")
-	jsonEncodeFloat64(buffer, "gpuCost", a.GPUCost, ",")
-	jsonEncodeFloat64(buffer, "gpuCostAdjustment", a.GPUCostAdjustment, ",")
-	jsonEncodeFloat64(buffer, "networkTransferBytes", a.NetworkTransferBytes, ",")
-	jsonEncodeFloat64(buffer, "networkReceiveBytes", a.NetworkReceiveBytes, ",")
-	jsonEncodeFloat64(buffer, "networkCost", a.NetworkCost, ",")
-	jsonEncodeFloat64(buffer, "networkCostAdjustment", a.NetworkCostAdjustment, ",")
-	jsonEncodeFloat64(buffer, "loadBalancerCost", a.LoadBalancerCost, ",")
-	jsonEncodeFloat64(buffer, "loadBalancerCostAdjustment", a.LoadBalancerCostAdjustment, ",")
-	jsonEncodeFloat64(buffer, "pvBytes", a.PVBytes(), ",")
-	jsonEncodeFloat64(buffer, "pvByteHours", a.PVByteHours(), ",")
-	jsonEncodeFloat64(buffer, "pvCost", a.PVCost(), ",")
-	jsonEncode(buffer, "pvs", a.PVs, ",") // Todo Sean: this does not work properly
-	jsonEncodeFloat64(buffer, "pvCostAdjustment", a.PVCostAdjustment, ",")
-	jsonEncodeFloat64(buffer, "ramBytes", a.RAMBytes(), ",")
-	jsonEncodeFloat64(buffer, "ramByteRequestAverage", a.RAMBytesRequestAverage, ",")
-	jsonEncodeFloat64(buffer, "ramByteUsageAverage", a.RAMBytesUsageAverage, ",")
-	jsonEncodeFloat64(buffer, "ramByteHours", a.RAMByteHours, ",")
-	jsonEncodeFloat64(buffer, "ramCost", a.RAMCost, ",")
-	jsonEncodeFloat64(buffer, "ramCostAdjustment", a.RAMCostAdjustment, ",")
-	jsonEncodeFloat64(buffer, "ramEfficiency", a.RAMEfficiency(), ",")
-	jsonEncodeFloat64(buffer, "sharedCost", a.SharedCost, ",")
-	jsonEncodeFloat64(buffer, "externalCost", a.ExternalCost, ",")
-	jsonEncodeFloat64(buffer, "totalCost", a.TotalCost(), ",")
-	jsonEncodeFloat64(buffer, "totalEfficiency", a.TotalEfficiency(), ",")
-	jsonEncode(buffer, "rawAllocationOnly", a.RawAllocationOnly, "")
-	buffer.WriteString("}")
-	return buffer.Bytes(), nil
-}
-
 // Resolution returns the duration of time covered by the Allocation
 func (a *Allocation) Resolution() time.Duration {
 	return a.End.Sub(a.Start)
@@ -1882,16 +1847,6 @@ func (as *AllocationSet) Map() map[string]*Allocation {
 	return as.Clone().allocations
 }
 
-// MarshalJSON JSON-encodes the AllocationSet
-func (as *AllocationSet) MarshalJSON() ([]byte, error) {
-	if as == nil {
-		return json.Marshal(map[string]*Allocation{})
-	}
-	as.RLock()
-	defer as.RUnlock()
-	return json.Marshal(as.allocations)
-}
-
 // ResetAdjustments sets all cost adjustment fields to zero
 func (as *AllocationSet) ResetAdjustments() {
 	if as == nil {
@@ -2220,17 +2175,6 @@ func (asr *AllocationSetRange) Length() int {
 	return len(asr.allocations)
 }
 
-// MarshalJSON JSON-encodes the range
-func (asr *AllocationSetRange) MarshalJSON() ([]byte, error) {
-	if asr == nil {
-		return json.Marshal([]*AllocationSet{})
-	}
-
-	asr.RLock()
-	defer asr.RUnlock()
-	return json.Marshal(asr.allocations)
-}
-
 // Slice copies the underlying slice of AllocationSets, maintaining order,
 // and returns the copied slice.
 func (asr *AllocationSetRange) Slice() []*AllocationSet {

+ 114 - 0
pkg/kubecost/allocation_json.go

@@ -0,0 +1,114 @@
+package kubecost
+
+import (
+	"bytes"
+	"encoding/json"
+	"time"
+)
+
+// MarshalJSON implements json.Marshaler interface
+func (a *Allocation) MarshalJSON() ([]byte, error) {
+	buffer := bytes.NewBufferString("{")
+	jsonEncodeString(buffer, "name", a.Name, ",")
+	jsonEncode(buffer, "properties", a.Properties, ",")
+	jsonEncode(buffer, "window", a.Window, ",")
+	jsonEncodeString(buffer, "start", a.Start.Format(time.RFC3339), ",")
+	jsonEncodeString(buffer, "end", a.End.Format(time.RFC3339), ",")
+	jsonEncodeFloat64(buffer, "minutes", a.Minutes(), ",")
+	jsonEncodeFloat64(buffer, "cpuCores", a.CPUCores(), ",")
+	jsonEncodeFloat64(buffer, "cpuCoreRequestAverage", a.CPUCoreRequestAverage, ",")
+	jsonEncodeFloat64(buffer, "cpuCoreUsageAverage", a.CPUCoreUsageAverage, ",")
+	jsonEncodeFloat64(buffer, "cpuCoreHours", a.CPUCoreHours, ",")
+	jsonEncodeFloat64(buffer, "cpuCost", a.CPUCost, ",")
+	jsonEncodeFloat64(buffer, "cpuCostAdjustment", a.CPUCostAdjustment, ",")
+	jsonEncodeFloat64(buffer, "cpuEfficiency", a.CPUEfficiency(), ",")
+	jsonEncodeFloat64(buffer, "gpuCount", a.GPUs(), ",")
+	jsonEncodeFloat64(buffer, "gpuHours", a.GPUHours, ",")
+	jsonEncodeFloat64(buffer, "gpuCost", a.GPUCost, ",")
+	jsonEncodeFloat64(buffer, "gpuCostAdjustment", a.GPUCostAdjustment, ",")
+	jsonEncodeFloat64(buffer, "networkTransferBytes", a.NetworkTransferBytes, ",")
+	jsonEncodeFloat64(buffer, "networkReceiveBytes", a.NetworkReceiveBytes, ",")
+	jsonEncodeFloat64(buffer, "networkCost", a.NetworkCost, ",")
+	jsonEncodeFloat64(buffer, "networkCostAdjustment", a.NetworkCostAdjustment, ",")
+	jsonEncodeFloat64(buffer, "loadBalancerCost", a.LoadBalancerCost, ",")
+	jsonEncodeFloat64(buffer, "loadBalancerCostAdjustment", a.LoadBalancerCostAdjustment, ",")
+	jsonEncodeFloat64(buffer, "pvBytes", a.PVBytes(), ",")
+	jsonEncodeFloat64(buffer, "pvByteHours", a.PVByteHours(), ",")
+	jsonEncodeFloat64(buffer, "pvCost", a.PVCost(), ",")
+	jsonEncode(buffer, "pvs", a.PVs, ",")
+	jsonEncodeFloat64(buffer, "pvCostAdjustment", a.PVCostAdjustment, ",")
+	jsonEncodeFloat64(buffer, "ramBytes", a.RAMBytes(), ",")
+	jsonEncodeFloat64(buffer, "ramByteRequestAverage", a.RAMBytesRequestAverage, ",")
+	jsonEncodeFloat64(buffer, "ramByteUsageAverage", a.RAMBytesUsageAverage, ",")
+	jsonEncodeFloat64(buffer, "ramByteHours", a.RAMByteHours, ",")
+	jsonEncodeFloat64(buffer, "ramCost", a.RAMCost, ",")
+	jsonEncodeFloat64(buffer, "ramCostAdjustment", a.RAMCostAdjustment, ",")
+	jsonEncodeFloat64(buffer, "ramEfficiency", a.RAMEfficiency(), ",")
+	jsonEncodeFloat64(buffer, "sharedCost", a.SharedCost, ",")
+	jsonEncodeFloat64(buffer, "externalCost", a.ExternalCost, ",")
+	jsonEncodeFloat64(buffer, "totalCost", a.TotalCost(), ",")
+	jsonEncodeFloat64(buffer, "totalEfficiency", a.TotalEfficiency(), ",")
+	jsonEncode(buffer, "rawAllocationOnly", a.RawAllocationOnly, "")
+	buffer.WriteString("}")
+	return buffer.Bytes(), nil
+}
+
+// UnmarshalJSON prevent nil pointer on PVAllocations
+func (a *Allocation) UnmarshalJSON(b []byte) error {
+	// initialize PV to prevent nil panic
+	a.PVs = PVAllocations{}
+	// Aliasing Allocation and casting to alias gives access to the default unmarshaller
+	type alloc Allocation
+	err := json.Unmarshal(b, (*alloc)(a))
+	if err != nil {
+		return err
+	}
+	// clear PVs if they are empty, it is not initialized when empty
+	if len(a.PVs) == 0 {
+		a.PVs = nil
+	}
+	return nil
+}
+
+// MarshalJSON marshals PVAllocation as map[*PVKey]*PVAllocation this allows PVKey to retain its values through marshalling
+func (pv PVAllocations) MarshalJSON() (b []byte, err error) {
+	pointerMap := make(map[*PVKey]*PVAllocation)
+	for pvKey, pvAlloc := range pv {
+		kp := pvKey
+		pointerMap[&kp] = pvAlloc
+	}
+	return json.Marshal(pointerMap)
+}
+
+// MarshalText converts PVKey to string to make it compatible with JSON Marshaller as an Object key
+// this function is required to have a value caller for the actual values to be saved
+func (pvk PVKey) MarshalText() (text []byte, err error) {
+	return []byte(pvk.String()), nil
+}
+
+// UnmarshalText converts JSON key string to PVKey it compatible with JSON Unmarshaller from an Object key
+// this function is required to have a pointer caller for values to be pulled into marshalling struct
+func (pvk *PVKey) UnmarshalText(text []byte) error {
+	return pvk.FromString(string(text))
+}
+
+// MarshalJSON JSON-encodes the AllocationSet
+func (as *AllocationSet) MarshalJSON() ([]byte, error) {
+	if as == nil {
+		return json.Marshal(map[string]*Allocation{})
+	}
+	as.RLock()
+	defer as.RUnlock()
+	return json.Marshal(as.allocations)
+}
+
+// MarshalJSON JSON-encodes the range
+func (asr *AllocationSetRange) MarshalJSON() ([]byte, error) {
+	if asr == nil {
+		return json.Marshal([]*AllocationSet{})
+	}
+
+	asr.RLock()
+	defer asr.RUnlock()
+	return json.Marshal(asr.allocations)
+}

+ 154 - 0
pkg/kubecost/allocation_json_test.go

@@ -0,0 +1,154 @@
+package kubecost
+
+import (
+	"encoding/json"
+	"testing"
+	"time"
+)
+
+func TestAllocation_MarshalJSON(t *testing.T) {
+	start := time.Date(2021, time.January, 1, 0, 0, 0, 0, time.UTC)
+	end := time.Date(2021, time.January, 2, 0, 0, 0, 0, time.UTC)
+	hrs := 24.0
+
+	gib := 1024.0 * 1024.0 * 1024.0
+
+	cpuPrice := 0.02
+	gpuPrice := 2.00
+	ramPrice := 0.01
+	pvPrice := 0.00005
+
+	before := &Allocation{
+		Name: "cluster1/namespace1/node1/pod1/container1",
+		Properties: &AllocationProperties{
+			Cluster:   "cluster1",
+			Node:      "node1",
+			Namespace: "namespace1",
+			Pod:       "pod1",
+			Container: "container1",
+		},
+		Window:                NewWindow(&start, &end),
+		Start:                 start,
+		End:                   end,
+		CPUCoreHours:          2.0 * hrs,
+		CPUCoreRequestAverage: 2.0,
+		CPUCoreUsageAverage:   1.0,
+		CPUCost:               2.0 * hrs * cpuPrice,
+		CPUCostAdjustment:     3.0,
+		GPUHours:              1.0 * hrs,
+		GPUCost:               1.0 * hrs * gpuPrice,
+		GPUCostAdjustment:     2.0,
+		NetworkCost:           0.05,
+		LoadBalancerCost:      0.02,
+		PVs: PVAllocations{
+			disk: {
+				ByteHours: 100.0 * gib * hrs,
+				Cost:      100.0 * hrs * pvPrice,
+			},
+		},
+		PVCostAdjustment:       4.0,
+		RAMByteHours:           8.0 * gib * hrs,
+		RAMBytesRequestAverage: 8.0 * gib,
+		RAMBytesUsageAverage:   4.0 * gib,
+		RAMCost:                8.0 * hrs * ramPrice,
+		RAMCostAdjustment:      1.0,
+		SharedCost:             2.00,
+		ExternalCost:           1.00,
+		RawAllocationOnly:      &RawAllocationOnlyData{},
+	}
+
+	data, err := json.Marshal(before)
+	if err != nil {
+		t.Fatalf("Allocation.MarshalJSON: unexpected error: %s", err)
+	}
+
+	after := &Allocation{}
+	err = json.Unmarshal(data, after)
+	if err != nil {
+		t.Fatalf("Allocation.UnmarshalJSON: unexpected error: %s", err)
+	}
+
+	// TODO:CLEANUP fix json marshaling of Window so that all of this works.
+	// In the meantime, just set the Window so that we can test the rest.
+	after.Window = before.Window.Clone()
+	if !after.Equal(before) {
+		t.Fatalf("Allocation.MarshalJSON: before and after are not equal")
+	}
+}
+
+func TestPVAllocations_MarshalJSON(t *testing.T) {
+	testCases := map[string]PVAllocations{
+		"empty": {},
+		"single": {
+			{
+				Cluster: "cluster1",
+				Name:    "pv1",
+			}: {
+				ByteHours: 100,
+				Cost:      1,
+			},
+		},
+		"multi": {
+			{
+				Cluster: "cluster1",
+				Name:    "pv1",
+			}: {
+				ByteHours: 100,
+				Cost:      1,
+			},
+			{
+				Cluster: "cluster1",
+				Name:    "pv2",
+			}: {
+				ByteHours: 200,
+				Cost:      2,
+			},
+		},
+		"emptyPV": {
+			{
+				Cluster: "cluster1",
+				Name:    "pv1",
+			}: {},
+		},
+		"emptyKey": {
+			{}: {
+				ByteHours: 100,
+				Cost:      1,
+			},
+		},
+	}
+	for name, before := range testCases {
+		t.Run(name, func(t *testing.T) {
+			data, err := json.Marshal(before)
+			if err != nil {
+				t.Fatalf("PVAllocations.MarshalJSON: unexpected error: %s", err)
+			}
+
+			after := PVAllocations{}
+			err = json.Unmarshal(data, &after)
+			if err != nil {
+				t.Fatalf("PVAllocations.UnmarshalJSON: unexpected error: %s", err)
+			}
+
+			if len(before) != len(after) {
+				t.Fatalf("PVAllocations.MarshalJSON: before and after are not equal")
+			}
+
+			for pvKey, beforePV := range before {
+				afterPV, ok := after[pvKey]
+				if !ok {
+					t.Fatalf("PVAllocations.MarshalJSON: after missing PVKey %s", pvKey)
+				}
+				if beforePV.Cost != afterPV.Cost {
+					t.Fatalf("PVAllocations.MarshalJSON: PVAllocation Cost not equal for PVKey %s", pvKey)
+				}
+
+				if beforePV.ByteHours != afterPV.ByteHours {
+					t.Fatalf("PVAllocations.MarshalJSON: PVAllocation ByteHours not equal for PVKey %s", pvKey)
+				}
+			}
+
+		})
+	}
+
+}

+ 0 - 72
pkg/kubecost/allocation_test.go

@@ -379,78 +379,6 @@ func TestAllocation_AddDifferentController(t *testing.T) {
 
 }
 
-func TestAllocation_MarshalJSON(t *testing.T) {
-	start := time.Date(2021, time.January, 1, 0, 0, 0, 0, time.UTC)
-	end := time.Date(2021, time.January, 2, 0, 0, 0, 0, time.UTC)
-	hrs := 24.0
-
-	gib := 1024.0 * 1024.0 * 1024.0
-
-	cpuPrice := 0.02
-	gpuPrice := 2.00
-	ramPrice := 0.01
-	pvPrice := 0.00005
-
-	before := &Allocation{
-		Name: "cluster1/namespace1/node1/pod1/container1",
-		Properties: &AllocationProperties{
-			Cluster:   "cluster1",
-			Node:      "node1",
-			Namespace: "namespace1",
-			Pod:       "pod1",
-			Container: "container1",
-		},
-		Window:                NewWindow(&start, &end),
-		Start:                 start,
-		End:                   end,
-		CPUCoreHours:          2.0 * hrs,
-		CPUCoreRequestAverage: 2.0,
-		CPUCoreUsageAverage:   1.0,
-		CPUCost:               2.0 * hrs * cpuPrice,
-		CPUCostAdjustment:     3.0,
-		GPUHours:              1.0 * hrs,
-		GPUCost:               1.0 * hrs * gpuPrice,
-		GPUCostAdjustment:     2.0,
-		NetworkCost:           0.05,
-		LoadBalancerCost:      0.02,
-		PVs: PVAllocations{
-			disk: {
-				ByteHours: 100.0 * gib * hrs,
-				Cost:      100.0 * hrs * pvPrice,
-			},
-		},
-		PVCostAdjustment:       4.0,
-		RAMByteHours:           8.0 * gib * hrs,
-		RAMBytesRequestAverage: 8.0 * gib,
-		RAMBytesUsageAverage:   4.0 * gib,
-		RAMCost:                8.0 * hrs * ramPrice,
-		RAMCostAdjustment:      1.0,
-		SharedCost:             2.00,
-		ExternalCost:           1.00,
-		RawAllocationOnly:      &RawAllocationOnlyData{},
-	}
-
-	data, err := json.Marshal(before)
-	if err != nil {
-		t.Fatalf("Allocation.MarshalJSON: unexpected error: %s", err)
-	}
-
-	after := &Allocation{}
-	err = json.Unmarshal(data, after)
-	if err != nil {
-		t.Fatalf("Allocation.UnmarshalJSON: unexpected error: %s", err)
-	}
-
-	// TODO:CLEANUP fix json marshaling of Window so that all of this works.
-	// In the meantime, just set the Window so that we can test the rest.
-	after.Window = before.Window.Clone()
-	// TODO Sean: fix JSON marshaling of PVs
-	after.PVs = before.PVs
-	if !after.Equal(before) {
-		t.Fatalf("Allocation.MarshalJSON: before and after are not equal")
-	}
-}
-
 func TestAllocationSet_generateKey(t *testing.T) {
 	var alloc *Allocation
 	var key string

+ 1 - 1
pkg/kubecost/asset.go

@@ -3243,7 +3243,7 @@ func (asr *AssetSetRange) TotalCost() float64 {
 
 // This is a helper type. The Asset API returns a json which cannot be natively
 // unmarshaled into any Asset struct. Therefore, this struct IN COMBINATION WITH
-// DESERIALIZATION LOGIC DEFINED IN asset_unmarshal.go can unmarshal a json directly
+// DESERIALIZATION LOGIC DEFINED IN asset_json.go can unmarshal a json directly
 // from an Assets API query
 type AssetAPIResponse struct {
 	Code int                   `json:"code"`

+ 0 - 0
pkg/kubecost/asset_unmarshal.go → pkg/kubecost/asset_json.go


+ 0 - 0
pkg/kubecost/asset_unmarshal_test.go → pkg/kubecost/asset_json_test.go


+ 4 - 1
pkg/kubecost/mock.go

@@ -8,7 +8,10 @@ import (
 const gb = 1024 * 1024 * 1024
 const day = 24 * time.Hour
 
-var disk = PVKey{}
+var disk = PVKey{
+	Cluster: "cluster1",
+	Name:    "pv1",
+}
 
 // NewMockUnitAllocation creates an *Allocation with all of its float64 values set to 1 and generic properties if not provided in arg
 func NewMockUnitAllocation(name string, start time.Time, resolution time.Duration, props *AllocationProperties) *Allocation {