Przeglądaj źródła

fix: Add resource hour tracking to idle allocations

When computing idle allocations, the code was calculating idle costs
(CPUCost, GPUCost, RAMCost) but not tracking the corresponding resource
hours (CPUCoreHours, GPUHours, RAMByteHours). This caused discrepancies
when comparing totals between Prometheus mode and promless mode in
integration tests.

Changes:
- Calculate idle resource hours as the difference between asset and
  allocation totals
- Clamp idle resource hours to zero (matching the existing idle cost
  clamping behavior)
- Include resource hours in the idle allocation struct

This ensures that when totals are computed, the resource hours are
properly accounted for in both regular allocations and idle allocations,
making comparisons between Prometheus and promless modes accurate.

Related to commit 9bf926c which added resource hour fields to totals.
Claude 5 miesięcy temu
rodzic
commit
69c5b75839
1 zmienionych plików z 30 dodań i 5 usunięć
  1. 30 5
      pkg/costmodel/costmodel.go

+ 30 - 5
pkg/costmodel/costmodel.go

@@ -2054,6 +2054,11 @@ func computeIdleAllocations(allocSet *opencost.AllocationSet, assetSet *opencost
 		gpuIdleCost := assetTotal.TotalGPUCost() - allocTotal.TotalGPUCost()
 		ramIdleCost := assetTotal.TotalRAMCost() - allocTotal.TotalRAMCost()
 
+		// Calculate idle resource hours
+		cpuIdleCoreHours := assetTotal.CPUCoreHours - allocTotal.CPUCoreHours
+		gpuIdleHours := assetTotal.GPUHours - allocTotal.GPUHours
+		ramIdleByteHours := assetTotal.RAMByteHours - allocTotal.RAMByteHours
+
 		// Clamp idle costs to zero to prevent negative idle allocations
 		if cpuIdleCost < 0 {
 			log.Warnf("Negative CPU idle cost detected for %s: asset total (%.4f) < allocation total (%.4f), clamping to 0",
@@ -2071,6 +2076,23 @@ func computeIdleAllocations(allocSet *opencost.AllocationSet, assetSet *opencost
 			ramIdleCost = 0
 		}
 
+		// Clamp idle resource hours to zero to prevent negative values
+		if cpuIdleCoreHours < 0 {
+			log.Warnf("Negative CPU idle core hours detected for %s: asset total (%.4f) < allocation total (%.4f), clamping to 0",
+				key, assetTotal.CPUCoreHours, allocTotal.CPUCoreHours)
+			cpuIdleCoreHours = 0
+		}
+		if gpuIdleHours < 0 {
+			log.Warnf("Negative GPU idle hours detected for %s: asset total (%.4f) < allocation total (%.4f), clamping to 0",
+				key, assetTotal.GPUHours, allocTotal.GPUHours)
+			gpuIdleHours = 0
+		}
+		if ramIdleByteHours < 0 {
+			log.Warnf("Negative RAM idle byte hours detected for %s: asset total (%.4f) < allocation total (%.4f), clamping to 0",
+				key, assetTotal.RAMByteHours, allocTotal.RAMByteHours)
+			ramIdleByteHours = 0
+		}
+
 		err := idleSet.Insert(&opencost.Allocation{
 			Name:   name,
 			Window: idleSet.Window.Clone(),
@@ -2079,11 +2101,14 @@ func computeIdleAllocations(allocSet *opencost.AllocationSet, assetSet *opencost
 				Node:       assetTotal.Node,
 				ProviderID: assetTotal.ProviderID,
 			},
-			Start:   assetTotal.Start,
-			End:     assetTotal.End,
-			CPUCost: cpuIdleCost,
-			GPUCost: gpuIdleCost,
-			RAMCost: ramIdleCost,
+			Start:        assetTotal.Start,
+			End:          assetTotal.End,
+			CPUCost:      cpuIdleCost,
+			GPUCost:      gpuIdleCost,
+			RAMCost:      ramIdleCost,
+			CPUCoreHours: cpuIdleCoreHours,
+			GPUHours:     gpuIdleHours,
+			RAMByteHours: ramIdleByteHours,
 		})
 		if err != nil {
 			return nil, fmt.Errorf("failed to insert idle allocation %s: %w", name, err)