Преглед изворни кода

Revert "Add logic for Allocation structs for max usage"

This reverts commit 039ccfe825780dd581f59b9cded3f30b5e01a805.

This logic for aggregating vs. accumulating maximum usage does not work.
Essentially, determining overall maximum of a set of weighted intervals
is a fun algorithms problem and requires us to keep around a set of
intervals and maximums for every sub-allocation that a cumulative
Allocation is composed of. That's too heavy for the Allocation type, so
we will instead just keep max at the raw level (next commit) and zero
it out as soon as any operation like .add() is called on Allocation.
Michael Dresser пре 5 година
родитељ
комит
6966a08281
2 измењених фајлова са 52 додато и 187 уклоњено
  1. 27 103
      pkg/kubecost/allocation.go
  2. 25 84
      pkg/kubecost/allocation_test.go

+ 27 - 103
pkg/kubecost/allocation.go

@@ -3,7 +3,6 @@ package kubecost
 import (
 	"bytes"
 	"fmt"
-	"math"
 	"sort"
 	"strings"
 	"sync"
@@ -80,11 +79,10 @@ type Allocation struct {
 // returning true for any given Allocation if a condition is met.
 type AllocationMatchFunc func(*Allocation) bool
 
-// AddAccumulate returns the result of combining the two given Allocations,
-// under the assumption that they refer to the same resource. Costs (and
-// similar fields) are summed, usage maximums are MAXED, and efficiency is
-// recomputed. Neither of the original Allocations are mutated.
-func (a *Allocation) AddAccumulate(that *Allocation) (*Allocation, error) {
+// Add returns the result of summing the two given Allocations, which sums the
+// summary fields (e.g. costs, resources) and recomputes efficiency. Neither of
+// the two original Allocations are mutated in the process.
+func (a *Allocation) Add(that *Allocation) (*Allocation, error) {
 	if a == nil {
 		return that.Clone(), nil
 	}
@@ -95,33 +93,7 @@ func (a *Allocation) AddAccumulate(that *Allocation) (*Allocation, error) {
 
 	// Note: no need to clone "that", as add only mutates the receiver
 	agg := a.Clone()
-	agg.add(that, accumulation)
-
-	return agg, nil
-}
-
-// AddAggregate returns the result of combining the two given Allocations,
-// under the assumption that they refer to different resources. The intended
-// usage is e.g. "aggregate containers by namespace" where the resulting
-// allocation ultimately refers to a greater number of resources than either
-// of the original Allocations. Most fields, including usage maximums, are
-// summed. Neither of the original allocations are mutated.
-//
-// To explain why usage maximums are summed, consider using this method for
-// aggregating by pod. The maximum CPU usage of a pod can be roughly equated
-// to the sum of the maximum CPU usages of its containers.
-func (a *Allocation) AddAggregate(that *Allocation) (*Allocation, error) {
-	if a == nil {
-		return that.Clone(), nil
-	}
-
-	if that == nil {
-		return a.Clone(), nil
-	}
-
-	// Note: no need to clone "that", as add only mutates the receiver
-	agg := a.Clone()
-	agg.add(that, aggregation)
+	agg.add(that)
 
 	return agg, nil
 }
@@ -393,21 +365,7 @@ func (a *Allocation) String() string {
 	return fmt.Sprintf("%s%s=%.2f", a.Name, NewWindow(&a.Start, &a.End), a.TotalCost())
 }
 
-// allocationCombinationType is an enum-like value for
-// flagging what mode an operation that combines allocations,
-// like add(), should operate in.
-//
-// Intentionally unexported - it should only be used by internal
-// methods. Exported methods should have a different variant,
-// like AddAccumulate and AddAggregate, for API clarity.
-type allocationCombinationType int
-
-const (
-	accumulation allocationCombinationType = iota
-	aggregation
-)
-
-func (a *Allocation) add(that *Allocation, addType allocationCombinationType) {
+func (a *Allocation) add(that *Allocation) {
 	if a == nil {
 		log.Warningf("Allocation.AggregateBy: trying to add a nil receiver")
 		return
@@ -489,19 +447,6 @@ func (a *Allocation) add(that *Allocation, addType allocationCombinationType) {
 	a.LoadBalancerCost += that.LoadBalancerCost
 	a.SharedCost += that.SharedCost
 	a.ExternalCost += that.ExternalCost
-
-	if addType == accumulation {
-		// Accumulation-type additions imply same resource, so the overall
-		// maximum is the correct resulting value.
-		a.CPUCoreUsageMax = math.Max(a.CPUCoreUsageMax, that.CPUCoreUsageMax)
-		a.RAMBytesUsageMax = math.Max(a.RAMBytesUsageMax, that.RAMBytesUsageMax)
-	} else if addType == aggregation {
-		// Aggregation-type additions imply different resources, same
-		// aggregation group, so the correct maximum is actually the sum
-		// of maxima.
-		a.CPUCoreUsageMax += that.CPUCoreUsageMax
-		a.RAMBytesUsageMax += that.RAMBytesUsageMax
-	}
 }
 
 // AllocationSet stores a set of Allocations, each with a unique name, that share
@@ -527,7 +472,7 @@ func NewAllocationSet(start, end time.Time, allocs ...*Allocation) *AllocationSe
 	}
 
 	for _, a := range allocs {
-		as.InsertAccumulate(a)
+		as.Insert(a)
 	}
 
 	return as
@@ -622,7 +567,7 @@ func (as *AllocationSet) AggregateBy(properties Properties, options *AllocationA
 		if alloc.IsExternal() {
 			delete(as.externalKeys, alloc.Name)
 			delete(as.allocations, alloc.Name)
-			externalSet.InsertAggregate(alloc)
+			externalSet.Insert(alloc)
 			continue
 		}
 
@@ -634,9 +579,9 @@ func (as *AllocationSet) AggregateBy(properties Properties, options *AllocationA
 			delete(as.allocations, alloc.Name)
 
 			if options.ShareIdle == ShareEven || options.ShareIdle == ShareWeighted {
-				idleSet.InsertAggregate(alloc)
+				idleSet.Insert(alloc)
 			} else {
-				aggSet.InsertAggregate(alloc)
+				aggSet.Insert(alloc)
 			}
 
 			continue
@@ -649,7 +594,7 @@ func (as *AllocationSet) AggregateBy(properties Properties, options *AllocationA
 			if sf(alloc) {
 				delete(as.idleKeys, alloc.Name)
 				delete(as.allocations, alloc.Name)
-				shareSet.InsertAggregate(alloc)
+				shareSet.Insert(alloc)
 				break
 			}
 		}
@@ -753,7 +698,7 @@ func (as *AllocationSet) AggregateBy(properties Properties, options *AllocationA
 
 			totalSharedCost := cost * hours
 
-			shareSet.InsertAggregate(&Allocation{
+			shareSet.Insert(&Allocation{
 				Name:       fmt.Sprintf("%s/%s", name, SharedSuffix),
 				Start:      as.Start(),
 				End:        as.End(),
@@ -855,7 +800,7 @@ func (as *AllocationSet) AggregateBy(properties Properties, options *AllocationA
 
 		// Inserting the allocation with the generated key for a name will
 		// perform the actual basic aggregation step.
-		aggSet.InsertAggregate(alloc)
+		aggSet.Insert(alloc)
 	}
 
 	// (6) If idle is shared and resources are shared, it's possible that some
@@ -982,7 +927,7 @@ func (as *AllocationSet) AggregateBy(properties Properties, options *AllocationA
 			key := alloc.generateKey(properties)
 
 			alloc.Name = key
-			aggSet.InsertAggregate(alloc)
+			aggSet.Insert(alloc)
 		}
 	}
 
@@ -991,7 +936,7 @@ func (as *AllocationSet) AggregateBy(properties Properties, options *AllocationA
 		for _, idleAlloc := range aggSet.IdleAllocations() {
 			aggSet.Delete(idleAlloc.Name)
 			idleAlloc.Name = IdleSuffix
-			aggSet.InsertAggregate(idleAlloc)
+			aggSet.Insert(idleAlloc)
 		}
 	}
 
@@ -1617,35 +1562,14 @@ func (as *AllocationSet) IdleAllocations() map[string]*Allocation {
 	return idles
 }
 
-// InsertAggregate aggregates the current entry in the AllocationSet by the given
-// Allocation, but only if the Allocation is valid, i.e. matches the AllocationSet's
-// window.
-// If there is no existing entry, one is created.
-// If there is an existing entry, the given Allocation is added to it using
-// aggregation logic, see Allocation.AddAggregate() for an explanation.
-// Nil error response indicates success.
-//
-// A good heuristic for whether you should use this method is:
-// Are you generating a new, less-specific key for a new Allocation from multiple
-// more specific Allocations?
-func (as *AllocationSet) InsertAggregate(that *Allocation) error {
-	return as.insert(that, aggregation)
-}
-
-// InsertAccumulate aggregates the current entry in the AllocationSet by the given
-// Allocation, but only if the Allocation is valid, i.e. matches the AllocationSet's
-// window.
-// If there is no existing entry, one is created.
-// If there is an existing entry, the given Allocation is added to it using
-// accumulation logic, see Allocation.AddAccumulate() for an explanation.
-// Nil error response indicates success.
-//
-// If you don't know which insert to use, this is a safe default.
-func (as *AllocationSet) InsertAccumulate(that *Allocation) error {
-	return as.insert(that, accumulation)
-}
-
-func (as *AllocationSet) insert(that *Allocation, combType allocationCombinationType) error {
+// Insert aggregates the current entry in the AllocationSet by the given Allocation,
+// but only if the Allocation is valid, i.e. matches the AllocationSet's window. If
+// there is no existing entry, one is created. Nil error response indicates success.
+func (as *AllocationSet) Insert(that *Allocation) error {
+	return as.insert(that)
+}
+
+func (as *AllocationSet) insert(that *Allocation) error {
 	if as == nil {
 		return fmt.Errorf("cannot insert into nil AllocationSet")
 	}
@@ -1670,7 +1594,7 @@ func (as *AllocationSet) insert(that *Allocation, combType allocationCombination
 	if _, ok := as.allocations[that.Name]; !ok {
 		as.allocations[that.Name] = that
 	} else {
-		as.allocations[that.Name].add(that, combType)
+		as.allocations[that.Name].add(that)
 	}
 
 	// If the given Allocation is an external one, record that
@@ -1831,14 +1755,14 @@ func (as *AllocationSet) accumulate(that *AllocationSet) (*AllocationSet, error)
 	defer that.RUnlock()
 
 	for _, alloc := range as.allocations {
-		err := acc.insert(alloc, accumulation)
+		err := acc.insert(alloc)
 		if err != nil {
 			return nil, err
 		}
 	}
 
 	for _, alloc := range that.allocations {
-		err := acc.insert(alloc, accumulation)
+		err := acc.insert(alloc)
 		if err != nil {
 			return nil, err
 		}
@@ -1982,7 +1906,7 @@ func (asr *AllocationSetRange) InsertRange(that *AllocationSetRange) error {
 
 		// Insert each Allocation from the given set
 		thatAS.Each(func(k string, alloc *Allocation) {
-			err = as.InsertAccumulate(alloc)
+			err = as.Insert(alloc)
 			if err != nil {
 				err = fmt.Errorf("error inserting allocation: %s", err)
 				return

+ 25 - 84
pkg/kubecost/allocation_test.go

@@ -69,59 +69,12 @@ func NewUnitAllocation(name string, start time.Time, resolution time.Duration, p
 	return alloc
 }
 
-// Because it is the standard case, the test for AddAccumulate is expected
-// to test all Add behavior except for Aggregate-specific behavior. This test
-// can therefore be somewhat minimal.
-func TestAllocation_AddAggregate(t *testing.T) {
-	s1 := time.Date(2021, time.January, 1, 0, 0, 0, 0, time.UTC)
-	e1 := time.Date(2021, time.January, 1, 12, 0, 0, 0, time.UTC)
-	gib := 1024.0 * 1024.0 * 1024.0
-	a1 := &Allocation{
-		Start:            s1,
-		End:              e1,
-		CPUCoreUsageMax:  3.1,
-		RAMBytesUsageMax: 5.0 * gib,
-	}
-	a1b := a1.Clone()
-
-	s2 := time.Date(2021, time.January, 1, 6, 0, 0, 0, time.UTC)
-	e2 := time.Date(2021, time.January, 1, 24, 0, 0, 0, time.UTC)
-	a2 := &Allocation{
-		Start:            s2,
-		End:              e2,
-		CPUCoreUsageMax:  1.2,
-		RAMBytesUsageMax: 10.0 * gib,
-	}
-	a2b := a2.Clone()
-
-	act, err := a1.AddAggregate(a2)
-	if err != nil {
-		t.Fatalf("Allocation.AddAggregate: unexpected error: %s", err)
-	}
-
-	// Neither Allocation should be mutated
-	if !a1.Equal(a1b) {
-		t.Fatalf("Allocation.AddAccumulate: a1 illegally mutated")
-	}
-	if !a2.Equal(a2b) {
-		t.Fatalf("Allocation.AddAccumulate: a1 illegally mutated")
-	}
-
-	// Usage maximums should be added in the aggregate case
-	if !util.IsApproximately(3.1+1.2, act.CPUCoreUsageMax) {
-		t.Errorf("Allocation.AddAggregate: CPUCoreUsageMax: expected %f; actual %f", 3.1+1.2, act.CPUCoreUsageMax)
-	}
-	if !util.IsApproximately(10.0*gib+5.0*gib, act.RAMBytesUsageMax) {
-		t.Errorf("Allocation.AddAggregate: RAMBytesUsageMax: expected %f; actual %f", 10.0*gib+5.0*gib, act.RAMBytesUsageMax)
-	}
-}
-
-func TestAllocation_AddAccumulate(t *testing.T) {
+func TestAllocation_Add(t *testing.T) {
 	var nilAlloc *Allocation
 	zeroAlloc := &Allocation{}
 
 	// nil + nil == nil
-	nilNilSum, err := nilAlloc.AddAccumulate(nilAlloc)
+	nilNilSum, err := nilAlloc.Add(nilAlloc)
 	if err != nil {
 		t.Fatalf("Allocation.Add unexpected error: %s", err)
 	}
@@ -130,7 +83,7 @@ func TestAllocation_AddAccumulate(t *testing.T) {
 	}
 
 	// nil + zero == zero
-	nilZeroSum, err := nilAlloc.AddAccumulate(zeroAlloc)
+	nilZeroSum, err := nilAlloc.Add(zeroAlloc)
 	if err != nil {
 		t.Fatalf("Allocation.Add unexpected error: %s", err)
 	}
@@ -153,7 +106,6 @@ func TestAllocation_AddAccumulate(t *testing.T) {
 		CPUCoreHours:           2.0 * hrs1,
 		CPUCoreRequestAverage:  2.0,
 		CPUCoreUsageAverage:    1.0,
-		CPUCoreUsageMax:        3.1,
 		CPUCost:                2.0 * hrs1 * cpuPrice,
 		GPUHours:               1.0 * hrs1,
 		GPUCost:                1.0 * hrs1 * gpuPrice,
@@ -162,7 +114,6 @@ func TestAllocation_AddAccumulate(t *testing.T) {
 		RAMByteHours:           8.0 * gib * hrs1,
 		RAMBytesRequestAverage: 8.0 * gib,
 		RAMBytesUsageAverage:   4.0 * gib,
-		RAMBytesUsageMax:       5.0 * gib,
 		RAMCost:                8.0 * hrs1 * ramPrice,
 		SharedCost:             2.00,
 		ExternalCost:           1.00,
@@ -178,7 +129,6 @@ func TestAllocation_AddAccumulate(t *testing.T) {
 		CPUCoreHours:           1.0 * hrs2,
 		CPUCoreRequestAverage:  1.0,
 		CPUCoreUsageAverage:    1.0,
-		CPUCoreUsageMax:        1.2,
 		CPUCost:                1.0 * hrs2 * cpuPrice,
 		GPUHours:               0.0,
 		GPUCost:                0.0,
@@ -187,7 +137,6 @@ func TestAllocation_AddAccumulate(t *testing.T) {
 		RAMByteHours:           8.0 * gib * hrs2,
 		RAMBytesRequestAverage: 0.0,
 		RAMBytesUsageAverage:   8.0 * gib,
-		RAMBytesUsageMax:       10.0 * gib,
 		RAMCost:                8.0 * hrs2 * ramPrice,
 		NetworkCost:            0.01,
 		LoadBalancerCost:       0.05,
@@ -196,65 +145,65 @@ func TestAllocation_AddAccumulate(t *testing.T) {
 	}
 	a2b := a2.Clone()
 
-	act, err := a1.AddAccumulate(a2)
+	act, err := a1.Add(a2)
 	if err != nil {
-		t.Fatalf("Allocation.AddAccumulate: unexpected error: %s", err)
+		t.Fatalf("Allocation.Add: unexpected error: %s", err)
 	}
 
 	// Neither Allocation should be mutated
 	if !a1.Equal(a1b) {
-		t.Fatalf("Allocation.AddAccumulate: a1 illegally mutated")
+		t.Fatalf("Allocation.Add: a1 illegally mutated")
 	}
 	if !a2.Equal(a2b) {
-		t.Fatalf("Allocation.AddAccumulate: a1 illegally mutated")
+		t.Fatalf("Allocation.Add: a1 illegally mutated")
 	}
 
 	// Costs should be cumulative
 	if !util.IsApproximately(a1.TotalCost()+a2.TotalCost(), act.TotalCost()) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", a1.TotalCost()+a2.TotalCost(), act.TotalCost())
+		t.Fatalf("Allocation.Add: expected %f; actual %f", a1.TotalCost()+a2.TotalCost(), act.TotalCost())
 	}
 	if !util.IsApproximately(a1.CPUCost+a2.CPUCost, act.CPUCost) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", a1.CPUCost+a2.CPUCost, act.CPUCost)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", a1.CPUCost+a2.CPUCost, act.CPUCost)
 	}
 	if !util.IsApproximately(a1.GPUCost+a2.GPUCost, act.GPUCost) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", a1.GPUCost+a2.GPUCost, act.GPUCost)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", a1.GPUCost+a2.GPUCost, act.GPUCost)
 	}
 	if !util.IsApproximately(a1.RAMCost+a2.RAMCost, act.RAMCost) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", a1.RAMCost+a2.RAMCost, act.RAMCost)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", a1.RAMCost+a2.RAMCost, act.RAMCost)
 	}
 	if !util.IsApproximately(a1.PVCost+a2.PVCost, act.PVCost) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", 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.AddAccumulate: 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.AddAccumulate: expected %f; actual %f", 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) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", a1.SharedCost+a2.SharedCost, act.SharedCost)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", a1.SharedCost+a2.SharedCost, act.SharedCost)
 	}
 	if !util.IsApproximately(a1.ExternalCost+a2.ExternalCost, act.ExternalCost) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", a1.ExternalCost+a2.ExternalCost, act.ExternalCost)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", a1.ExternalCost+a2.ExternalCost, act.ExternalCost)
 	}
 
 	// ResourceHours should be cumulative
 	if !util.IsApproximately(a1.CPUCoreHours+a2.CPUCoreHours, act.CPUCoreHours) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", a1.CPUCoreHours+a2.CPUCoreHours, act.CPUCoreHours)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", a1.CPUCoreHours+a2.CPUCoreHours, act.CPUCoreHours)
 	}
 	if !util.IsApproximately(a1.RAMByteHours+a2.RAMByteHours, act.RAMByteHours) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", 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.AddAccumulate: expected %f; actual %f", 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)
 	if !act.Start.Equal(a1.Start) || !act.End.Equal(a2.End) {
-		t.Fatalf("Allocation.AddAccumulate: expected %s; actual %s", NewWindow(&a1.Start, &a2.End), NewWindow(&act.Start, &act.End))
+		t.Fatalf("Allocation.Add: expected %s; actual %s", NewWindow(&a1.Start, &a2.End), NewWindow(&act.Start, &act.End))
 	}
 	if act.Minutes() != 1440.0 {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", 1440.0, act.Minutes())
+		t.Fatalf("Allocation.Add: expected %f; actual %f", 1440.0, act.Minutes())
 	}
 
 	// Requests and Usage should be averaged correctly
@@ -263,24 +212,16 @@ func TestAllocation_AddAccumulate(t *testing.T) {
 	// RAM requests = (8.0*12.0 + 0.0*18.0)/(24.0) = 4.00
 	// RAM usage = (4.0*12.0 + 8.0*18.0)/(24.0) = 8.00
 	if !util.IsApproximately(1.75, act.CPUCoreRequestAverage) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", 1.75, act.CPUCoreRequestAverage)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", 1.75, act.CPUCoreRequestAverage)
 	}
 	if !util.IsApproximately(1.25, act.CPUCoreUsageAverage) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", 1.25, act.CPUCoreUsageAverage)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", 1.25, act.CPUCoreUsageAverage)
 	}
 	if !util.IsApproximately(4.00*gib, act.RAMBytesRequestAverage) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", 4.00*gib, act.RAMBytesRequestAverage)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", 4.00*gib, act.RAMBytesRequestAverage)
 	}
 	if !util.IsApproximately(8.00*gib, act.RAMBytesUsageAverage) {
-		t.Fatalf("Allocation.AddAccumulate: expected %f; actual %f", 8.00*gib, act.RAMBytesUsageAverage)
-	}
-
-	// Usage maximums should be maxed in the accumulate case
-	if !util.IsApproximately(3.1, act.CPUCoreUsageMax) {
-		t.Errorf("Allocation.AddAccumulate: CPUCoreUsageMax: expected %f; actual %f", 3.1, act.CPUCoreUsageMax)
-	}
-	if !util.IsApproximately(10.0*gib, act.RAMBytesUsageMax) {
-		t.Errorf("Allocation.AddAccumulate: RAMBytesUsageMax: expected %f; actual %f", 10.0*gib, act.RAMBytesUsageMax)
+		t.Fatalf("Allocation.Add: expected %f; actual %f", 8.00*gib, act.RAMBytesUsageAverage)
 	}
 
 	// Efficiency should be computed accurately from new request/usage