|
|
@@ -33,21 +33,25 @@ func NewUnitAllocation(name string, start time.Time, resolution time.Duration, p
|
|
|
end := start.Add(resolution)
|
|
|
|
|
|
alloc := &Allocation{
|
|
|
- Name: name,
|
|
|
- Properties: properties,
|
|
|
- Window: NewWindow(&start, &end).Clone(),
|
|
|
- Start: start,
|
|
|
- End: end,
|
|
|
- CPUCoreHours: 1,
|
|
|
- CPUCost: 1,
|
|
|
- CPUCoreRequestAverage: 1,
|
|
|
- CPUCoreUsageAverage: 1,
|
|
|
- GPUHours: 1,
|
|
|
- GPUCost: 1,
|
|
|
- NetworkCost: 1,
|
|
|
- LoadBalancerCost: 1,
|
|
|
- PVByteHours: 1,
|
|
|
- PVCost: 1,
|
|
|
+ Name: name,
|
|
|
+ Properties: properties,
|
|
|
+ Window: NewWindow(&start, &end).Clone(),
|
|
|
+ Start: start,
|
|
|
+ End: end,
|
|
|
+ CPUCoreHours: 1,
|
|
|
+ CPUCost: 1,
|
|
|
+ CPUCoreRequestAverage: 1,
|
|
|
+ CPUCoreUsageAverage: 1,
|
|
|
+ GPUHours: 1,
|
|
|
+ GPUCost: 1,
|
|
|
+ NetworkCost: 1,
|
|
|
+ LoadBalancerCost: 1,
|
|
|
+ PVBreakdown: map[string]PVUsage{
|
|
|
+ "disk": {
|
|
|
+ ByteHours: 1,
|
|
|
+ Cost: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
RAMByteHours: 1,
|
|
|
RAMCost: 1,
|
|
|
RAMBytesRequestAverage: 1,
|
|
|
@@ -60,8 +64,7 @@ func NewUnitAllocation(name string, start time.Time, resolution time.Duration, p
|
|
|
|
|
|
// If idle allocation, remove non-idle costs, but maintain total cost
|
|
|
if alloc.IsIdle() {
|
|
|
- alloc.PVByteHours = 0.0
|
|
|
- alloc.PVCost = 0.0
|
|
|
+ alloc.PVBreakdown = nil
|
|
|
alloc.NetworkCost = 0.0
|
|
|
alloc.LoadBalancerCost = 0.0
|
|
|
alloc.CPUCoreHours += 1.0
|
|
|
@@ -105,19 +108,23 @@ func TestAllocation_Add(t *testing.T) {
|
|
|
e1 := time.Date(2021, time.January, 1, 12, 0, 0, 0, time.UTC)
|
|
|
hrs1 := e1.Sub(s1).Hours()
|
|
|
a1 := &Allocation{
|
|
|
- Start: s1,
|
|
|
- End: e1,
|
|
|
- Properties: &AllocationProperties{},
|
|
|
- CPUCoreHours: 2.0 * hrs1,
|
|
|
- CPUCoreRequestAverage: 2.0,
|
|
|
- CPUCoreUsageAverage: 1.0,
|
|
|
- CPUCost: 2.0 * hrs1 * cpuPrice,
|
|
|
- CPUCostAdjustment: 3.0,
|
|
|
- GPUHours: 1.0 * hrs1,
|
|
|
- GPUCost: 1.0 * hrs1 * gpuPrice,
|
|
|
- GPUCostAdjustment: 2.0,
|
|
|
- PVByteHours: 100.0 * gib * hrs1,
|
|
|
- PVCost: 100.0 * hrs1 * pvPrice,
|
|
|
+ Start: s1,
|
|
|
+ End: e1,
|
|
|
+ Properties: &AllocationProperties{},
|
|
|
+ CPUCoreHours: 2.0 * hrs1,
|
|
|
+ CPUCoreRequestAverage: 2.0,
|
|
|
+ CPUCoreUsageAverage: 1.0,
|
|
|
+ CPUCost: 2.0 * hrs1 * cpuPrice,
|
|
|
+ CPUCostAdjustment: 3.0,
|
|
|
+ GPUHours: 1.0 * hrs1,
|
|
|
+ GPUCost: 1.0 * hrs1 * gpuPrice,
|
|
|
+ GPUCostAdjustment: 2.0,
|
|
|
+ PVBreakdown: map[string]PVUsage{
|
|
|
+ "disk1": {
|
|
|
+ ByteHours: 100.0 * gib * hrs1,
|
|
|
+ Cost: 100.0 * hrs1 * pvPrice,
|
|
|
+ },
|
|
|
+ },
|
|
|
PVCostAdjustment: 4.0,
|
|
|
RAMByteHours: 8.0 * gib * hrs1,
|
|
|
RAMBytesRequestAverage: 8.0 * gib,
|
|
|
@@ -143,8 +150,6 @@ func TestAllocation_Add(t *testing.T) {
|
|
|
CPUCost: 1.0 * hrs2 * cpuPrice,
|
|
|
GPUHours: 0.0,
|
|
|
GPUCost: 0.0,
|
|
|
- PVByteHours: 0,
|
|
|
- PVCost: 0,
|
|
|
RAMByteHours: 8.0 * gib * hrs2,
|
|
|
RAMBytesRequestAverage: 0.0,
|
|
|
RAMBytesUsageAverage: 8.0 * gib,
|
|
|
@@ -192,8 +197,8 @@ func TestAllocation_Add(t *testing.T) {
|
|
|
if !util.IsApproximately(a1.RAMCostAdjustment+a2.RAMCostAdjustment, act.RAMCostAdjustment) {
|
|
|
t.Fatalf("Allocation.Add: expected %f; actual %f", a1.RAMCostAdjustment+a2.RAMCostAdjustment, act.RAMCostAdjustment)
|
|
|
}
|
|
|
- if !util.IsApproximately(a1.PVCost+a2.PVCost, act.PVCost) {
|
|
|
- t.Fatalf("Allocation.Add: expected %f; actual %f", a1.PVCost+a2.PVCost, act.PVCost)
|
|
|
+ if !util.IsApproximately(a1.PVCost()+a2.PVCost(), act.PVCost()) {
|
|
|
+ t.Fatalf("Allocation.Add: expected %f; actual %f", a1.PVCost()+a2.PVCost(), act.PVCost())
|
|
|
}
|
|
|
if !util.IsApproximately(a1.NetworkCost+a2.NetworkCost, act.NetworkCost) {
|
|
|
t.Fatalf("Allocation.Add: expected %f; actual %f", a1.NetworkCost+a2.NetworkCost, act.NetworkCost)
|
|
|
@@ -215,8 +220,8 @@ func TestAllocation_Add(t *testing.T) {
|
|
|
if !util.IsApproximately(a1.RAMByteHours+a2.RAMByteHours, act.RAMByteHours) {
|
|
|
t.Fatalf("Allocation.Add: expected %f; actual %f", a1.RAMByteHours+a2.RAMByteHours, act.RAMByteHours)
|
|
|
}
|
|
|
- if !util.IsApproximately(a1.PVByteHours+a2.PVByteHours, act.PVByteHours) {
|
|
|
- t.Fatalf("Allocation.Add: expected %f; actual %f", a1.PVByteHours+a2.PVByteHours, act.PVByteHours)
|
|
|
+ if !util.IsApproximately(a1.PVByteHours()+a2.PVByteHours(), act.PVByteHours()) {
|
|
|
+ t.Fatalf("Allocation.Add: expected %f; actual %f", a1.PVByteHours()+a2.PVByteHours(), act.PVByteHours())
|
|
|
}
|
|
|
|
|
|
// Minutes should be the duration between min(starts) and max(ends)
|
|
|
@@ -275,19 +280,23 @@ func TestAllocation_Share(t *testing.T) {
|
|
|
e1 := time.Date(2021, time.January, 1, 12, 0, 0, 0, time.UTC)
|
|
|
hrs1 := e1.Sub(s1).Hours()
|
|
|
a1 := &Allocation{
|
|
|
- Start: s1,
|
|
|
- End: e1,
|
|
|
- Properties: &AllocationProperties{},
|
|
|
- CPUCoreHours: 2.0 * hrs1,
|
|
|
- CPUCoreRequestAverage: 2.0,
|
|
|
- CPUCoreUsageAverage: 1.0,
|
|
|
- CPUCost: 2.0 * hrs1 * cpuPrice,
|
|
|
- CPUCostAdjustment: 3.0,
|
|
|
- GPUHours: 1.0 * hrs1,
|
|
|
- GPUCost: 1.0 * hrs1 * gpuPrice,
|
|
|
- GPUCostAdjustment: 2.0,
|
|
|
- PVByteHours: 100.0 * gib * hrs1,
|
|
|
- PVCost: 100.0 * hrs1 * pvPrice,
|
|
|
+ Start: s1,
|
|
|
+ End: e1,
|
|
|
+ Properties: &AllocationProperties{},
|
|
|
+ CPUCoreHours: 2.0 * hrs1,
|
|
|
+ CPUCoreRequestAverage: 2.0,
|
|
|
+ CPUCoreUsageAverage: 1.0,
|
|
|
+ CPUCost: 2.0 * hrs1 * cpuPrice,
|
|
|
+ CPUCostAdjustment: 3.0,
|
|
|
+ GPUHours: 1.0 * hrs1,
|
|
|
+ GPUCost: 1.0 * hrs1 * gpuPrice,
|
|
|
+ GPUCostAdjustment: 2.0,
|
|
|
+ PVBreakdown: map[string]PVUsage{
|
|
|
+ "disk1": {
|
|
|
+ ByteHours: 100.0 * gib * hrs1,
|
|
|
+ Cost: 100.0 * hrs1 * pvPrice,
|
|
|
+ },
|
|
|
+ },
|
|
|
PVCostAdjustment: 4.0,
|
|
|
RAMByteHours: 8.0 * gib * hrs1,
|
|
|
RAMBytesRequestAverage: 8.0 * gib,
|
|
|
@@ -312,8 +321,6 @@ func TestAllocation_Share(t *testing.T) {
|
|
|
CPUCost: 1.0 * hrs2 * cpuPrice,
|
|
|
GPUHours: 0.0,
|
|
|
GPUCost: 0.0,
|
|
|
- PVByteHours: 0,
|
|
|
- PVCost: 0,
|
|
|
RAMByteHours: 8.0 * gib * hrs2,
|
|
|
RAMBytesRequestAverage: 0.0,
|
|
|
RAMBytesUsageAverage: 8.0 * gib,
|
|
|
@@ -376,8 +383,8 @@ func TestAllocation_Share(t *testing.T) {
|
|
|
if !util.IsApproximately(a1.RAMByteHours, act.RAMByteHours) {
|
|
|
t.Fatalf("Allocation.Share: expected %f; actual %f", a1.RAMByteHours, act.RAMByteHours)
|
|
|
}
|
|
|
- if !util.IsApproximately(a1.PVByteHours, act.PVByteHours) {
|
|
|
- t.Fatalf("Allocation.Share: expected %f; actual %f", a1.PVByteHours, act.PVByteHours)
|
|
|
+ if !util.IsApproximately(a1.PVByteHours(), act.PVByteHours()) {
|
|
|
+ t.Fatalf("Allocation.Share: expected %f; actual %f", a1.PVByteHours(), act.PVByteHours())
|
|
|
}
|
|
|
|
|
|
// Minutes should match before
|
|
|
@@ -435,21 +442,25 @@ func TestAllocation_MarshalJSON(t *testing.T) {
|
|
|
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,
|
|
|
- PVByteHours: 100.0 * gib * hrs,
|
|
|
- PVCost: 100.0 * hrs * pvPrice,
|
|
|
+ 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,
|
|
|
+ PVBreakdown: map[string]PVUsage{
|
|
|
+ "disk1": {
|
|
|
+ ByteHours: 100.0 * gib * hrs,
|
|
|
+ Cost: 100.0 * hrs * pvPrice,
|
|
|
+ },
|
|
|
+ },
|
|
|
PVCostAdjustment: 4.0,
|
|
|
RAMByteHours: 8.0 * gib * hrs,
|
|
|
RAMBytesRequestAverage: 8.0 * gib,
|
|
|
@@ -696,14 +707,9 @@ func generateAllocationSet(start time.Time) *AllocationSet {
|
|
|
a23vwx9.Properties.Annotations = map[string]string{"team": "team1"}
|
|
|
|
|
|
// Services
|
|
|
-
|
|
|
a12jkl6.Properties.Services = []string{"service1"}
|
|
|
a22pqr6.Properties.Services = []string{"service1"}
|
|
|
|
|
|
- // PV BreakDown
|
|
|
- a22mno4.Properties.PVBreakdown = map[string]PVUsage{"disk1": {Cost: 2.5, ByteHours: 2.5 * gb}, "disk2": {Cost: 5, ByteHours: 5 * gb}}
|
|
|
- a22mno5.Properties.PVBreakdown = map[string]PVUsage{"disk1": {Cost: 2.5, ByteHours: 2.5 * gb}, "disk2": {Cost: 5, ByteHours: 5 * gb}}
|
|
|
-
|
|
|
return NewAllocationSet(start, start.Add(day),
|
|
|
// idle
|
|
|
a1i, a2i,
|
|
|
@@ -959,7 +965,7 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
// container8: an[team=team2] 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// container9: an[team=team1] 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// +----------------------------------------+------+------+------+------+------+------+------+
|
|
|
- // cluster2 subtotal 46.00 11.00 11.00 6.00 6.00 6.00 6.00
|
|
|
+ // cluster2 subtotal 46.00 11.00 11.00 6.00 6.00 6.00 6.00
|
|
|
// +----------------------------------------+------+------+------+------+------+------+------+
|
|
|
// total 112.00 22.00 42.00 12.00 12.00 12.00 12.00
|
|
|
// +----------------------------------------+------+------+------+------+------+------+------+
|
|
|
@@ -1772,6 +1778,12 @@ func TestAllocationSet_ReconcileAllocations(t *testing.T) {
|
|
|
for key := range as.idleKeys {
|
|
|
as.Delete(key)
|
|
|
}
|
|
|
+ // add reconcilable pvs to pod-mno
|
|
|
+ for _, a := range as.allocations {
|
|
|
+ if a.Properties.Pod == "pod-mno" {
|
|
|
+ a.AddPVBreakDown(map[string]PVUsage{"disk1": {Cost: 2.5, ByteHours: 2.5 * gb}, "disk2": {Cost: 5, ByteHours: 5 * gb}})
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
assetSets := generateAssetSets(start, end)
|
|
|
|
|
|
@@ -2161,11 +2173,11 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
|
|
|
if alloc.LoadBalancerCost != 2.0 {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.LoadBalancerCost)
|
|
|
}
|
|
|
- if alloc.PVByteHours != 2.0 {
|
|
|
- t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.PVByteHours)
|
|
|
+ if alloc.PVByteHours() != 2.0 {
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.PVByteHours())
|
|
|
}
|
|
|
- if alloc.PVCost != 2.0 {
|
|
|
- t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.PVCost)
|
|
|
+ if alloc.PVCost() != 2.0 {
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.PVCost())
|
|
|
}
|
|
|
if alloc.RAMByteHours != 2.0 {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.RAMByteHours)
|
|
|
@@ -2269,11 +2281,11 @@ func TestAllocationSetRange_InsertRange(t *testing.T) {
|
|
|
if !util.IsApproximately(a.GPUCost, unit.GPUCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.GPUCost, a.GPUCost)
|
|
|
}
|
|
|
- if !util.IsApproximately(a.PVByteHours, unit.PVByteHours) {
|
|
|
- t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVByteHours, a.PVByteHours)
|
|
|
+ if !util.IsApproximately(a.PVByteHours(), unit.PVByteHours()) {
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVByteHours(), a.PVByteHours())
|
|
|
}
|
|
|
- if !util.IsApproximately(a.PVCost, unit.PVCost) {
|
|
|
- t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVCost, a.PVCost)
|
|
|
+ if !util.IsApproximately(a.PVCost(), unit.PVCost()) {
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVCost(), a.PVCost())
|
|
|
}
|
|
|
if !util.IsApproximately(a.NetworkCost, unit.NetworkCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
|
@@ -2320,11 +2332,11 @@ func TestAllocationSetRange_InsertRange(t *testing.T) {
|
|
|
if !util.IsApproximately(a.GPUCost, 2*unit.GPUCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.GPUCost, a.GPUCost)
|
|
|
}
|
|
|
- if !util.IsApproximately(a.PVByteHours, 2*unit.PVByteHours) {
|
|
|
- t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVByteHours, a.PVByteHours)
|
|
|
+ if !util.IsApproximately(a.PVByteHours(), 2*unit.PVByteHours()) {
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVByteHours(), a.PVByteHours())
|
|
|
}
|
|
|
- if !util.IsApproximately(a.PVCost, 2*unit.PVCost) {
|
|
|
- t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVCost, a.PVCost)
|
|
|
+ if !util.IsApproximately(a.PVCost(), 2*unit.PVCost()) {
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVCost(), a.PVCost())
|
|
|
}
|
|
|
if !util.IsApproximately(a.NetworkCost, 2*unit.NetworkCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
|
@@ -2357,11 +2369,11 @@ func TestAllocationSetRange_InsertRange(t *testing.T) {
|
|
|
if !util.IsApproximately(a.GPUCost, unit.GPUCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.GPUCost, a.GPUCost)
|
|
|
}
|
|
|
- if !util.IsApproximately(a.PVByteHours, unit.PVByteHours) {
|
|
|
- t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVByteHours, a.PVByteHours)
|
|
|
+ if !util.IsApproximately(a.PVByteHours(), unit.PVByteHours()) {
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVByteHours(), a.PVByteHours())
|
|
|
}
|
|
|
- if !util.IsApproximately(a.PVCost, unit.PVCost) {
|
|
|
- t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVCost, a.PVCost)
|
|
|
+ if !util.IsApproximately(a.PVCost(), unit.PVCost()) {
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.PVCost(), a.PVCost())
|
|
|
}
|
|
|
if !util.IsApproximately(a.NetworkCost, unit.NetworkCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|