|
@@ -45,6 +45,7 @@ func NewUnitAllocation(name string, start time.Time, resolution time.Duration, p
|
|
|
GPUHours: 1,
|
|
GPUHours: 1,
|
|
|
GPUCost: 1,
|
|
GPUCost: 1,
|
|
|
NetworkCost: 1,
|
|
NetworkCost: 1,
|
|
|
|
|
+ LoadBalancerCost: 1,
|
|
|
PVByteHours: 1,
|
|
PVByteHours: 1,
|
|
|
PVCost: 1,
|
|
PVCost: 1,
|
|
|
RAMByteHours: 1,
|
|
RAMByteHours: 1,
|
|
@@ -58,7 +59,7 @@ func NewUnitAllocation(name string, start time.Time, resolution time.Duration, p
|
|
|
alloc.PVByteHours = 0.0
|
|
alloc.PVByteHours = 0.0
|
|
|
alloc.PVCost = 0.0
|
|
alloc.PVCost = 0.0
|
|
|
alloc.NetworkCost = 0.0
|
|
alloc.NetworkCost = 0.0
|
|
|
-
|
|
|
|
|
|
|
+ alloc.LoadBalancerCost = 0.0
|
|
|
alloc.CPUCoreHours += 1.0
|
|
alloc.CPUCoreHours += 1.0
|
|
|
alloc.CPUCost += 1.0
|
|
alloc.CPUCost += 1.0
|
|
|
alloc.RAMByteHours += 1.0
|
|
alloc.RAMByteHours += 1.0
|
|
@@ -138,6 +139,7 @@ func TestAllocation_Add(t *testing.T) {
|
|
|
RAMBytesUsageAverage: 8.0 * gib,
|
|
RAMBytesUsageAverage: 8.0 * gib,
|
|
|
RAMCost: 8.0 * hrs2 * ramPrice,
|
|
RAMCost: 8.0 * hrs2 * ramPrice,
|
|
|
NetworkCost: 0.01,
|
|
NetworkCost: 0.01,
|
|
|
|
|
+ LoadBalancerCost: 0.05,
|
|
|
SharedCost: 0.00,
|
|
SharedCost: 0.00,
|
|
|
ExternalCost: 1.00,
|
|
ExternalCost: 1.00,
|
|
|
}
|
|
}
|
|
@@ -175,6 +177,9 @@ func TestAllocation_Add(t *testing.T) {
|
|
|
if !util.IsApproximately(a1.NetworkCost+a2.NetworkCost, act.NetworkCost) {
|
|
if !util.IsApproximately(a1.NetworkCost+a2.NetworkCost, act.NetworkCost) {
|
|
|
t.Fatalf("Allocation.Add: expected %f; actual %f", a1.NetworkCost+a2.NetworkCost, act.NetworkCost)
|
|
t.Fatalf("Allocation.Add: expected %f; actual %f", a1.NetworkCost+a2.NetworkCost, act.NetworkCost)
|
|
|
}
|
|
}
|
|
|
|
|
+ if !util.IsApproximately(a1.LoadBalancerCost+a2.LoadBalancerCost, act.LoadBalancerCost) {
|
|
|
|
|
+ t.Fatalf("Allocation.Add: expected %f; actual %f", a1.LoadBalancerCost+a2.LoadBalancerCost, act.LoadBalancerCost)
|
|
|
|
|
+ }
|
|
|
if !util.IsApproximately(a1.SharedCost+a2.SharedCost, act.SharedCost) {
|
|
if !util.IsApproximately(a1.SharedCost+a2.SharedCost, act.SharedCost) {
|
|
|
t.Fatalf("Allocation.Add: expected %f; actual %f", a1.SharedCost+a2.SharedCost, act.SharedCost)
|
|
t.Fatalf("Allocation.Add: expected %f; actual %f", a1.SharedCost+a2.SharedCost, act.SharedCost)
|
|
|
}
|
|
}
|
|
@@ -283,6 +288,7 @@ func TestAllocation_Share(t *testing.T) {
|
|
|
RAMBytesUsageAverage: 8.0 * gib,
|
|
RAMBytesUsageAverage: 8.0 * gib,
|
|
|
RAMCost: 8.0 * hrs2 * ramPrice,
|
|
RAMCost: 8.0 * hrs2 * ramPrice,
|
|
|
NetworkCost: 0.01,
|
|
NetworkCost: 0.01,
|
|
|
|
|
+ LoadBalancerCost: 0.05,
|
|
|
SharedCost: 0.00,
|
|
SharedCost: 0.00,
|
|
|
ExternalCost: 1.00,
|
|
ExternalCost: 1.00,
|
|
|
}
|
|
}
|
|
@@ -325,6 +331,9 @@ func TestAllocation_Share(t *testing.T) {
|
|
|
if !util.IsApproximately(a1.NetworkCost, act.NetworkCost) {
|
|
if !util.IsApproximately(a1.NetworkCost, act.NetworkCost) {
|
|
|
t.Fatalf("Allocation.Share: expected %f; actual %f", a1.NetworkCost, act.NetworkCost)
|
|
t.Fatalf("Allocation.Share: expected %f; actual %f", a1.NetworkCost, act.NetworkCost)
|
|
|
}
|
|
}
|
|
|
|
|
+ if !util.IsApproximately(a1.LoadBalancerCost, act.LoadBalancerCost) {
|
|
|
|
|
+ t.Fatalf("Allocation.Share: expected %f; actual %f", a1.LoadBalancerCost, act.LoadBalancerCost)
|
|
|
|
|
+ }
|
|
|
if !util.IsApproximately(a1.ExternalCost, act.ExternalCost) {
|
|
if !util.IsApproximately(a1.ExternalCost, act.ExternalCost) {
|
|
|
t.Fatalf("Allocation.Share: expected %f; actual %f", a1.ExternalCost, act.ExternalCost)
|
|
t.Fatalf("Allocation.Share: expected %f; actual %f", a1.ExternalCost, act.ExternalCost)
|
|
|
}
|
|
}
|
|
@@ -405,6 +414,7 @@ func TestAllocation_MarshalJSON(t *testing.T) {
|
|
|
GPUHours: 1.0 * hrs,
|
|
GPUHours: 1.0 * hrs,
|
|
|
GPUCost: 1.0 * hrs * gpuPrice,
|
|
GPUCost: 1.0 * hrs * gpuPrice,
|
|
|
NetworkCost: 0.05,
|
|
NetworkCost: 0.05,
|
|
|
|
|
+ LoadBalancerCost: 0.02,
|
|
|
PVByteHours: 100.0 * gib * hrs,
|
|
PVByteHours: 100.0 * gib * hrs,
|
|
|
PVCost: 100.0 * hrs * pvPrice,
|
|
PVCost: 100.0 * hrs * pvPrice,
|
|
|
RAMByteHours: 8.0 * gib * hrs,
|
|
RAMByteHours: 8.0 * gib * hrs,
|
|
@@ -667,7 +677,7 @@ func assertAllocationTotals(t *testing.T, as *AllocationSet, msg string, exps ma
|
|
|
as.Each(func(k string, a *Allocation) {
|
|
as.Each(func(k string, a *Allocation) {
|
|
|
if exp, ok := exps[a.Name]; ok {
|
|
if exp, ok := exps[a.Name]; ok {
|
|
|
if math.Round(a.TotalCost()*100) != math.Round(exp*100) {
|
|
if math.Round(a.TotalCost()*100) != math.Round(exp*100) {
|
|
|
- t.Fatalf("AllocationSet.AggregateBy[%s]: expected total cost %.2f, actual %.2f", msg, exp, a.TotalCost())
|
|
|
|
|
|
|
+ t.Fatalf("AllocationSet.AggregateBy[%s]: expected total cost %f, actual %f", msg, exp, a.TotalCost())
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
t.Fatalf("AllocationSet.AggregateBy[%s]: unexpected allocation: %s", msg, a.Name)
|
|
t.Fatalf("AllocationSet.AggregateBy[%s]: unexpected allocation: %s", msg, a.Name)
|
|
@@ -700,45 +710,45 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
// Test AggregateBy against the following workload topology, which is
|
|
// Test AggregateBy against the following workload topology, which is
|
|
|
// generated by generateAllocationSet:
|
|
// generated by generateAllocationSet:
|
|
|
|
|
|
|
|
- // | Hierarchy | Cost | CPU | RAM | GPU | PV | Net |
|
|
|
|
|
- // +----------------------------------------+------+------+------+------+------+------+
|
|
|
|
|
|
|
+ // | Hierarchy | Cost | CPU | RAM | GPU | PV | Net | LB |
|
|
|
|
|
+ // +----------------------------------------+------+------+------+------+------+------+------+
|
|
|
// cluster1:
|
|
// cluster1:
|
|
|
- // idle: 20.00 5.00 15.00 0.00 0.00 0.00
|
|
|
|
|
|
|
+ // idle: 20.00 5.00 15.00 0.00 0.00 0.00 0.00
|
|
|
// namespace1:
|
|
// namespace1:
|
|
|
// pod1:
|
|
// pod1:
|
|
|
- // container1: [app=app1, env=env1] 15.00 1.00 11.00 1.00 1.00 1.00
|
|
|
|
|
|
|
+ // container1: [app=app1, env=env1] 16.00 1.00 11.00 1.00 1.00 1.00 1.00
|
|
|
// pod-abc: (deployment1)
|
|
// pod-abc: (deployment1)
|
|
|
- // container2: 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
|
|
+ // container2: 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// pod-def: (deployment1)
|
|
// pod-def: (deployment1)
|
|
|
- // container3: 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
|
|
+ // container3: 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// namespace2:
|
|
// namespace2:
|
|
|
// pod-ghi: (deployment2)
|
|
// pod-ghi: (deployment2)
|
|
|
- // container4: [app=app2, env=env2] 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
- // container5: [app=app2, env=env2] 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
|
|
+ // container4: [app=app2, env=env2] 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
+ // container5: [app=app2, env=env2] 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// pod-jkl: (daemonset1)
|
|
// pod-jkl: (daemonset1)
|
|
|
- // container6: {service1} 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
- // +-----------------------------------------+------+------+------+------+------+------+
|
|
|
|
|
- // cluster1 subtotal 60.00 11.00 31.00 6.00 6.00 6.00
|
|
|
|
|
- // +-----------------------------------------+------+------+------+------+------+------+
|
|
|
|
|
|
|
+ // container6: {service1} 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
+ // +-----------------------------------------+------+------+------+------+------+------+------+
|
|
|
|
|
+ // cluster1 subtotal 66.00 11.00 31.00 6.00 6.00 6.00 6.00
|
|
|
|
|
+ // +-----------------------------------------+------+------+------+------+------+------+------+
|
|
|
// cluster2:
|
|
// cluster2:
|
|
|
- // idle: 10.00 5.00 5.00 0.00 0.00 0.00
|
|
|
|
|
|
|
+ // idle: 10.00 5.00 5.00 0.00 0.00 0.00 0.00
|
|
|
// namespace2:
|
|
// namespace2:
|
|
|
// pod-mno: (deployment2)
|
|
// pod-mno: (deployment2)
|
|
|
- // container4: [app=app2] 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
- // container5: [app=app2] 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
|
|
+ // container4: [app=app2] 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
+ // container5: [app=app2] 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// pod-pqr: (daemonset1)
|
|
// pod-pqr: (daemonset1)
|
|
|
- // container6: {service1} 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
|
|
+ // container6: {service1} 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// namespace3:
|
|
// namespace3:
|
|
|
// pod-stu: (deployment3)
|
|
// pod-stu: (deployment3)
|
|
|
- // container7: an[team=team1] 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
|
|
+ // container7: an[team=team1] 6.00 1.00 1.00 1.00 1.00 1.00 1.00
|
|
|
// pod-vwx: (statefulset1)
|
|
// pod-vwx: (statefulset1)
|
|
|
- // container8: an[team=team2] 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
- // container9: an[team=team1] 5.00 1.00 1.00 1.00 1.00 1.00
|
|
|
|
|
- // +----------------------------------------+------+------+------+------+------+------+
|
|
|
|
|
- // cluster2 subtotal 40.00 11.00 11.00 6.00 6.00 6.00
|
|
|
|
|
- // +----------------------------------------+------+------+------+------+------+------+
|
|
|
|
|
- // total 100.00 22.00 42.00 12.00 12.00 12.00
|
|
|
|
|
- // +----------------------------------------+------+------+------+------+------+------+
|
|
|
|
|
|
|
+ // 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
|
|
|
|
|
+ // +----------------------------------------+------+------+------+------+------+------+------+
|
|
|
|
|
+ // total 112.00 22.00 42.00 12.00 12.00 12.00 12.00
|
|
|
|
|
+ // +----------------------------------------+------+------+------+------+------+------+------+
|
|
|
|
|
|
|
|
// Scenarios to test:
|
|
// Scenarios to test:
|
|
|
|
|
|
|
@@ -809,7 +819,7 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
// There are two clusters, so each gets an idle entry when they are split
|
|
// There are two clusters, so each gets an idle entry when they are split
|
|
|
numSplitIdle := 2
|
|
numSplitIdle := 2
|
|
|
|
|
|
|
|
- activeTotalCost := 70.0
|
|
|
|
|
|
|
+ activeTotalCost := 82.0
|
|
|
idleTotalCost := 30.0
|
|
idleTotalCost := 30.0
|
|
|
sharedOverheadHourlyCost := 7.0
|
|
sharedOverheadHourlyCost := 7.0
|
|
|
|
|
|
|
@@ -838,8 +848,8 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{ClusterProp: ""}, nil)
|
|
err = as.AggregateBy(Properties{ClusterProp: ""}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1a", err, numClusters+numIdle, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1a", err, numClusters+numIdle, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1a", map[string]float64{
|
|
assertAllocationTotals(t, as, "1a", map[string]float64{
|
|
|
- "cluster1": 40.00,
|
|
|
|
|
- "cluster2": 30.00,
|
|
|
|
|
|
|
+ "cluster1": 46.00,
|
|
|
|
|
+ "cluster2": 36.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1a", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1a", startYesterday, endYesterday, 1440.0)
|
|
@@ -849,9 +859,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, nil)
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1b", err, numNamespaces+numIdle, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1b", err, numNamespaces+numIdle, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1b", map[string]float64{
|
|
assertAllocationTotals(t, as, "1b", map[string]float64{
|
|
|
- "namespace1": 25.00,
|
|
|
|
|
- "namespace2": 30.00,
|
|
|
|
|
- "namespace3": 15.00,
|
|
|
|
|
|
|
+ "namespace1": 28.00,
|
|
|
|
|
+ "namespace2": 36.00,
|
|
|
|
|
+ "namespace3": 18.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1b", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1b", startYesterday, endYesterday, 1440.0)
|
|
@@ -861,15 +871,15 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{PodProp: true}, nil)
|
|
err = as.AggregateBy(Properties{PodProp: true}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1c", err, numPods+numIdle, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1c", err, numPods+numIdle, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1c", map[string]float64{
|
|
assertAllocationTotals(t, as, "1c", map[string]float64{
|
|
|
- "pod-jkl": 5.00,
|
|
|
|
|
- "pod-stu": 5.00,
|
|
|
|
|
- "pod-abc": 5.00,
|
|
|
|
|
- "pod-pqr": 5.00,
|
|
|
|
|
- "pod-def": 5.00,
|
|
|
|
|
- "pod-vwx": 10.00,
|
|
|
|
|
- "pod1": 15.00,
|
|
|
|
|
- "pod-mno": 10.00,
|
|
|
|
|
- "pod-ghi": 10.00,
|
|
|
|
|
|
|
+ "pod-jkl": 6.00,
|
|
|
|
|
+ "pod-stu": 6.00,
|
|
|
|
|
+ "pod-abc": 6.00,
|
|
|
|
|
+ "pod-pqr": 6.00,
|
|
|
|
|
+ "pod-def": 6.00,
|
|
|
|
|
+ "pod-vwx": 12.00,
|
|
|
|
|
+ "pod1": 16.00,
|
|
|
|
|
+ "pod-mno": 12.00,
|
|
|
|
|
+ "pod-ghi": 12.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1c", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1c", startYesterday, endYesterday, 1440.0)
|
|
@@ -879,15 +889,15 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{ContainerProp: true}, nil)
|
|
err = as.AggregateBy(Properties{ContainerProp: true}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1d", err, numContainers+numIdle, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1d", err, numContainers+numIdle, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1d", map[string]float64{
|
|
assertAllocationTotals(t, as, "1d", map[string]float64{
|
|
|
- "container2": 5.00,
|
|
|
|
|
- "container9": 5.00,
|
|
|
|
|
- "container6": 10.00,
|
|
|
|
|
- "container3": 5.00,
|
|
|
|
|
- "container4": 10.00,
|
|
|
|
|
- "container7": 5.00,
|
|
|
|
|
- "container8": 5.00,
|
|
|
|
|
- "container5": 10.00,
|
|
|
|
|
- "container1": 15.00,
|
|
|
|
|
|
|
+ "container2": 6.00,
|
|
|
|
|
+ "container9": 6.00,
|
|
|
|
|
+ "container6": 12.00,
|
|
|
|
|
+ "container3": 6.00,
|
|
|
|
|
+ "container4": 12.00,
|
|
|
|
|
+ "container7": 6.00,
|
|
|
|
|
+ "container8": 6.00,
|
|
|
|
|
+ "container5": 12.00,
|
|
|
|
|
+ "container1": 16.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1d", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1d", startYesterday, endYesterday, 1440.0)
|
|
@@ -897,11 +907,11 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{ControllerKindProp: true}, nil)
|
|
err = as.AggregateBy(Properties{ControllerKindProp: true}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1e", err, numControllerKinds+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1e", err, numControllerKinds+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1e", map[string]float64{
|
|
assertAllocationTotals(t, as, "1e", map[string]float64{
|
|
|
- "daemonset": 10.00,
|
|
|
|
|
- "deployment": 35.00,
|
|
|
|
|
- "statefulset": 10.00,
|
|
|
|
|
|
|
+ "daemonset": 12.00,
|
|
|
|
|
+ "deployment": 42.00,
|
|
|
|
|
+ "statefulset": 12.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
- UnallocatedSuffix: 15.00,
|
|
|
|
|
|
|
+ UnallocatedSuffix: 16.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1e", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1e", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -910,13 +920,13 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{ControllerProp: true}, nil)
|
|
err = as.AggregateBy(Properties{ControllerProp: true}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1f", err, numControllers+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1f", err, numControllers+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1f", map[string]float64{
|
|
assertAllocationTotals(t, as, "1f", map[string]float64{
|
|
|
- "deployment/deployment2": 20.00,
|
|
|
|
|
- "daemonset/daemonset1": 10.00,
|
|
|
|
|
- "deployment/deployment3": 5.00,
|
|
|
|
|
- "statefulset/statefulset1": 10.00,
|
|
|
|
|
- "deployment/deployment1": 10.00,
|
|
|
|
|
|
|
+ "deployment/deployment2": 24.00,
|
|
|
|
|
+ "daemonset/daemonset1": 12.00,
|
|
|
|
|
+ "deployment/deployment3": 6.00,
|
|
|
|
|
+ "statefulset/statefulset1": 12.00,
|
|
|
|
|
+ "deployment/deployment1": 12.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
- UnallocatedSuffix: 15.00,
|
|
|
|
|
|
|
+ UnallocatedSuffix: 16.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1f", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1f", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -925,9 +935,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{ServiceProp: true}, nil)
|
|
err = as.AggregateBy(Properties{ServiceProp: true}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1g", err, numServices+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1g", err, numServices+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1g", map[string]float64{
|
|
assertAllocationTotals(t, as, "1g", map[string]float64{
|
|
|
- "service1": 10.00,
|
|
|
|
|
|
|
+ "service1": 12.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
- UnallocatedSuffix: 60.00,
|
|
|
|
|
|
|
+ UnallocatedSuffix: 70.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1g", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1g", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -936,10 +946,10 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{LabelProp: map[string]string{"app": ""}}, nil)
|
|
err = as.AggregateBy(Properties{LabelProp: map[string]string{"app": ""}}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1h", err, numLabelApps+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1h", err, numLabelApps+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1h", map[string]float64{
|
|
assertAllocationTotals(t, as, "1h", map[string]float64{
|
|
|
- "app=app1": 15.00,
|
|
|
|
|
- "app=app2": 20.00,
|
|
|
|
|
|
|
+ "app=app1": 16.00,
|
|
|
|
|
+ "app=app2": 24.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
- UnallocatedSuffix: 35.00,
|
|
|
|
|
|
|
+ UnallocatedSuffix: 42.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1h", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1h", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -948,9 +958,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{ControllerKindProp: "deployment"}, nil)
|
|
err = as.AggregateBy(Properties{ControllerKindProp: "deployment"}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1i", err, 1+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1i", err, 1+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1i", map[string]float64{
|
|
assertAllocationTotals(t, as, "1i", map[string]float64{
|
|
|
- "deployment": 35.00,
|
|
|
|
|
|
|
+ "deployment": 42.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
- UnallocatedSuffix: 35.00,
|
|
|
|
|
|
|
+ UnallocatedSuffix: 40.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1i", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1i", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -959,10 +969,10 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{AnnotationProp: map[string]string{"team": ""}}, nil)
|
|
err = as.AggregateBy(Properties{AnnotationProp: map[string]string{"team": ""}}, nil)
|
|
|
assertAllocationSetTotals(t, as, "1j", err, 2+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "1j", err, 2+numIdle+numUnallocated, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "1j", map[string]float64{
|
|
assertAllocationTotals(t, as, "1j", map[string]float64{
|
|
|
- "team=team1": 10.00,
|
|
|
|
|
- "team=team2": 5.00,
|
|
|
|
|
|
|
+ "team=team1": 12.00,
|
|
|
|
|
+ "team=team2": 6.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
- UnallocatedSuffix: 55.00,
|
|
|
|
|
|
|
+ UnallocatedSuffix: 64.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "1i", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "1i", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -978,11 +988,11 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
// sets should be {idle, unallocated, app1/env1, app2/env2, app2/unallocated}
|
|
// sets should be {idle, unallocated, app1/env1, app2/env2, app2/unallocated}
|
|
|
assertAllocationSetTotals(t, as, "2d", err, numIdle+numUnallocated+3, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "2d", err, numIdle+numUnallocated+3, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "2d", map[string]float64{
|
|
assertAllocationTotals(t, as, "2d", map[string]float64{
|
|
|
- "app=app1/env=env1": 15.00,
|
|
|
|
|
- "app=app2/env=env2": 10.00,
|
|
|
|
|
- "app=app2/" + UnallocatedSuffix: 10.00,
|
|
|
|
|
|
|
+ "app=app1/env=env1": 16.00,
|
|
|
|
|
+ "app=app2/env=env2": 12.00,
|
|
|
|
|
+ "app=app2/" + UnallocatedSuffix: 12.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
- UnallocatedSuffix: 35.00,
|
|
|
|
|
|
|
+ UnallocatedSuffix: 42.00,
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 2e AggregationProperties=(Cluster, Label:app, Label:environment)
|
|
// 2e AggregationProperties=(Cluster, Label:app, Label:environment)
|
|
@@ -990,12 +1000,12 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{ClusterProp: "", LabelProp: map[string]string{"app": "", "env": ""}}, nil)
|
|
err = as.AggregateBy(Properties{ClusterProp: "", LabelProp: map[string]string{"app": "", "env": ""}}, nil)
|
|
|
assertAllocationSetTotals(t, as, "2e", err, 6, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "2e", err, 6, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "2e", map[string]float64{
|
|
assertAllocationTotals(t, as, "2e", map[string]float64{
|
|
|
- "cluster1/app=app2/env=env2": 10.00,
|
|
|
|
|
|
|
+ "cluster1/app=app2/env=env2": 12.00,
|
|
|
"__idle__": 30.00,
|
|
"__idle__": 30.00,
|
|
|
- "cluster1/app=app1/env=env1": 15.00,
|
|
|
|
|
- "cluster1/" + UnallocatedSuffix: 15.00,
|
|
|
|
|
- "cluster2/app=app2/" + UnallocatedSuffix: 10.00,
|
|
|
|
|
- "cluster2/" + UnallocatedSuffix: 20.00,
|
|
|
|
|
|
|
+ "cluster1/app=app1/env=env1": 16.00,
|
|
|
|
|
+ "cluster1/" + UnallocatedSuffix: 18.00,
|
|
|
|
|
+ "cluster2/app=app2/" + UnallocatedSuffix: 12.00,
|
|
|
|
|
+ "cluster2/" + UnallocatedSuffix: 24.00,
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 2f AggregationProperties=(annotation:team, pod)
|
|
// 2f AggregationProperties=(annotation:team, pod)
|
|
@@ -1003,16 +1013,16 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{AnnotationProp: map[string]string{"team": ""}, PodProp: ""}, nil)
|
|
err = as.AggregateBy(Properties{AnnotationProp: map[string]string{"team": ""}, PodProp: ""}, nil)
|
|
|
assertAllocationSetTotals(t, as, "2e", err, 11, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "2e", err, 11, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "2e", map[string]float64{
|
|
assertAllocationTotals(t, as, "2e", map[string]float64{
|
|
|
- "pod-jkl/" + UnallocatedSuffix: 5.00,
|
|
|
|
|
- "pod-stu/team=team1": 5.00,
|
|
|
|
|
- "pod-abc/" + UnallocatedSuffix: 5.00,
|
|
|
|
|
- "pod-pqr/" + UnallocatedSuffix: 5.00,
|
|
|
|
|
- "pod-def/" + UnallocatedSuffix: 5.00,
|
|
|
|
|
- "pod-vwx/team=team1": 5.00,
|
|
|
|
|
- "pod-vwx/team=team2": 5.00,
|
|
|
|
|
- "pod1/" + UnallocatedSuffix: 15.00,
|
|
|
|
|
- "pod-mno/" + UnallocatedSuffix: 10.00,
|
|
|
|
|
- "pod-ghi/" + UnallocatedSuffix: 10.00,
|
|
|
|
|
|
|
+ "pod-jkl/" + UnallocatedSuffix: 6.00,
|
|
|
|
|
+ "pod-stu/team=team1": 6.00,
|
|
|
|
|
+ "pod-abc/" + UnallocatedSuffix: 6.00,
|
|
|
|
|
+ "pod-pqr/" + UnallocatedSuffix: 6.00,
|
|
|
|
|
+ "pod-def/" + UnallocatedSuffix: 6.00,
|
|
|
|
|
+ "pod-vwx/team=team1": 6.00,
|
|
|
|
|
+ "pod-vwx/team=team2": 6.00,
|
|
|
|
|
+ "pod1/" + UnallocatedSuffix: 16.00,
|
|
|
|
|
+ "pod-mno/" + UnallocatedSuffix: 12.00,
|
|
|
|
|
+ "pod-ghi/" + UnallocatedSuffix: 12.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -1021,38 +1031,38 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
// // 3 Share idle
|
|
// // 3 Share idle
|
|
|
|
|
|
|
|
// 3a AggregationProperties=(Namespace) ShareIdle=ShareWeighted
|
|
// 3a AggregationProperties=(Namespace) ShareIdle=ShareWeighted
|
|
|
- // namespace1: 39.6875 = 25.00 + 5.00*(3.00/6.00) + 15.0*(13.0/16.0)
|
|
|
|
|
- // namespace2: 40.3125 = 30.00 + 5.0*(3.0/6.0) + 15.0*(3.0/16.0) + 5.0*(3.0/6.0) + 5.0*(3.0/6.0)
|
|
|
|
|
- // namespace3: 20.0000 = 15.00 + 5.0*(3.0/6.0) + 5.0*(3.0/6.0)
|
|
|
|
|
|
|
+ // namespace1: 42.6875 = 28.00 + 5.00*(3.00/6.00) + 15.0*(13.0/16.0)
|
|
|
|
|
+ // namespace2: 46.3125 = 36.00 + 5.0*(3.0/6.0) + 15.0*(3.0/16.0) + 5.0*(3.0/6.0) + 5.0*(3.0/6.0)
|
|
|
|
|
+ // namespace3: 23.0000 = 18.00 + 5.0*(3.0/6.0) + 5.0*(3.0/6.0)
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{ShareIdle: ShareWeighted})
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{ShareIdle: ShareWeighted})
|
|
|
assertAllocationSetTotals(t, as, "3a", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "3a", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "3a", map[string]float64{
|
|
assertAllocationTotals(t, as, "3a", map[string]float64{
|
|
|
- "namespace1": 39.69,
|
|
|
|
|
- "namespace2": 40.31,
|
|
|
|
|
- "namespace3": 20.00,
|
|
|
|
|
|
|
+ "namespace1": 42.69,
|
|
|
|
|
+ "namespace2": 46.31,
|
|
|
|
|
+ "namespace3": 23.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "3a", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "3a", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
|
// 3b AggregationProperties=(Namespace) ShareIdle=ShareEven
|
|
// 3b AggregationProperties=(Namespace) ShareIdle=ShareEven
|
|
|
- // namespace1: 35.0000 = 25.00 + 5.00*(1.0/2.0) + 15.0*(1.0/2.0)
|
|
|
|
|
- // namespace2: 45.0000 = 30.00 + 5.0*(1.0/2.0) + 15.0*(1.0/2.0) + 5.0*(1.0/2.0) + 5.0*(1.0/2.0)
|
|
|
|
|
- // namespace3: 20.0000 = 15.00 + 5.0*(1.0/2.0) + 5.0*(1.0/2.0)
|
|
|
|
|
|
|
+ // namespace1: 38.0000 = 28.00 + 5.00*(1.0/2.0) + 15.0*(1.0/2.0)
|
|
|
|
|
+ // namespace2: 51.0000 = 36.00 + 5.0*(1.0/2.0) + 15.0*(1.0/2.0) + 5.0*(1.0/2.0) + 5.0*(1.0/2.0)
|
|
|
|
|
+ // namespace3: 23.0000 = 18.00 + 5.0*(1.0/2.0) + 5.0*(1.0/2.0)
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{ShareIdle: ShareEven})
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{ShareIdle: ShareEven})
|
|
|
assertAllocationSetTotals(t, as, "3a", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "3a", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "3a", map[string]float64{
|
|
assertAllocationTotals(t, as, "3a", map[string]float64{
|
|
|
- "namespace1": 35.00,
|
|
|
|
|
- "namespace2": 45.00,
|
|
|
|
|
- "namespace3": 20.00,
|
|
|
|
|
|
|
+ "namespace1": 38.00,
|
|
|
|
|
+ "namespace2": 51.00,
|
|
|
|
|
+ "namespace3": 23.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "3b", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "3b", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
|
// 4 Share resources
|
|
// 4 Share resources
|
|
|
|
|
|
|
|
// 4a Share namespace ShareEven
|
|
// 4a Share namespace ShareEven
|
|
|
- // namespace1: 32.5000 = 25.00 + 15.00*(1.0/2.0)
|
|
|
|
|
- // namespace2: 37.5000 = 30.00 + 15.00*(1.0/2.0)
|
|
|
|
|
|
|
+ // namespace1: 37.5000 = 28.00 + 18.00*(1.0/2.0)
|
|
|
|
|
+ // namespace2: 45.5000 = 36.00 + 18.00*(1.0/2.0)
|
|
|
// idle: 30.0000
|
|
// idle: 30.0000
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{
|
|
@@ -1061,8 +1071,8 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
})
|
|
})
|
|
|
assertAllocationSetTotals(t, as, "4a", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "4a", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "4a", map[string]float64{
|
|
assertAllocationTotals(t, as, "4a", map[string]float64{
|
|
|
- "namespace1": 32.50,
|
|
|
|
|
- "namespace2": 37.50,
|
|
|
|
|
|
|
+ "namespace1": 37.00,
|
|
|
|
|
+ "namespace2": 45.00,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "4a", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "4a", startYesterday, endYesterday, 1440.0)
|
|
@@ -1078,16 +1088,16 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
})
|
|
})
|
|
|
assertAllocationSetTotals(t, as, "4b", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "4b", err, numNamespaces, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "4b", map[string]float64{
|
|
assertAllocationTotals(t, as, "4b", map[string]float64{
|
|
|
- "namespace1": 31.82,
|
|
|
|
|
- "namespace2": 38.18,
|
|
|
|
|
|
|
+ "namespace1": 35.88,
|
|
|
|
|
+ "namespace2": 46.125,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "4b", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "4b", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
|
// 4c Share label ShareEven
|
|
// 4c Share label ShareEven
|
|
|
- // namespace1: 15.0000 = 25.00 - 15.00 + 15.00*(1.0/3.0)
|
|
|
|
|
- // namespace2: 35.0000 = 30.00 + 15.00*(1.0/3.0)
|
|
|
|
|
- // namespace3: 20.0000 = 15.00 + 15.00*(1.0/3.0)
|
|
|
|
|
|
|
+ // namespace1: 17.3333 = 28.00 - 16.00 + 16.00*(1.0/3.0)
|
|
|
|
|
+ // namespace2: 41.3333 = 36.00 + 16.00*(1.0/3.0)
|
|
|
|
|
+ // namespace3: 23.3333 = 18.00 + 16.00*(1.0/3.0)
|
|
|
// idle: 30.0000
|
|
// idle: 30.0000
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{
|
|
@@ -1096,17 +1106,17 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
})
|
|
})
|
|
|
assertAllocationSetTotals(t, as, "4c", err, numNamespaces+numIdle, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "4c", err, numNamespaces+numIdle, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "4c", map[string]float64{
|
|
assertAllocationTotals(t, as, "4c", map[string]float64{
|
|
|
- "namespace1": 15.00,
|
|
|
|
|
- "namespace2": 35.00,
|
|
|
|
|
- "namespace3": 20.00,
|
|
|
|
|
|
|
+ "namespace1": 17.33,
|
|
|
|
|
+ "namespace2": 41.33,
|
|
|
|
|
+ "namespace3": 23.33,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "4c", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "4c", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
|
// 4d Share overhead ShareWeighted
|
|
// 4d Share overhead ShareWeighted
|
|
|
- // namespace1: 85 = 25.00 + (7.0*24.0)*(25.00/70.00)
|
|
|
|
|
- // namespace2: 102 = 30.00 + (7.0*24.0)*(30.00/70.00)
|
|
|
|
|
- // namespace3: 51 = 15.00 + (7.0*24.0)*(15.00/70.00)
|
|
|
|
|
|
|
+ // namespace1: 85.366 = 28.00 + (7.0*24.0)*(28.00/82.00)
|
|
|
|
|
+ // namespace2: 109.756 = 36.00 + (7.0*24.0)*(36.00/82.00)
|
|
|
|
|
+ // namespace3: 54.878 = 18.00 + (7.0*24.0)*(18.00/82.00)
|
|
|
// idle: 30.0000
|
|
// idle: 30.0000
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: true}, &AllocationAggregationOptions{
|
|
@@ -1115,9 +1125,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
})
|
|
})
|
|
|
assertAllocationSetTotals(t, as, "4d", err, numNamespaces+numIdle, activeTotalCost+idleTotalCost+(sharedOverheadHourlyCost*24.0))
|
|
assertAllocationSetTotals(t, as, "4d", err, numNamespaces+numIdle, activeTotalCost+idleTotalCost+(sharedOverheadHourlyCost*24.0))
|
|
|
assertAllocationTotals(t, as, "4d", map[string]float64{
|
|
assertAllocationTotals(t, as, "4d", map[string]float64{
|
|
|
- "namespace1": 85.00,
|
|
|
|
|
- "namespace2": 102.00,
|
|
|
|
|
- "namespace3": 51.00,
|
|
|
|
|
|
|
+ "namespace1": 85.366,
|
|
|
|
|
+ "namespace2": 109.756,
|
|
|
|
|
+ "namespace3": 54.878,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "4d", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "4d", startYesterday, endYesterday, 1440.0)
|
|
@@ -1144,9 +1154,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
FilterFuncs: []AllocationMatchFunc{isCluster("cluster1")},
|
|
FilterFuncs: []AllocationMatchFunc{isCluster("cluster1")},
|
|
|
ShareIdle: ShareNone,
|
|
ShareIdle: ShareNone,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "5a", err, 2, 60.0)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "5a", err, 2, 66.0)
|
|
|
assertAllocationTotals(t, as, "5a", map[string]float64{
|
|
assertAllocationTotals(t, as, "5a", map[string]float64{
|
|
|
- "cluster1": 40.00,
|
|
|
|
|
|
|
+ "cluster1": 46.00,
|
|
|
IdleSuffix: 20.00,
|
|
IdleSuffix: 20.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "5a", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "5a", startYesterday, endYesterday, 1440.0)
|
|
@@ -1157,9 +1167,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
FilterFuncs: []AllocationMatchFunc{isCluster("cluster1")},
|
|
FilterFuncs: []AllocationMatchFunc{isCluster("cluster1")},
|
|
|
ShareIdle: ShareWeighted,
|
|
ShareIdle: ShareWeighted,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "5b", err, 1, 60.0)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "5b", err, 1, 66.0)
|
|
|
assertAllocationTotals(t, as, "5b", map[string]float64{
|
|
assertAllocationTotals(t, as, "5b", map[string]float64{
|
|
|
- "cluster1": 60.00,
|
|
|
|
|
|
|
+ "cluster1": 66.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "5b", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "5b", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -1169,10 +1179,10 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
FilterFuncs: []AllocationMatchFunc{isCluster("cluster1")},
|
|
FilterFuncs: []AllocationMatchFunc{isCluster("cluster1")},
|
|
|
ShareIdle: ShareNone,
|
|
ShareIdle: ShareNone,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "5c", err, 3, 60.0)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "5c", err, 3, 66.0)
|
|
|
assertAllocationTotals(t, as, "5c", map[string]float64{
|
|
assertAllocationTotals(t, as, "5c", map[string]float64{
|
|
|
- "namespace1": 25.00,
|
|
|
|
|
- "namespace2": 15.00,
|
|
|
|
|
|
|
+ "namespace1": 28.00,
|
|
|
|
|
+ "namespace2": 18.00,
|
|
|
IdleSuffix: 20.00,
|
|
IdleSuffix: 20.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "5c", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "5c", startYesterday, endYesterday, 1440.0)
|
|
@@ -1183,10 +1193,10 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
FilterFuncs: []AllocationMatchFunc{isNamespace("namespace2")},
|
|
FilterFuncs: []AllocationMatchFunc{isNamespace("namespace2")},
|
|
|
ShareIdle: ShareNone,
|
|
ShareIdle: ShareNone,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "5d", err, 3, 40.31)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "5d", err, 3, 46.31)
|
|
|
assertAllocationTotals(t, as, "5d", map[string]float64{
|
|
assertAllocationTotals(t, as, "5d", map[string]float64{
|
|
|
- "cluster1": 15.00,
|
|
|
|
|
- "cluster2": 15.00,
|
|
|
|
|
|
|
+ "cluster1": 18.00,
|
|
|
|
|
+ "cluster2": 18.00,
|
|
|
IdleSuffix: 10.31,
|
|
IdleSuffix: 10.31,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "5d", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "5d", startYesterday, endYesterday, 1440.0)
|
|
@@ -1198,9 +1208,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{SplitIdle: true})
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{SplitIdle: true})
|
|
|
assertAllocationSetTotals(t, as, "6a", err, numNamespaces+numSplitIdle, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "6a", err, numNamespaces+numSplitIdle, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "6a", map[string]float64{
|
|
assertAllocationTotals(t, as, "6a", map[string]float64{
|
|
|
- "namespace1": 25.00,
|
|
|
|
|
- "namespace2": 30.00,
|
|
|
|
|
- "namespace3": 15.00,
|
|
|
|
|
|
|
+ "namespace1": 28.00,
|
|
|
|
|
+ "namespace2": 36.00,
|
|
|
|
|
+ "namespace3": 18.00,
|
|
|
fmt.Sprintf("cluster1/%s", IdleSuffix): 20.00,
|
|
fmt.Sprintf("cluster1/%s", IdleSuffix): 20.00,
|
|
|
fmt.Sprintf("cluster2/%s", IdleSuffix): 10.00,
|
|
fmt.Sprintf("cluster2/%s", IdleSuffix): 10.00,
|
|
|
})
|
|
})
|
|
@@ -1208,36 +1218,36 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
|
|
|
|
|
// 6b Share idle weighted with filters
|
|
// 6b Share idle weighted with filters
|
|
|
// Should match values from unfiltered aggregation (3a)
|
|
// Should match values from unfiltered aggregation (3a)
|
|
|
- // namespace2: 40.3125 = 30.00 + 5.0*(3.0/6.0) + 15.0*(3.0/16.0) + 5.0*(3.0/6.0) + 5.0*(3.0/6.0)
|
|
|
|
|
|
|
+ // namespace2: 46.3125 = 36.00 + 5.0*(3.0/6.0) + 15.0*(3.0/16.0) + 5.0*(3.0/6.0) + 5.0*(3.0/6.0)
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
|
FilterFuncs: []AllocationMatchFunc{isNamespace("namespace2")},
|
|
FilterFuncs: []AllocationMatchFunc{isNamespace("namespace2")},
|
|
|
ShareIdle: ShareWeighted,
|
|
ShareIdle: ShareWeighted,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "6b", err, 1, 40.31)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "6b", err, 1, 46.31)
|
|
|
assertAllocationTotals(t, as, "6b", map[string]float64{
|
|
assertAllocationTotals(t, as, "6b", map[string]float64{
|
|
|
- "namespace2": 40.31,
|
|
|
|
|
|
|
+ "namespace2": 46.31,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "6b", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "6b", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
|
// 6c Share idle even with filters
|
|
// 6c Share idle even with filters
|
|
|
// Should match values from unfiltered aggregation (3b)
|
|
// Should match values from unfiltered aggregation (3b)
|
|
|
- // namespace2: 45.0000 = 30.00 + 5.0*(1.0/2.0) + 15.0*(1.0/2.0) + 5.0*(1.0/2.0) + 5.0*(1.0/2.0)
|
|
|
|
|
|
|
+ // namespace2: 51.0000 = 36.00 + 5.0*(1.0/2.0) + 15.0*(1.0/2.0) + 5.0*(1.0/2.0) + 5.0*(1.0/2.0)
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
|
FilterFuncs: []AllocationMatchFunc{isNamespace("namespace2")},
|
|
FilterFuncs: []AllocationMatchFunc{isNamespace("namespace2")},
|
|
|
ShareIdle: ShareEven,
|
|
ShareIdle: ShareEven,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "6b", err, 1, 45.00)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "6b", err, 1, 51.00)
|
|
|
assertAllocationTotals(t, as, "6b", map[string]float64{
|
|
assertAllocationTotals(t, as, "6b", map[string]float64{
|
|
|
- "namespace2": 45.00,
|
|
|
|
|
|
|
+ "namespace2": 51.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "6b", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "6b", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
|
// 6d Share overhead with filters
|
|
// 6d Share overhead with filters
|
|
|
- // namespace1: 85 = 25.00 + (7.0*24.0)*(25.00/70.00)
|
|
|
|
|
- // namespace2: 102 = 30.00 + (7.0*24.0)*(30.00/70.00)
|
|
|
|
|
- // namespace3: 51 = 15.00 + (7.0*24.0)*(15.00/70.00)
|
|
|
|
|
|
|
+ // namespace1: 85.366 = 28.00 + (7.0*24.0)*(28.00/82.00)
|
|
|
|
|
+ // namespace2: 109.756 = 36.00 + (7.0*24.0)*(36.00/82.00)
|
|
|
|
|
+ // namespace3: 54.878 = 18.00 + (7.0*24.0)*(18.00/82.00)
|
|
|
// idle: 30.0000
|
|
// idle: 30.0000
|
|
|
// Then namespace 2 is filtered.
|
|
// Then namespace 2 is filtered.
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
@@ -1246,20 +1256,20 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
SharedHourlyCosts: map[string]float64{"total": sharedOverheadHourlyCost},
|
|
SharedHourlyCosts: map[string]float64{"total": sharedOverheadHourlyCost},
|
|
|
ShareSplit: ShareWeighted,
|
|
ShareSplit: ShareWeighted,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "6d", err, 2, 132.00)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "6d", err, 2, 139.756)
|
|
|
assertAllocationTotals(t, as, "6d", map[string]float64{
|
|
assertAllocationTotals(t, as, "6d", map[string]float64{
|
|
|
- "namespace2": 102.00,
|
|
|
|
|
|
|
+ "namespace2": 109.756,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "6d", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "6d", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
|
// 6e Share resources with filters
|
|
// 6e Share resources with filters
|
|
|
// --- Shared ---
|
|
// --- Shared ---
|
|
|
- // namespace1: 25.00 (gets shared among namespace2 and namespace3)
|
|
|
|
|
|
|
+ // namespace1: 28.00 (gets shared among namespace2 and namespace3)
|
|
|
// --- Filtered ---
|
|
// --- Filtered ---
|
|
|
- // namespace3: 23.33 = 15.00 + (25.00)*(15.00/45.00) (filtered out)
|
|
|
|
|
|
|
+ // namespace3: 27.33 = 18.00 + (28.00)*(18.00/54.00) (filtered out)
|
|
|
// --- Results ---
|
|
// --- Results ---
|
|
|
- // namespace2: 46.67 = 30.00 + (25.00)*(15.00/45.00)
|
|
|
|
|
|
|
+ // namespace2: 54.667 = 36.00 + (28.00)*(36.00/54.00)
|
|
|
// idle: 30.0000
|
|
// idle: 30.0000
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
@@ -1267,9 +1277,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
ShareFuncs: []AllocationMatchFunc{isNamespace("namespace1")},
|
|
ShareFuncs: []AllocationMatchFunc{isNamespace("namespace1")},
|
|
|
ShareSplit: ShareWeighted,
|
|
ShareSplit: ShareWeighted,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "6e", err, 2, 76.67)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "6e", err, 2, 84.667)
|
|
|
assertAllocationTotals(t, as, "6e", map[string]float64{
|
|
assertAllocationTotals(t, as, "6e", map[string]float64{
|
|
|
- "namespace2": 46.67,
|
|
|
|
|
|
|
+ "namespace2": 54.667,
|
|
|
IdleSuffix: 30.00,
|
|
IdleSuffix: 30.00,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "6e", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "6e", startYesterday, endYesterday, 1440.0)
|
|
@@ -1278,20 +1288,20 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
//
|
|
//
|
|
|
// First, share idle weighted produces:
|
|
// First, share idle weighted produces:
|
|
|
//
|
|
//
|
|
|
- // namespace1: 39.6875
|
|
|
|
|
- // initial cost 25.0000
|
|
|
|
|
|
|
+ // namespace1: 42.6875
|
|
|
|
|
+ // initial cost 28.0000
|
|
|
// cluster1.cpu 2.5000 = 5.00*(3.00/6.00)
|
|
// cluster1.cpu 2.5000 = 5.00*(3.00/6.00)
|
|
|
// cluster1.ram 12.1875 = 15.00*(13.0/16.0)
|
|
// cluster1.ram 12.1875 = 15.00*(13.0/16.0)
|
|
|
//
|
|
//
|
|
|
- // namespace2: 40.3125
|
|
|
|
|
- // initial cost 30.0000
|
|
|
|
|
|
|
+ // namespace2: 46.3125
|
|
|
|
|
+ // initial cost 36.0000
|
|
|
// cluster1.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster1.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster1.ram 2.8125 = 15.00*(3.0/16.0)
|
|
// cluster1.ram 2.8125 = 15.00*(3.0/16.0)
|
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
|
//
|
|
//
|
|
|
- // namespace3: 20.0000
|
|
|
|
|
- // initial cost 15.0000
|
|
|
|
|
|
|
+ // namespace3: 23.0000
|
|
|
|
|
+ // initial cost 18.0000
|
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
|
//
|
|
//
|
|
@@ -1299,15 +1309,15 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
// computed before allocating idle (so that weighting idle differently
|
|
// computed before allocating idle (so that weighting idle differently
|
|
|
// doesn't adversely affect the sharing mechanism):
|
|
// doesn't adversely affect the sharing mechanism):
|
|
|
//
|
|
//
|
|
|
- // namespace2: 66.7708
|
|
|
|
|
|
|
+ // namespace2: 74.7708
|
|
|
// initial cost 30.0000
|
|
// initial cost 30.0000
|
|
|
// idle cost 10.3125
|
|
// idle cost 10.3125
|
|
|
- // shared cost 26.4583 = (39.6875)*(30.0/45.0)
|
|
|
|
|
|
|
+ // shared cost 28.4583 = (42.6875)*(36.0/54.0)
|
|
|
//
|
|
//
|
|
|
- // namespace3: 33.2292
|
|
|
|
|
- // initial cost 15.0000
|
|
|
|
|
|
|
+ // namespace3: 37.2292
|
|
|
|
|
+ // initial cost 18.0000
|
|
|
// idle cost 5.0000
|
|
// idle cost 5.0000
|
|
|
- // shared cost 13.2292 = (39.6875)*(15.0/45.0)
|
|
|
|
|
|
|
+ // shared cost 14.2292 = (42.6875)*(18.0/54.0)
|
|
|
//
|
|
//
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
@@ -1317,8 +1327,8 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
})
|
|
})
|
|
|
assertAllocationSetTotals(t, as, "6f", err, 2, activeTotalCost+idleTotalCost)
|
|
assertAllocationSetTotals(t, as, "6f", err, 2, activeTotalCost+idleTotalCost)
|
|
|
assertAllocationTotals(t, as, "6f", map[string]float64{
|
|
assertAllocationTotals(t, as, "6f", map[string]float64{
|
|
|
- "namespace2": 66.77,
|
|
|
|
|
- "namespace3": 33.23,
|
|
|
|
|
|
|
+ "namespace2": 74.77,
|
|
|
|
|
+ "namespace3": 37.23,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "6f", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "6f", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -1326,20 +1336,20 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
//
|
|
//
|
|
|
// First, share idle weighted produces:
|
|
// First, share idle weighted produces:
|
|
|
//
|
|
//
|
|
|
- // namespace1: 39.6875
|
|
|
|
|
- // initial cost 25.0000
|
|
|
|
|
|
|
+ // namespace1: 42.6875
|
|
|
|
|
+ // initial cost 28.0000
|
|
|
// cluster1.cpu 2.5000 = 5.00*(3.00/6.00)
|
|
// cluster1.cpu 2.5000 = 5.00*(3.00/6.00)
|
|
|
// cluster1.ram 12.1875 = 15.00*(13.0/16.0)
|
|
// cluster1.ram 12.1875 = 15.00*(13.0/16.0)
|
|
|
//
|
|
//
|
|
|
- // namespace2: 40.3125
|
|
|
|
|
- // initial cost 30.0000
|
|
|
|
|
|
|
+ // namespace2: 46.3125
|
|
|
|
|
+ // initial cost 36.0000
|
|
|
// cluster1.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster1.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster1.ram 2.8125 = 15.00*(3.0/16.0)
|
|
// cluster1.ram 2.8125 = 15.00*(3.0/16.0)
|
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
|
//
|
|
//
|
|
|
- // namespace3: 20.0000
|
|
|
|
|
- // initial cost 15.0000
|
|
|
|
|
|
|
+ // namespace3: 23.0000
|
|
|
|
|
+ // initial cost 18.0000
|
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
|
//
|
|
//
|
|
@@ -1347,17 +1357,17 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
// computed before allocating idle (so that weighting idle differently
|
|
// computed before allocating idle (so that weighting idle differently
|
|
|
// doesn't adversely affect the sharing mechanism):
|
|
// doesn't adversely affect the sharing mechanism):
|
|
|
//
|
|
//
|
|
|
- // namespace2: 66.7708
|
|
|
|
|
- // initial cost 30.0000
|
|
|
|
|
|
|
+ // namespace2: 74.7708
|
|
|
|
|
+ // initial cost 36.0000
|
|
|
// idle cost 10.3125
|
|
// idle cost 10.3125
|
|
|
- // shared cost 26.4583 = (39.6875)*(30.0/45.0)
|
|
|
|
|
|
|
+ // shared cost 28.4583 = (42.6875)*(36.0/54.0)
|
|
|
//
|
|
//
|
|
|
- // namespace3: 33.2292
|
|
|
|
|
- // initial cost 15.0000
|
|
|
|
|
|
|
+ // namespace3: 37.2292
|
|
|
|
|
+ // initial cost 18.0000
|
|
|
// idle cost 5.0000
|
|
// idle cost 5.0000
|
|
|
- // shared cost 13.2292 = (39.6875)*(15.0/45.0)
|
|
|
|
|
|
|
+ // shared cost 14.2292 = (42.6875)*(18.0/54.0)
|
|
|
//
|
|
//
|
|
|
- // Then, filter for namespace2: 66.7708
|
|
|
|
|
|
|
+ // Then, filter for namespace2: 74.7708
|
|
|
//
|
|
//
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
err = as.AggregateBy(Properties{NamespaceProp: ""}, &AllocationAggregationOptions{
|
|
@@ -1366,9 +1376,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
ShareSplit: ShareWeighted,
|
|
ShareSplit: ShareWeighted,
|
|
|
ShareIdle: ShareWeighted,
|
|
ShareIdle: ShareWeighted,
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "6g", err, 1, 66.77)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "6g", err, 1, 74.77)
|
|
|
assertAllocationTotals(t, as, "6g", map[string]float64{
|
|
assertAllocationTotals(t, as, "6g", map[string]float64{
|
|
|
- "namespace2": 66.77,
|
|
|
|
|
|
|
+ "namespace2": 74.77,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "6g", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "6g", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -1376,28 +1386,28 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
//
|
|
//
|
|
|
// Share idle weighted:
|
|
// Share idle weighted:
|
|
|
//
|
|
//
|
|
|
- // namespace1: 39.6875
|
|
|
|
|
- // initial cost 25.0000
|
|
|
|
|
|
|
+ // namespace1: 42.6875
|
|
|
|
|
+ // initial cost 28.0000
|
|
|
// cluster1.cpu 2.5000 = 5.00*(3.00/6.00)
|
|
// cluster1.cpu 2.5000 = 5.00*(3.00/6.00)
|
|
|
// cluster1.ram 12.1875 = 15.00*(13.0/16.0)
|
|
// cluster1.ram 12.1875 = 15.00*(13.0/16.0)
|
|
|
//
|
|
//
|
|
|
- // namespace2: 40.3125
|
|
|
|
|
- // initial cost 30.0000
|
|
|
|
|
|
|
+ // namespace2: 46.3125
|
|
|
|
|
+ // initial cost 36.0000
|
|
|
// cluster1.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster1.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster1.ram 2.8125 = 15.00*(3.0/16.0)
|
|
// cluster1.ram 2.8125 = 15.00*(3.0/16.0)
|
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
|
//
|
|
//
|
|
|
- // namespace3: 20.0000
|
|
|
|
|
- // initial cost 15.0000
|
|
|
|
|
|
|
+ // namespace3: 23.0000
|
|
|
|
|
+ // initial cost 18.0000
|
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.cpu 2.5000 = 5.00*(3.0/6.0)
|
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
// cluster2.ram 2.5000 = 5.00*(3.0/6.0)
|
|
|
//
|
|
//
|
|
|
// Then share overhead:
|
|
// Then share overhead:
|
|
|
//
|
|
//
|
|
|
- // namespace1: 99.6875 = 39.6875 + (7.0*24.0)*(25.00/70.00)
|
|
|
|
|
- // namespace2: 112.3125 = 40.3125 + (7.0*24.0)*(30.00/70.00)
|
|
|
|
|
- // namespace3: 56.0000 = 20.0000 + (7.0*24.0)*(15.00/70.00)
|
|
|
|
|
|
|
+ // namespace1: 100.0533 = 42.6875 + (7.0*24.0)*(28.00/82.00)
|
|
|
|
|
+ // namespace2: 120.0686 = 46.3125 + (7.0*24.0)*(36.00/82.00)
|
|
|
|
|
+ // namespace3: 59.8780 = 23.0000 + (7.0*24.0)*(18.00/82.00)
|
|
|
//
|
|
//
|
|
|
// Then namespace 2 is filtered.
|
|
// Then namespace 2 is filtered.
|
|
|
as = generateAllocationSet(start)
|
|
as = generateAllocationSet(start)
|
|
@@ -1407,9 +1417,9 @@ func TestAllocationSet_AggregateBy(t *testing.T) {
|
|
|
ShareIdle: ShareWeighted,
|
|
ShareIdle: ShareWeighted,
|
|
|
SharedHourlyCosts: map[string]float64{"total": sharedOverheadHourlyCost},
|
|
SharedHourlyCosts: map[string]float64{"total": sharedOverheadHourlyCost},
|
|
|
})
|
|
})
|
|
|
- assertAllocationSetTotals(t, as, "6h", err, 1, 112.31)
|
|
|
|
|
|
|
+ assertAllocationSetTotals(t, as, "6h", err, 1, 120.07)
|
|
|
assertAllocationTotals(t, as, "6h", map[string]float64{
|
|
assertAllocationTotals(t, as, "6h", map[string]float64{
|
|
|
- "namespace2": 112.31,
|
|
|
|
|
|
|
+ "namespace2": 120.07,
|
|
|
})
|
|
})
|
|
|
assertAllocationWindow(t, as, "6h", startYesterday, endYesterday, 1440.0)
|
|
assertAllocationWindow(t, as, "6h", startYesterday, endYesterday, 1440.0)
|
|
|
|
|
|
|
@@ -1716,8 +1726,8 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
|
|
|
if result == nil {
|
|
if result == nil {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
|
}
|
|
}
|
|
|
- if result.TotalCost() != 5.0 {
|
|
|
|
|
- t.Fatalf("accumulating AllocationSetRange: expected total cost 5.0; actual %f", result.TotalCost())
|
|
|
|
|
|
|
+ if result.TotalCost() != 6.0 {
|
|
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected total cost 6.0; actual %f", result.TotalCost())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
result, err = NewAllocationSetRange(todayAS, nil).Accumulate()
|
|
result, err = NewAllocationSetRange(todayAS, nil).Accumulate()
|
|
@@ -1727,8 +1737,8 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
|
|
|
if result == nil {
|
|
if result == nil {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
|
}
|
|
}
|
|
|
- if result.TotalCost() != 5.0 {
|
|
|
|
|
- t.Fatalf("accumulating AllocationSetRange: expected total cost 5.0; actual %f", result.TotalCost())
|
|
|
|
|
|
|
+ if result.TotalCost() != 6.0 {
|
|
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected total cost 6.0; actual %f", result.TotalCost())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
result, err = NewAllocationSetRange(nil, todayAS, nil).Accumulate()
|
|
result, err = NewAllocationSetRange(nil, todayAS, nil).Accumulate()
|
|
@@ -1738,8 +1748,8 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
|
|
|
if result == nil {
|
|
if result == nil {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
|
}
|
|
}
|
|
|
- if result.TotalCost() != 5.0 {
|
|
|
|
|
- t.Fatalf("accumulating AllocationSetRange: expected total cost 5.0; actual %f", result.TotalCost())
|
|
|
|
|
|
|
+ if result.TotalCost() != 6.0 {
|
|
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected total cost 6.0; actual %f", result.TotalCost())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Accumulate two non-nil should result in sum of both with appropriate start, end
|
|
// Accumulate two non-nil should result in sum of both with appropriate start, end
|
|
@@ -1750,8 +1760,8 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
|
|
|
if result == nil {
|
|
if result == nil {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
t.Fatalf("accumulating AllocationSetRange: expected AllocationSet; actual %s", result)
|
|
|
}
|
|
}
|
|
|
- if result.TotalCost() != 10.0 {
|
|
|
|
|
- t.Fatalf("accumulating AllocationSetRange: expected total cost 10.0; actual %f", result.TotalCost())
|
|
|
|
|
|
|
+ if result.TotalCost() != 12.0 {
|
|
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected total cost 12.0; actual %f", result.TotalCost())
|
|
|
}
|
|
}
|
|
|
allocMap := result.Map()
|
|
allocMap := result.Map()
|
|
|
if len(allocMap) != 1 {
|
|
if len(allocMap) != 1 {
|
|
@@ -1779,6 +1789,9 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
|
|
|
if alloc.NetworkCost != 2.0 {
|
|
if alloc.NetworkCost != 2.0 {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.NetworkCost)
|
|
t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.NetworkCost)
|
|
|
}
|
|
}
|
|
|
|
|
+ if alloc.LoadBalancerCost != 2.0 {
|
|
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.LoadBalancerCost)
|
|
|
|
|
+ }
|
|
|
if alloc.PVByteHours != 2.0 {
|
|
if alloc.PVByteHours != 2.0 {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.PVByteHours)
|
|
t.Fatalf("accumulating AllocationSetRange: expected 2.0; actual %f", alloc.PVByteHours)
|
|
|
}
|
|
}
|
|
@@ -1794,8 +1807,8 @@ func TestAllocationSetRange_Accumulate(t *testing.T) {
|
|
|
if alloc.RAMEfficiency() != 1.0 {
|
|
if alloc.RAMEfficiency() != 1.0 {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.RAMEfficiency())
|
|
t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.RAMEfficiency())
|
|
|
}
|
|
}
|
|
|
- if alloc.TotalCost() != 10.0 {
|
|
|
|
|
- t.Fatalf("accumulating AllocationSetRange: expected 10.0; actual %f", alloc.TotalCost())
|
|
|
|
|
|
|
+ if alloc.TotalCost() != 12.0 {
|
|
|
|
|
+ t.Fatalf("accumulating AllocationSetRange: expected 12.0; actual %f", alloc.TotalCost())
|
|
|
}
|
|
}
|
|
|
if alloc.TotalEfficiency() != 1.0 {
|
|
if alloc.TotalEfficiency() != 1.0 {
|
|
|
t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.TotalEfficiency())
|
|
t.Fatalf("accumulating AllocationSetRange: expected 1.0; actual %f", alloc.TotalEfficiency())
|
|
@@ -1896,6 +1909,9 @@ func TestAllocationSetRange_InsertRange(t *testing.T) {
|
|
|
if !util.IsApproximately(a.NetworkCost, unit.NetworkCost) {
|
|
if !util.IsApproximately(a.NetworkCost, unit.NetworkCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
|
}
|
|
}
|
|
|
|
|
+ if !util.IsApproximately(a.LoadBalancerCost, unit.LoadBalancerCost) {
|
|
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.LoadBalancerCost, a.LoadBalancerCost)
|
|
|
|
|
+ }
|
|
|
if !util.IsApproximately(a.TotalCost(), unit.TotalCost()) {
|
|
if !util.IsApproximately(a.TotalCost(), unit.TotalCost()) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.TotalCost(), a.TotalCost())
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.TotalCost(), a.TotalCost())
|
|
|
}
|
|
}
|
|
@@ -1944,6 +1960,10 @@ func TestAllocationSetRange_InsertRange(t *testing.T) {
|
|
|
if !util.IsApproximately(a.NetworkCost, 2*unit.NetworkCost) {
|
|
if !util.IsApproximately(a.NetworkCost, 2*unit.NetworkCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
|
}
|
|
}
|
|
|
|
|
+ if !util.IsApproximately(a.LoadBalancerCost, 2*unit.LoadBalancerCost) {
|
|
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.LoadBalancerCost, a.LoadBalancerCost)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if !util.IsApproximately(a.TotalCost(), 2*unit.TotalCost()) {
|
|
if !util.IsApproximately(a.TotalCost(), 2*unit.TotalCost()) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.TotalCost(), a.TotalCost())
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.TotalCost(), a.TotalCost())
|
|
|
}
|
|
}
|
|
@@ -1977,6 +1997,9 @@ func TestAllocationSetRange_InsertRange(t *testing.T) {
|
|
|
if !util.IsApproximately(a.NetworkCost, unit.NetworkCost) {
|
|
if !util.IsApproximately(a.NetworkCost, unit.NetworkCost) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.NetworkCost, a.NetworkCost)
|
|
|
}
|
|
}
|
|
|
|
|
+ if !util.IsApproximately(a.LoadBalancerCost, unit.LoadBalancerCost) {
|
|
|
|
|
+ t.Fatalf("allocation %s: expected %f; got %f", k, unit.LoadBalancerCost, a.LoadBalancerCost)
|
|
|
|
|
+ }
|
|
|
if !util.IsApproximately(a.TotalCost(), unit.TotalCost()) {
|
|
if !util.IsApproximately(a.TotalCost(), unit.TotalCost()) {
|
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.TotalCost(), a.TotalCost())
|
|
t.Fatalf("allocation %s: expected %f; got %f", k, unit.TotalCost(), a.TotalCost())
|
|
|
}
|
|
}
|